RP2040-PIOで125MHzで16チャンネルをキャプチャできるロジアナを作る

# 目的
　RP2040と言うMCUのPIO(プログラム可能な入出力)は面白い。
　MCU以外に、オマケで8個のMCUが仕えるのだから(機能はチープだけど)。
　オマケのMCU(PIO)は125MHzで信号を操作できる。
　手持ちのロジアナも100MHzで動くが、100MHz動作時は2CHしか使えない。
　◆◆◆　よし、RP2040のPIOで125MHzで動くロジアナを作ってみよう　◆◆◆
　といっても、本格的なロジアナを作れるだけのやる気は持ってないので、
　なんちゃってロジアナですけど。

# 経緯
　RP2040というMCUにPIOを色々弄って遊んでいた。
　多少分かってきたので、高速動作を生かし役に立つものを作ろうではないかと考えた。
　そこで思いついたのが多チャンネルロジアナ、手持ちのロジアナは100MHz動作時の入力は2CHに制限なので。
　　※USB2(480Mbps)で通信すれば、この程度が限界だろう。
　RP2040なら、125MHzで32CHも可能ではないかとの妄想。
　　※後で示すように、之は実現できない妄想でした。

　PR2040のexamplesにはlogic_analyserと言うサンプルが有るが、トリガが無いという欠陥が有る。
　そこでサンプルを拡張し、トリガ入力とトリガ後の信号キャプチャ機能を追加する。
　併せて、キャプチャデータのグラフ表示も行う。


# 開発環境のインスツール
　前回を見てくれ。
　「[RRP2040-PIOのソフトをお手軽に開発するぞ](https://qiita.com/hi631/items/011218929d3e89dced42)」


# ソフト構成
　「[RP2040側ソフト(Github)](https://github.com/hi631/rp2040-PIO/tree/master/Logiana)」
　　・信号の取り込み、キャプチャ
　　・トリガ動作
　　・信号の簡易表示
　　・パソコンへのデータ送出

　「[パソコン側表示ソフト(Github)](https://github.com/hi631/rp2040-PIO/tree/master/LogianalTest)」
　　・データ受信
　　・データの表示と拡大


# 信号の取り込みとトリガ動作
　トリガ前後の信号をキャプチャする為に、下記のような動作を行っている。
　　1.信号は常に取り込まれ、DMAによりMCU内RAMに書き込まれる。
　　2.DMAはカスケード接続しており、信号キャプチャを連続的に行っている。
　　3.トリガ信号発生に遅延カウンタを起動し、トリガ信号を遅延させる。
　　4.遅延させた信号により、割り込み(IRQ)を発生。
　　5.割り込みによるMCU動作により、DMAを停止させる。
　　6,トリガ信号の発生位置で、キャプチャ信号をトリガ前とトリガ後に分けて表示。

# DMAのカスケード接続
　信号を連続的にキャプチャするには、DMAが連続動作する必要が有る。
　SDKにはDMA1の動作停止でDMA2を起動させ、DMA2でDMA1の再セットと再起動の事例が有る。
　しかし、このやり方ではDMA1の再起動が間に合わないと取りこぼす(ような気がした)。
　そこで色々調べ、ループDMAという手法を発見した。

　ループDMAに設定しておくと、DMA完了時にDMAアドレスは初期設定したアドレスに戻る。
　従って、DMA完了時に他方のDMAを起動するだけで、継続的に同一なDMAが実行される。
　　※但し、DMAを行うアドレス設定に制約が発生する。


# RP2040側ソフト
　arduino環境で開発。
　PIO設定部分はPIOアセンブラを通した後、必要部分をコピーして作成。

　コンパイルしたプログラムが起動すると、">"を表示してコマンド待ちとなる。
　　※TeraTermは横方向表示を150文字程度に伸ばしておくこと。
　　コマンド
　　　"C" : キャプチャを開始し、トリガ待ちとなる。
　　　　　トリガが発生すると、キャプチャ結果を表示。
　　　"D" : キャプチャを開始し、トリガ待ちとなる。
　　　　　トリガが発生すると、キャプチャ結果をデータモードで表示。
　　　"Txx" : キャプチャクロックをxxに設定。
　キャプチャ結果の表示では、データを圧縮して(128文字で)表示している。
　Disp Capture(1/xxx)と表記の場合、一文字が、xxxドットの信号を代表している。

　例として表示した画面では、8点入力に設定している。
　　00-03は、信号入力未接続。
　　04-05は、内部で発生させたダミー信号を表示(非表示に設定可能)。
　　06は、トリガ入力として内部で発生したダミー信号(外部入力可能)。
　　07は、トリガ後の遅延期間を表示。
　この様に、8点入力に設定して居るが、2点は内部制御に使用するので、実質は6点入力となる。
![logiana_dos.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/43857a36-8658-a16f-77e2-b0b1caf211dd.jpeg)

# パソコン側ソフト
　VisualStudio2017のC#で開発している。
　[「C#フォームプログラムでのシリアル通信の仕方 のサンプルプロジェクト」](https://github.com/mag02243/SerialTest)をベースに使用している、公開に感謝。

　画面の操作
　　capture釦：　押すと、キャプチャが開始されトリガ信号が入力すると、波形が表示される。
　　clock_division:　変更が可能。変更するとTxxコマンドを発行している。
　　ns/Div_[scale]：　表示のみ。表示最下行の定規(四角)のスケールサイズを表示。
　　Disp_HEX:　チェックすると、受信データを16進で表示。(デバッグ用)
　　ドロップダウンリスト：接続可能なCOMを列挙。選択するとCOMxに反映する。
　　COMx:　接続中のCOMを表示。※作者の環境を反映してCOM5がデフォルト、自分の環境にあわせてくれ。
　　接続/切断釦：　緑は接続中、赤は切断中。(起動時にデフォルトに接続しに行く)
　　終了：　終了する。
　画面上でマウスホイールを回すと、マウスカーソルを中心としてスケールが変化し、併せて表示が更新される。
　　※リミットの設定をしてないので回し過ぎると落ちるので注意。

![logiana_win.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/1ca73c01-2f31-471d-936c-d1dee9cbffe6.jpeg)


# 性能及び制限
　1.入力が4CH迄は、125MHzで262144サンプルのキャプチャが可能。
　2.入力が16CH迄は、125MHzで65536サンプルのキャプチャが可能。
　3.入力CH数は最大32CHの筈だが、30点以上ではトリガが掛からなくなる。※なぜ？。
　　入力30CHの場合は制御に2CH使用しているので、実質は28CHが最大入力となる。
　　但し、この時(17-30CH入力)には125MHz動作は不可。(DMAが優先されMCUが動けない)
　　　※当然、入力の多いRP2040が必要。
　4.トリガポイントはPIOのみの処理なので正確だが、キャプチャの開始/終了点は割り込み処理に依存しており、正確ではない。

# 感想
　かなり高速で多入力ななロジアナとして、一応使えるとは思う。
　但し、使い勝手とかキャプチャ容量に制限が有るので、実際には使うシーンは限られるような気がする。
　更に、外部信号による動作確認は殆ど行っていないので、記載の性能を有しているなんて保障はしないよ。
　なお、上記記載内容は全て無保証であり、各自の責任においてご利用願います。