I²C (Part 1) - Building an I²C slave + Theory
i2c is a nice protocol: it is quite fast, reliable, and most importantly, it's addressable. This means that on a single 2-wire bus, you'll be able to plug up to 128 devices using 7bits addresses, and even 1024 using 10bits address. Far enough for most usage... I won't cover i2c in depth, as there are plenty resources on the Web (and I personally like this page).
A few words before getting our hands dirty...
i2c is found in many chips and many modules. Most of the time, you create a master, like when accessing an EEPROM chip. This time, in this three parts tutorial, we're going to build a slave, which will thus respond to master's requests.
The slave side is somewhat more difficult (as you may have guess from the name...) because, as it does not initiate the talk, it has to listen to "events", and be as responsive as possible. You've guessed, we'll use interrupts. I'll only cover i2c hardware slave, that is using SSP peripheral1. Implementing an i2c software slave may be very difficult (and I even wonder if it's reasonable...).
There are different way implementing an i2c slave, but one seems to be quite common: defining a finite state machine. This implementation is well described in Microchip AppNote AN734. It is highly recommended that you read this appnote, and the i2c sections of your favorite PIC datasheet as well (I swear it's quite easy to read, and well explained).
- Master writes, and last byte was an address: to sum up, master wants to talk to a specific slave, identified by the address, it wants to send data (write)
- Master writes, and last byte was data: this time, master sends data to the slave
- Master read, and last byte was an address: almost the same as 1., but this time, master wants to read something from the salve
- Master read, and last byte was data: just the continuation of state 3., master has started to read data, and still wants to read more data
- Master sends a NACK: basically, master doesn't want to talk to the slave anymore, it hangs up...
Example: consider the following address (8-bits long, last bit is for operation type)
0x5C => 0b_0101_1100 => write operation
The same address for read operation will be:
0x93 => 0b_0101_1101 => read operation
OK, enough for now. Next time, we'll see how two PICs must be connected for i2c communication, and we'll check the i2c bus is fully working, before diving into the implementation.