PSoC 42xx を使って MCP2515 の命令フレームを生成する

PSoC 42xx は SPI コンポーネントが提供されていて、クロックは 4MHz まで設定できます。しかしながら、これを使って可能な限り速く MCP2515 と通信することはそれほど単純ではありません。

問題は、MCP2515 の命令は複数のバイトでできていることです。一つの命令は CS 信号で束ねられていて、命令を送っている最中はずっと L (イネーブル)にしておかないといけません。しかしながら、PSoC の SPI は CS 信号を直接制御できません。コンポーネントとの通信は FIFO を通じて行われており、FIFO がデータを受け取ると、内部で自動的に CS をイネーブルに変え、データの送信が終わって FIFO が空になると自動的に CS をディスエイブルに戻します。自動生成される API 関数はあまり効率が良くなくて、SPI のクロック周波数が高いとスピードに追い付けず、送信の間が空いてしまいます。そのためクロック周波数が高いと API 関数を使って MCP2515 の命令フレームを作ることができません。

datasheet_read_instruction

この問題を解決するために、API 関数を使わずに SPI を制御する関数を書きました。方針は

  • より低レベルのインタフェースを使って SPI とやり取りを行う
  • いったん送信が始まったら可能な限り速く Tx FIFO にデータを送り込み、送信が途絶えないようにする
  • データを送るのと並行して可能な限り早く Rx FIFO からデータを取り出す

いくつか制限事項があります

  • SPI 設定の Rx および Tx バッファサイズは 4 でないといけない。これより大きいと、PSoC Creator がソフトウェアバッファを生成してしまいソースコードの管理が難しくなる
  • 取り出したデータの最初の2バイトはダミーで意味をなさない。実際のデータは3バイト目から始まる。
  • まだ実装していないがたぶんこの関数を実行中は割り込みを停止しておかないといけない

以下がソースコードです。SPI コンポーネント名は SPIM_CAN で種類は SPI マスタ (SCB を使わない) です。

MCP2515 から 16 バイト取り出してみました。4MHz のクロックで想定通りに動いています。

read_instruction

read_instruction2

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です