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 problem

HI,

I work on TM4C129 EVM to verify i2c read/write function, basically, it works well.

But I have one RX data shift problem.

I made a test is like this

void test(void)
{
	unsigned char ucData[2];
	unsigned char ucREGData;

	ucData[0] = REG;
	ucData[1] = 0xAA;
	I2CMasterWriteBytes(SLAVE_ADDR, ucData, 2);
	
	ucData[0] = REG;
	I2CMasterBurstReadAfterWrite(SLAVE_ADDR, (unsigned char *)ucData[0], 1, (unsigned char *)&ucREGData, 1);
}

But I can't get the correct data untill I check the RX buffer, the correct data is shifted one byte.

So I modified it to get the correct data.

void test(void)
{
	unsigned char ucData[2];
	unsigned char ucREGData[2]; // modified

	ucData[0] = REG;
	ucData[1] = 0xAA;
	I2CMasterWriteBytes(SLAVE_ADDR, ucData, 2);
	
	ucData[0] = REG;
	I2CMasterBurstReadAfterWrite(SLAVE_ADDR, (unsigned char *)ucData[0], 1, (unsigned char *)&ucREGData[0], 2); // modified
	
	//ucREGData[1] is the required data
}

I also post I2CMasterBurstReadAfterWrite()

int I2CMasterBurstReadAfterWrite(unsigned char ucAddr, unsigned char *pucWriteData, uint_fast16_t ui16WriteCount, unsigned char *pucReadBuff, unsigned short usReadCount)
{
	unsigned char ucRetCode = I2CSUCCESS;

	//Wait for I2C bus idle
	I2CAppWaitTransaction();

	//Set busy state for transation
	g_ucI2CTranState = TRAN_BUSY;
	g_ucI2CDataAccesssState = ACCESS_START;

	//Prepare data
	g_sI2CCallBackData.ucAction = I2C_BURST_READ_AFTER_WRITE;
	g_sI2CCallBackData.ucAddr = ucAddr;
	g_sI2CCallBackData.ucWriteData = pucWriteData;
	g_sI2CCallBackData.ui16WriteCountOfRead = ui16WriteCount;
	g_sI2CCallBackData.usReadCount = usReadCount;
	g_ulRetryCount = 0;

	//I2C access
	ucRetCode = I2CMRead(&g_sI2CInst, ucAddr, (const uint8_t *)pucWriteData, ui16WriteCount, g_pucI2C0Data, usReadCount, I2C0AppCallback, &g_sI2CCallBackData);

	//Wait access finish
	I2CAppWaitAccessFinish();
	if (g_ucI2CDataAccesssState == ACCESS_FAIL)
	{
		ucRetCode = I2CFAIL; //0: fail, 1: success
	}

	//Get the read data
	memcpy(pucReadBuff, g_pucI2C0Data, usReadCount);

	//Release I2C
	g_ucI2CTranState = TRAN_IDLE;

	return(ucRetCode);
}

I didn't meet the such problem before.

Does anyone get idea about my problem?

thanks

Gavin

  • Hello Gavin,

    What I think is happening is that the I2CMasterBusy condition is not getting asserted with one of the byte reads causing the RX data to be shifted by one byte. This is a known limitation on the TM4C129 due to the high frequency of System Clock.

    What you an do is to put the condition as

    while(!I2CMasterBusy(...);

    while(I2CMasterBusy(...);

    instead of

    while(I2CMasterBusy(...);

    Regards,

    Amit