「電子工作な日々」カテゴリーアーカイブ

電子工作に関連するお話など・・

RXマイコン、ポート・マップ・ピン情報を追加

ポート・マップ候補機能

  • C++フレームワークでは、各ペリフェラルを扱う場合、どのポートを選択するかを、簡潔に扱う為に、「ポート・マップ候補機能」を導入しています
  • 今まで、「候補」がどのポートを選択するかを知る為、各ソースコードを参照するようにとアナウンスしていました
  • それを、少しだけ便利にする為、単純に、候補とポートの関係を表にして、各MPUのルートにある、README.md ファイルに集約するようにしました
  • これは、ソースコードの修正とは、異なり、単なるドキュメントの更新なんだけど、分量がかなり多く、又、ピン番号も同時に記入してあるので、それなりに大掛かりな作業でした
  • ピン番号は、良く使うであろう、パッケージだけに絞り、(例えば、64 ピン、100 ピン、144 ピンなど)全てを網羅している訳では無いのだけど・・・
  • パッケージとピン番号の正確性は、ミスもあるかと思うので、実際に配線する前に確認が必要です

各CPUの特徴とリンクなど

現在サポートされ、動作確認済みデバイス:

シリーズ MinV MaxV MHz コア FPU TFU DFPU 動作確認 rx_prog リンカーファイル
RX110 1.8 3.6 32 RXv1 R5F51103/4/5
RX111 1.8 3.6 32 RXv1 R5F51115/6/7
RX113 1.8 3.6 32 RXv1 R5F51136/8
RX130 1.8 5.5 32 RXv1 R5F51305/6
RX140 1.8 5.5 48 RXv2 Yes R5F51403/5/6
RX13T 2.7 5.5 32 RXv1 Yes R5F513T3/5
RX210 1.62 5.5 32 RXv1 R5F52108/B
RX220 1.62 5.5 32 RXv1 R5F52206
RX231 1.8 5.5 54 RXv2 Yes R5F52316/7/8
RX23T 2.7 5.5 40 RXv2 Yes R5F523T5
RX24T 2.7 5.5 80 RXv2 Yes R5F524T8/A
RX24U 2.7 5.5 80 RXv2 Yes R5F524UB/E
RX261 1.6 5.5 64 RXv3 Yes R5F52618
RX26T 2.7 5.5 120 RXv3 Yes V2 R5F526TF
RX621 2.7 3.6 100 RXv1 Yes R5F56218
RX62N 2.7 3.6 100 RXv1 Yes R5F562N7/8
RX631 2.7 3.6 100 RXv1 Yes R5F5631F
RX63N 2.7 3.6 100 RXv1 Yes R5F563NE
RX63T 3.3 5 100 RXv1 Yes R5F563T6
RX64M 2.7 3.6 120 RXv2 Yes R5F564MF/G/J/L
RX71M 2.7 3.6 240 RXv2 Yes R5F571MF/G/J/L
RX651 2.7 3.6 120 RXv2 Yes R5F5651E
RX65N 2.7 3.6 120 RXv2 Yes R5F565NE
RX66N 2.7 3.6 120 RXv3 Yes V1 Yes R5F566ND/N
RX660 2.7 5.5 120 RXv3 Yes R5F56609
RX671 2.7 5.5 120 RXv3 Yes R5F5671C/E
RX72N 2.7 3.6 240 RXv3 Yes V1 Yes R5F572ND/N
RX72M 2.7 3.6 240 RXv3 Yes V1 Yes R5F572MD/N
RX66T 2.7 5.5 160 RXv3 Yes R5F566TA/E/F/K
RX72T 2.7 5.5 200 RXv3 Yes V1 R5F572TF/K

基本的な候補の使い方など

「候補」は以下のようになっています:

    enum class ORDER : uint8_t {
        BYPASS,         ///< ポートマップの設定をバイパスする場合

        FIRST,          ///< 第1候補
        SECOND,         ///< 第2候補
        THIRD,          ///< 第3候補
        FOURTH,         ///< 第4候補
        FIFTH,          ///< 第5候補
        SIXTH,          ///< 第6候補
        SEVENTH,        ///< 第7候補
        EIGHTH,         ///< 第8候補
        NINTH,          ///< 第9候補
        TENTH,          ///< 第10候補
        ELEVENTH,       ///< 第11候補
        TWELVETH,       ///< 第12候補

        USER,           ///< ユーザー設定

        LOCAL0,         ///< 独自の特殊な設定0
        LOCAL1,         ///< 独自の特殊な設定1
    };
  • 現在、ポート候補は、グループ設定の場合と、単独ポートの場合が混在しています
  • たとえば、SCI、CAN、RSPI、IICA などはグループ指定、MTU、TPU、GPT、GPTW、QSPI などは単独で指定可能になっています
  • なので、SCI などで、グループを超えて設定(TXD を FIRST、RXD を SECOND みたいな)事は出来ないです
  • グループ指定は、複数あるポートを一括して行うものです
  • 一般的に、グループ候補の場合、近接するポートを選んでいるので、通常それで困る場合は無いと思います
  • 急遽、ペリフェラルの機能が必要になり、余っているポートをかき集めたり、改造を最小限にする為に、異なる候補を選択するしか無い場合はあるかと思います
  • そのような場合は、「USER」設定を使って、独自に設定する必要があります

SCI ポート候補の選択例

  • 例として RX231、LFQFP64 パッケージの場合
  • SCI5 を使いたい場合

Github RX231 ルート

Port map order / ポートマップ候補

LFQFP64

Peripheral FIRST SECOND THIRD FOURTH
SCI5 / RXD PA2 (--) PA3 (43) PC2 (32) PC2 (32)
SCI5 / TXD PA4 (42) PA4 (42) PC3 (31) PC3 (31)

候補の選択と管理

  • 「Port map order / ポートマップ候補、LFQFP64」の表から、「SCI5 / RXD, SCI5 / TXD」の欄を見ます
  • 実際のハードを吟味して、SECOND の RXD/PA3 (43)、TXD/PA4 (42) が使えそうと判断します
  • SCI の入出力では、「sci_io.hpp」のテンプレートクラスを使います
  • 以下のコードのように、「SECOND」を指定して、sci_io のテンプレートを typedef して型を定義します
  • それの実態を定義して、初期化するだけで、使えるようになります
  • new しても構いませんが、固定されたハードウェアーで、動的にクラスを生成する必要性が無いので、static に宣言します
  • 出来るだけ、new を使わない方法を選択する事が寛容です
  • static に宣言すれば、必要なメモリは、C++ コンパイラが適切に領域を設定して配置してくれます
  • C++ では、static と宣言しても良いのですが、main 関数があるソースに、無名の名前空間で囲んで定義するのが一般的です
  • sci_io クラスでは、定義に、受信、送信バッファの型を伴って定義します
  • バッファは、固定長のリングバッファを使います、「fixed_fifo」テンプレートクラス
  • 以下の例では、それぞれ、512 バイト、256 バイトの大きさで定義しています
#include "common/renesas.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"

namespace {
    typedef utils::fixed_fifo<char, 512> RXB;  // RX (受信) バッファの定義
    typedef utils::fixed_fifo<char, 256> TXB;  // TX (送信) バッファの定義
    typedef device::sci_io<device::SCI5, RXB, TXB, device::port_map_order::SECOND> SCI5_IO;

    SCI5_IO sci5_io_;
}
  • もし、あーやっぱり、「RXD/PA3 (43)、TXD/PA4 (42)」じゃなく、「RXD/PC2 (32)、TXD/PC3 (31)」の方が、都合が良いとなれば
  • 候補を、「SECOND」から「THIRD」にするだけです
  • 他は変更する必要がありません
    typedef device::sci_io<device::SCI5, RXB, TXB, device::port_map_order::THIRD> SCI5_IO;

標準入出力の設定

  • 一般的な gcc を使った、組み込みアプリケーションでは、標準入出力とのインターフェースを設定する必要があります
  • この C++ フレームワークでは、syscall.c をリンクする事で、インターフェースを有効にする事が出来ます
  • SCI5 のインスタンスをこの標準入出力と繋げる場合、以下のように定義します
extern "C" {

    // syscalls.c から呼ばれる、標準出力(stdout, stderr)
    void sci_putch(char ch)
    {
        sci5_io_.putch(ch);
    }

    void sci_puts(const char* str)
    {
        sci5_io_.puts(str);
    }

    // syscalls.c から呼ばれる、標準入力(stdin)
    char sci_getch(void)
    {
        return sci5_io_.getch();
    }

    uint16_t sci_length()
    {
        return sci5_io_.recv_length();
    }
}
  • この定義で、SCI5 での入出力は、標準入出力とリンクされます
  • printf や scanf などで入出力を行えます
  • C++ では、C 言語の関数は使わないので、format クラス、input クラスの用意があります

初期化

  • SCI の初期化は簡単で、ボーレート、割り込みレベル、プロトコルを選択するだけです
// 起動時、1度行って、マスタークロックをブーストして下さい
    SYSTEM_IO::boost_master_clock();

    {  // SCI の開始
        constexpr uint32_t baud = 115200;  // ボーレート(任意の整数値を指定可能)
        static_assert(SCI5_IO::probe_baud(baud), "Failed baud rate accuracy test");  // 許容誤差(3%)を超える場合、コンパイルエラー
        auto intr = device::ICU::LEVEL::_2;     // 割り込みレベル(NONE を指定すると、ポーリング動作になる)
        if(!sci5_io_.start(baud, intr)) {  // 標準では、8ビット、1ストップビットを自動選択
            halt_();
        }
// 通信プロトコルを設定する場合は、通信プロトコルのタイプを指定する事が出来る。
// sci_io.hpp PROTOCOL enum class のタイプを参照
//      sci_.start(baud, intr, SCI::PROTOCOL::B8_E_1S);
    }
  • これで、入出力が行える準備が整います
  • 後は、標準入出力を使って、データ通信を行います
    {  // SCI の設定レポート表示
        utils::format("SCI5 PCLK: %u [Hz]\n") % SCI5_IO::sci_type::PCLK;
        utils::format("SCI5 Baud rate (set): %u [BPS]\n") % sci5_io_.get_baud_rate();
        float rate = 1.0f - static_cast<float>(sci5_io_.get_baud_rate()) / sci5_io_.get_baud_rate(true);
        rate *= 100.0f;
        utils::format("  Baud rate (real): %u (%3.2f [%%])\n") % sci5_io_.get_baud_rate(true) % rate;
        utils::format("  SEMR_BRME: %s\n") % utils::str::get_bool_text(SCI5_IO::sci_type::SEMR_BRME);
        utils::format("  SEMR_BGDM: %s\n") % utils::str::get_bool_text(SCI5_IO::sci_type::SEMR_BGDM);
    }

独自ポート設定(ORDER::USER)

  • 以下の例は、候補として「USER」を行う場合の方法です
  • SCI5: TXD/PA3, RXD/PC3 を利用する例です
  • この設定は、初期化 (sci5io.start) を行う前に設定する必要があります(初期化時に、設定された関数が呼ばれます)
  • 又、C++ のランタイムをリンクする必要があります(Makefile に supc++ ライブラリを追加してください)
  • 独自設定の場合、特別なレジスター郡へのアクセスがあるので、独自関数が呼ばれる前に、書き込み保護が解除された状態になっています
    typedef device::sci_io<device::SCI5, RXB, TXB, device::port_map_order::USER> SCI5_IO;
        device::port_map::set_user_func( [=](device::peripheral per, bool ena) {
            // SCI5: TXD/PA3, RXD/PC3 の場合
            using namespace device;

            // セレクターのビット列は、MPC の解説を参照して下さい
            uint8_t sel = ena ? 0b0'1010 : 0;
            MPC::PA3PFS.PSEL = sel;
            PORTA::PMR.B3 = ena;
            MPC::PC3PFS.PSEL = sel;
            PORTC::PMR.B3 = ena;

            return true;
        }
        );

Makefile への C++ ランタイムライブラリの追加:

USER_LIBS   =   supc++
  • この例ではラムダ式を使って簡潔に行っています
  • 詳しくは、「std::function ラムダ式」などで検索して、使い方を参照して下さい
  • これらのサンプルは、「SCI_sample/main.cpp」に具体的なコードが示されていますので参考にしてください
  • ポートの機能設定は、ハードウェアーマニュアルの MPC の解説を参照して下さい
  • MPC に、機能を設定するビット列には特別な意味があります、間違えると、正しく動作しません
  • ポートの独自設定は、設定を合格とする為「true」で戻る必要があります

まとめ

  • 今回の更新は、ドキュメントの追加程度ですが、github に色々な情報を集約するのに都合が良いものでした
  • マークダウンの表は、そこそこ見やすいものなので、多少利便性が向上したものと思います
  • 又、ポートマップの仕組み、具体的な独自設定の方法などをさらに詳しく示しました

リンカースクリプトを更新、そして元に戻す

やらかした・・・

良かれと思って行った修正が、実は、良く無かった事は良くある事とはいえ、今回は久しぶりにやらかした・・・

リンカースクリプトを更新

以前のリンカースクリプトは、gcc-6.4.0 位の物で、現在メインに利用している gcc-8.3.0 の物より若干古い。
そこで、8.3.0 ベースの物に全て更新した。

独自の記述もあるので、多少切り貼りをしているものの、基本は同じものと思う。


RAYTRACER_sample を動かして気がついた・・・

リンカースクリプトを更新して、全てでは無いものの、いくつかのソフトを動かして、まぁちゃんと動いているなぁーと確認して、全てコミットした。
全 RX マイコンのリンカースクリプトなので、それなりのファイル数となっている。

ところが、「RAYTRACER_sample」で奇妙な動作をしている事に気がついた。

    bool        run_ = false;
    int         sampling_ = 1;
    int         render_width_  = 320;
    int         render_height_ = 240;

このコードは、main.cpp 無地の namespace でくくられている部分で、起動時に、ROM 領域から、コピーされる。

ところが、renderheight が、「0」になっていて、起動時にこのパラメータでレンダリングするのだが、それが原因で奇妙な動作になる・・・

初期値が正しくコピーされていない。

以前は、正しく動いていたと思えるので、どうやら、リンカースクリプトが怪しい事と思い、以前のリンカースクリプトに戻してみた。
すると、この問題が解消された。

うーーん、これはヤバイなぁーと、リンカースクリプトの更新時のすり合わせを行った。

異なる部分

gcc-8.3.0 の rx.ld では、C++ のインスタンスを初期化するルーチンのリスト「ctor」は ROM 領域にのみ配置されている。

 .init :
  {
   KEEP (*(.init))
   __preinit_array_start = .;
   KEEP (*(.preinit_array))
   __preinit_array_end = .;
   __init_array_start = (. + 3) & ~ 3;
   KEEP (*(.init_array))
   KEEP (*(SORT(.init_array.*)))
   __init_array_end = .;
   __fini_array_start = .;
   KEEP (*(.fini_array))
   KEEP (*(SORT(.fini_array.*)))
   __fini_array_end = .;
   } > ROM

一方、gcc-6.4.0 では、data 領域に配置されており、起動時に、ROM 領域から RAM にコピーされて利用される。

  .data : {
    . = ALIGN(4);
    PROVIDE (__datastart = .); /* IF_ROROM */
    PROVIDE (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE (__preinit_array_end = .);
    PROVIDE (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array))
    PROVIDE (__init_array_end = .);
    PROVIDE (__fini_array_start = .);
    KEEP (*(.fini_array))
    KEEP (*(SORT(.fini_array.*)))
    PROVIDE (__fini_array_end = .);
    LONG(0); /* Sentinel.  */

...

    . = ALIGN(4);
    _edata = .;
    PROVIDE (edata = .);
    PROVIDE (__dataend = .);
  } > RAM AT> ROM

この関数リストは、起動時、わざわざ RAM にコピーするのは無駄なので、ROM 領域だけに配置する事は、メモリを節約する意味もあり、意味があると思える。
ただ、これを元に戻すと、正しく動作しなくなる・・・

不思議なのだが、gcc-8.3.0 だと、data 領域は 2168 バイトとなっている。

rx-elf-size raytracer_sample.elf
   text    data     bss     dec     hex filename
  51244    2168    8120   61532    f05c raytracer_sample.elf

ところが、gcc-6.4.0 だと、data 領域は 48 バイトと少なくなっている

rx-elf-size raytracer_sample.elf
   text    data     bss     dec     hex filename
  53364      48    8120   61532    f05c raytracer_sample.elf

text 領域の 2120 バイト分が data 領域に移動している?

何故、こうなるのか、さっぱり判らない・・・

結局、元に戻すしか無いのかもしれないが、直すファイル数がとてつもなく多い・・・うーーーん・・・
しかし、原因が判らないので、とりあえず、元に戻してコミットしなおした。


FPU の無い RX220 で RAYTRACER_sample を走らせたら、劇遅かったw

RX220 でも走らせた、最初、何か止まるなぁー、何が悪いの?
と、色々調べたらー、単に遅いだけだったw

# render
Render time: 291320ms (1)

「291秒」・・・
48MHz の RX140 では 1.8 秒なのを考えると、劇遅・・・
動作周波数が 32MHz と少し遅い事もあるけど、FPU が無いと 100 倍以上遅い、こんだけハンディになるのかー、まぁ、それはそうだけど、これは厳しいよなぁー・・・

やっぱ、FPU が無いマイコンは使う価値が薄いとつくづく実感するー

RX マイコンの場合、FPU の有る無しで、コストがそんなに変わらない場合もあり、浮動小数点を扱わないアプリなら別だけど、逆説的に、FPU を搭載していない RX マイコンを選択する理由が無いように思える。

シェーバーの充電池を何とかする

充電池が消耗してる・・・

最近、充電しても、直ぐに電池切れになる。
このシェーバーは3年前くらいに買ったもの。
自分は、そんなに髭が濃い方では無いので、そんなに使用頻度は多く無いと思うが、1日でそれなりに伸びる。
多い時で、1日1回は使うかも・・・
外出しない場合や、忘れていると、使わない事もある。

現在の状況は、満充電になって1回使うと、次の日には電池切れになる。
充電は、8時間くらいはかかり、使いたい時に使えないのはストレスが溜まる。
又、このシェーバーは、充電アダプタを挿しても、満充電にならないと使う事が出来ない。


とりあえず、新品は注文した

まぁ、2~3年で買い替えしてもらわないと、メーカーにしてみれば商売にならないだろうと思う。

以前はamazonで買ったが、値段を観ると1万超えで、えーーー高いってなって、ビックカメラを観たら8千円くらいだったので、納得はしなかったが、ビックで注文した。
※前買った時は5000円くらいだと思ったけどなぁー
※替え刃だけでも3000円くらいのコスト

ただ、とりあえず、ヘッドや刃は問題なく、動けば、使えるので、分解してみた。


分解するー

分解は、非常にトリッキーで、爪を折らないように慎重に行った。
けっこう難儀したー

最初は、充電池を交換して、使えるようにしようかとも思ったが、タブ付き充電池(ニッケル水素充電池)を買う必要もあり、外部に「直」にエネループを接続すれば良いのでは?
と思い、配線を加工する事にした。

充電コネクタ周辺のラインをカットして、そこから直に、充電池の端子に接続した。

充電アダプタのケーブルを切り、単三2本の電池ボックスを接続した。


動かない・・・

電源ボタンを「ON」にするー
オレンジのLEDが点滅して、言う事を聞かない・・・

色々調べたら、どうも、内部の充電池マネージメントが働き、外部電源から充電を行い、正常な状態に初期化しないと、モーターを起動しないようだった
まぁ、安全装置と言えば聞こえが良いが、魔改造を受け付けない合理的な機構なのだろうと思う。
そもそも、充電に8時間とかかかるのが、おかしいよなぁーと思う。


こうなったらダイレクトにモーターに接続

基板の写真を撮らなかったが、結局、外部端子からのラインをモーターに直接接続して強制的に動かしたw

ちょっと、スマートとは言えない結果にはなったが、とりあえず、使えるので良しとするw
それに、新品も買ったしねw

次、充電池が消耗したら、魔改造で使い倒す!w
※同じシェーバーを持っている人は、今回の記事を参考にしてもらいたいw

RXマイコンサポート(RX110、RX111、RX113)と、データフラッシュの操作系見直し

RX110, RX111, RX113 などをサポート

RX マイコン C++ フレームワークでは、なるべく多くの品種をサポートするべく作業を行っている。

これらの RX マイコンは、現行品で、比較的低価格のマイコンとなっている。
FPU が無いとか、5V で動かせない(1.8~3.6V)とか、色々と制限があるものの、特定の分野なら十分な能力があると思う。
動作周波数は 32MHz だが、8/16 ビット系に比べて、扱い易く、高性能だと思える。

  • FPU はアプリケーションによっては、無い事が不利益にならない場合がある
  • 32 ビット CPU なので、バンクを気にする必要が無く、プログラムの実装は、非常にやりやすいと思う
  • それでいて、十分低消費電力であり、コストパフォーマンスも良い
  • 必要十分なペリフェラル(MTU, RTC, SCI, I2C, RSPI)を内蔵しており、通常の用途では十分と思える
  • USB、LCD、静電タッチ機能を使える物など、そこそこバリエーションがある
  • 基本的に RX マイコンのリソースを再利用出来る

サポートと言っても、以前のリソースを集めたり、定義を少し書くだけなので、そんなに大げさなものでは無い。
ただ、デバイスを入手して、実験していないので、ちゃんと動作するかは判らない、近々にデバイスを入手して、簡単なテストは行いたい。

  • ROM 容量が 64K 以上ある RX140 が安価に入手出来れば良いのだが、チップワンストップには在庫が確認出来ない
  • ROM 容量が大きい RX140、海外の販売サイトには在庫があるようだが、単価が高いので、RX231とかの方が良いかもしれない
  • 上記 RX100 系は、動作電圧範囲が狭いので、A/D を使う場合に、ダイナミックレンジが狭く、色々と制限が多いのは、マイナスポイント
  • 当然、電源電圧が低いと、ノイズ耐性にも影響があるものと思う

チップワンストップ:

RX110: 64LQFP, RXv1, 32MHz, Code: 32K, RAM: 10K, DataFlash: 0K, R5F51101ADFM
1個:256円
10個:@190円
RX110 Github

RX111: 64LQFP, RXv1, 32MHz, USB2.0, Code: 128K, RAM: 16K, DataFlash: 8K, R5F51115ADFM
1個:368円
10個:@234円
RX111 Github

RX113: 64LQFP, RXv1, 32MHz, USB2.0, Code: 512K, RAM: 64K, DataFlash: 8K, R5F51138ADFM
1個:630円
10個:@483円
RX113 Github


データフラッシュの操作

今まで、RX64M 系、RX24T 系のデータフラッシュの操作は、実装して、試していたが、それとは異なる系統の場合、実装されていなかった。
構成が異なり、シーケンスも微妙に異なるグループがある。
これは、デバイスにより、内蔵フラッシュメモリの構造や特性が異なるのが要因と思う。
このデータフラッシュ操作は、RX220/RX621/RX62N/RX631/RX63N など、古いタイプの RX マイコンなのもある。
しかし、RX26T が、このグループに近い操作系となっており、ついでにサポートして実験した。

  • 消去は基本、バンク単位で行う
  • 1バイト単位で書き込め、消去後の値が 0xFF の場合、多分従来型の EEPROM に近いものと思う
    - 消去後の値が未定の場合は、新しいタイプ(E2?)のフラッシュメモリとなっている
CPU 容量 バンクサイズ 書き込み単位 消去後の値 ユニークID数
RX140 4K 256 1 0xFF 4
RX220 8K 2048 2 0x?? 4
RX231 8K 1024 1 0xFF 4
RX24T 8K 1024 1 0xFF 4
RX26T 16K 64 4 0x?? 3
RX62N 32K 2048 8 0x?? 0
RX631 32K 2048 4 0x?? 4
RX64M 64K 64 4 0x?? 3
RX71M 64K 64 4 0x?? 3
RX65N 32K 64 4 0x?? 4
RX72N 32K 64 4 0x?? 4
RX66T 32K 64 4 0x?? 3
RX72T 32K 64 4 0x?? 3

FLASH_sample: 各プロジェクト、データフラュシュ操作クラス、アプリケーションの動作確認

Project File flash_io 動作確認
RX140/Makefile RX24T/flash_io.hpp
RX220/Makefile RX62x/flash_io.hpp
RX231/Makefile RX24T/flash_io.hpp
RX24T/Makefile RX24T/flash_io.hpp
RX26T/Makefile RX62x/flash_io.hpp
RX62N/Makefile RX62x/flash_io.hpp
RX631/Makefile RX62x/flash_io.hpp
RX64M/Makefile RX600/flash_io.hpp
RX71M/Makefile RX600/flash_io.hpp
RX65N/Makefile RX600/flash_io.hpp
RX72N/Makefile RX600/flash_io.hpp
RX66T/Makefile RX600/flash_io.hpp
RX72T/Makefile RX600/flash_io.hpp

RX220/RX26T/RX62[1N]/RX63[1N] などサポート

これらグループは、ほぼ同じ操作系なのだが、微妙に異なる部分もあり、やりたくは無かったが、「#if defined(xxx)」でより分けている。
多少工夫すると、無くせなくも無いが、コードの見通しがもっと悪くなると思ったのもあって、とりあえず、制御文で別けている。

RX26T は、ほぼ同じとは言え、構成も異なるので、ソースを別けた方が良いかもしれないが、同じようなコードをコピペする事になる、コピー元を変更したら、コピー先に反映させなければならないしで、どうしたものか・・・
※まぁ、機能違いは、継承させて、分離する方が良いかもしれないが、それも複雑になるし、一長一短ではある・・・

  • RX62[1N]、RX63[1N]は、ファームの転送が必要
  • RX26T は、FACI コマンド発行アドレスが異なる
  • RX26T は、データフラッシュ操作アドレス用に、専用のレジスタがあり、適切な値を設定する必要がある
  • それぞれ、書き込みサイズ、バンクサイズ等が異なる場合があり、FLASH レジスタークラスで定義を行って、flash_io クラスからは参照するようにしている

まとめ

Start Data Flash sample for 'RX62N FRK-RX62N' 96 [MHz]
Flash drive clock: 48 [MHz]
Data Flash total size: 0x00008000
Data Flash block size: 2048 bytes
Data Flash word size: 8 byte
# check 2
Erase check: bank 2: 0x1000 to 0x17FF OK
# write 1000 123456789abcdef0 fa926534bcdea021
# r 1000 100f
0x1000: 123456789ABCDEF0 FA926534BCDEA021
# check 2
Erase check: bank 2: 0x1000 to 0x17FF NG
# erase 2
Erase OK: bank 2, 0x1000 to 0x17FF
# check 2
Erase check: bank 2: 0x1000 to 0x17FF OK
# r 1000 100f
0x1000: 1274567892BCDEF0 FA926514BCDEA021
#
  • RX220 は、RX62[1N]/RX63[1N] この系列なのだが、動作確認で失敗し、原因を調査・・・
  • RX220 は ROM ブロック領域の説明も実際と異なっている
  • データフラッシュのバンクサイズも128バイト、2048バイトと説明が2つあり、どちらが正解なのか判らない
  • 多分 2048 バイトだと思う
  • RX220 は保守外の品種なので、どうかと思うが、一応、ルネサスに質問しておこうと思う
  • RX220 のフラッシュ操作が動かない理由は、判ったー
  • FCU クロック通知を、データ領域では無く、コード領域に行う必要がある・・・
  • 「フラッシュ P/E モードエントリレジスタ(FENTRYR)」のアドレスがタイポしていた・・・
  • レジスタアドレスは、構成が同等の RX マイコンでも、微妙に異なっている場合がある・・・
  • それを修正して動作するようになった!(確認したつもりだったが・・・)
  • 消去後のデータが不定だと、消去されているか不明なので、ワード単位の消去チェックや消去操作が必要となる
  • これは、今後ワード単位の API を追加する(RX64M 系も同じように追加が必要)

RX C++ フレームワーク、RX261 サポート

RX260/RX261 が発売された

ルネサス社は、RXマイコンの新シリーズ、RX260/RX261 を発売した。

https://www.nikkei.com/article/DGXZRSP680552_S4A021C2000000/

チップワンストップでの価格は、以下(現在、1品種しか確認していない)

RX261 100QFP, ROM: 512K, RAM: 128K, DataFlash: 8K

  • R5F52618BGFP#70 @852、10個時 @621

※RX260 は、RX261 から、CANFD、USB、セキリティ関係IP を省いたタイプのようだ
※セキリティ関係IPは、ルネサス社との特別な契約により、内容が公開されるようだ


主な特徴

  • RXv3 コア
  • 最大動作周波数 64MHz
  • 32 ビット単精度浮動小数点
  • 1.6V ~ 5.5V 動作
  • 高速動作モード:84 µA/MHz
  • CAN FD Module (CANFD)
  • USB2.0 Full Speed, Host, Function
  • 12ビットA/D変換器
  • 8ビットD/A変換器

このシリーズ、RX26T の系統なのかと思ったけど、RXv3 コアにして、低消費電力化を図り、RX140、RX231、のリソースを統合したような CPU で、USB が使える事は良いものの、SSIE、SDHI が省かれるなど、単純に RX231 を代替えする事が出来ないのが少し勿体ないと思う。
※RX231 の代わりが出来てしまうと、RX231 が存在する理由が無くなってしまう・・、D/A も 8 Bits だし・・・

RX231 の 54MHz に比べて、64MHz は少しだけ速くなったが、微妙な感じ。

それでも、C++ フレームワークではサポートファイルを用意して、とりあえず、使えるようにしておいた。(コミット済)

  • RX140、RX231 のペリフェラルと同等の部分が多いので、新規に作成したファイルは少ない為、労力は少なかった。
  • クロック構成が多少特殊なので、それらのファイルは新規に用意した。
  • ただ、まだ実際にデバイスを入手していないので、動作確認をしていないのだけど・・・

この CPU 割り込みが、全て標準ベクタにアサインされていて、選択型や、グループ割り込みが無い設計になっている。


CANFD のドライバーを、本格的に用意したい

このデバイス、CANFD を搭載しているので、自動用途にも向いているように思う、しかも電気を食わない。
現状 CANFD のドライバーを実装していないので、それも早々に用意したい処だ・・


まとめ

新しいシリアルコミュニケーション RSCI も搭載している、これは、他で展開する(ARM、RISC-V)新しいもので、それらと共通の仕様となっているようだ。
※CANFD もそのようだ・・
とりあえず、ドライバーは用意してある(まだ、ちゃんとした動作確認はしていない)

値段もそこそこ安いし、色々使えそうなので、早急にチップを購入して実験してみたい。

rx_prog の更新

Renesas RX Series Programmer Version 1.90
Copyright (C) 2016, 2024 Hiramatsu Kunihito (hira@rvf-rc45.net)
usage:
rx_prog [options] [mot file] ...

Options :
    -P PORT,   --port=PORT     Specify serial port
    -s SPEED,  --speed=SPEED   Specify serial speed
    -d DEVICE, --device=DEVICE Specify device name
    -e, --erase                Perform a device erase to a minimum
    --id=ID[:,]ID[:,] ...      Specify protect ID (16 bytes)
    -r, --read                 Perform data read
    -v, --verify               Perform data verify
    -w, --write                Perform data write
    --progress                 display Progress output
    --erase-page-wait=WAIT     Delay per read page  (2000) [uS]
    --write-page-wait=WAIT     Delay per write page (5000) [uS]
    --device-list              Display device list
    --verbose                  Verbose output
    -h, --help                 Display this

rx_prog の歴史的背景

RX マイコンのフラッシュ書き換えに、独自に実装したプログラムを保守、管理している。

「Renesas Flash Programmer」があるのに、何故?と思われるかもしれないが、歴史的な背景がある。

最初は、コマンドラインから動かせるとか、マルチプラットホーム(Windows,Linux,OS-X)とか、色々な理由があって、少しづつ機能追加していって、現在の姿になっている。

R8C/M120AN マイコン用のフラッシュプログラマーを実装したのもあって、「RX マイコン用も欲しいなぁー」と単純に思ったのも要因としてある。
なので、同じように使えるような仕様にしてある。

自分は、どうも GUI の操作が面倒だと感じる、複数のマイコンを試す場合など、R.F.P.では、プロジェクトを開き直す必要がある。

又、マルチプラットホームで動作するようにしてあるので、個々に専用の設定キーがあったり、色々な環境で使い回すのに都合が良いように工夫してある。

ただ、現状、機能的には完全では無い。


RX26T のサポート

RX26T は、今までの RX マイコンと異なり、書き込むページサイズが 128 バイトとなっている。
※以前は 256 バイト

その仕様に伴い、細かく色々変更したものの、何故か、書き込みに失敗する不具合があり、長い間、ほったらかしていた・・

丁度良い機会だったので、不具合の原因を調べてみたー
ところが、中々原因が掴めない。

結局、「erase_page」にバグがあり、それが引き金となり、ちゃんと消去されていない為、書き込みに失敗する事が判った。
この原因を見つけるのに、かなり時間を使ってしまったが、ちゃんと動作するのは嬉しいのものだー

これで、手持ちの RX マイコンは全て、サポートして、動作実績がある事になる!
※RX65x は、ボードを作って無いので、試せていないが・・・


RX220 の erase_page で不具合

RX220 は、ID コードプロテクトをしていない状態だと、ブートモードでデバイスと接続して、P/E モードに入ると、自動でフラッシュを消去してくれる機能がある。
※P/E モード: プログラム、イレース モード
※このような仕様は、RX220 に限らず、RX24T、RX63T など、少し古いデバイスでは、そのようになっている場合がある。
※その為、「erase_page」の機能をちゃんと実装していなかった。

又、消去されている、されていないに限らず、必ず「消去」コマンドを発行する事で、プログラムの書き込みに関する手順を一般化出来るので、消去の機能を省くのは良くない。

今回、そのケアも行った。
ただ、古い、RX マイコンでは、フラッシュのプログラミングプロトコルが、あまり洗練されていない事がある。

RX220 のハードウェアーマニュアルを読み、「erase_page」の実装を行い、実験すると、エラーで消去出来ない。

エラーのステータスを調べると、「ブロック番号エラー」となっている。

「ブロック番号」とは、RX220 の解説によると、2K バイト単位で、128 ブロックあると書かれている。(256K品)
※「36.4 ブロック構成」

ところが、この仕様に沿って、適切なブロック番号を渡しても、エラーとなる・・

そもそも、ブロック単位が 2K バイトって「変」だよな・・と思って、デバイスの接続時に、取得するエリア情報を観てみたー

#01/26: Area: FFFFF000, FFFFFFFF
#02/26: Area: FFFFE000, FFFFEFFF
#03/26: Area: FFFFD000, FFFFDFFF
#04/26: Area: FFFFC000, FFFFCFFF
#05/26: Area: FFFFB000, FFFFBFFF
#06/26: Area: FFFFA000, FFFFAFFF
#07/26: Area: FFFF9000, FFFF9FFF
#08/26: Area: FFFF8000, FFFF8FFF
#09/26: Area: FFFF4000, FFFF7FFF
#10/26: Area: FFFF0000, FFFF3FFF
#11/26: Area: FFFEC000, FFFEFFFF
#12/26: Area: FFFE8000, FFFEBFFF
#13/26: Area: FFFE4000, FFFE7FFF
#14/26: Area: FFFE0000, FFFE3FFF
#15/26: Area: FFFDC000, FFFDFFFF
#16/26: Area: FFFD8000, FFFDBFFF
#17/26: Area: FFFD4000, FFFD7FFF
#18/26: Area: FFFD0000, FFFD3FFF
#19/26: Area: FFFCC000, FFFCFFFF
#20/26: Area: FFFC8000, FFFCBFFF
#21/26: Area: FFFC4000, FFFC7FFF
#22/26: Area: FFFC0000, FFFC3FFF

やっぱりね・・・
このリストによると、FFFC0000~FFFF7FFF は 16K 単位で、
FFFF8000~FFFFFFFF は 4K 単位であるようだ・・・

この事実に沿って、ブロック番号を指定したら、ちゃんと消去出来たー
マニュアルの嘘は勘弁して欲しい~、これは、あまりに酷いので、報告しておこうかな・・・


RX231/RX24T の書き込み速度

最近、RX231、RX24T の書き込みで、途中ストールする場合が多くなった・・・
この症状は、ページライト時に、十分な遅延が不適切で、書き込みデータを転送出来ない場合に起こると思われる。

そこで、通常の倍、遅延を取るように common/makefile に指示した。
※「--write-page-wait=15000, --erase-page-wait=4000」


ブランク・チェック

主に、RX200 系や、古い RX62x 系、RX63x 系では、ブランクチェックの仕様が古く、全体が消去されているか、いないかしか判らない。
rx_prog は、書き込む際、書き込むデータのマップを 256 バイト単位で作成して、必要な領域のみ、消去するようにしている。

又、ID コードが無指定の場合、デバイス接続で、自動で消去される仕様なので、ブランクチェックを行い、全体が消去されていたら、余分な消去操作を行わないようにした。

さらに、消去領域は、広いので、一旦消去されたブロックに対して、何度も消去操作が発生しないようにした。


まとめ

マイコンの違いで、手順を完全に分けているが、マイコンが異なっても、同じ手順で重複している物がかなりある。
現状では、これらは、コピー、ペーストになっていて、保守性が最悪な状態だ・・・
次は、これらの仕組みを整理してまとめようと思う。

又、まだサポートしていない機能が色々あるのでそれも何とかしたい・・

  • Config memory への書き込み
  • プロテクト ID の書き込みと管理
  • 読出し機能と管理など
  • 詳細なエラーレポート

RXマイコン関数電卓、他


※ 120km を mi に変換 (74.56 mi)

関数電卓を考える

関数電卓は、丁度良いボリュームで、難易度も適当な事から、昔から興味の尽きないアプリケーションとなっている。

マイコンで作る電卓なら、大容量メモリや周辺機能を活かして、通常流通している物には無い機能を盛り込める。
前回、倍精度浮動小数点よりも高精度に計算が行える、gmp、mpfr ライブラリを使って、計算の核を実装している。

RX マイコン EnvisionKit の機能を活かして実現が出来るのもガジェットとして都合が良い。

最終的には、簡単に持ち運びが出来る形態で、実用的なハンドヘルド関数電卓を作りたいと考えている。

構成的には、タッチキーでは無く、物理ボタンが欲しい処ではあるけど、複雑な操作は GUI じゃないと作りずらい場合もある。
物理ボタンなら、フルキーボードが欲しい処ではあるけど、気軽に使えるような、小型のフルキーも少ない・・
市販されているボタンを組み合わせてキーアレイを構築するにしても、コストの割に良い物を作る事が難しい・・

それでも、手頃な RX マイコン、液晶、物理キーを組み合わせた、スクラッチの関数電卓も作ってみたい。

色々考えても、一長一短で最適解があるのか無いのか・・、とりあえず、ソフトで出来る事を地道に積み上げて、完成度を高めるのが良さそうだと感じている。

GUI が無くても、シリアル接続で、対話式に計算を行えるようにしてあり、殆どのRXマイコンで動作する。
※容量が 256K 品では不足するのが、多少問題で、最低でも 512K 品が必要・・


単位の換算機能

2進、16進の変換機能などを実装して、及第点にはなった感があるのだけど、自分としては前から欲しいと思った機能もある。
Qiita の記事:RXマイコンで動作する関数電卓
※上記記事は、2進、10進、16進の機能を追加したバージョンの記事で、内部の構成などを解説している。

新たに追加した機能は「単位の変換」機能だ。

単位変換は、長さ、速度、重量など相互に変換したい場合があり、電卓の専用機能として実装すれば、利便性が格段に上がると思われる。

電卓では、単純に小数点の位置をオフセットして、10 の乗数で表す機能(ENG)があり、単位の変換は、これに近い機能。
そうすれば、元の値を保持したまま、自由に単位を変更出来るので、非常に便利。
※元の値を保持したまま変換出来る点が利便性が高い。

追加で、貨幣の変換も追加した、貨幣の場合、レートが日々変化するので、変換レートを更新する必要がある。
なので、貨幣レートのみ、変換レートを再設定出来るようにしてある。
※GUI版は、貨幣レートを入力するダイアログ関係を実装中で、現在、コマンド入力では再設定出来る。


GUI spinboxt

スピンボックスtは、登録された単語集を、左右の小さいボタンにより変更して、目的の機能を選択する。
※通常のスピンボックスは、数値を変化させて、定量的な値を得るもので、それとは少し異なるものだ。

  • ボタンを三等分して、左、右、中心で機能を別けているので、ある程度の幅が必要となる
  • 左右の小さい三角は、選択肢の有無を表している
  • メニューの方が良いかもしれないが、画面タッチでは、シンプルな操作性の方が使い易いと思う

レートの再設定

貨幣レート変換の場合、時間と共にレートが変わるので、レートを変更出来るようにする必要がある。
コマンドラインのインターフェースでは、その機能を入れてあるが、GUI は、現在実装中となっている。


RX231 のフラッシュ書き込みの不具合

RX231 を、rx_prog でフラッシュ書き込みを行った処、途中でストールして書き込めなくなった・・・
色々調べたが原因が良く判らない・・
とりあえず、「--write-page-wait=10000 --erase-page-wait=5000」書き込み時の遅延を大きくしたら、ストールしなくなったので、RX231 だけ遅延を再設定するように、common/makefile を修正した。


sci_io、rsci_io、scif_io クラスのエラーハンドリング

以前の実装では、オーバーランエラー、フレーミングエラー、パリティエラーが発生した場合、受信を受け付けなくなる不具合があった。

長い間、放置され修正を忘れていたものだった・・・
それを思い出し、ちゃんと実装した。

  • エラー割り込みを有効にして、エラーフラグを消去する
  • エラーの回数を記録する

まだ、緻密なテストを行っていないが、多分問題無いと思う。
エラーが発生した場合、受信データを捨てる事になるが、エラーをクリアして、正常に受信を行えば自動で復帰する。


RXマイコン GUI ダイアログ

ダイアログボックスは、優先度の高い GUI で、フォーカスを占有する。
現状、gui/widget_director は、これらの管理を全くしておらず、新規に実装する必要がある・・

しかし、ここにきて、行き当たりばったりで実装してきた事がかなり痛いー、ちゃんと良く考えないと管理が難しく複雑になる。
少し時間を取って、ゆっくり考えたい。
glfw3_app では、実装済みなのだが、昔実装した時には、かなり面倒だったと記憶している。
本来、こんなに高機能にするつもりが無かった、シンプルな構造で十分と思っていたのだが、関数電卓の GUI を実装する過程で、やっぱり、シンプルな機能だけでは、不可能な事案が出てきてしまった。

RX140ボード、RXマイコンC++フレームワークの整備など

最近ブログ書いて無かったので・・

RX140ボードは出来て、組み立て途中、クリスタルのフットプリントを間違えていた・・
新たに、USBシリアルとして安価なCH340、を採用した、それは動いている事は確認した。
@70円は、確かに安いが、どうだろうか・・・

クリスタルの表面実装品は取り付けが困難な事が判ったー、ハンダペーストは出来れば使いたく無い・・

1603サイズのLEDが見つからないので、動作検査はまだ出来ていないが、まぁ問題無いと思う。

今回、JLPCBを使った。

準備が出来たら、領府を行う予定、多分1000円位。


RX マイコンC++フレームワークの構成など、細かく見直した

まず、サポートしているRXマイコンの種別を増やした、ただ、実際にデバイスに書き込んで動作検査をしていない品種もある。
ChipOne ストップでの入手性、値段などから品種の追加等を行っている。
現行デバイスでは無いものでも、まだ流通している品種はそのまま残しているが、古いデバイスを新たに追加するかは未定。

又、各ディレクトリに「README.md」を置いて、特徴、リンカーファイルの構成、専用ファイル、基本ピンアサイン、フラッシュプログラマ関係の情報などを記述してコミットした。
これを観れば、デバイスを選択する際の要点などが判ると思う。


最近、秋月で、RX231 の販売を開始したようだが、値段が高く、フラッシュ容量も少ない品種で、中途半端な感じだ・・
※フラッシュ容量128Kは、USBが使えても、少ないと思う、それで580円、まぁCANが使える品種のようだが・・
それでも、一応、リンカーファイルは追加しておいた。
ChipOne ストップで、もっとフラッシュ容量が大きく、ピン数が多い品種を買った方が良いと思える。

CAN は自動車やバイクで使えるので、そのような用途に使えるかもしれない。
C++フレームワークでは、現在「RSCAN」は未サポートなので、早急に何とかしたい~


format_class を少しだけ更新

GitHub の format_class 関係、少しだけ修正した。

「make run」で、セルフテストを行うと、文字出力で、「ゼロサプレス」を使った場合にリファレンスと異なった動作をしていた。
それを修正した。
この評価は、clangコンパイラで行っており、「標準」的な動作なのだと思われる。

RX140ボード

トラックを引いてみた

イマイチ電源品質が悪いので、もう少し色々やってみる感じだけど、このサイズで両面基板で作れそうな感じ。

KiCAD のオートルーターはかなり優秀で、この程度の規模なら、配線も速いので、何度でも試せる。
昔、プロテルで基板を作っていた時は、コストもそれなりにかかって、かなり苦労したものだが、フリーのCADでこれだけ出来れば文句は無い。
KiCAD 7 は、色々やってもクラッシュしないし、抜群の安定性で、操作性も申し分ない処まで来ている。
このプロジェクトに参加している人には本当に頭が下がる。

32ビット160円のRXマイコンRX140のテスト

160円マイコン

RX140 は、RX100 シリーズ中で唯一の RXv2 コアを採用するマイコンで、単精度浮動小数点演算命令を実行出来る。
この価格帯で、このような高性能マイコンがあるのに少々ビックリした。
詳細は、Qiitaで述べている。

8/16 ビットマイコン(RL78 など)の代替えにベストな選択だと思える。


ROM は 64K、RAM は 16K

容量的には、多少物足りないが、100円 マイコン R8C/M120AN に比べて、大きなアドバンテージがある。
データフラッシュも 4K 内臓するのはありがたい。
RX マイコンは 32ビットだが、CISC 系なので、オブジェクト効率が高く、R8C や RL78 より効率が高い場合もあり、バンクを意識しなくても良いのと、FPU を内蔵するので、ソフトの制作では、非常に助かると思える。


オーバークロック耐性は低い

この CPU は最大 48MHz 動作と、低めの CPU だが、1.8V から動作する。
その仕様のせいなのか、オーバークロックの耐性は低いようだ。
実験した範囲では、60MHz で動作しなくなり、54MHz も一応動作するが、少し怪しい・・

まぁ、48MHz でも十分な性能があると思う。


基板を作りたい

以前から、組み込みマイコンの C++ 勉強会を開きたいと思っており、その場合の教材として良いと思う。
R8C/M120AN では、多少トリッキーな部分もあり、入門用に勧められない部分もあるが、RX140 なら現行品でもあり、機能も十分なので、「お勧め」出来る。
ただ、QFP パッケージでは、扱い難いので、簡単な基板を作りたいと思っている。


USB シリアル

ただの DIP への変換基板だと、フラッシュ書き換え時、USB シリアルを用意する必要がある。
そこで、最低でも、USB シリアルは載せておこうと思い、以前に使った、CP2102N を採用しようと思ったのだが・・・
最近、このデバイスのデリバリーを調べたら、単価が爆上がりしていた。
これでは、採用が難しい・・・
仕方なく、安価な、CH340 を使ってみる事にした。


まとめ

中々気力が沸かなくて、基板の制作は停滞しているけど、今度はちゃんと作ろうと思う。
出来たら、領府しようと思っている。