RP2040で書き込み後にソフトリセットでは大丈夫なのに、ハードリセットでファームウェアが立ち上がらない問題

tl;dr

  • RP2040にファームウェアを書き込んだときに書き込んだ直後はファームウェアが起動するが、ハードリセットでは立ち上がらなくなることがあった。
  • RP2040は「実装によっては、水晶発振器の安定まで時間がかかる」という問題がある。pico sdkの場合、PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64 を入れると、遅らせることができて、起動できる
  • 水晶発振器に付けるキャパシタを変更しても直ったが、このパラメータを入れた方がよさそう

起こった現象

新作自作キーボードキット SparrowS v3 を準備しています。これはRP2040を使うのですが、RP2040は予め私の方で実装して出荷します。

この実装をしていたところ、5枚中2枚しか動作しない問題に遭遇しました。 この時の現象は以下のようなものでした。

  • BOOTSELボタンを押しながら接続すると、USB経由で書き込める RP Boot が立ち上がる
  • picotool loadでテスト用ファームウェアを書き込み、さらにpicotool rebootでソフトリセットすると、書き込んだファームウェアが立ち上がる
  • しかし、その後電源USBを抜き差ししたり、RUNポートによるハードリセットを行うと、書き込んだファームウェアが立ち上がらない

この現象は、RP2040の実装基板を作りはじめた初期に遭遇していました。 ProMicroサイズの小型基板を作ったときに遭遇しており、この時はFlashの配線などを直すことで改善したと思っていました。

そのため、Flashの配線をさらに短くした新基板を作成しました 💸 が、またこの現象が発生しました。 よくよく考えれば、ソフトリセットでファームウェアが立ち上がることから「Flashの配線については問題ない」のだろうと思いました。

AIに事例を探してもらう

最近調べものにはperplexityを使っています。 perplexityがプロンプトから検索ワードを考え出して検索し、記事の中身を参照して検索結果を表示し、さらに一次情報へのリンクも提供してくれます。 逐一ページを開いてみなくても必要な情報の記事か一次スクリーニングしてくれることや、検索ワードが曖昧であったとしても言葉で伝えて検索してくれることが便利で、もう手放せないツールになっています。

実際に、直接の現象ではないですが、類似の現象のスレッドを見つけてくれました。

水晶発振器の安定までに時間がかかる現象

見つけてくれたスレッドの中で「いくつかのボードで、水晶発振器がデフォルトの遅延時間にすむほど速く安定しないと言う現象がある」というコメントが付いていました。 そしてpico sdkではパラメータ PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64 を設定することで、この遅延時間を延ばすことができるというものでした。

github.com

これをテスト用ファームウェアに設定したところ、ハードリセット後も起動することを確認できました。

pico sdkを使う場合、CMakeLists.txtに以下のように設定を加えました。

https://github.com/74th/mcu-pin-check-firmware/commit/20f2a9a5a20e8f4e6b85fedd4c799a9834b141cd

ソフトリセットの場合は既に水晶発振器が安定していた状態であったとすれば、ハードリセットでのみ発生していたことに納得がいきます。

実際に、Adafruitのボードや、純正でさえもこのパラメータが設定されているとのことでした。希によくある現象のようです。

このパラメータで解決したときのツイート

水晶発振器のキャパシタ

最近水晶発振器につけるキャパシタに、RP2040 Hardware Design Guideに乗っていたキャパシタの容量の選定を参考にしていました。

https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040-JP.pdf

以下の式を用いることで、理想の負荷キャパシタの容量を求めることができます。

以前計算したスプレッドシートを見ると以下のようにしていました。

  • 負荷容量: 20pF(用いた安物の水晶発振器の値)
  • 回路寄生容量: 3pF
  • 理想負荷キャパシタ: 34pF
  • 実際に利用するキャパシタ: 33pF
  • 実際に利用するキャパシタでの負荷容量: 19.50pF

RP2040 Hardware Design Guideに載っていた例では回路寄生容量を5pFとしていたのに、自分が3pFとした理由は思い出せませんでした。5pFとすると、所有しているキャパシタでは27pFでも良さそうです。

所有している複数のキャパシタを接続して、PICO_XOSC_STARTUP_DELAY_MULTIPLIERの設定なしに動くか確認しました。

結果以下のようになりました

  • 10pF: OK
  • 20pF: OK
  • 27pF: OK
  • 33pF: NG

27pF以下ではパラメータ設定なしに動作することを確認できました。

動くけどパラメータは入れておこう

今回水晶発振器につけるキャパシタを調整することで、機能するようになることを確認できました。 一方 PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64 を設定しても人間に分かるほど副作用はなさそうなため、これは入れるようにしようと思います。

また、今回自作キーボードで使いたく、QMK Firmwareで設定できる必要があります。 QMK Firmwareリポジトリを見てみると、config.hに定義されているのをいくつも見つけることができます。 ここに記述すれば良いようです。

github.com

この後たくさんRP2040を実装

これでRP2040実装の問題を解決できたため、SparrowS v3の製造を再開しました。

Sparrow62v2の後継モデルですが、トラックパッドやマウスなどを近くに置くことを引き続き重視し、右手はかなり変則的な形になりました。

他の特徴としては以下の通りです。

  • ガスケットマウントで、キー入力の衝撃を抑える
  • MX互換、Kailh Choc両対応
  • 3Dプリンタケース付き(ただし、MX互換、Kailh Chocでケースは異なります)
  • 左手にRP2040を内蔵、右手はCH32V003を使用
  • なるべく薄くするため、ゴム足を使わずゴムシートでグリップ

良ければ3月22日開催のキーケット 2025で、触れる形で展示、キット販売しますので、ご来場を検討いただければと思います。

keyket.jp