PIC Chip Testing
Notes about getting I2C to run on a PIC chip.
Setting up the test equipment
Bus Pirate - Note the order of the wires. On my version Yellow is Clock(SCL) and Orange is MOSI(SDA). Connect ground (Blk) to board.
LogicSniffer - Java program. Use2 Channel 2 (clk) and Channel 3 (data) for the lines. Use Hex Mask 'c' to trigger on lines 2 and 3. This doesn't match the tutorials, which use lines 0 and 1.
Used i2c-tools in BBB as the master test device. P9 pin 19 = SCL and P9 pin 20 = SDA. The SRM calls these pins as I2C2, but i2ctools refer to these as '1'.
Used 5.6K pull up resistors on SDA/SCL.
i2cdetect -y -r -1
[email protected]:~# i2cdetect -l i2c-0 i2c OMAP I2C adapter I2C adapter i2c-1 i2c OMAP I2C adapter I2C adapter
PICkit 3 works great for program. Does not have debugger support in MPLAB X. Use simulator for debugging.
Used 3.3V from BBB to power 12LF1552.
- Link to PICKit3 manual: http://ww1.microchip.com/downloads/en/DeviceDoc/51795B.pdf
- Link to 12LF1552 manual: http://ww1.microchip.com/downloads/en/DeviceDoc/41674B.pdf
- Link to BBB SRM: https://www.adafruit.com/datasheets/BBB_SRM.pdf
To dump the first three registers:
i2cdump -y -r 0x00 0x02 1 0x08
MCC Generated Code for I2C
MPLAB X generates the I2C code, but it wasn't obvious how to use it and I couldn't find any example. However, it's easy once you know a couple of things. I'm using I2C tools to interrogate the I2C bus. i2cdump asks for values in successive register locations. (e.g. register 0x00, 0x01, 0x02, etc.)
- Each data element coming from the master generates an interrupt in the 12LF1552.
- I2C_ISR() evaluates the various bits to decide what type of data it just received
- Then I2C_ISR() calls the callback function, I2C_Status_Callback() to react
The general flow goes like this:
- The master sends the address byte with R bit set followed by ACK.
- The slave decodes/matches the address, sets a flag to let the program know the next byte is the register address.
- The master sends the data byte, followed by an ACK, which is the register value to read.
- The slave retrieves the register value and puts it into SSP1BUF
- The slave sends START, the slave address with the W bit set, followed by the data byte, NACK and STOP
- Process is repeated for the next register address.
Here is the bus pirate output.
[0x10+0x00+[0x11+0x03-[0x10+0x01+[0x11+0x02-][0x10+0x02+[0x11+0x14-] Where: [ start + ACK ] stop -NACK So start 0x08 with R/W 0 ACK 0x00 ACK -> Looking for register zero at address 0x08 Response: start 0x08 with R/W 1 ACK 0x03 NACK -> response was 0x03
The default MCC code uses an 'EEPROM_Buffer' array as an example, but for my project, I replaced it with a simple three byte array. The array represents the module type, A/D high byte and A/D low byte.