PSoC4をMiniProg等を使わずSWD書き込み

しばらく研究を重ねていましたが、昨日の晩にやっと SWD 書き込み・動作を確認しましたのでこちらにまとめます。

2種類の書き込み方法

手持ちの PSoC4 Prototyping Kit では2種類の書き込み方法があり、1つが UART を用いたもの、もう1つが SWD を用いたものです。それぞれについて軽く説明します。

UART 書き込み(Bootloader経由)

まず最初に言うと、PSoC4 は通常 UART 書き込みはできません。ここで「通常」とつけたのは、生のチップを買ってきて UART をやろうとしても無理です。
一方で Bootloader の書き込まれているものでは書き込み可能であり、PSoC4 Prototyping Kit では最初からこれが構築された状態で出荷されるため、本書き込み方法が可能となっています。それ以外の裸のチップでも Bootloader を書き込めばこの方法は利用可能です。

今回はこの方法はスキップします。

SWD 書き込み

PSoC4 は ARM Cortex-M0 アーキテクチャの CPU を積んでいますので、定番の SWD 接続が可能です。PSoC4 / 5LP 用の MiniProg3(3で合ってたっけ)ではこの方式を採用し、負論理のリセット端子 XRES を含めて HSSP と名付けられています(多分)。上に述べた Bootloader を消してしまったり、生のチップを買ってきた場合はこの方法しか利用できません。

本記事ではこの SWD を利用します。でも MiniProg は高いですから、今回は手持ちの CMSIS-DAP で書き込みをやろうよ、と言うわけです。

環境

いつもの通り、Mac です。SW は以下を用いました。

  • OpenOCD 0.10.0

HWの準備

まずなんとなくですが、PSoC さんの首をへし折ります。えいや。

下側を使います。上側は USB-シリアル変換のため、使いません。下側は足をつけてあげましょう。

手前に SWDIO、SWCLK、RESET、GND、VDD がありますね。この内 SWDIOSWCLK に端子を繋げるわけです。
アダプタは お手持ちの CMSIS-DAP で行ってください。おそらく ST-Link でも行けると思います。

コマンド操作

実際の手順です。バイナリデータは HEX 形式 とします。cyacd ではありません。

操作は以下のブログを参考にしました。OpenOCD バージョンが 0.9.0 ではうまくいくのかな? 僕が使っている 0.10.0 では すんなり行かないのでいかゴリ押しによる方法です。

1. ターゲットとの接続、Halt

通常は OpenOCD にて program 関数を使えば良いのですが、なぜか ターゲット halt 時に OpenOCD が abort を吐いて落ちる ので今回は workaround の方法を示しますね。

openocd -f interface/cmsis-dap.cfg -f target/psoc4.cfg -c 'init;reset halt'

上のコマンドをまず打ちます。すると OpenOCD が落ちます。それで良いのです。ログを示します。

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
  http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 1500 kHz
cortex_m reset_config sysresetreq
ocd_process_reset_inner
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1500 kHz
Info : SWD DPIDR 0x0bb11477
Info : psoc4.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : SWD DPIDR 0x0bb11477
target halted due to debug-request, current mode: Thread
xPSR: 0xa1000000 pc: 0x10000046 msp: 0x20000fe8
pc (/32): 0x10000046
zsh: abort      openocd -f interface/cmsis-dap.cfg -f target/psoc4.cfg -c 'init;reset halt'

2. 再接続、書き込み実行

OpenOCD が落ちた所で再接続しましょう。落ちていてもターゲットはしっかりと halt されているようです。ということでそのスキを突いて書き込みをしてしまいます。その際に hex ファイルのパスを指定するのですが、コマンド実行時のディレクトリをカレントとして相対パスを指定してもいいですし、絶対パス指定でもいいです。

$ openocd -f interface/cmsis-dap.cfg -f target/psoc4.cfg -c 'init;flash write_image erase LED_SWPolling.hex 0;reset;exit'

めちゃくちゃ時間がかかりますが書き込みはちゃんとできているはずです(Verify は失敗しているっぽい?)!!僕は 43秒位かかりました。以下ログです。

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
  http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 1500 kHz
cortex_m reset_config sysresetreq
ocd_process_reset_inner
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1500 kHz
Info : SWD DPIDR 0x0bb11477
Info : psoc4.cpu: hardware has 4 breakpoints, 2 watchpoints
auto erase enabled
Info : SPCIF geometry: 32 kb flash, row 128 bytes.
Info : CY8C4245AXI-483 device detected.
Info : flash size = 32 kbytes
Info : flash bank set 256 rows
Warn : no flash bank found for address 90300000
Warn : no flash bank found for address 90400000
Warn : no flash bank found for address 90500000
Warn : no flash bank found for address 90600000
wrote 32768 bytes from file LED_SWPolling.hex in 43.484100s (0.736 KiB/s)
Info : SWD DPIDR 0x0bb11477

ネットでググってみても「MiniProg 買おうね」的な記事が多くて辟易していました。どうせ Cortex-M だから SWD でサクッとできるやろと思い挑戦してみたというのが経緯です。なかなか茨の道でしたが一応はそれっぽくできて安心です。
また halt 時に OpenOCD が落ちるという事案は多分バグじゃないですかね?そもそも PSoC がサポートされたのが最近なので仕方ないですね。