こんにちは。Yukiです。
今回は、CH32V003F4P6のPD7をIOピンで使用することができたので、備忘録で書いておきたいと思います。
(正直言うと、なんで動いているのかよく分かっていません)
やったこと
簡単に言うと、User Option Bytesという特殊な役割を持つフラッシュ領域を変更しただけです。
PICとかでいうとConfiguration bits とか AVRだとFuseとかに近い設定ですかね。
具体的には、User Option Bytes の USER領域を変更してあげました。
USER領域の[4:3] RST_MODE を 11にすることでIOモードとして使用することができます。(ここら辺はリファレンスマニュアルを参照してください)
リファレンスマニュアルにはUser Option Bytes領域に書き込む方法が書いてあったので、それ通りに書いただけです。ただ、NRSTを無効化することには成功しましたが、NRSTをプログラム上で有効化することはできませんでした。
手順
注意:この方法が正しいかは分かりません。というか書いた張本人にも、なぜNRSTが有効化できないのか分かりません。なにかアクセス方法が間違っている気もします。
フラッシュにアクセルするため、ロックを解除する
FLASH領域・User Option Bytes領域にアクセスするには、ロックを解除する必要があります。
FLASH->KEYレジスタとFLASH->OBKEYRレジスタに特別な値を書き込みます。
//ロック解除シーケンス
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
FLASH->OBKEYR = 0x45670123;
FLASH->OBKEYR = 0xCDEF89AB;
本来であれば、LOCKされていなければ実行する必要がない的なことが書いてありましたが、なぜかLOCKが常に0のままなので(なのに書き込めない)if文とかは使っていません。
//フラッシュの動作が終了するまで待機 (BSY)
while(FLASH->STATR & 0x01);
次に、User Option Bytes領域を変更するためのレジスタを変更します。
//ユーザーオプションバイトのプログラミング開始 (OBPG)
FLASH->CTLR |= (1 << 4);
//ユーザーオプションバイトのプログラミング開始(STRT)
FLASH->CTLR |= (1 << 6);
次に、User Option Bytes のアドレスに書き込みます。
volatile uint16_t *CONFIG = (uint16_t*) 0x1FFFF802;
*CONFIG = 0x001F;
Volatileで最適化が起こらないようにはしていますが、どこまで意味があるのかは不明です。(念のために書いてあります)
volatile uint16_t *CONFIG = (uint16_t*) 0x1FFFF802;
*CONFIG = 0x001F;
後、リファレンスマニュアルにはハーフワード(2byte)で書き込む的なことが書いてあったので、uint16_tを使用しています。ただ過去にはuint32_tで一気に書き込みできた過去もあるので、詳しくはわかりません。
(そもそもリファレンスマニュアルに書いてあるSTATなんてレジスタありませんし…)
//フラッシュの動作が終了するまで待機 (BSY)
while(FLASH->STATR & 0x01);
u_int16_t check = *CONFIG;
FLASHがBUSYであるか確認します。
また、書き込んだ値をcheckに保存します。
//ユーザーオプションバイトのプログラミング終了 (OBPG)
FLASH->CTLR &= ~(1 << 4);
//FLASH LOCK
FLASH->CTLR |= (1 << 7);
return check;
最後にFLASHのロックをして終了です。
おそらく起動直後にFLASH(User Option Byte領域)から内部メモリにコピーさせる仕様なので、一度リセット(電源断でも可)すると、それ以降はリセットされなくなる仕様だと思います。
よくわからない点
なぜMounRiver Studio上で設定できないのかよく分かりません。
また、なんでこれで動いているのかもよく分かりません。
(というかなんでこのプログラムでNRSTの有効化できないのでしょうか…)
結論
ハッキリいうと、MounRiver Studioがまだ開発途中なのだと思います。
IDEとしては良いのですが、書き込みソフトとしては全然といった感じ。
特に細かい点が残念です。
ということで、開発とコンパイルはMounRiver Studioで行い、書き込みはWCH-LinkUtilityで行うのが大正解なのかなといった感じです。
(なぜ1日かけてこの結論しか得られなかったのでしょうか…)
またWCH-LinkUtilityで簡単に書き込む方法は記事にしようかなと思います。
ちなみに
NRSTを再度有効化するには、Flash→Configuration の上のErase Code FlashをBy power Offにして、ApplyするとNRSTが再度有効になります。
後、間違えてフラッシュ保護をかけてしまい、書き込めなくなってしまった場合でもこの方法でなんとかなります。