お知らせ:この記事はJLCPCBの提供でお送りしています。

みなさんこんにちは。CH554で作るUSB-MIDIホストの製作記の後編になります。後編では基板の製作と、ソフトウェア実装の残りの部分について解説します。

なお、今回製作した基板とソフトウェアのデータはそれぞれGitHubにて公開しています。

基板:https://github.com/JA1TYE/CH554USBMIDIBoard

ソフトウェア:https://github.com/JA1TYE/CH554USBMIDIHost

実験用のプリント基板を作る

前編での評価基板を使った実装でおおよそソフトウェアの実装にめどがついたので、USB-MIDIホストを実装するための機能に絞った実験用のプリント基板を設計しました。

設計はいつも通りKiCADで行っています。CH554が最低限必要とする回路については以前作成した自作マクロパッドのデータから引っ張ってきました。レガシーMIDIの送受信回路は一般的なマイコンのUARTの入出力ピンに少し回路を追加するような形で実装することができます。ここで注意したいのが、オリジナルのMIDI1.0規格ではマイコンのUARTが5V I/Oである前提である点です。

CH554は電源として5Vを入力することができますが、内部のレギュレーターで降圧した3.3Vで動作する仕様なので、I/Oは3.3V仕様となっています。ネットで検索して出てくるMIDIの送受信用の回路は5V I/O前提の物が多いため、MIDI規格を制定している団体のAMEIの3.3V I/Oへの接続の追加仕様のドキュメントを引くことをお勧めします。今回もこのドキュメントの仕様に沿ったMIDI送信回路を実装しています。

私の使い方ではレガシーMIDIを受信してUSB-MIDIにデータを送信することはあまりなさそうなので、MIDIの受信用回路については載せず、CH554のUARTのRXをそのままパッドに引き出しています。

製造はいつも通りJLCPCBにお願いしました。KiCADからJLCPCB向けのデータを出力する手順については以前書いた記事が参考になるかと思います。My Parts Libの在庫を使い切るというのが当初の目的の一つだったので、当然PCBAまで依頼しています。USB-Aのコネクタだけは手持ちがたくさんあったので、それ以外のパーツを実装してもらいました。

届くまでの所要時間

今回はPCBAの製造費用(5枚)がUSD23.631、送料はOCSをチョイスしてUSD2.07で合計USD25.70でした。送料が激安のOCSですが、基板製造の時間も含めて、着荷までの所要時間は10日でした。データ送信から届くまでのタイムラインは以下の表のような感じです。

日付 状態
1/10(火) 2時2 JLCPCBにデータ送信
1/12(木)18時 発送通知メールが届く。OCSの追跡番号も記載されていたがまだOCSのWebサイトでは状態確認できず
1/14(土) OCSのWebサイト上で荷物がOCSに引き渡されたことを確認
1/20(金)午前 基板が届く

JLCPCBのWebサイト上だと、OCSでは発送に6営業日かかると書いてあったはずなので、大体その通りということになりそうです。今回は基板サイズが小さく、実装部品も少なかったためか、普段以上にPCBAの製造がすぐ終わった印象です。本当に急ぎならばDHLで発送してもらうのがよさそうですが、10日~2週間程度で安定して届くのであれば、全然待てるというシーンもありそうです。今後も使い分けていこうと思います。

ちなみに新年だったからか、届いた基板と一緒に2023年を祝うシールが入っていました。

届いた基板はこんな感じです。R1のシルクがビアにかぶっているのだけ気が付かず作ってしまったのが反省点です。(GitHubにアップロードしたデータでは直してあります。)

届いた基板に手持ちのUSB-Aのコネクタを取り付けるとこんな感じです。USB-Aコネクタのフットプリントは過去に検証済みなので、ここも特に問題なく実装できました。

残りのソフトウェアを実装する

実験用の基板の準備が整ったところで、ソフトウェアの実装に戻りました。USB-MIDIホストとして使う上で、前編で実装していたプログラムに足りていないのは以下の機能です。

  1. レガシーMIDI(UART)の受信処理
  2. レガシーMIDIのデータ解釈処理
  3. USB-MIDIパケットの解釈・生成処理
  4. USB-MIDIの送信処理

まず1.のレガシーMIDI(UART)の受信処理です。UARTの送受信処理はサンプルコードにも含まれていてデバッグにも使っていたのですが、今回はUSBの通信処理の合間にレガシーMIDIの受信もするということになるため、データを取りこぼさないように、UARTで1バイト受信したことを割り込みで検知し、ソフトウェア的に実装したバッファに受信データをコピーする実装を追加しました。

次に2.のレガシーMIDIのデータ解釈処理です。レガシーMIDIは1バイト単位でデータをやり取りしますが、USB-MIDIはヘッダ1バイト+データ3バイト単位でデータをやり取りします。そのため、レガシーMIDIのデータをUSB-MIDIのデータに変換するためには、1バイト単位でやってくるレガシーMIDIのデータを解釈して、適切なヘッダを付与しつつ、3バイト単位のデータの塊を作ってやる3必要があります。幸い、レガシーMIDIのデータの解釈処理は過去に作ったMIDI音源のものがあったので、C++で書いたものをCに移植しました。いやしかし、2023年にもなってC++→Cへの移植をやるとは思いませんでしたが…

ちょっと苦戦したのが、MIDIのシステムエクスクルーシブメッセージの取り扱いでした。システムエクスクルーシブメッセージはMIDIデバイスごとに固有の設定データなどを送受信するための仕様であるため、MIDI規格の中で唯一の可変長データになっています。USB-MIDIではこのデータをハンドリングするために、あとに続いたデータの数によってヘッダの種別を変えるような処理が必要になっています。ここのデバッグにちょっと手こずってしまいました。

3.のUSB-MIDIのパケットの解釈・生成処理は、2.で言及したヘッダ1バイト+データ3バイトのデータの塊を適切に詰め込んでパケットを生成したり、逆にUSB-MIDIデバイスからやってきたパケットの中のヘッダ1バイト+データ3バイトのデータの塊を解釈してレガシーMIDIに出力する処理になります。USB-MIDIのデータの塊は、ヘッダの種別によってデータ3バイトの中の何バイト分が有効なデータかが判別できるようになっているので、そこだけ判別して適切にUARTにデータを流してやるだけでOKです。実際にはヘッダ内にCable Index Numberというフィールドがあり、レガシーMIDIの16ポート分を1つのUSBデバイスで扱えるようになっている4のですが、今回の実装ではCable Index Numberが0のデータのみをレガシーMIDI側に流す実装としています。大体の機器はこれで動くのではないかと思います。

4はUSB-MIDIデバイス側にデータを送出する処理です。下敷きにしたCH559のサンプルプログラムはUSB HIDからのデータを読み取るサンプルだったので、デバイスからホストにデータを送る処理がメインでした。USBは通信内容と送受信の方向ごとにパイプという仮想的な通信路を設けてデータをやり取りする仕組み5になっています。したがって、ホストからデバイスにデータを送る場合、その方向のパイプを判別してデータを送る必要があります。サンプルプログラムでは初期セットアップの部分でホストからデバイスにデータを送っている処理が実装されていたので、そこを参考にしつつ、USB-MIDI用のパイプを判別する処理を追加で実装しました。

ここまでの機能を実装することで、レガシーMIDIとUSB-MIDIの相互変換ができるようになりました。当初の目的である在庫の解消とコンパクト化したUSB-MIDIホストの実装ができたので、シンプルな工作ではありましたが個人的には結構満足しています。作ったUSB-MIDIホストについては今後の展示等で活用していきたいと思います。

参考情報

記事中でもいくつか紹介しましたが、そのほかのUSB周りの実装をする際に参考にしたWebサイトを記載しておきます。

たぶんUSBデバイスやホストの開発をしている人はみんなインストールしているんじゃないかと思うド定番ソフト。PCに接続したUSBデバイスのディスクリプタを解釈して表示してくれるソフトです。USB-MIDIデバイスの認識処理を実装する際に、手持ちのUSB-MIDIデバイスをPCにつないで、このソフトで表示したディスクリプタ情報を参考にしました。

USBのディスクリプタについてまとまっています。もちろん原典に当たる方がよいのですが、ちょっとデバッグしたいときなんかにはとても参考になります。

言わずと知れた後閑さんのWebサイトのページ。USBの通信の考え方について簡潔にまとまっています。サンプルコードを読むときに頭に入れておくと理解が進むかもしれません。

  1. USD9.00のSMT向けクーポン適用
  2. こんな時間まで作業してるのか、というのは言わない約束…
  3. このあたりの仕様はusb.orgの仕様書を読みましょう!
  4. 例えば、USB-MIDI I/Fで2系統以上のレガシーMIDI IN/OUTを持ったものなどは、この機能を活用しているのだと思います。
  5. 例外的に、初期セットアップに使うコントロールパイプのみは双方向です。
公開日:2023/01/29