秋月BL652ボードをArduinoとして使えるようにするまでの記録（Picoprobe使用）

ESP32からIoT機器のDIYにはまった勢いで低消費電力なBL652（nRF52832）が載ったボードを入手したものの、ブートローダを書き換えてArduino化するためのプログラマを用意していなかったので手持ちのマイコンボードでなんとかした時の記録です。

# 環境

- 秋月電子 BL652ブレークアウトボードキット AE-BL652-BO
- RP2040 Zero
- Windows PC
- Arduino IDE 2.2.1
- ボードパッケージはAdafruitのものを利用

# 手順

## RP2040にファームウェアを書き込む

1. https://github.com/raspberrypi/debugprobe/releases
  ここから```debugprobe_on_pico.uf2```をダウンロード
  
2. BOOTを押しながらRESETを押して、認識されたドライブにuf2を置く
  
3. ボードが自動的にリセットされてCMSIS-DAP V2として認識する
  

:::note
登録商標とかぶるのを避けてプロジェクトはDebugprobeに改名していますが、専用設計のプローブの名前でもあるため当記事では旧称のPicoprobleで呼んでいます。
:::

## 秋月ボードを繋ぐ

以下のように配線しました。
Serial Wire Debugインターフェースに最低限必要なのはSWDCLK(SWCLK)とSWDIO、GNDの3本だけですが、秋月ボードに給電するので5Vを、続けてシリアルでプログラムを書き込むのでRXDとTXDを配線しています。

| RP2040 Zero | AE-BL652-BO |
| --- | --- |
| 5V  | 5V  |
| GND | GND |
| GPIO2 | SWDCLK |
| GPIO3 | SWDIO |
| GPIO4 | RXD |
| GPIO5 | TXD |

## ソフトウェアとブートローダの入手

ハードの次はソフトの準備です。
Adafruitのボードパッケージにも含まれているものですが、Arduino IDEから呼び出せる状態ではないし深い階層にインストールされて使いにくいので別途ダウンロードします。

1. OpenOCDのWindows版バイナリを入手
  https://github.com/xpack-dev-tools/openocd-xpack/releases
  現時点で最新の0.12.0-3にWindowsのバイナリがなかったため、一つ前の```xpack-openocd-0.12.0-2-win32-x64.zip```をダウンロードしました。
  
2. Adafruitのブートローダを入手
  https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases
  たくさんファイルがありますが、AE-BL652-BO用が用意されていたので```ae_bl652_bo_bootloader-0.8.3_s132_6.1.1.hex```をダウンロードしました。
  

## ブートローダを書き込む

OpenOCDのzipを展開して、分かりやすいようにhexファイルも同じ場所に置きました。
xpack-openocdフォルダをカレントディレクトリとして作業します。

```:フォルダ構成（抜粋）
└──workdir
   └── xpack-openocd
      ├── ae_bl652_bo_bootloader-0.8.3_s132_6.1.1.hex
      └── bin\openocd.exe
```

OpenOCDコマンドの引数には、インターフェースの設定ファイルとしてcmdsis-dap.cfg、ボードの設定ファイルとしてnrf52.cfgを指定します。
さらにリセット、実行停止、Flash消去、書き込み、リセット、終了といった一連の処理を指定します。

```cmd:実行コマンド
C:\workdir\xpack-openocd> .\bin\openocd.exe ^
  -f interface\cmsis-dap.cfg ^
  -f target\nrf52.cfg ^
  -c init -c "reset init" -c halt -c "nrf5 mass_erase" ^
  -c "program ae_bl652_bo_bootloader-0.8.3_s132_6.1.1.hex verify" -c reset -c exit
```

```cmd:実行結果（抜粋）
Info : [nrf52.cpu] Cortex-M4 r0p1 processor detected
Info : [nrf52.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for nrf52.cpu on 3333
Info : Listening on port 3333 for gdb connections
[nrf52.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x000008e4 msp: 0x20000400
Info : nRF52832-QFAA(build code: E0) 512kB Flash, 64kB RAM
Info : Mass erase completed.
[nrf52.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
Info : Padding image section 0 at 0x00000b00 with 1280 bytes
Info : Flash write discontinued at 0x00025150, next section at 0x00074000
Warn : Adding extra erase range, 0x00025150 .. 0x00025fff
Warn : Adding extra erase range, 0x00079514 .. 0x00079fff
Warn : Adding extra erase range, 0x10001000 .. 0x10001013
Warn : Adding extra erase range, 0x1000101c .. 0x10001fff
** Programming Finished **
** Verify Started **
** Verified OK **
```

書き込み完了後、LED1がふんわり点滅し始めました。

## Arduino IDEでボードを追加する

設定画面からボードマネージャのURLに
```https://adafruit.github.io/arduino-board-index/package_adafruit_index.json```
を追加するとボードマネージャ画面に```Adafruit nRF52```が出現するのでインストールして```Adafruit Feather nRF52832```を選択します。

## プログラムを書き込んでみる

パッと書けて結果の分かりやすいLチカを書き込んで動作確認します。

```c:Lチカ.ino
void setup() {
  pinMode(17, OUTPUT);
}

void loop() {
  digitalWrite(17, !digitalRead(17));
  delay(300);
}
```

LED1がゆっくりした点滅から速くはっきりした点滅に変わりました。書き込み成功です。

## DFUモードについて

プログラムが書き込まれていない状態ではずっとDFUモードになっていたので普通に書き込みできましたが、その後は通常のArduinoと同様にリセット直後だけの受付になります。
ArduinoボードにはたいていシリアルのDTRピンを使って書き込みのとき自動的にリセットする回路がありますが、それと同じ事をしようとしても標準のPicoprobeにはDTRピンが割り当てられていません。

そこでブートローダに用意されている、モードを強制する機能を利用します。

- BTN1を押しながらリセット：DFUモードにする
- BTN1とBTN2を同時押ししながらリセット：OTA DFUモードにする

:::note warn
これはGPIOの11と15がブートローダで使用されるので使い方に注意が必要ということでもあります。
:::