Prototyped an SPI – USB communication bridge framework by Atmel (current Microchip) SAMD21 microcomputer.
久々の投稿です。2〜3月頃はお客様からの大量のお仕事を頂戴して、とてもブログを書く余裕がありませんでした。ごめんなさい。
さて。休日を利用して、また一つ試作をしました。これは、SPI(Serial Peripheral Interface Bus)で高速にデータを出力するデバイスから、USB インターフェイスを経由し、パソコンあるいは Raspberry Pi に転送するブリッジデバイス(フレームワーク)です。(SPI で出力されるデータを、高速にパソコンに取り込みたいというニーズは案外に多いのです。)
プロセッサには、SAMD21 と呼ばれる Atmel 社(現 Microchip)の ARM Cortex-M0+ マイコン(クロック48MHz)を初めて利用しました。Arduino ZERO PRO と同じ ATSAMD21G18 を搭載した小さなボードで、SparkFun 社の製品です。
今回は Arduino の開発環境を使いましたが、SERCOM SPI という通信ペリフェラルや DMAC(DMA コントローラ)を使うことになったため、直接にレジスタを叩くコードが大量に入りました。プロジェクトの規模(設計容易度曲線?)としては、Arduino で設計するのと、Atmel の開発環境を直接使うのと、ちょうど交点にありそうなレベルです。
実を言うと、当初は Arduino のライブラリで簡単に書けるだろうと思っていたのですが、SPI ペリフェラルや DMAC のライブラリあるいはサンプルコードがなかなか見つからなかったため、少々、目論見が外れました。もし今後作り直すとしたら、Atmel の開発環境に移行する、、、かも知れません。もちろん、Arduino 開発環境の「初めてのデバイスでも、とりあえず簡単なプログラムを書いて、フラッシュに焼いて試してみることができる」は、捨てがたい特質であり、Arduino 開発環境には手放せない利点があります。
今回の試作のスペックですが、
- あるセンサデバイスが、SPI マスタとして数メガ bps でデータを出力する。
- それをマイコンで USB(2.0 Full Speed)に変換し、
- パソコンや Raspberry Pi で取り込む
というものです。USB 通信としては、Arduino 標準環境にある USB CDC(Communications Device Class)の USB device 機能を使いました。フロー制御まで面倒を見てくれて、かつ数メガ bps でバイトストリームを送れる便利な機能です。(ただし、あくまでもストリーム転送なので、パケット転送あるいはフレーム転送をするには工夫が必要です。)
今回、最初に気になったのは、USB CDC でどの程度の速度が得られるか、という点です。USB 2.0 Full Speed の生レートは 12Mbps ですが、CDC では理論最大速度が 9.6Mbps 程度に制限されるという話でした。また、実際にパソコンの USB CDC ドライバとアプリケーションでどの程度の実行速度が得られるかも検証が必要です。私がパソコン(および Raspberry Pi)と SAMD21 マイコンで実測したレートは以下の通りです。
機材
- Apple Mac mini (Late 2014), 3 GHz Intel Core i7
- Raspberry Pi 2 Model B
いずれも、クライアントソフトとしては Python 2.7 と PySerial ライブラリを利用しました。マイコン側が無負荷(通信だけに専念)の状態で、前者だと 6Mbps 弱、後者だと 3.7Mbps 程度の実効レートが得られているようです。
最後に、マイコン上にコマンドラインインターフェイスを載せてみました。あとは、パソコンや Raspberry Pi 上に Python のラッパーコマンドを用意して、完成です。(あ、画面上のメッセージがなんか間違ってる。)
おしまい。