AoiSayaのアイコン画像
AoiSaya 2021年04月26日作成 (2021年12月12日更新) © CERN-OHL-P 2
製作品 製作品 閲覧数 1980
AoiSaya 2021年04月26日作成 (2021年12月12日更新) © CERN-OHL-P 2 製作品 製作品 閲覧数 1980

I2CでSPIを制御する変換デバイスを自作する

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デバイスの選択

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

GitHub/AoiSaya
Twitter ID @La_zlo

2
AoiSayaのアイコン画像
こころの赴くままに豆をまきます。投稿内容は趣味と煩悩に基づいており、無保証です。また、所属団体を代表するものではありません。
  • AoiSaya さんが 2021/04/26 に 編集 をしました。 (メッセージ: 初版)
  • Opening
    takezのアイコン画像 takez 2021/05/23

    こんにちは
    参考にさせていただいています
    変更すれば7bit SPIにも対応することできるでしょうか?
    例えばLTC7106などです
    可能であれば、頑張ってみようかと思います

    0 件の返信が折りたたまれています
  • Opening
    AoiSayaのアイコン画像 AoiSaya 2021/06/07

    はじめまして。

    LTC7106はPMbusとのことですので、この設計を使わなくても通常のI2Cマスタにつないで使えるかと思います。PMbusはI2Cをベースにしており、バスのハングを防ぐタイムアウトと、パケット・エラー・チェック(PEC)が追加されていると聞いています。
    他に使いたい7bit SPIがありましたら教えていただけますか?

    0 件の返信が折りたたまれています
  • AoiSaya さんが 2021/12/11 に 編集 をしました。 (メッセージ: 分類およびライセンスを追加)
  • AoiSaya さんが 2021/12/12 に 編集 をしました。
  • Opening
    AoiSayaのアイコン画像 AoiSaya 2022/02/18

    e paperは、WAVESHAREのものを想定してますか?
    3wire SPIモードであればつながると思います。
    WAVESHAREのものであれば、4wire SPIモードも一般的なLEDと同じ、DC端子が2バイト目からHighという仕様のようですので、おそらくつながると思います。
    試したことがないので断言はできませんが、ご参考まで。

    Uta-Aoyaのアイコン画像 Uta-Aoya 2022/02/20

    回答ありがとうございます。はい、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

    AoiSayaのアイコン画像 AoiSaya 2022/02/20

    I²Cで使うには、I2C用の関数を用意する必要があります。既存のSPI用の関数を改造するのが早いと思います。自分はSPIで作った自作関数をI2C向けに修正して動作確認しました。FlashAir用なのでこれ自体は参考にならないと思いますが、どちらもシリアル通信なので置き換えはそれほど難しくないと思います。

    Uta-Aoyaのアイコン画像 Uta-Aoya 2022/02/21

    ありがとうございます。まずSPI関数をi2c関数へ改造するところから勉強します

    4 件の返信が折りたたまれています
ログインしてコメントを投稿する