I2C Slave¶
The TWI module of the Atmega’s allows slave operations as well. Unfortunately it is a lot more complex to setup and use. Basically an interrupt routine does all the work needed to receive and send data.
Initialization¶
The I2C slave mode needs only the address. This address has to be in the 7 bit range of the i2c address space. Any address will do.
> $42 i2c.slave.init
With that, an I2C Bus Scanner from the master’s side reveals the presence of an device at address $42.
(ATmega1284P)> i2c.detect
0 1 2 3 4 5 6 7 8 9 A B C D E F
0: -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- 3D -- --
40: -- -- 42 -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
ok
Data exchange¶
This section describes work-in-progress. The design may change considerably in the future, check the actual code.
Circular buffer¶
The I2C slave mode uses a small circular buffer for data exchange. Bytes received are appended to it, wrapping around after 16 bytes. Every I2C read reads from it.
On the client side there are three words: i2c-in
i2c-out
and
i2c-buffer
. The last one is the base address of the i2c send/receive
buffer. The i2c-in
points into that buffer at the most recently
received byte. Similarly the i2c-out
points to the most recently
read byte. Both pointers wrap around if the buffer size is reached.
Direct Address¶
TBD, Idea: send a start address and start reading from or writing to it until NACK. The EEPROM 24Cxx protocol is probably a good starting point.