RaspberryPi PicoのPIOについての覚書
話題のRaspberryPi Pico、発表当初からいろいろ調べ実際に入手して遊んでいたのだが、PIOはGPIOのtypoもしくは亜種だろくらいに考えて重要視していなかったのだが、ちょっと知ったらこれこそがPico(そのMCUであるRP2040、以下こちらの名称で記述予定)の本質なのでは?となったので、何周で遅れかわからないけど、いまから知った&調べたことをここに書き連ねていく。
あとでまとめるかはわからない。
上の記事からPIOの概要を意訳&要約すると以下のようになる:
- RP2040には2つのPIOブロックが搭載されている
- 1つのPIOブロックは4つの状態機械(State Machine=以下SM)で構成されている
- 1つのSMには入力と出力のFIFOが1つずつ接続されている
- TODO: FIFOのサイズが不明なので別途調べる
- またその4つの状態機械を動かすプログラムは最大32命令で4つのSMに共有されている
- このプログラムは4つのSMが独立に読み出せる。
これでできることを考えると、最大2つの異なる入出力アルゴリズムを各最大4並行で、CPUであるCore M0を占有することなく適用できるということだ。I/Oによくある周期処理やそれにともなうウェイトをCPUを占有せずにプログラムできる、これがあの価格に収まってるのが凄い。
次にざっくりとどう使うのかを見ていく。お題はサンプルに含まれるWS2812のドライバー。
WS2812とはRGBを制御できるLEDで、自作キーボードによく使われているSK6812MINI-Eのオリジナルというと一部の人にはわかるだろうか。これの制御はビットストリームで行うのでCPUでやると結構パワーを使うのだ。
さて上記のサンプルのうちをみて分かったことを列挙しよう:
- PIO用のプログラムは
*.pio
に書く(以下pioファイル) -
ws2812.pioにはPIO命令のアセンブラ、Cで書かれた初期設定コード、CとPython用の定数定義の3つから構成されている
- 実は通常版とパラレル版の2つのプログラムが1つのpioファイルに含まれてる
- pioファイルからCヘッダーとPythonのコードが生成される
- Cヘッダーにはアセンブルされた命令が数値列で記載されている
- プログラムは
pio_add_program()
関数で書き込んでいる - そのあと
pio_*()
な関数でPIOの動作設定をしている -
pio_sm_init()
してpio_sm_set_enabled()
することでSMが動き出す -
pio_sm_put_blocking()
でSMへRGBデータを送り出してる
ここまではpioファイルと通常版に関してのみ。
パラレル版は現時点では理解に至ってない。DMAでデータを送っているが、どうやってエンコードしているのかとかDMAの終了もしくはバッファ溢れ検知はとかそういうことが気になる。またpioファイル側のアセンブラも良くわかってない。これはPIOそのものに対する理解が足りないと考えられるので別の資料に移る。
各種公式ドキュメントはココから辿れる。
https://www.raspberrypi.org/documentation/pico/getting-started/
RP2040 Datasheetの第3章がPIOそのもののリファレンスになっている。ただいきなり細かすぎて初学者が最初に読むものとしては適さないかも。あと字が小さいw
前に上げた https://www.cnx-software.com/2021/01/27/a-closer-look-at-raspberry-pi-rp2040-programmable-ios-pio/ の後半のほうが適しているかも。
いったんここまで。