MachiKania

MachiKaniaでI2C接続 技術編

2017年3月12日

MachiKaniaでI2C接続」の技術的なことに関するメモ。なお、この記事はver 0.5に基づいて記述されている。

I2C接続のBASICコードのSVNレポジトリーは、こちら。
https://osdn.net/users/kmorimatsu/pf/kmbasic/scm/tree/head/applications/trunk/i2c/

主に、I2Cnauplia.txtで記述しているコードについて、解説したい。以下の図の黒字で記述された部分は、I2C仕様書からの引用である。

2017-03-04-I2C.png
このシグナルを、BASICコードでどの様にして扱っているかについて(赤字での記述)、述べる。

PIC32ペリフェラルへのBASICコードからのアクセス

コード中で、コメントを以下のように書いた。
REM PIX32MX peripheral:
REM   TRISB   =0xBF886110
REM   TRISBCLR=0xBF886114 (TRISB+4*1)
REM   TRISBSET=0xBF886118 (TRISB+4*2)
REM   PORTB   =0xBF886120 (TRISB+4*4)
REM   LATBCLR =0xBF886134 (TRISB+4*9)
TRISBのアドレスは0xBF886110で、TRISBCLR, TRISBSET, PORTB, LATBCLRはそれぞれ、TRISBより1, 2, 4, 9 ワード先にある。BASICのコード中では、配列を記述する方法で、以下の例のようにアクセスすることが可能である。
B=0xBF886110
B(2)=gosub(I2CCLK)+gosub(I2CDAT)
B(9)=gosub(I2CCLK)+gosub(I2CDAT)
この例では、TRISBSETに0x0480を、LATBCLRに0x0480を出力している(gosub(I2CCLK)は0x0400を、gosub(I2CDAT)は0x0080を返す)。RB7とRB10の両方を読み込みに設定し、LATB7とLATB10をLに設定するためのコードである。

PORTBからの読み込みも、以下の例のように、「B(4)」の値を読み込むことで可能である。
if B(4) and gosub(I2CDAT) then I2CWH2
PORTB10からの読み込み値に従って、分岐している。

I2Cシグナル作成

I2Cで1ビットのデーター部分処理部分をピックアップすると、以下のようになる。
2017-03-04-I2C1bit.png
I2Cの接続速度を100 kHzとする実装にした。1クロックに10 μ秒の時間を掛けることになる。上図で赤点線の部分でシグナルのやりとりを行なうので、2.5 μ秒と5 μ秒の待ち時間を儲ける必要がある。この時間待ちルーチンを、以下のように記述した。
REM Wait for 2.6 usec
exec 0x34020090,0x1440FFFF,0x2442FFFF

REM Wait for 5.2 usec
exec 0x34020120,0x1440FFFF,0x2442FFFF
2.6 μ秒待ちのコードのアセンブリは、以下のようなものである。
ORI   $zero,$v0,0x0090
BNE   $v0,$zero,0xffff
ADDIU $v0,$v0,0xffff
2倍の時間待ちのルーチンも、同様の物である。

これに従い、Lシグナルを1ビット送出するルーチン(I2CWL)は、以下のような仕様にした。
 1. SDA=L
 2. 2.6 μ秒待ち
 3. SCL=H
 4. 5.2 μ秒待ち
 5. SCL=L
 6. 2.6 μ秒待ち
また、Hシグナルを1ビット送出するルーチン(I2CWHR)は、以下のような仕様。ただし、1ビット読み込みも兼ねている。
 1. SDA=H
 2. 2.6 μ秒待ち
 3. SCL=H
 4. 5.2 μ秒待ち
 5. データー読み取り
 6. SDA=Lなら、L出力
 7. SCL=L
 8. 2.6 μ秒待ち
これらのルーチンが、完全なI2Cシグナルにどう対応するのかは、最初の図を参照して頂きたい。StartシグナルとStopシグナルも、同様に、I2CSとI2CPで作成される。なお、I2CSは、Repeated Startにも対応している。

I2C通信の例

記述が簡潔な、Zoea用のコードを取り上げて説明する。出力は、例えば次のコードのように実装している。
gosub I2CZ,0x40,0x00,0xFE,-1
I2CZサブルーチンが呼ばれると、まずI2CSサブルーチンによりStartシグナルが送出され、続けて0x40, 0x00, 0xFEの3バイトのコードが送出される。なお、1バイトごとにACKシグナルが返されることを確認している。最後に、-1のところでI2CPサブルーチンが呼ばれて、Stopシグナルが送出される。

入力は、次のコードのように実装している。
gosub(I2CZ,0x40,0x13,-3,0x41,-2)
まず、0x40, 0x13を続けて出力し、次に-3でRepeated Startシグナルを送る。続けて0x41で読み込みモードに指定し、最後に-2でNAKモードの1バイト読み込みを行なう。

通信速度

MachiKaniaではNTSCビデオシグナルの作成にCPUのリソースをかなり取られるので、実際の速度は100 kHzよりも落ちる。SYSTEMステートメントでビデオ出力を停止すれば、最大速度で接続する事が出来る。

コメント

コメントはありません

コメント送信