93C56というEEPROMからデータを読み書きする必要があったのだけれど、ROMリーダー/ライターが売られてない…
そこで手元にあったESP32とmicropythonでEEPROMと通信し、データの読み書きをしてみました。
こんな事やりたい人いないだろうけど、、
概要
EEPROMは家電や車載システムなどに搭載され、永続的にデータを保持するために用いる。
EEPROMにも通信方式や容量で様々な種類があるけど、今回は93CシリーズというチップをESP32+micropythonを使って通信する。
93Cx6
93Cx6は、EEPROMのシリーズの一つで、通信方式はMicrowire
。ROHMによるとこうらしい。なんか微妙だね。。
Microwire
比較的古い通信方式です。通信速度もSPIと比較し遅く、低容量をラインアップしています。
インターフェースの本数は4本とI2Cと比較し多いです。
- SPIと比較し、通信速度が遅い
- 容量ラインアップが低容量のみ
容量によって型番が次のように決まっている。
型番 | 容量 |
---|---|
93C46 | 128Byte |
93C56 | 256Byte |
93C66 | 512Byte |
93C76 | 1024Byte |
93C86 | 2048Byte |
尚、93Cx6という名前は通称名で、同じ名前のチップが各社から発売されている。
物によってはアドレス指定をバイト単位かワード単位か選べたり、シーケンシャルリードができたりするけど基本的には同じ。使ってるチップのデータシートを参照のこと。
アドレッシング
メーカーによって違いがあるが、アドレス指定の単位をバイト(B)かワード(2B)か指定できる。
ワード単位を選んだ場合、指定できるアドレスの上限は総バイト数の半分となる。
環境
- ESP32-devkit-C
- S93C56(EEPROM)
- micropython
- M1 Macbook Air
ESP32にMicropythonを書き込む
ファームウェアをダウンロード
https://micropython.org/download/esp32/
Firmwareから最新版のstableリリースをダウンロードする
esptool, ampyをインストール
pip install esptool
pip install adafruit-ampy
ファームウェアの書き込み
ESP32をPCに接続する。
macの場合は/dev/
配下にcu.usbserial-0001
が現れる。
Flashの消去
esptool.py --port /dev/cu.usbserial-0001 erase_flash
書き込み
ダウンロードしたファームウェアがesp32-20220117-v1.18.bin
の場合:
esptool.py --chip esp32 --port /dev/cu.usbserial-0001 --baud 46080 write_flash -z 0x1000 esp32-20220117-v1.18.bin
main.pyを書く
main.pyにやりたい処理を書いてESP32に転送する。
拙作のライブラリ(https://github.com/namacha/micropython-93cx6) を使ってEEPROMとやりとりする。
model
: 型番。対象のチップに合わせて変更する。
org
: チップのアドレッシングがバイト単位かワード単位かによって変える
cs sk di do
通信に使うピンを番号で指定。
以下は93C56(ワード単位)の例
データ読み出し
データを読み出して16進ダンプを表示する例
from eeprom_93cx6 import Device
dev = eeprom_93cx6.Device(
model=56,
org=eeprom_93cx6.EEPROM_MODE_16BIT,
cs=12,
sk=13,
di=14,
do=15,
)
def dump_buffer(buf, start=0):
num_lines = len(buf) // 8
for nlines in range(num_lines):
addr = (8 * nlines) + start
print(f"0x{addr:02X} ", end="")
for v in buf[nlines * 8 : 8 * (nlines + 1)]:
print(f"{v:04X} ", end="")
print()
buf = []
for addr in range(0, 128):
value = dev.read(addr)
buf.append(value)
dump_buffer(buf, start=0)
データ書き込み
0x0aに0xcdを書き込む例。
from eeprom_93cx6 import Device
dev = eeprom_93cx6.Device(
model=56,
org=eeprom_93cx6.EEPROM_MODE_16BIT,
cs=12,
sk=13,
di=14,
do=15,
)
dev.ew_enable()
addr = 0xa
dev.write(addr, 0xcd)
dev.ew_disable()
def dump_buffer(buf, start=0):
num_lines = len(buf) // 8
for nlines in range(num_lines):
addr = (8 * nlines) + start
print(f"0x{addr:02X} ", end="")
for v in buf[nlines * 8 : 8 * (nlines + 1)]:
print(f"{v:04X} ", end="")
print()
buf = []
for addr in range(0, 128):
value = dev.read(addr)
buf.append(value)
dump_buffer(buf, start=0)
スクリプトをESP32に転送する
ESP32にはmicropythonの処理系が書き込まれている前提。
プログラムの転送にはampy
を使った。
ライブラリをローカルに落としてくる。
$ git clone https://github.com/namacha/micropython-93cx6
ライブラリの転送
ampy -p /dev/cu.usbserial-0001 put micropython-93cx6/eeprom_93cx6.py
main.pyの転送
ampy -p /dev/cu.usbserial-0001 put main.py
配線
main.py
で設定したピン番号に合わせてICと接続する
VCC
| NC(Don't Care)
| | TEST(Don't Care)
| | | GND
| | | |
__|__|__|__|__
| | | | | |
| 8 7 6 5 |
| |
|.1 2 3 4 |
|_|__|__|__|_|
| | | |
| | | DO(Data Out)
| | DI(Data In)
| SK(Serial clocK)
CS(Chip Select)
オンボードのチップに接続する場合、グラバーというクリップがあるとICの足をつかみやすい。ただし、表面実装のICの場合1本だけは狭すぎてクリップが噛み込めないので読み書きの際に手で当てる。
読み出し・書き込み
screen /dev/cu.usbserial-0001 115200
で、ESP32のシリアルコンソールに接続できる。
この状態でCtrl-DでESP32をリセットするとmain.pyが実行される。
0x00 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x08 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x10 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x18 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x20 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x28 FF80 FF80 FF80 FF80 FF80 FF80 FF80 FF80
0x30 FF80 66AF FF66 66AF FF66 66AF FF66 FFFF
0x38 FFFF FFFF FFFF A2AD A2AD A2AD A2AD CBA9
0x40 FFED A2AD CBA9 FFED A2AD CBA9 FFED A2AD
0x48 CBA9 FFED A2AD CBA9 FFED A2AD CBA9 FFED
0x50 FFFF 3333 FF33 ACFF ACFF ACFF FFFF FFFF
0x58 FFFF 1A1A 1A1A FFFF 1BFF FFFF 1EFB FFFF
0x60 1E1E 1E1E FFFF FFFF FFFF FFFF FFFF FFFF
0x68 FFFF FFFF 1F1F 1F1F 9EB6 FFFE FBFB FBFB
0x70 FBFB FFED FFED FFED FDFE FDFE FDFE FFFF
0x78 FFFF FFFF FFFF FFFF FFFF FFFF F7FF F7F7