クロックのブーストを改修
俺俺C++フレームワークでは、クロックのブーストを独自に行っている。
RX64M、RX71M、RX65x、RX671、RX66N、RX72N、RX72M、RX66T、RX72T は、ほぼ共通のレジスタ構成で、共有化していた。
ただ、共有出来ない部分もあり、「#if、#endif」を使って、デバイス毎に、別けていた。
最近、新たな方法を導入して、これを、もっとスマートな方法で分ける方法を実装した。
無効なアクセスを行う定義
RX66T/RX72T には、サブクロック発信器が無いので、それに関係するレジスタは存在しない。
以前は、以下のようにしていた。
#if defined(SIG_RX66T) || defined(SIG_RX72T)
#else
// サブクロック発信器制御
device::SYSTEM::SOSCWTCR = 0b0'1010;
device::SYSTEM::SOSCCR = device::SYSTEM::SOSCCR.SOSTP.b(!clock_profile::TURN_SBC);
#endif
この、「#if ~ #endif」で分ける実装は、一か所くらいなら、まだ良いが多くなると、読み辛くなるしスマートとは言えない、どうしたものかと考えていた。
そこで、根本に返り、レジスタクラスの定義をダミーにする事で、「#if ~ #endif」を除く事が出来る。
その代わり、見た目には、普通にレジスタをアクセスしているようにしか見えないのが問題ではある。
レジスタの定義を確認して、初めて、このアクセスがダミーで無効である事に気が付く。
一応、コメントには、そのように書いてあるが・・・
template <uint32_t base>
struct sosccr_null_t : public rw8_null_t<base> {
typedef rw8_null_t<base> io_;
using io_::operator =;
using io_::operator ();
using io_::operator |=;
using io_::operator &=;
bit_rw_t<io_, bitpos::B0> SOSTP;
};
- rw8_null_t は、中身は空で、アクセスが発生しても何もしない
- これは、最適化により、完全に無くなる
この手法をとりあえず、system.hpp に導入し、関係レジスタの定義を見直した
#if defined(SIG_RX64M)
typedef system_64m_t SYSTEM;
#elif defined(SIG_RX65N) || defined(SIG_RX651)
typedef system_65x_t SYSTEM;
#elif defined(SIG_RX66N)
typedef system_66n_t SYSTEM;
#elif defined(SIG_RX671)
typedef system_671_t SYSTEM;
#elif defined(SIG_RX71M)
typedef system_71m_t SYSTEM;
#elif defined(SIG_RX72N) || defined(SIG_RX72M)
typedef system_72n_72m_t SYSTEM;
#elif defined(SIG_RX66T) || defined(SIG_RX72T)
typedef system_66t_72t_t SYSTEM;
#endif
- 各クラスは、共通では無い部分のみ定義を行い、共通部分(system_base_t)は、継承している
struct system_66t_72t_t : public system_base_t {
static constexpr bool NCRGx_reg = false;
static constexpr bool NCRCx_reg = false;
// オプション設定メモリ
static inline spcc_t<0x0012'0040> SPCC;
static inline ofs0_t<0x0012'0068> OFS0;
static inline ofs1_t<0x0012'006C> OFS1;
static inline mde_t <0x0012'0064> MDE;
static inline memwait8_t<0x0008'101C> MEMWAIT;
static inline romwt_null_t<0x0000'0000> ROMWT;
static inline sosccr_null_t<0x0000'0000> SOSCCR;
static inline soscwtcr_null_t<0x0000'0000> SOSCWTCR;
};
- 一応、コメントを入れてあるが、コメントはコードとは異なるので、多少問題があるとは思う・・
// サブクロック発信器制御
// サブクロックが RX66T/RX72T では、ダミーアクセスとなる。
device::SYSTEM::SOSCWTCR = 0b0'1010;
device::SYSTEM::SOSCCR = device::SYSTEM::SOSCCR.SOSTP.b(!clock_profile::TURN_SBC);
実装ミスがあり、RX66T/RX72T が起動しなかった・・・
- 電卓プログラムを確認している時、RX66T が起動しなかった。
- RX66T は RAM が少ないので、それが問題と思って、色々修正したが、動作しない。
- あれ?と思い、LED 点滅を実験したら、やっぱり起動しない。
- 調べると、上記のダミーアクセスコードに実装ミスがあり、それが原因だった。
- 大きな変更をしたら、ちゃんと確認しないと駄目だと痛感した。
RX24T のクロック設定にも問題が・・・
- 以前に、ソフトディレイループを、アセンブラコードにしたので、RX24T の微調整を行った。
- クロックを落とすとソフトディレイの誤差が大きくなる。
- 調べると、「SCKCR」の予約ビットの設定があり、それが抜けていたので修正した。
- それで、クロックを落とした場合でも、ソフトディレイがある程度正確になった。
- 最大速度(80MHz)で動かす場合には、問題無かった。