Raspberry Pi PicoのPIO

職場で製品評価用の治具を作る話があって、けっこうお金かかるが作ろうと動いているよう。

従来、ファンクションジェネレータを接続していたところ、

治具にマイコンを乗せて代替するアイデアを出したところそれでいこうと。

で、USB接続できると便利だよなとか色々考えると Raspberry Pi Pico を載せるのが手軽ではないかと、

治具にはそれ用のソケットを用意するということで話が動いている。


Raspberry Piといえばシングルボードコンピュータの代表例で、

その上でLinuxなど動かしたりして使われることが多い。

ただ、Picoは高級なOSが動くようなものではないので全く違うものである。

今回想定しているのはUSBインターフェースだけのものだが、

無線LAN, Bluetoothを搭載したものもあって、通常インターネットにつながらない機器をインターネット接続化できる。

すなわちIoTの担い手を想定して作られたマイコンボードである。


ファンクションジェネレータの代わりというだけなら、もっと別の方法もあるが、

もう1つやりたいことがあって、それがシフトレジスタからのデータ取得である。

外部からクロックを入力すると、シフトレジスタのデータが読み出せて、

それで機器の状態を取得できる仕組みがある。

クロックを入力することはファンクションジェネレータでもできる。

ところが、このシフトレジスタから読み出したデータを取得するとなれば、

オシロスコープで読めなくもないが、やはりマイコンの出番であろうと。


クロックを出してデータを読み出すというのはSPI通信そのものだが、

困ったことに1つのクロックで2つのシフトレジスタから同時に信号が出てくるのである。

こういうのなんかあったなと思ったらQuad SPIか。

そういうのに対応したマイコンもありますけど。


というわけで、結局はGPIOでガリガリ操作しないといけないのか、

と思ったのだが、いろいろ調べているとRaspberry Pi PicoにはPIOという機能があるそう。

GPIOに接続できるステートマシンが4台あって、その4台共有で32個の命令を格納できるメモリがある。

このステートマシンはメインのプログラムとは独立して動作する。

いろいろ制約はあるのだが、特殊なインターフェースの制御に使用されるようだ。


PIOのステートマシンはIN命令用の入力、JMP命令用の入力、

OUT命令用の出力、SET命令用の出力、Side Set出力とそれぞれ連番で複数ピン設定できる。

さっき書いた2bit入力のSPIみたいなのは入力を2つ連番で取っておけばよいと。

IN命令・OUT命令はGPIOからFIFO、FIFOからGPIOに数ビット動かす命令で、

シリアル通信のデータはこの命令で出し入れするのが通常である。

SET命令はそれとは別にON/OFFを制御する命令なのだが、

実は命令に付帯してピンの出力値を規定できるSide Setという機能があって、

SPIのクロック出力みたいなのはこちらの方が容易に書ける。


ステートマシンの動作クロックを1MHzに設定して、

IN命令+Side Set 0とJMP命令+Side Set 1をぐるぐる回すと、

非常に大雑把には500kHzのSPIとして機能するということになる。

こういうのはわかりやすいが、実際にループ・条件分岐と複雑な動きもあるので、

思ったタイミングにするにはいろいろ工夫が必要そうだが。

命令数が32個と限られるのも制約ではある。

すくない命令を上手くやりくりする工夫として全命令にSide Setと遅延を付けられるが、

あわせて5bitという制約があり、Side Setを1bit使うと、

遅延時間は最大4bit、すなわち15cycleまでの遅延しかできないという。


制約は多いのだが、複数のステートマシンを組み合わせたり、工夫の余地はいろいろある。

命令が最大32個だと複数ステートマシンなんて厳しいと思ってしまうが、

同じ命令で動くステートマシンを複数作ることもできる。

そういうのも上手く活用している例もあるのかな。


GPIOでも作れそうではあるけど、せっかくならこういうのを使うのもいいのかも。

Raspberry Pi Picoなのは入手性・価格・利便性などを考えた結果だが、

特殊なインターフェースを作り込むことが想定されてたんですね。