Other Parts Discussed in Thread: TM4C129DNCPDT
Basic information:
Processor: TM4C129DNCPDT
Eeprom: Atmel AT24C256C (256kbits)
Environment: IAR Embedded Workbench
TivaWare_C_Series-2.1.0.12573
I2C set 100KHz rate.
I am trying to understand how the I2C controller works and how to make it work properly with denser EEPROMS.
Bellow the relevant code (adapted from another topic - omitted stuff to avoid too much clutter):
void eepromRead(uint16_t address_u16, uint32_t *rxdata_pu8, uint32_t rxdataLen_u32)
{
uint32_t ret = 0;
I2CMasterSlaveAddrSet(I2C4_BASE, SLAVE_ADDRESS, false);
I2CMasterDataPut(I2C4_BASE, ((address_u16 >> 8) & 0xFF)); //MSB
I2CMasterControl(I2C4_BASE, I2C_MASTER_CMD_BURST_SEND_START);
SysCtlDelay(I2C_CONTROL_DELAY);
while(I2CMasterBusy(I2C4_BASE)) {}
I2CMasterDataPut(I2C4_BASE, (address_u16 & 0xFF)); //LSB
I2CMasterControl(I2C4_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
SysCtlDelay(I2C_CONTROL_DELAY);
while(I2CMasterBusy(I2C4_BASE)) {}
I2CMasterSlaveAddrSet(I2C4_BASE, SLAVE_ADDRESS, true);
I2CMasterControl(I2C4_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE );
SysCtlDelay(I2C_CONTROL_DELAY);
while(I2CMasterBusy(I2C4_BASE)) {}
ret = I2CMasterDataGet(I2C4_BASE) & 0xFF;
rxdata_pu8[0] = ret;
}
int
main(void)
{
ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_10MHZ |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 40000000u);
uint32_t rx[8];
I2C_Init();
while(1)
{
SimpleDelay();
rx[0] = 0x0;
eepromRead(0x248, rx, 1);
eepromRead(0x249, rx, 1);
}
}
To read a random byte out from the EEPROM I must issue a dummy write with two bytes and then a read.
The thing that is baffling me is that I get different results depending on the I2C_CONTROL_DELAY parameter in eepromRead(). With 100 (which if I understand it right causes a delay of about 300 clocks) the read operation works fine.
With a lower value, say 50 (around 150 clocks) I get this:
As you can see on the bottom of the screen, the LSB of the address is missed. I would like to know what I am doing wrong.
To be honest I adde the SysCtlDelay() call after reading somewhere that there was some internal delay in the microcontroller but I do not think one would need so many clocks for the I2C to set the busy flag.
Thank you in advance for any hint.




