WioTerminalでCAN通信~ライブラリ実装編~

本記事は、WioTerminal(ATSAMD51)でこれまでに試してきたWioTerminalとMCP2515のSPI通信について、ライブラリを作成して使いやすくする過程を示します。
なお、ライブラリをC++でコーディングしていますが、C++コーディング手法については手本にはなりません。ご了承ください。

開発中のGitリポジトリはこちらです。
github.com


これまでにMCP2515を試した記録記事は次の2本です。
embaud-ot.hateblo.jp

embaud-ot.hateblo.jp

ステップ1 : MCP2515のアドレス定義

まずは、ヘッダファイルにMCP2515の固定値を定義します。
プリプロセッサのDefine命令によって、コーディング用の固定値として登録し、コーディングをスムーズに間違いなく行えるようにします。
今回定義したのは、大まかに次の3つの値です。

それぞれの定義名の規則は次のようにしました。

  • 「MCP2515_REG_」をレジスタ名の定義
  • 「MCP2515_MD_ 」を動作モード
  • 「MCP2515_CMD_」を短縮命令

MCP2515の定義を追加したコミット

ステップ2 : SPI通信で命令を発行する関数の実装

命令のみの発行、命令発行+データの送信、命令発行+データ送信+データ受信 というパターンがあるので、それぞれを行う関数を定義しました。

  • orderInst
  • orderSend
  • orderRecv

MCP2515のSPIインターフェースを実装したコミット

ステップ3 : MCP2515の構成設定を実装

CAN通信設定として、CNF1, CNF2, CNF3を設定することで、CAN通信速度を定義します。
setConfig関数を、3つの設定パターンで実装しました。

  • セグメント長を手動入力で指定するタイプ
  • CNF1, CNF2, CNF3に値を設定するタイプ
  • 所望のCANボーレートと、MCP2515への供給クロックを指定することでセグメント長を自動計算するタイプ

MCP2515のConfigurationレジスタ設定を実装したコミット

この時点で、CANCTRLレジスタをオペレーションモードをNormalや、ListenOnlyモード、LoopBackモードに設定することでCAN通信をテストすることができます。

ステップ4 データ受信構造を実装

CANデータを受信するメソッドを実装しました。
READ RX STATUS 命令を用いて、受信データの有無、何番のバッファにデータが入っているかをはじめに調べます。
次に、READ RX BUFFER 命令で IDとデータ長を取得、最後に受信したデータ長分のデータを取り出します。
candata_stという構造体を作成し、そこにパケット情報を詰め込みました。

  • recv
    • 受信バッファ内のデータ取り出し
  • getRxStat
    • 受信バッファ内のデータ有無確認

MCP2515のデータ受信を実装したコミット

ステップ5 バッファ状態出力ピン設定を実装

CANデータがバッファに入ったことを、毎度SPI通信でレジスタを確認するのも良いですが、頻繁に確認するようだと、オーバヘッドが大きくなります。
MCP2515には、受信バッファのデータ有無をデジタル信号出力する機能があるため、マイコンに信号線をつなげることで信号状態High/Lowによってデータの有無を確認することができます。

  • pinMode

MCP2515のDigital Outputピンの設定を実装したコミット

単にデジタルアウトプットピンとしても使用できるため、マイコン入門用にMCP2515のLチカも実装してみました。
MCP2515のLチカ (blink LED)サンプルスケッチ

ステップ6 データ送信構造を実装

データ受信で使用したcandata_st構造体を使用し、そこに格納されたデータを送信する構造を作りました。
送信データの格納は、TXバッファへのロード命令を使用しました。

  • setTxData
    • バッファへ格納
  • send
    1. バッファへの格納と送信リクエストを同時に発行する
    2. 送信リクエストを発行(setTxDataと併用)

データ送信を実装したコミット

まとめ

WioTerminalとMCP2515とのSPI通信、SPI通信で命令を発行してレジスタ読み書きをすることで、初期設定、データ受信、データ送信、基本的な操作をするためのライブラリができました。