RL78を再開したのは、RL78関係の仕事を受注したのが大きい。
本来R8CやRXもまだまだなので、RL78をやるのは、現状では良く
ないが、仕事を請けたので、仕方がないが、丁度良かったかもしれない。
RL78は、他のマイコンに比べて、かなり魅力的なところがある。
・以外と高速で動作する。
※WAVファイル(16ビット、48KHz)をSDカードからSPIで
読み、再生する能力がある。
・とにかく電気を食わない。
・周辺機器(UART、I2C、SPI、ADCなど)が充実している。
・C++ で開発が可能。
・デバイスの値段が安く、バリエーションも多い。
マイナス要因:
・グループ(シリーズ)が多すぎる。
・内部は基本8ビットなので、32ビットなどの値を扱うと、肥大化して
遅くなる。
・アクセスできる範囲は16ビットが基本なので、64Kの空間を、特別
なポリシーを使って、RAM領域と、ROM領域に分けている為、設計の
段階で気を使う必要があり、リソースの再利用でも、注意を要する。
※これが結構、判りずらい場合がある。
仕事では、G13とL1Cグループに対応して欲しいとのオーダーを受け、
G13専用の構造を修正して、L1Cも含めるように改修した。
RXマイコンで複数グループ対応を行い、どのような構造にするとシンプル
(アプリケーション側でグループの違いを意識しなくて済む)になるのか、
実績があるので、それらの構造を継承している。
・デバイスのクラスでは、「ペリフェラル」型を設定して、それを取得でき
るようにした。
たとえば、SAU(シリアル・アレイ・ユニット)では、以下のテンプレート
として実装されている。
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// /*! @brief シリアル・アレイ・ユニット・テンプレート @param[in] PER ペリフェラル型 @param[in] UOFS ユニット・オフセット(0x00、0x40) @param[in] CHOFS チャネル・オフセット(0x00, 0x02, 0x04, 0x06) @param[in] SDR_O SDR レジスターオフセット */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// template <peripheral PER, uint32_t UOFS, uint32_t CHOFS, uint32_t SDR_O> struct sau_t { ... //-------------------------------------------------------------// /*! @brief ペリフェラル種別を取得 @return ペリフェラル種別 */ //-------------------------------------------------------------// static peripheral get_peripheral() { return PER; } }; typedef sau_t<peripheral::SAU00, 0x00, 0x00, 0x00> SAU00; typedef sau_t<peripheral::SAU01, 0x00, 0x02, 0x02> SAU01; typedef sau_t<peripheral::SAU02, 0x00, 0x04, 0x34> SAU02; typedef sau_t<peripheral::SAU03, 0x00, 0x06, 0x36> SAU03;
「peripheral」は、enum class で定義されている、RL78のデバイス機能
分類。
uart_io.hpp クラスのプロトタイプは、以下のようになっている。
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// /*! @brief UART 制御クラス・テンプレート @param[in] SAUtx シリアル・アレイ・ユニット送信・クラス(偶数チャネル) @param[in] SAUrx シリアル・アレイ・ユニット受信・クラス(奇数チャネル) @param[in] BUFtx 送信バッファサイズ(8バイト以上のサイズである事) @param[in] BUFrx 受信バッファサイズ(8バイト以上のサイズである事) */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// template <class SAUtx, class SAUrx, class BUFtx, class BUFrx> class uart_io {
割り込み関係を設定する場合、以下のようにシンプル
に書ける。
intr::set_level(SAUtx::get_peripheral(), level); intr::set_level(SAUrx::get_peripheral(), level); intr::enable(SAUrx::get_peripheral());
また、ポートの設定などは、デバイス毎にイレギュラー的に異なるが、これも
シンプルに書ける。
manage::set_uart_port(SAUtx::get_peripheral()); manage::set_uart_port(SAUrx::get_peripheral());
「L1C」は扱ってみると、「G13」と大きく違う事が判った。
・割り込みテーブルのエントリーがかなり異なり、完全に分ける必要がある。
・当然割り込み関係のハンドリングも異なるので、これらの違いを隠蔽して
ドライバーからは同じように扱えるように改修作業を行っている。
・L1CはUSB対応デバイスの為、最大動作周波数は24MHzとなって
いる。
※ソフトディレイをかなり強引な方法で実装している。
・A/Dコンバーターは、12ビットになっている。(G13は10ビット)
・DMAコントローラーが廃止され、DTC(データトランスファコントローラ)
と、ELC(イベントリンクコントローラ)が追加されている。
・USB2.0コントローラーがある(L1C特有)
※USBは、PC側のドライバーが関係するので、簡単では無いが、USB
接続機器を接続する事が出来るのは大きいかもしれない。
※2.0と言っても、フルスピード(12Mbps)、ロースピード
(1.5Mbps)しかサポートされない。
・LCDコントローラーを内臓している。(今回は使用しない)
今回使っているデバイスは、FlashROM:64K、RAM:8K、デー
タフラッシュ:8Kの仕様で、gcc リンクファイルの領域記述を誤り、謎の
挙動を示した、しばらく原因不明で苦労したが、ようやく原因を特定して、
思ったように走るようになった。
※個人的にはG14グループを使いたいなぁーと思うのだが・・・
-----
ハードウェアーマニュアルの書き方が、日立や三菱系では無く(多分NEC系)
慣れが必要で、レジスターの令名規則も、構造的になっていない為、テンプレート
クラスを実装する際、整理しないと駄目なところが痛い。
※アセンブラで、直接ビット操作をするような場合には都合が良いのかもしれ
ない・・
※RXの三菱系が一番スマートだと思う。