nRF52でRESETピンを利用したリセットが動作しないので原因調査し解決した件
作成者:TZ
はじめに
nRF52を外部からの操作でリセットする必要があったのですが、この機能はプロジェクトにCONFIG_GPIO_AS_PINRESETを定義すると実現できる事がわかりました。
SDKのサンプルプロジェクト(例えばble_app_uart)などでは、最初からCONFIG_GPIO_AS_PINRESETが定義されており、そのまま実行すれば問題ないハズなのに何故かRESETが利かない。。。
このままでは困るので原因を調査してみました。
環境
・nRF52810
・nRF5 SDK 17.0.2
・SEGGER Embedded Studio for ARM Release 5.40c Build 2021022405.45437
原因調査
結論からいくとSDKの不具合のようでsystem_nrf52810.cのコード修正などが必要となります。
原因としてはCONFIG_GPIO_AS_PINRESETが定義されている場合に有効になるNRF_UICR->PSELRESET[0]と[1]に21(ピン番号)を書き込む処理の後に、DEVELOP_IN_NRF52832の定義で有効になる処理ブロックが悪さをしているようです。
詳細としてはアドレス0x10001200と0x10001204に0を書き込む実装となってますが、このアドレス指定は誤りであり、実際はNRF_UICR->PSELRESETであるため、せっかく21(ピン番号)を設定しても、後で0設定で上書きされる動作となっていました。NRF_UICR->PSELRESET[0]への書き込み、0x10001200への書き込み、と一見違うレジスタ書き込みに見えますが、実際には一緒という一見では分からない問題です。
/* PSELRESETの定義抜粋 */
#define NRF_UICR ((NRF_UICR_Type*) NRF_UICR_BASE)
#define NRF_UICR_BASE 0x10001000UL
__IOM uint32_t PSELRESET[2]; /*!< (@ 0x00000200) Description collection: Mapping of the nRESET function (see POWER chapter for details) */
考えられる対策として、DEVELOP_IN_NRF52832の定義を削除する or コードを削除する or コードを修正し正しいアドレスを指定・制御する(こちらは本件関係ないので未調査です)、のうち確実なコード削除で対応し、PIN.21の制御でnRF52にリセットがかかる事が確認できました。
注意事項
ちなみに、CONFIG_GPIO_AS_PINRESET定義の処理を実行させるには、FLASH ERASEが必要となりますので、設定を変更したい場合はお忘れなきようご注意下さい。