ちょっと横道にそれて、ソースコードをクリーンアップしている。
開発初期では、あまり深く考えないで、安全確実なシンプルなコードで運転
していたが、もうそろそろ、気になっていた、柔軟性に欠ける部分を更新す
る時期なのかもしれない。
まず、ポート関係、RXマイコンでは、非常に沢山のラインナップがあり、
パッケージによっても使えるポートが変化するので柔軟な創りが要求される。
ただ、全てのRXマイコンに対応させる品質にするのは大変だし、自分で使
うデバイスのみ定義を行い、新しいデバイスを使う必要性が生じ場合を考慮
して、「対応できるように」を目標に実装しておく。
とりあえず、カレントのデバイスは、RX64M、RX24Tなので、それ
らを中心に考える。
※最近は使わなくなった、RX621も(秋月@950)なので、CPはそ
れなりに高いから追加しておくべきかもしれない。
デバイスで異なる典型的なレジスタとして「ODR」(オープンドレイン制
御)がある。
RX64M、RX24Tで以下のようになっている
P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 PA PB PC PD PE PF PG PJ RX24T ODR0 o o o o x x x o o o o o x o o - - - ODR1 x x o x x x x o x o o o x o o - - - RX64M ODR0 o o o o o o o o o o o o o o o o o o ODR1 o o o o o o o o o o o o o o o o o o
※o: 有効、x: 無効、-: ポート無し
この事実を踏まえ、ポートのテンプレートを以下のように定義して、
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// /*! @brief ポート定義基底クラス(PDR, PODR, PIDR, PMR, PCR, DSCR) @param[in] base ベースアドレス @param[in] option オプション */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// template <uint32_t base, class option> struct port_t : public option { ... };
ODR の定義は、option クラスとして継承させる事にすると・・
typedef port_t<0x0008C002, odr_oo_t<0x0008C084> > PORT2; typedef port_t<0x0008C003, odr_oo_t<0x0008C086> > PORT3; typedef port_t<0x0008C004, odr_oo_t<0x0008C088> > PORT4; ...
※RX64M
... typedef port_t<0x0008C002, odr_oo_t<0x0008C084> > PORT2; typedef port_t<0x0008C003, odr_ox_t<0x0008C086> > PORT3; typedef port_t<0x0008C004, odr_xx_t<0x0008C088> > PORT4; ...
※RX24T
のように最終的な定義とした。
ここで、ODR 定義の option クラスは、
odr_oo_t ---> ODR0、ODR1 の定義がある odr_ox_t ---> ODR0 のみ定義がある odr_xx_t ---> ODR0、ODR1 両方の定義が無い
とする。
※「odr_xx_t」は、中身の何も無いテンプレートとなっている。
あと、ポートのビット割り当ては、パッケージのピン数などでも変化があるの
で、今回は見送った(そこまでする必要があるか?)、しかしながら対応する
事は可能。
次にクロック関係の定義:
本来、特別な理由が無い限り、マイコンを定格より低いクロックで動作させる
事は稀(消費電力など)と思うが、一応定義はスマートに出来るようにしてお
きたい。
※初期のRXマイコンでは、USBを使う場合、12MHzのn倍にしか設定
できないので、RX621などでは、100MHzまで動作が可能でも、96
MHzでしか動かせない制限がある。
※最近のRXではPLLの設定範囲や、構成を見直し、なるべく最大のパフォ
ーマンスが出せるような工夫がされている。
(1)外部接続のクリスタルを選べる事
(2)PLL動作周波数の選択
(3)内部ペリフェラルのクロック選択
RXマイコンでは、内部のペリファラルをグループ分けしてあり、それに対応
するクロックを個別に供給している。
※専用の分周期を持っている。
以前から、Makefile 内で、コンパイルオプションを利用して、変数定義として、
各モジュールのクロック周波数を定義していた。
-DF_ICLK=80000000 -DF_PCLKA=80000000 -DF_PCLKB=40000000 -DF_PCLKD=40000000 -DF_FCLK=20000000
※しかし、実際の分周非の設定は、適切な値を直接設定していた。
これは、(3)に相当する部分で、シリアルのボーレートや、タイマー周期、
時間待ちループなどの基数として利用してきた。
外部クリスタルの周波数を変更した場合、それに合わせて、適切な値を設定す
る必要があるので、イマイチ柔軟性に欠けるものの、通常は、クリスタルを頻
繁に交換する事も少ないので、特に仕様を変更せずにそのままにした。
※分周比の設定は、一応計算されるが、割り切れないような設定では問題とな
ってしまう。
(2)は、内部PLLの構成がより柔軟となったもので、RX64Mなどは、
最大速度は120MHzだが、より広範囲の基底周波数を選択できるように、
内部PLLは倍の240MHzまで設定可能となっている。
そこで、クロック設定の際に、内部PLLをどの速度にするかを設定できるよ
うにした。
※PLLの倍率には、制限があるので、入れた数字がそのまま内部基数になる
訳ではないのだが・・
// 10MHz X-Tal, 80MHz typedef device::system_io<10000000> SYSTEM_IO; SYSTEM_IO::setup_system_clock(80000000);
※RX24Tでは、内部PLLの最大速度は80MHzなので、上記のように
使用する。