ワンコインデコーダXのメインマイコンであるWCH製「CH32V003」は、非常に安価でありながら高速なRISC-Vコアを搭載した素晴らしいチップです。しかし、一般的な鉄道模型用デコーダによく使われるマイコン(PICやAVRなど)とは異なり、「データを保存するための内蔵EEPROMメモリ」が搭載されていません。
デコーダにとって、ユーザーが設定したCV値(アドレスや加減速スピードなど)は、線路からの電源が切れても絶対に消えてはならない最重要データです。内蔵EEPROMがないこのチップで、一体どのようにしてCV値を保持し続けているのか、その仕組みとソースコードの工夫を解説します。
CH32V003には、プログラムを書き込むための「Flashメモリ(不揮発性メモリ)」が16KB搭載されています。ワンコインデコーダXでは、このプログラム領域の末尾の1ページ(セクタ)をまるごと「CV値保存専用のエリア」として確保し、EEPROMの代わりにデータを読み書きする「疑似EEPROM」を実装しています。
- データの展開(起動時:EEPROM_Init)
電源が入った瞬間、Flashメモリ内(CV_FLASH_PAGE_ADDR)に保存されているCVデータを、マイコン内部の高速なRAM上のバッファ(cv_cache配列)へ全てコピーします。通常、走行中のCV値の読み出しはこの高速なRAMを介して行われます。 - データの書き込み(Write_CV)
コマンドステーションからCV書き込みコマンドを受信すると、まずRAM上のバッファ(cv_cache)を書き換えた後、Flashメモリの該当ページを一度消去し、最新のデータを一括して再書き込みします。
Flashメモリへの書き込み(消去・書き込みタスク)は、マイコンのハードウェア的な制約により、処理が完了するまでに数ミリ秒(ms)という膨大な時間の間、CPUの動作が一時的にロック(ストップ)してしまいます。
ここで大きな問題が発生します。CPUがストップしている間にも、線路からは約50〜100マイクロ秒(μs)周期という超高速なDCC信号のパルス波形が絶え間なく流れてきています。もしFlash書き込みの最中にパルスの変化(外部割り込み)が発生すると、マイコンはパルスを検知できず、信号の取りこぼしや処理のハングアップ(暴走)を引き起こしてしまいます。
これを完全に防ぐため、cv_manager.c の内部では書き込みを行う直前に以下の重要な処理を行っています。
void EEPROM_SaveAll(void) {
// Flash書き込みを安全に行うため、DCC信号の受信割り込みを一時的に禁止する
NVIC_DisableIRQ(DCC_IRQn);
// ─── ここで安全に不揮発性Flashメモリへデータを書き込む ───
// 書き込み完了後、割り込みを再許可する
NVIC_EnableIRQ(DCC_IRQn);
}Flashへの物理書き込みを行う一瞬だけ、あえてDCC信号の割り込み(NVIC_DisableIRQ)を完全にシャットアウトすることで、マイコンのハードウェア競合を防ぎ、安全かつ確実な不揮発データ保存を実現しています。
このように、ワンコインデコーダXは単に「動けば良い」というだけでなく、物理的なハードウェアリソース(EEPROMの有無)の制約を考慮し、最悪のケース(パルス受信中のデータ破損)を完全に排除する堅牢な設計が行われています。
ソースコードを読む際は、ぜひ cv_manager.c に実装されている、限られたマイコンの性能を限界まで引き出すアイデアに触れてみてください。

