RX24TでSDカードの読み書き

RX24TにもSDカードを接続してみた。

ほとんどは、RL78のリソースを使ったものの、FatFS を ff12b と最新の
実装を使った。
また、なるべく、固有のハードウェアー設定を追い出して、ハードの依存を
少なくする仕組みを整えた。

RX24Tには、専用のSPIチャネル(RSPI0)が1つだけあるので、
SDカードに割り当てた。
SDカードを扱うと、このチャネルはほぼ占有されてしまうと思うので、他
とのシェアをあまり考えなくてもも良いと思うが、一応、それも可能に出来る
ようにはしてある。

img_0855s

新規に作成したUSBシリアルコンバーターから、電源を取っているのだけど、
SDカードをマウントすると、USBシリアルデバイスが不安定になる現象が
起こった、これは、SDカードマウント時に大きな電流が流れ、電圧効果が大
きいのだろう、そこで、解消の為、USBシリアルモジュール側に47uFの
コンデンサを追加した、(22uFくらいで十分だと思うが、手持ちが無かっ
た)これで、安定的に動作するようになった。
念のため、RX24T側にも10uFのコンデンサを足した。

簡単なベンチマークを行った。
※サンプルのSDカードは、Transcend の8GB
※RX24Tでは、SPIの最大クロックは20MHzとなっている。

RX24T:
SD Speed test start...
SD Write test...
Write frame: 460
Write: 136770 Bytes/Sec
Write: 133 KBytes/Sec
SD Read test...
Read frame: 133
Read: 473041 Bytes/Sec
Read: 461 KBytes/Sec

RL78/G13:
SD Write test...
Write frame: 541
Write: 116293 Bytes/Sec
Write: 113 KBytes/Sec
SD Speed test start...
SD Read test...
Read frame: 180
Read: 349525 Bytes/Sec
Read: 341 KBytes/Sec

※書き込み速度は、あまり変化は無いが、読み込み速度はかなり改善している。
※RL78では、SPIのクロックは16MHzだったので、その分と、CPU
の処理能力の違いと思える。

-----

ポートを1ビット単位で定義できるようなクラスを実装した、これはRL78
でも同じようなクラスを実装したけど、より汎用的な仕様にした。

定義の仕方は、RL78とほぼ同じだが、ポートの指定は、テンプレートクラス名とした。

    typedef device::PORT<device::PORT6, device::bitpos::B5> sdc_select;    ///< カード選択信号
    typedef device::PORT<device::PORT6, device::bitpos::B4> sdc_power;    ///< カード電源制御
    typedef device::PORT<device::PORT6, device::bitpos::B3> sdc_detect;    ///< カード検出

RXマイコンでは、ポートの出力と、入力は、異なったレジスターを利用する
為、テンプレートクラスは、この対応が非常にやりやすい。
以下は、ポートクラスの一部:

struct port_t {
    static bit_rw_t<rw8_t<PORTx::base_address_ + 0x20>, bpos> PO;  // ポート出力用
    static bit_ro_t<ro8_t<PORTx::base_address_ + 0x40>, bpos> PI;  // ポート入力用

        void operator = (bool val) { PO = val; }
        bool operator () () { return PI(); }
    };
    static port_t P;

operator をオーバーロードする事で、「P」に対して、「=」で、値を設定、
「()」で読み出す事が出来る。

RX24T SD カードアクセスサンプル

RX64Mフラッシュ書き込みプログラム

RX24Tに続き、RX64Mでも、フラッシュへの書き込みが出来るようになった。

RX64Mは、RX24Tとは、全く違うプロトコルで、機能も増えている為、かなり
の部分が作り直しとなった。

RX63T、RX24Tでは、接続が確立され、コマンドを受け付けるようになった時
には、フラッシュは自動で消去されている為、「--erase」動作は必要無いのだが、
RX64Mでは、消去は、個別に対応する必要がある。

また、デバイスを自動で認識する訳では無い為、書き込み時、デバイス種別を選択する
必要がある。

./rx_prog -d RX64M -P COM11 --verbose --progress --erase --write --verify uart_sample.mot
# Platform: 'Cygwin'
# Configuration file path: 'rx_prog.conf'
# Device: 'RX64M'
# Serial port path: 'COM11'
# Serial port speed: 115200
# Input file path: 'uart_sample.mot'
# Motolola Sx format load map: (exec: 0x00000000)
#   0xFFE00000 to 0xFFE00FCB (4044 bytes)
#   0xFFFFFFD0 to 0xFFFFFFFF (48 bytes)
#   Total (4092 bytes)
# Serial port alias: COM11 ---> /dev/ttyS10
# Serial port path: '/dev/ttyS10'
# Connection OK.
#01/01: Device Type OSA: 16000000
#01/01: Device Type OSI: 16000000
#01/01: Device Type CPA: 120000000
#01/01: Device Type CPI: 120000000
#01/01: Endian is little.
#01/01: System clock: 120000000
#01/01: Device clock: 60000000
#01/01: Change baud rate: 115200
#01/01: ID: Disable
Erase:  ###############################################
Write:  ###############################################
Verify: ###############################################

RX Flash Programmer

RXマイコン用 gcc-6.2.0 の構築

以前に、gcc-6.2.0 で、RL78 の gcc をビルドした時、C++ の構築時に
失敗した(16ビットCPUだとポインターが16ビットなのが原因の
よう)ので、試さなかったが、RXマイコンは純粋な32ビットなので、
ビルドできるよなと思い、やってみた。

普通に成功した・・・
※6系は、ビルドも速い気がする。

5.4.0 では、「-flto」でビルドすると、ソースによっては、リンク時に
gcc がクラッシュする事があった、6.2.0 だと、今のところ、クラッシュ
しない~
バイナリーも小さくなる~
これは、もしかしたら、「良い」のかもしれない・・・

6系は、主に、C++1z に向けた、コンパイラと思っていたのだが、色々と
改修が進んでいるのかもしれない。

gcc-6.2.0 でコンパイルしたRXマイコンのプログラムも普通に動作する
ようだ。

RX24Tフラッシュ書き込みプログラム

RX24Tのフラッシュ書き込みプログラムが動くようになった。

以前に実装したRX63T版と微妙に違うので、それを修正して、対応しただけ
なのだけど、RX63Tより簡略化されているので、簡単だった。
※まだ、実装されていないプロトコルがある。(プロテクションIDの設定など)

RX63Tでは、内臓発振器の周波数が低い為、速度をキックする場合には、外部
接続クリスタルの周波数を設定して、内部のクロックデバィダをプログラムする必
要があったが、RX24Tでは、内部発振器の周波数はそこそこ高いので、その必
要は無くなった。

# Platform: 'Cygwin'
# Configuration file path: 'rx_prog.conf'
# Device: 'RX24T'
# Serial port path: 'COM12'
# Serial port speed: 115200
# Input file path: 'DS3231_sample.mot'
# Motolola Sx format load map: (exec: 0x00000000)
#   0xFFFC0000 to 0xFFFC1B4B (6988 bytes)
#   0xFFFFFFD0 to 0xFFFFFFFF (48 bytes)
#   Total (7036 bytes)
# Serial port alias: COM12 ---> /dev/ttyS11
# Serial port path: '/dev/ttyS11'
# Connection OK.
#01/01: Device: RX200 Series (LittleEndian)
#01/01: Device ID: 0x33306638
#01/01: Data area: 1D
#01/01: User Area: FFFC0000, FFFFFFFF
#01/01: Data Area: 00100000, 00101FFF
#01/02: Block: FFFC0000, 00000800, 00000080
#02/02: Block: 00100000, 00000400, 00000008
#01/01: Change baud rate:
#01/01: ID Protect: Disable
Write:  ################################################
Verify: ################################################

RX24T対応、フラッシュライター

-----
rx_prog では、rx63t_protocol.hpp、rx24t_protocol.hpp と2つの制御プログラム
を使っている、C++ では、通常このような場合には、インターフェースクラスを使
って切り替えるのが一般的ではあるが、「new」を使いたくないとか、ポインター
でアクセスするのが好きじゃ無いとか色々あり、boost::variant を使ってみた。
これを使って、各メソッドに対応する visitor クラスを実装すれば、同じような
共有化が出来る。

最初は、個々の visitor クラスの実装が面倒とも思ったが、インターフェースクラス
を書くのと大差無い事が判った。
これからは、boost::variant を積極的に使っていきたい~
ただ、エラー発生時に、非常にわかり難いエラーメッセージが出力される・・・
この辺りは慣れが必要と思う・・・

USBシリアルコンバーターCP2102

RL78で、単線によるフラッシュプログラムですが、Windows 以外、シリアル
ドライバーの挙動に問題があり、全滅です・・

最近、アマゾンで買った中華製CP2102シリアルコンバーターも試しましたが、
やはり駄目でした、Linux 環境では、かなり良いとこまで進みますが、やはり途中
で駄目になります。

この問題は、以下のような事のようです。
・TXD信号からBRKを信号を送出できない(OS-Xの場合)
・フレーミングエラーを無視出来ない(OS-X、Linux)
※RL78では、送信は2ストップビット、受信は1ストップビットの為

何か、別の方法があるのかもしれませんが、簡単に解決するには、中間に、単線信号
に変換するマイコンを入れるなどするしか無いようです。
※最新ドライバーをインストールしても、状況は同じようです・・・

-----

CP2102シリアルモジュールですが、裸で使うと、ショートの危険などあるので、
ケースに入れました。
・USBのコネクターは、マイクロUSBに交換しています。
・電源ランプとして、赤色LEDが付いているので、上部に穴をあけ、ホットボンド
で塞いであります。
・3.3V専用です。
・レギュレーターチップの上にスペーサーとして3mmの板を乗せ、中の基板を固定
してあります。
・コネクターは6ピンの圧着用ピンヘッダーを使いました、これもアマゾンで、大量
購入したものです。
・信号としては、電源、送受信、/RTS、/CTS を出しています。

ケースは、「タカチ電気工業」のCS75Nを使いました。
・このケース、デザインも機能も優れており、加工しやすく、安く、お気に入りです!

img_0851s

加工は、リューターと棒ヤスリを使いましたが、いつも、削りすぎで、余分な隙間な
どできたりしますが、今回はパーフェクトでは無いけど、まぁまぁの出来です。

img_0853s

RX24TでLED点滅

先日購入したRX24Tで、LEDの点滅が出来た。

RXシリーズは、RX621に始まり、RX63T、RX64M、RX24Tと色々扱う
事になった。

基本的にシリーズが違っても、内蔵ペリフェラルは、似通っているので、リソースの使い
まわしが出来るのがありがたい。

以前から、マイクロマウスをやろうかと思い、非常にゆっくり準備している。
本来、RX24Tは、モーターの制御向けシリーズとして、RX23Tの後継で、動作
周波数が80MHzまでアップされ、注目していたが、チップワンストップで、
数量をある程度まとめると安いのを見つけて、購入した。
※10個で@460円くらい。
80MHzで動作し、256Kのフラッシュと16KのRAMなど、コストパフォーマン
スが高い。
元々、このシリーズは、ブラシレスモーターの制御をターッゲットにしたものなのだが、
もちろん、それ以外の用途でも十分使えると思う、多少RAMの容量が少ないが・・

とりあえず、モーター制御に特化したものに利用する予定で、迷路の解析部分の「頭脳」
は、別に何かを使う予定でいる。
※1個のマイコンで全てまかなえればシンプルなのだが、初号機は、柔軟性など考えて、
とりえあず分離しておきたい。

RX24Tで少し違うのは、内部のフラッシュは、最大でも32MHzまでしか動作しな
い為、フルスピード(80MHz)で動かす場合には、ウェイトを入れる必要がある点で、

	device::SYSTEM::PRCR = 0xA50B;	// クロック、低消費電力、関係書き込み許可

	device::SYSTEM::MEMWAIT = 0b10; // 80MHz 動作 wait 設定

レジスタのプロテクトを解除後、スピードをキックする為に備えて、ウェイトを入れてお
く必要がある。

今回最大周波数は80MHzなので、外部発信は、10MHzのクリスタルを使った。

LEDは、P00(4)に赤色LED(VF:1.9V)を1.5Kの抵抗を入れて、吸い
込みで接続してある。

img_0849s

RX24T LED 点滅

RXマイコン用 gcc-5.4.0 の構築

LTO のトラブルをうけて、gcc をより新しいバージョンへ移行する事にした。

とは言っても、時間はかかるものの(1時間もかからないが・・)、そんなに新しい
事は無い。

まず、パッケージの選択、6系は、まだ移るには早いようなので、5系の最新、5.4
にする。
合わせて、binutils、newlib も割と最新で統一した。

  binutils-2.27.tar.gz
  gcc-5.4.0.tar.gz
  newlib-2.4.0.tar.gz

今回から、C コンパイラのビルドオプションは、「--disable-multilib」に変更した。
32ビットのRXマイコンには必要ないうえに、付けるとビルド時間が長くなるようだ。

gcc-4.9.4 で、「-flto」を付けた場合に、リンク時に gcc がクラッシュするトラブルは
起こらないようだ・・
ただ、コンパイルするプログラムに依存すると思われるものなので、たまたま、クラッシュ
しないだけかもしれない・・
クラッシュするようだと、-flto は諦めるしかない・・・

・-flto の場合

   text    data     bss     dec     hex filename
   4012      48    1316    5376    1500 uart_sample.elf

・無しの場合

   text    data     bss     dec     hex filename
   4092      48    1316    5456    1550 uart_sample.elf

プログラムが短いので、効果が分かりにくいものの、小さくなっている。

gcc LTO のトラブル

最近 gcc の最適化オプションに関連するトラブルで悩んでいる・・・

gcc 4.8 から導入されたと言われる「LTO」(Link-Time Optimization)は、ソース単位
を超えた最適化を行う。
非常に有用で、サイズ、スピード、共に改善するようだ。

RL78では、SDカードを扱うようになってバイナリーサイズが肥大化してきたので、
積極的に「-flto」を追加するようになった。
バイナリーが10%程小さくなり、大きな効果がある事が分かった。

しかし・・・

最近、RL78のフラッシュ書き込みプログラムの実装を進めて、MSYS2環境では
書き込みが出来るようになった。
そこで、OS-XやLinuxでもテストを始めてみたのだが、書き込みプログラムは
MSYS2以外では動作しなかった。
まあこれは、仕方無い、原因を特定して修正するだけなのだが、問題は、OS-X、
Linuxでビルドした rl78-elf-gcc だった。
明らかにMSYS2で作成したバイナリーと異なっている。

調べると、どうやら、どこからも参照されないテーブルや関数が、全て無くなっていて、
最終的なバイナリーに含まれていない。
これは、主に、割り込みベクターや、割り込みプログラムなどで、無ければ当然動作し
ない。
しかしながら、MSYS2でビルドしたバイナリーには、ちゃんと含まれている。

つまり、MSYS2で作成した gcc と、OS-X、Linuxでビルドした gcc では
異なっているという事だ、確かに、ファイルパスの扱いなどが違うので、異なってはい
ると思うが、ビルドしたバイナリーが異なるのは、非常に問題だ。

リンカースクリプト内には、「KEEP」宣言もしてあっても、削除されてしまう。
※これは、MSYS2 でビルドした gcc では起こらない。

とりあえず、「#pragma GCC optimize ("O0")」をベクター領域で宣言する事で、回避
できる事は分かったものの、釈然としない・・
まだ LTO は実装が始まったばかりで、「枯れていない」という事なのかもしれない。

それと、RL78では、0x0000~0x2FFFまでの領域は、ミラー領域として、
データ領域のアクセスでは、実際には、0xF0000~0xF2FFFの、データ・
フラッシュ領域がアクセスされるのだが、LTOを使うと、コードが、0x0000~
0x2FFFまでには配置されずに、その領域を有効に使えない為、割り込み駆動のタ
スクをその領域に配置するようにセクションを調整しているものの、これも、全く配置
されない・・・
MSYS2 の gcc では、ちゃんと配置される。

さらに問題は色々あって、RX マイコン用 gcc でも、LTO を使うと、リンカー時に、
gcc がクラッシュする場合があるようだ・・・
これは、プログラムによって、する場合としない場合があるようで、非常に困る。
当面 LTO を使う事ができない。

gcc-5.4.0 で、このバグが直っているかもと思い、試してみたが、駄目のようだ・・・

RX64M 割り込みなど・・

RX64M用に定義ファイルの整備を進めている。

実装して、動かしてみると、RX63Tと色々違う部分も多い事が分かる。
大きく変わったところは、割り込みベクター関係で、割り込み要因や、ベクター番号
がかなり違う・・・
ペリフェラルが多いので、以前と同じようには扱えなくなり、苦肉の策で拡張した感
じが見受けられる。

たとえば、タイマー割り込み(CMT)は2ユニット2チャンネルあり、割り込みは
4つだが、そのうち2つを使う事ができる。(CMI0、CMI1)
CMI2、CMI3は、「選択型割り込み」に分類されており、要因と割り込みベク
ターをどうするかをプログラムしなければならない。

シリアルコミュニケーションでは、受信エラーと、送信完了割り込みが、グループ割
り込みに分類されており、それらを使う場合にやはりプログラムしなければならない。

送信動作は、送信完了割り込みを使った方が、実装が簡単なので、以前の実装では、
送信完了割り込みを使っていたが、そうすると、RX63Tなどと共通化が難しくな
るので、実装を変更して、送信割り込みに変更する事にした。

とりあえず、この割り込み修正は、うまくいった。

RX64Mの他にRX24Tも10個購入したので、近いうちに、LED点滅から始
める予定なのだが、主に、各ペリフェラルの制御クラスを共通化したいのだけど、
RX63T、RX64M、RX24T、RX621、RX630、RX62Nと、様
々なグループがあり、似ている部分とそうでも無い部分など、うまくグループの違い
を吸収する構成を考えないと・・・
img_0845s

RX64M UART(SCI)サンプル

俺俺 RX マイコンボードを作ろう!(その3)

RL78に寄り道していた為、RXマイコン関係はしばらく停滞していたが、ようやく
再開、RX64Mのブートが出来た。

RX64Mは、RXマイコングループ中では、かなり豪勢なデバイスで、単価も高く
2000円くらいした。
Flashは2MBあり、内蔵RAMも512Kバイトもある。
※外部バスに32ビットでSDRAMを繫ぐ予定なので、176ピンのタイプとした。

・176ピンLQFPタイプ
img_0844s

単純に電源を全て接続し、パスコンを入れ、制御端子を設定する。

今回、USB接続は行わず、シリアル接続とした。
※OS-XやLinuxの開発環境を意識している。

RL78やR8Cと違い、RXマイコンは内臓発信機を使う文化が無いため、必ず外部
にクリスタルを接続する必要がある。
※今回12MHzを使った。

RX64Mには高速オンチップオシレーターが内臓されており、16MHz、18MHz、20MHz
から選択できるようになっている。
しかし、やはりクリスタルの方が正確であるので、クリスタルを接続する事とする。
※最近の内臓発信器の精度は、極めて高いので、そのうち、クリスタルを必要としなくなるのだと思う。

EMLE(10) ---> Vss
MD/FINED(18) ---> Boot:Low / SingleChip:High
PC7/UB(76) ---> Vss (serial boot)
VCL(14) ---> 0.1uF で Vss に接続
RES#(21) ---> Reset ボタン(10K でプルアップ)

さて、ブートが出来たので、早速LEDの点滅でもやってみよう~
RX64Mには、非常に沢山のI/Oがあるので、定義を実装するのは相当時間がかか
りそうではある・・・、かなり共通に出来そうなのと、R8C、RL78で、テンプレ
ートの書き方が進歩した事もあり、洗練されてきている感があるが、とりあえず、必要
になったら実装する感じで、進める事とする~

さて、LEDをどこに接続するか・・・
色々考えたが、P07(176)に吸い込みで赤色LEDを接続した、電流制限は
1.5Kオーム

電源用にブルーLEDでも接続しようと思ったが、古いロットなので、順方向電圧降下が
3.8Vもあり、無理と分かった・・・
最近のブルーLEDは、VFが2.9Vとかで、効率が上がっている。

LEDの点滅は、簡単なので、直ぐに出来た。

rx64m_first_sample