皆さんお待ちかねのRaspberry pi PICO 、無事入手したので
早速マジョカアイリス液晶に接続してみることにしました。
最近発売されている普通のRaspberyPi用の液晶はほとんどSPI接続ですが、パラレル接続の液晶を制御しようとすると、それなりのピクセルレートで信号を生成しないといけないため、結構早くGPIOを制御する必要があります。
それだけの信号を生成できるか、まず確認してみます。
検索用:「Raspberry Pi PICO GPIO 高速」
Raspbery pi PICOはMycroPythonとやらで簡単にプログラムを書けるらしいですが、残念ながら私は ぱいそん はさっぱりなのです。
仕方ありませんのでC言語で書いていくことにします。
ここからいろいろ書いていきますが、C言語での開発環境は公式などを参照してすでにできているものとします。
・C言語でGPIOを制御するには
付属のSDKの中にある「Blink」を改造して作っていきます。
まず、通常のGPIOを1ピンずつ制御してみることにします。
このような、単純にforループで出力した場合、1ピン当たり少々遅延して出力されているのがわかると思います。
この時のパルス幅は1.31us*2=2.62us周期、周波数にすると381KHz、決して高い周波数ではありません。
forループを展開してみます
明らかに速くなりました。… forの判定にそんなに時間がかかっているのでしょうか??ここまでの二つは順次ON/OFFでしたが、
今度は一ピンの上げ下げを連続させてみます。
…何だこりゃ??
一ピンの上げ下げはすぐですが、隣のピンを触ろうとするとまた時間がかかります。
拡大してみると、一ピンのパルスは10nsで済みますが、隣のパルスの発生まで465nsぐらいかかっています。
これは、gpio_put関数周辺の処理がなんか複雑なんだと思います。
このように、ピンの制御が厳密なタイミングで行えるとは限りません。
クロック同期式ならまぁどうにか通信できるとは思いますが、ちょっと気持ち悪いです。
あれこれ探してみると、複数ビットを一括で制御する関数「gpio_put_masked」もありました。
これを使ってみると…
お、はやいやはい。そして出力も同期しています。
(ずれてるのはたぶんロジアナが悪い)。
この時、周波数は1/70ns=約14MHzとなり、そこそこの速さが出せるようです。
では、PICOの売りであるPIO(Programmable IO)の機能を使ってみることにします。
これは、内蔵のステートマシンにアセンブラを食わせて、SPIやパラレル出力、LED制御用のパルス幅デジタル出力などをメインCPUとは別に行うことができる機能です。
詳しくはこちら
などに書かれています。
今回は、マジョカアイリス液晶制御を目標にしているため、もともとSPI液晶用に準備されていたサンプルコードをもとに修正することで超高速パラレル出力を実現させました。
改変したファイルはこのあたりです。
コメント等が修正されていないため、嘘コメント部分があります(ひどい)
そのうちメンテしたい…
まぁ、GPIOがどのぐらい出るか、っていうのを見てみてください。
この機能を使うと、きちんとクロック同期させたパラレル信号を、CPU時間を消費することなく出力することができます。
PIOファイルを適当にいじったので、もしかするともっと早くできる気がするんですが、いまいちわかんないですこれw
拡大してみると、
書き込みパルスを5-10nsで生成できているようです。
上にある最短パルス幅に近いようですね。
この方法を使ってマジョカアイリス基板を制御しているのがこちらです。
raspberry pi pico + マジョカアイリス液晶で寿司廻しできた
— ひろみつ(honeylab) (@bakueikozo) 2021年2月3日
せっかくだからラズベリー寿司にしたよ
ラズベリー寿司ってなんだよ#マジョカアイリスハック pic.twitter.com/pQ4CCRydIW
まだまだチューニングの余地はあるんですが、結構なフレームレートで画面更新ができている気がします。
・まとめ
速度:遅い順にgpio_put →gpio_put_masked→PIO
難易度はまさにこの逆です。
まずは、GPIOの制御方法の違いとその速度、PIOの存在についてこれからラズピコで遊ぶ人の参考になればと思いまとめてみました。