Lispと一緒(34) ラズパイPico2でもuLisp、I2Cメモリ読み書き

Joseph Halfmoon

Common Lispの系譜を継ぐuLispをラズパイPico2マイコン上で練習中。前回はI2CバスにSCANをかけ、接続したメモリが接続したつもりのアドレスに「居る」ことを確認できました。今回は実際にメモリにライトしてリードしてみます。リードのところの手順にちょっとテク?いるけれども、どおってことない。ホントか?

※Lispと一緒 投稿順 index はこちら

※実機確認は Raspberry Pi Pico2で行ってます。

※使用させていただいとります uLisp のバージョンは 4.6b (Arm用)です。

24LC64、I2C接続 64kb EEPROM

今回I2Cバスに接続したのは以下のEEPROMです。

MICROCHIP 24LC64 64Kb I2C compatible 2-wire Serial EEPROM

I2Cアドレスは0x50(10進で80)から0x57(10進で87)のうち1か所を指定できるようになっているので、0x50(10進で80)としてあります。Pico2ボードとの回路結線図は前回ご参照くだされ。

64Kビット(8bit x 8K構成)です。I2Cバスなので8ビット単位の出し入れとなり、アドレスは上位5ビット、下位8ビットの合計13ビットを2回にわけて送信です。なおEEPROMであるので、書き込み後、電源を落としても値は保持されます。

シーケンシャルRWなどのモードを使うとまとまった塊で連続したリード、ライトを行えます。今回はランダム・アクセスで1バイトづつ書きこむ/読み出す方法を実験してみたいと思います。

書き込み、読み出し関数の定義

書き込みはWriteを連続すればよいだけなので、SPI使ったWriteとほぼ同様です。I2Cバス上のアドレスを指定、(str 80)の80は先ほど出てきたI2Cバスのアドレス(10進)した後、2回にわけてメモリアドレスを送り、最後にデータ8ビットを送ります。

しかし、読み出しはまずI2Cライトでメモリ・アドレスを書きこんでから、今度は一転I2Cリードを行わないとならない(I2Cリードの頭で2回目のスタートビットが必要)です。SPIのときとはチョイと異なり with-i2cを2回やってます。なおリードのときの(str 80 1)の1はリードで読み込むのは1バイトね、という御印です。メモリ側からはリードの末尾でACKが返ってこないので1バイト読んだら末尾ね、と言っておく必要ありみたいです。

(defun write24LC64 (addr dat)
  (with-i2c (str 80)
    (write-byte (logand #xFF (ash addr -8)) str)
    (write-byte (logand #xFF addr) str)
    (write-byte (logand #xFF dat) str)))

(defun read24LC64 (addr)
  (with-i2c (str 80)
    (write-byte (logand #xFF (ash addr -8)) str)
    (write-byte (logand #xFF addr) str))
  (with-i2c (str 80 1)
    (read-byte str)))
実機実行結果

ブレッドボード上に組み立てた実機が以下に。I2CmemRW_BB

上記のRW関数を定義した上で実機上で実行した結果が以下に。I2CmemRWsample

読み書き出来ているようだね。

Lispと一緒(33) ラズパイPico2でもuLisp、I2Cポートスキャン へ戻る

コメントを残す

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