![閲覧数](/assets/img/view.png)
I2CでSPIを制御する変換デバイスを自作する
I2C-to-SPI bridge and GPIO extender using GreenPAK. (緑豆壱拾陸號)
はじめに
SPIデバイスをI2Cにつなぎたいな。変換ICがあればいいのかな。
でもそんなIC手元にないし、買っても機能が多すぎて使いこなせないかも。
それに買うのは時間もお金もかかる。
はんだづけだってめんどうだし、モジュールは数千円もする。
そうだ!DIP版GreenPAKでつくってみよう。
これからはハードウェアも欲しいときに自作する時代かもしれません。
動作
- I2C信号をSPI信号に変換します。
- I2Cバスに同時に4つのSPIデバイスを接続できます。
- 一部のカラーLCD特有の4線式SPIインタフェースに対応しています。
- 同時にGPIOを4本使えます。
- I2C端子にプルアップ抵抗を内蔵しています。
- リード及びライトが可能です。
本デザインの使用イメージ
SDカードスロット付きカラーLCDモジュールとの接続例です。
パスコンは省略してあります。
部品一覧
部品名 | 型番等 | 数量 | 備考 |
---|---|---|---|
GreenPAK | SLG46826V-DIP | 1 | Dialog直販で購入 |
設計方針の検討
タイミングチャート
まず、I2CフォーマットとSPIフォーマットの間の基本的なタイミングチャートを検討しました。
SPIではライトとリードが可能です。また、LEDパネルにアクセスしたかったので、アドレスをライトしてすぐリードする使い方も想定されます。そこでタイミングチャートを3種類作成しました。
モード0の時のタイミングチャートを示します。
LCD対応
一部のLCDのSPIインタフェースにはデータとコマンドを区別するためのDC端子(RS端子ともよぶ)が追加されています。
そこで、DC端子を設け、SPIデータ出力の2バイト目でLowからHighになる信号が自動的に出力されるようにしました。
たいていのLCDは1バイト目がコマンドで、2バイト目からデータを設定するようなアクセスが可能なため、これで十分対応できます。
また、データ端子が双方向になっているものもあります。
データリード時にデータ端子が出力に切り替わるデバイスに対応するには、SO端子に数kΩの抵抗を挟んでつなぐようにし、コンフィギュレーションレジスタで選択できるようにしました。SPIライトまたはリードの前にその都度レジスタを設定すれば、SPIデバイスごとの使い分けが可能です。
SPIモード
一般的にSPIには4つのモードがあります。接続する4種類のSPIデバイスが同じモードに対応しているとは限りません。しかし別々のモードが選べるようにするには、外部端子では8本の端子が必要になります。それでは端子も回路ももったいので、本設計ではレジスタ選択式にしました。
電源投入後にコンフィギュレーションレジスタのアドレス0x9A,0x9Bを書き換えることで、SPIの動作モードを切り替えることができます。設定は全てのSPI端子で共通ですが、SPIライトまたはリードの前にその都度レジスタを設定すれば、SPIデバイスごとの使い分けが可能です。
なお、SPIのデフォルトはモード0としました。
SPIデバイスの選択
SPIデバイスの選択は、I2Cアドレスの下位2ビット([1:0])で行うようにしました。
上位5ビット([6:2])はコンフィギュレーションレジスタで変更することができますが、デフォルト値におけるSS0~SS3とデバイスアドレスとの対応は以下のようにしました。
SS | select bit | default | hex |
---|---|---|---|
SS0 | xxxxx00 | 1010100 | 0x54 |
SS1 | xxxxx01 | 1010101 | 0x55 |
SS2 | xxxxx10 | 1010110 | 0x56 |
SS3 | xxxxx11 | 1010111 | 0x57 |
コンフィギュレーションレジスタ
GreenPAKは回路構成をI2Cからレジスタ設定で書き換えることができます。
そこでSPIモードの選択や データ端子の双方向通信への対応などは、回路の作り込みではなく、回路の書き換えで対応することにしました。
一方、GPIO端子の設定はGreenPAKの機能を利用しています。
レジスタの詳細はGitHubのREADME.MDを参照ください。
GreenPAKの設計
GreenPAKはCPLDのようなプログラマブルデバイスです。汎用ロジックIC数個で組めるような回路の置き換えに適しており、簡単な回路がこれ一個で実現できます。今回はDIP版であるSLG46826V-DIPを使いました。
SLG46826のI2C端子とSPI制御用のI2C端子は別の端子になっています。
I2Cアドレスも独立しています。
通常はSCLとSCL2、SDAとSDA2をつないで使います。
モジュール化
DIP版のSLG46826V-DIPは購入時に最初から足がついています。
設計をI2Cで書き込むだけで、基板設計もはんだ付けも一切省略してオレオレモジュールが作れてしまいます。
ブレッドボードにさして書き込んだら、すぐにマイコン用インタフェースとして使えます。
おわりに
動作確認はFlashAirにカラーLCDを繋いで行いました。制御プログラムは自作のライブラリの出力先をSPIからI2Cに変え、DC端子の制御をなくしただけで動きました。
I2CでGPIOにつないだリセットもバックライトオンオフもバッチリ動作しました。
誰でもお試しいただけるように設計データをGitHubに公開しています。
https://github.com/AoiSaya/GreenPAK_I2C2SPI
オレオレモジュール作成のご参考になれば幸いです。
もし少量のGreenPAKの入手にお困りだったり、この設計を書き込んだDIP基板を販売して欲しい方がいらしたらご相談ください。
ライセンス等
CERN-OHL-P2とします。
以下の場合を除き、個人、法人、商用、非商用問わず無料でご利用頂けます。
ご相談いただきたい事項
・この記事や設計データそのもの(軽微な改変を含む)を販売する場合
・この設計(軽微な改変を含む)だけを焼いたデバイスもしくはモジュールを販売する場合
免責事項
本記事の正確性については努力しておりますが、当方は利用者が当記事の情報を用いて行う一切の行為について何ら責任を負うものではありません。本記事の情報の利用、内容によって、利用者にいかなる損害、被害が生じても、著者は一切の責任を負いません。ご自身の責任においてご利用いただきますようお願いいたします。
Author
投稿者の人気記事
-
AoiSaya
さんが
2021/04/26
に
編集
をしました。
(メッセージ: 初版)
Opening
takez
2021/05/23 Opening
AoiSaya
2021/06/07 -
AoiSaya
さんが
2021/12/11
に
編集
をしました。
(メッセージ: 分類およびライセンスを追加)
-
AoiSaya
さんが
2021/12/12
に
編集
をしました。
Opening
Uta-Aoya
2022/02/18
AoiSaya
2022/02/18
Uta-Aoya
2022/02/20
AoiSaya
2022/02/20
Uta-Aoya
2022/02/21
ログインしてコメントを投稿するこんにちは
参考にさせていただいています
変更すれば7bit SPIにも対応することできるでしょうか?
例えばLTC7106などです
可能であれば、頑張ってみようかと思います
はじめまして。
LTC7106はPMbusとのことですので、この設計を使わなくても通常のI2Cマスタにつないで使えるかと思います。PMbusはI2Cをベースにしており、バスのハングを防ぐタイムアウトと、パケット・エラー・チェック(PEC)が追加されていると聞いています。
他に使いたい7bit SPIがありましたら教えていただけますか?
はじめまして。
e paperにi2cで繋ぎたいと考えていますが、例えば、この製品のようなことは、可能でしょうか?
・e-Paper I2C モジュール
https://www.switch-science.com/catalog/3887/
e paperは、WAVESHAREのものを想定してますか?
3wire SPIモードであればつながると思います。
WAVESHAREのものであれば、4wire SPIモードも一般的なLEDと同じ、DC端子が2バイト目からHighという仕様のようですので、おそらくつながると思います。
試したことがないので断言はできませんが、ご参考まで。
回答ありがとうございます。はい、WAVESHAREを想定しています。3write/4writeにこだわりはありません。また別の質問です。
この記事ではLCD(driver:lil9341)への接続例になっていますが、arduino GFXなどのライブラリを経由してi2c→SPIを命令しているのでしょうか?GFXライブラリではSPIのPIN数だけ指定が必要なため、特別にi2cのPINを指定するプログラムが必要と考えました。
例:
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); //update
https://mobile.k05.biz/e/2021/03/microbit-ili9341-arduino-ide.html
I²Cで使うには、I2C用の関数を用意する必要があります。既存のSPI用の関数を改造するのが早いと思います。自分はSPIで作った自作関数をI2C向けに修正して動作確認しました。FlashAir用なのでこれ自体は参考にならないと思いますが、どちらもシリアル通信なので置き換えはそれほど難しくないと思います。
ありがとうございます。まずSPI関数をi2c関数へ改造するところから勉強します