UIAPduinoのシームレススイッチ
UIAPduinoを書き込みモードにするには,RSTスイッチを押したままUSBに接続する必要がある. マイコンのプログラムを作るときには,何度も書き換える必要があることが多く,その度にUSBを抜き挿しするのは面倒である. UIAPduinoの公式ページには,RSTスイッチで書き込みモードと実行モードを切り換える方法が,SeamlessSwitch.inoとして以下のようなコードと共に示されている.
void setup() {
if (FLASH->STATR & (1<<14)) NVIC_SystemReset();
SystemReset_StartMode(Start_Mode_BOOT);
pinMode(PD4, OUTPUT);
// ...
}
しかし,私が構築した環境はch32funを使っており,SystemReset_StartModeという関数が無い. そこで,同等の関数を以下のように定義してみた.
void SystemReset_StartMode(uint32_t Mode)
{
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
FLASH->BOOT_MODEKEYR = FLASH_KEY1;
FLASH->BOOT_MODEKEYR = FLASH_KEY2;
FLASH->STATR &= ~(1<<14);
if(Mode == Start_Mode_BOOT){
FLASH->STATR |= (1<<14);
}
FLASH->CTLR |= CR_LOCK_Set;
}
そして,指定したコードを実行してみたのだが,期待する挙動とならない. かなりの試行錯誤を経て,ようやくその原因が分った. ch32funでは,PD4は0x34=52という数値が割り当てられている. 一方,UIAPduinoではこのピンには14という番号がつけられており,私の環境ではその番号でピンを指定するようにしたので,PD4ではなく14をOUTPUTにする必要があったのである. このコードをmain.cppに組み込んでみたところ,無事にスイッチで書込と実行のモード切り替えできるようになった.
当たり前のことなのだが,USB serialなどを使っている場合には,USBがPD4を使うので,このPINを使うことが出来無い. そのため,スイッチによるモード切り替えも動作しない. その場合には,bootloaderに入るけどもUSBの初期化が出来無くなるのかなと思っていたが,実際にはリセット後で実行モードが立上がる. この理由が分らないが,bootloaderがUSBを認識できなかったら,実行モードに切り替わるのかな. いずれにせよ,USBを使っている場合には,やはり抜き挿しが必要となる.
2026/3/18追記 main.cppの中でUSBを組込む直前に,USBのD-に使われている14ピンを少しの間だけLOWにするようにしたら,書き込み後に自動でUSBを認識するようになった. bootloaderにもUSBの認識前に14ピンをLOWにするコードを入れられたら,USBを使っている場合でも,RSTでモード切り替えができるかもしれない. しかし,bootloaderのサイズはかつかつらしいので,難しいかも.