The Microchip I2C drivers and their APIs that ship with the MPLAB compiler are almost impossible to debug or understand. For some unfathomable reason, they have distributed the I2C access code in 10 (or more) different files with 5 lines of code each. So I’ve managed to put together a simple (and what I consider to be intuitive) driver. I have tested it with different slaves on PIC18, PIC24 and PIC32, and it seems to work seamlessly with only a change in .h file #defines for PIC24 and PIC32, while for PIC18 some register names are different.
Before you start, you should be aware that the PIC I2C engine cannot queue commands. So you have to wait in software for each command to be completed before issuing the next one. For example, you issue the start condition command then wait till the engine is not busy before issuing the next command.
The driver implements the following interfaces:
- Reading from the I2C peripheral:
1 2 3
This Writes the Regiser Number (reg) on to the slave, and then issues continuous Reads for a total of
len times. Typically the slave will just have one byte of data per resister, in which case you just have to pass len = 1. If the slave stores more than one byte in a perticular “register” location, you can read out that too. All the data is copied to the rxPtr.
slave_adr is the 7-bit I2C address of the slave device. Internally, the function also waits for some time (100 iterations of a loop) for the slave to generate an ACK, in case it is slow to respond. You can modify this to suit your peripheral.
- Writing to the I2C peripheral
1 2 3
Write is a bit simpler than the Read. You write the resigter number you want to write to, wait and repeat if there is no ACK. Once you get an ACK, just dump the data byte by byte on the poor old slave.
For most I2C slaves, this is all the access you need.
To port the driver, change the register mapping section in the .h file, along with the Slave address, and then configure the correct baud rate. These sections are highlighted below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
The code can be downloaded here. The PIC18 driver includes code to communicate with MLX90614 Infra Red Temperature Sensor and implements the SMBus protocol including the calculation of CRC. So you can use it to modify all of the MLX registers, not just read temperature.
An example of the usage is:
1 2 3 4 5 6 7 8 9 10 11 12