The legacy versions of Plib I2C has code for I2C1 and I2C2 only.  When you try and use fro I2C3, I2C4 etc you're buggered.  You have to use the modern I2C functions instead which is just great because they are horribly documented and don't have direct equivalents for things like IdleI2C1().

Setup I2C Bus


	//----- SETUP I2C 4 -----
	//Used for: 
	I2CConfigure(I2C4, I2C_ENABLE_HIGH_SPEED);
	I2CSetFrequency(I2C4, PERIPHERAL_CLOCK_FREQUENCY, 400000);			//400kHz I2C bus
	I2CEnable(I2C4, TRUE);

I2C Access Defines We Use



//PIC32
#define	LED_DRIVER_I2C_SEND_START					while(!I2CBusIsIdle(I2C4));I2CStart(I2C4)			//Generate bus start condition
#define	LED_DRIVER_I2C_START_IN_PROGRESS_BIT		I2C4CONbits.SEN										//Bit indicating start is still in progress
#define	LED_DRIVER_I2C_SEND_RESTART					I2CRepeatStart(I2C4)								//Generate bus restart condition
#define	LED_DRIVER_I2C_RESTART_IN_PROGRESS_BIT		I2C4CONbits.RSEN									//Bit indicating re-start is still in progress
#define	LED_DRIVER_I2C_SEND_STOP					I2CStop(I2C4)										//Generate bus stop condition
#define	LED_DRIVER_I2C_STOP_IN_PROGRESS_BIT			I2C4CONbits.PEN										//Bit indicating Stop is still in progress
#define	LED_DRIVER_I2C_WRITE_FUNCTION(a)			while(!I2CTransmitterIsReady(I2C4));I2CSendByte(I2C4, a)		//Write byte to I2C device
#define	LED_DRIVER_I2C_TX_IN_PROGRESS_BIT			(!I2CTransmissionHasCompleted(I2C4))				//Bit indicating transmit byte is still in progress
#define	LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT			(!I2CByteWasAcknowledged(I2C4))						//Bit that is high when ACK was not received
#define	LED_DRIVER_I2C_READ_FUNCTION(a)				I2CReceiverEnable(I2C4, TRUE); while(!I2CReceivedDataIsAvailable(I2C4)); a=I2CGetByte(I2C4)	//Read byte from I2C device function / result byte of TCN75_I2C_READ_FUNCTION_START (I2CReceiverEnable will only cause 1 byte to be read, you have to use it again for multiple bytes)
#define LED_DRIVER_I2C_SEND_ACK						I2CAcknowledgeByte(I2C4, TRUE)						//Generate bus ACK condition
#define LED_DRIVER_I2C_SEND_NACK					I2CAcknowledgeByte(I2C4, FALSE)						//Generate bus Not ACK condition
#define	LED_DRIVER_I2C_ACK_IN_PROGRESS_BIT			(!I2CAcknowledgeHasCompleted(I2C4))					//Bit indicating ACK is still in progress
#define	LED_DRIVER_I2C_WAIT_FOR_IDLE				//while(!I2CBusIsIdle(I2C4))						//Test if I2C module is idle (FOR XC32 THIS CAN'T BE USED AFTER START CONDITION SO WE DON'T USE IT)

Write Access



	//----- SEND THE START CONDITION -----
	LED_DRIVER_I2C_WAIT_FOR_IDLE;
	LED_DRIVER_I2C_SEND_START;
	while(LED_DRIVER_I2C_START_IN_PROGRESS_BIT)
		;

	//----- SEND THE I2C DEVICE ADDRESS WITH THE WRITE BIT SET -----
	LED_DRIVER_I2C_WAIT_FOR_IDLE;
	LED_DRIVER_I2C_WRITE_FUNCTION(LED_DRIVER_I2C_BASE_ADDRESS & 0xfe);			//Bit 0 low for write
	while(LED_DRIVER_I2C_TX_IN_PROGRESS_BIT)
		;
	if(LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT)
		goto led_driver_init_write_fail;

	//----- WRITE THE DATA BYTE -----
	LED_DRIVER_I2C_WAIT_FOR_IDLE;
	LED_DRIVER_I2C_WRITE_FUNCTION(0x80);
	while(LED_DRIVER_I2C_TX_IN_PROGRESS_BIT)
		;
	if(LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT)
		goto led_driver_init_write_fail;
		
	//----- SEND STOP -----
	LED_DRIVER_I2C_WAIT_FOR_IDLE;
	LED_DRIVER_I2C_SEND_STOP;
	while(LED_DRIVER_I2C_STOP_IN_PROGRESS_BIT)
		;

Write Address Then Read


<pre><code>

	//Send Start
	LED_DRIVER_I2C_IDLE_I2C;					//Wait for I2C bus to be ready
	LED_DRIVER_I2C_START_I2C;
	while(LED_DRIVER_I2C_START_IN_PROGRESS_BIT)
		;

	//Write Slave address and with RW bit 0 for write
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_WRITE_BYTE(LED_DRIVER_I2C_BASE_ADDRESS);
	while(LED_DRIVER_I2C_TX_IN_PROGRESS_BIT)
		;
	if(LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT ==1)
		goto led_driver_fail;
	
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_WRITE_BYTE(0x00);
	while(LED_DRIVER_I2C_TX_IN_PROGRESS_BIT);
	if(LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT == 1)
		goto led_driver_fail;

	//Send Restart
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_RESTART_I2C;
	while(LED_DRIVER_I2C_RESTART_IN_PROGRESS_BIT)
		;

	//Write Slave address and with RW bit 1 for read
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_WRITE_BYTE(LED_DRIVER_I2C_BASE_ADDRESS | 0x01);
	while(LED_DRIVER_I2C_TX_IN_PROGRESS_BIT)
		;
	if(LED_DRIVER_I2C_ACK_NOT_RECEIVED_BIT == 1)
		goto led_driver_fail;

	//Get byte 0
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_READ_BYTE(b_temp);
	our_reg1 = b_temp;


	//Send Ack
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_ACK;
	while(LED_DRIVER_I2C_ACK_IN_PROGRESS_BIT)
		;

	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_READ_BYTE(b_temp);
	our_reg2 = b_temp;

	//Send NAK
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_NOT_ACK;
	while(LED_DRIVER_I2C_ACK_IN_PROGRESS_BIT)
		;

	//Send Stop
	LED_DRIVER_I2C_IDLE_I2C;
	LED_DRIVER_I2C_STOP_I2C;
	while(LED_DRIVER_I2C_STOP_IN_PROGRESS_BIT)
		;

</code></pre>

 

UK Electronic Designer
USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.