This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129 I2C read

Other Parts Discussed in Thread: TM4C129ENCPDT

Hi,

I'm writing code for TM4C129ENCPDT and I'm having trouble reading from an I2C bus expander PCAL9555A.

This code is ported from Cortex LM3S9B96.

From the scope captures it seems that there is only 1/2 of the clock pulsed on the SCL line and the data that is read back is always "0"

Please help.

uint32_t gSysCtlClock;  					//the system clock
uint8_t  endPointAddress = 0x77;			//I2C bus address
uint8_t  data[2];							//data to read

#define I2C_WRITE_DIRECTION      0x00
#define I2C_READ_DIRECTION       0x01
#define I2C_MASTER_MAX_RETRIES   1000        // Number of retries

void main() {

	clockInit();
	GPIO_Init();
	I2C_Init();

	while(1) {

		//Write the command
		I2CMasterSlaveAddrSet(	I2C2_BASE,
								endPointAddress,		//7-bit slave address
								I2C_WRITE_DIRECTION);	//write
		I2CMasterDataPut(I2C2_BASE, 0x00);				//cmd = read registers
		if(I2CMasterBusBusyTimeOut(I2C2_BASE))	return BUSY;
		I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);

		if(I2CMasterBusyTimeOut(I2C2_BASE)) {
			I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);
			return FAIL;
		}

		//read 1th word
		I2CMasterSlaveAddrSet(	I2C2_BASE,
								endPointAddress,		//7-bit slave address
								I2C_READ_DIRECTION);	//read
		I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

		if(I2CMasterBusyTimeOut(I2C2_BASE)) {
			I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);
			return FAIL;
		}
		data_p[i++] = I2CMasterDataGet(I2C2_BASE);
		I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

		if(I2CMasterBusyTimeOut(I2C2_BASE)) {
			return FAIL;
		}

		//read the last word
		data_p[i] = I2CMasterDataGet(I2C2_BASE);

	}//while(1)
}//main



//wait for the bus to be ready
uint16_t I2CMasterBusBusyTimeOut(unsigned long ulBase){

	uint16_t i;

	//wait for the bus to be idle
	for(i = 0; i < I2C_MASTER_MAX_RETRIES; i++) {
		if(!I2CMasterBusBusy(ulBase))			return FALSE;
		SysCtlDelay(gSysCtlClock * 10e-6);		//wait 10us
	}
	if(I2CMasterBusBusy(ulBase))				return TRUE;
	else 										return FALSE;
}
void I2C_Init(void) {
	// Initialize the I2C master.
	I2CMasterInitExpClk(I2C2_BASE,
						gSysCtlClock,
						true);				//400 kbps
	I2CMasterEnable(	I2C2_BASE);			//set as master
}
void clockInit() {
	SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ);
	gSysCtlClock = SysCtlClockFreqSet(
						SYSCTL_USE_PLL    |
						SYSCTL_OSC_MAIN   |
						SYSCTL_XTAL_25MHZ |
						SYSCTL_CFG_VCO_400,
						120000000);		//desired system frequency
}

void GPIO_Init(void) {

	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);		//I2C: bus expander
	SysCtlPeripheralReset(SYSCTL_PERIPH_I2C2);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
	SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOL);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	SysCtlPeripheralReset(SYSCTL_PERIPH_GPION);


	GPIOPinConfigure(GPIO_PL1_I2C2SCL); //I2C2 SCL
	GPIOPinConfigure(GPIO_PN4_I2C2SDA); //I2C2 SDA

	GPIOPinTypeI2CSCL(GPIO_PORTL_BASE, GPIO_PIN_1);	//I2C2 SCL
	GPIOPinTypeI2C   (GPIO_PORTN_BASE, GPIO_PIN_4);	//I2C2 SDA
}

  • Might that "ported code" have suffered (some) loss in translation?

    Vendor's Amit has produced many I2C code examples for TM4C129 - there ARE substantial changes AND additions! (between past LM3S & 4C129)
  • I did several compares with code that has been posted on e2e and the only change that I found was the addition of the I2CMasterEnable( ).
    Everything else seemed to be exactly the same. except a single post that talks about the bus busy wait statements (see below).
    - while (!(I2CMasterBusy(I2C2_BASE))); //Wait till end of transaction
    - while (I2CMasterBusy(I2C2_BASE)); //Wait till end of transaction
    Played with the wait timing, but no success either.

    Khaled.
  • Yes - that (odd) double read of I2CMasterBusy does jump out.

    I did note that you employed I2CMasterBusBusy() and unless multiple I2C "Masters" are in play - I don't believe that function is one you want.

    While you've found (one) post dealing w/4C129 I believe there have been (many) such posts - and absent factory's arrival - that seems your best bet for progress...
  • Got it to work. I had the wrong I2C address :-)
    thanks.
    Khaled.