Brak opisu

kbere 65e9d87ef9 Initial commit. Basic tests successful 3 dni temu
firmware 65e9d87ef9 Initial commit. Basic tests successful 3 dni temu
host 65e9d87ef9 Initial commit. Basic tests successful 3 dni temu
.gitignore 65e9d87ef9 Initial commit. Basic tests successful 3 dni temu
README.md 65e9d87ef9 Initial commit. Basic tests successful 3 dni temu

README.md

USB-I2C bridge (ATmega8U2 + TCA9539)

USB CDC-ACM (virtual COM port) to I2C master. No LUFA, no interrupts: ~2.5 KB flash.

  • Windows 10/11: binds inbox usbser.sys automatically (no driver/INF). Windows 7/8 need a stock CDC INF.
  • Linux: cdc_acm -> /dev/ttyACMx. Add the udev rule below so ModemManager does not probe it.
  • I2C is bit-banged (the 8U2 has no TWI): SCL=PD3, SDA=PD2, open drain. External pull-ups (2.2-4.7 k to 5 V) are required. Default ~400 kHz (set_delay(4)), set_delay(0) is ~1 MHz (TCA9539 supports Fm+ if your pull-ups/capacitance allow).
  • Clock stretching supported; stuck-SDA bus recovery runs automatically before a transaction.

Build / flash (USBasp)

cd firmware
make
make fuses     # once: external crystal, CKDIV8 off (lfuse FF hfuse D9 efuse F4 - same as Arduino Uno 8U2)
make flash

Without the crystal fuse the chip runs from the 8 MHz/8 RC and USB will not enumerate. Flashing over ISP overwrites any DFU bootloader. Use make VBUS=1 if PB6 carries a VBUS sense (attach to USB only while PB6 high); not needed for a bus-powered board.

Protocol (binary, 0xA5-framed; frames may be concatenated)

Request Reply
A5 01 addr wlen rlen wdata.. (I2C xfer, 7-bit addr, <=32 B per phase; wlen&rlen>0 = repeated START; both 0 = probe) status [rdata]
A5 02 n set SCL delay status
A5 03 ping 00 proto maxlen
A5 04 bus recovery status

Status: 0 OK, 1 NACK addr, 2 NACK data, 3 bus error, 0x10 bad op, 0x11 bad length. Bytes outside a frame are ignored and a stalled frame is dropped after ~100 ms.

Speed: a USB bulk round trip is ~1 ms, so unbatched transactions are ~1000/s. Pipeline many frames in one write (Bridge.batch): the device answers a whole 64-byte OUT packet with one IN packet.

Host

pip install pyserial
python host/usbi2c.py COM5        # or /dev/ttyACM0 : scan, blink port 0, benchmark
from usbi2c import Bridge, TCA9539
io = TCA9539(Bridge("COM5"), 0x74)   # A1/A0 select 0x74..0x77
io.set_direction(0xFF00); io.write(0x00AA); print(hex(io.read()))

Linux udev (/etc/udev/rules.d/99-usbi2c.rules):

SUBSYSTEM=="tty", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="0001", ENV{ID_MM_DEVICE_IGNORE}="1", MODE="0666"

VID/PID 1209:0001 is the pid.codes test pair; change it in usb.c for anything shipped.