FC2ブログ

記事一覧

RP2040のPIO - MicroPythonでPIO

<前書き>
前回、ArduinoIDE下でPIOの動作を含んだ簡単なサンプルコードをRP2040に書き込んで動作させることができたと報告しました。
しかしPIOのコードをメインプログラムの中に記述することができるMicroPythonのコーディング作業は、それと比べるとやはり圧倒的に楽と言わざるを得ません。特に今取り組んでいるテーマのように試行錯誤を頻繁に繰り返す作業では、言語に慣れるまでの時間を勘定に入れても大きな時間の節約になります(実際そうなったと思います)。加えて、MicroPythonの方が関数の定義、レジスタの名前の付け方なども直感的に理解し易く、また記憶に残り易いように感じました。

今回の報告はMicroPythonのコーディングで、外部ADCを接続したRP2040のPIO、DMAの機能を使って高速なAD変換を確認できたという報告です。ただし、サンプリング周波数が想定よりもかなり小さく、かつそれが変動してしまうという段階での予備的な報告です。

<使用したハード>
Raspberry Pi PicoとAD9823をブレッドボードに載せて配線しました。
rp2040_mpy_pio_adc03.jpg

<開発環境>
・MicroPythonのファームウェアをアップロードしたRaspberry Pi Pico
・WinfdowsPC上のThonny

<コーディングの状況>
こんな感じということで、Thonnyのスクリプト(プログラム)画面を示します。
この画面でテキストをちょいと編集して、ツールバーのRunボタンを押すと、1秒も経たない内にターゲットでの実行が終了してしまいます。
rp2040_mpy_pio_adc01.jpg

<スクリプト(プログラム)>
スクリプトはまだ不完全なものですので、リストは示しません。
スクリプトの大まかな流れは以下の通りです(長さ100行余りのコンパクトなものです)。
・PIOを使ってADCからADCデータをISRを経由しRX-FIFOに書き込みます。
・RX-FIFOからのDREQ(DREQ_PIO0_RX0)をトリガとしてDMAがデータをメモリに転送します。
・4096回(TRANS_COUNTレジスタ値)のデータ転送を行うと一つのセッションが終わります。
・セッションの実行時間からサンプリング速度を算出します。
・上記のセッションを合計8回繰り返します。
・必要に応じてメモリの内容をダンプしてADCデータの妥当性をチェックします。

<結果>
Shell(コンソール出力)画面を示します。
8回のセッションのサンプリング速度が表示されています(ここにはThonnyからの警告、エラーメッセージ表示などが表示されるだけでなく、このようにスクリプト内のprint文を使って変数の値なども表示させることができます)。
rp2040_mpy_pio_adc02.jpg

見てお分かりのようにサンプリング速度が期待された62.5MHzではなく、16MSa/s~20MSa/sの間でバラついています。
オシロで確認してみるとPIOでアサインしたGPIOピンからは62.5MHzのサンプリングクロックが正しく出力されています(持っているオシロの帯域が100MHzですので悲しいことにSine波的に見えてしまいます)。つまり、PIOは期待された通り動作しています。

<今後の方向>
不調の原因はDMA転送をトリガするRX-FIFOからのDREQ(Data Request)が上手く働いていないからではないかと考えています。原因究明には時間がかかりそうですが、MicroPython環境で行えることは吉でしょう。

CPUのクロックアップにはあまり興味がありません。

もっと先のことはまだ定かではないのですが、オシロのユーザインタフェース関係、時間軸のズーミング/パン、FFT等の付加機能等はArduinoIDE下の資産が色々ありますから、MicroPythonで動作確認が済んだAD変換部分のスクリプトをArduinoにポーティングすることも考えられます。


<2022/08/04>
原点に返って見るという意味で、RP2040 Datasheet build-date: 2021-04-13, pp.103-122のDMA関連のレジスタの説明を見ながらスクリプトを思い切って大幅に書き直してみました。しかし、下図の通り、相変わらずサンプリング速度の変動が見られます。
ただ、40MSa/sの速度が出るようにはなってきました(何が奏功したのか分かりません)。
rp2040_mpy_pio_adc05.jpg

DMA転送先のバッファメモリの内容をダンプしてのチェックも当初からやってはいるのですが、直流から数kHzの信号の電圧の取り込みは特に問題はないようです。といっても4096点のサンプルが100~200usで終わってしまうので、この間の信号レベルの変化はあまりありませんが。
ここにかかわっても役に立つヒントは得られないような気がします。

<2022/08/04>
進展がありました。
バッファのサイズ(DMA転送のカウント)を大きくするとサンプリング速度が大きくなり、理想の値に近づいていくことが分かりました。
rp2040_mpy_pio_adc07.jpg

どうやらDMAのセッション実行時に、(多少の揺らぎはありますが、)一定時間のオーバーヘッドが存在するようです。
問題はこのオーバーヘッドがどこから来ているのか、ということになってきます。MicroPythonのファームに内在する本質的な問題なのかも知れません。スクリプトの工夫で解決できるものであればよいのですが。

P.S. グラフの元のデータを使って計算してみるとオーバーヘッド時間はバッファサイズが32768までは145~163usでほぼ一定、65536以上では205~224usでした。


コメント

コメントの投稿

非公開コメント

プロフィール

vabenecosi

Author:vabenecosi
ン十年間アキバに通い続けるオジサンです。自転車&バイク=二輪で旅するのも好きです。
本ブログはリンクフリーです。
本ブログの記事の内容を元にした製作等の行為は全て自己責任で行ってください。
またコメントを頂いてもスパム対策、あるいは管理者の判断により返信しない場合や削除する場合がありますが、ご了承ください。
旅関係の記事を書くこともあるでしょうが、専ら「アルバム」にて旅の写真のみを提供するつもりです。「アルバム」はPC画面では右下方に、スマホ画面では左上のメニューボタンの中にリンクがあります。

アルバム

FC2カウンター

FC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンターFC2無料カウンター