Other Parts Discussed in Thread: C2000WARE
I have written the following code to write a byte to an EEPROM (AT24C128C). I can't use interrupts:
uint16_t I2C_EEPROM_WriteByte(uint16_t address, uint16_t byte)
{
uint32_t WaitCount = 0;
// Wait until the STP bit is cleared from any previous master
// communication. Clearing of this bit by the module is delayed until after
// the SCD bit is set. If this bit is not checked prior to initiating a new
// message, the I2C could get confused.
//
if(I2C_getStopConditionStatus(I2CA_BASE))
{
return(ERROR_STOP_NOT_READY);
}
//disable write protect
GPIO_writePin(39, 0);
// To read a word from the EEPROM, an address must be given first in
// master transmitter mode. Then a restart is performed and data can
// be read back in master receiver mode.
I2C_setDataCount(I2CA_BASE, 0x03);
I2C_putData(I2CA_BASE, address>>8);
I2C_putData(I2CA_BASE, address);
//
// Setup data to send
//
I2C_putData(I2CA_BASE,byte);//data word
// Send start as master transmitter
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CA_BASE);
I2C_sendStopCondition(I2CA_BASE);
// Wait until communication done
while(I2C_getStopConditionStatus(I2CA_BASE))
{
if(I2C_getStatus(I2CA_BASE) & I2C_STR_NACK)
{
//clear the NACK bit and stop the transfer
I2C_sendStopCondition(I2CA_BASE);
HWREGH(I2CA_BASE + I2C_O_STR) |= I2C_STR_NACK;
//disable and enable FIFOs to flush them out
I2C_disableFIFO(I2CA_BASE);
I2C_enableFIFO(I2CA_BASE);
//enable write protect
GPIO_writePin(39, 1);
return I2C_NACK_ERROR;
}
}
// Wait until EEPROM is writing and is unresponsive to I2C (max 5ms)
do
{
I2C_setDataCount(I2CA_BASE, 0x02);
I2C_putData(I2CA_BASE, address>>8);
I2C_putData(I2CA_BASE, address);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CA_BASE);
I2C_sendStopCondition(I2CA_BASE);
while(I2C_getStopConditionStatus(I2CA_BASE))
{
if(I2C_getStatus(I2CA_BASE) & I2C_STR_NACK)
break;
}
if(I2C_getStatus(I2CA_BASE) & I2C_STR_NACK)
{
I2C_sendStopCondition(I2CA_BASE);
HWREGH(I2CA_BASE + I2C_O_STR) |= I2C_STR_NACK;
I2C_disableFIFO(I2CA_BASE);
I2C_enableFIFO(I2CA_BASE);
SysCtl_delay(20000);
WaitCount++;
}
else
break;
}
while(WaitCount < 15);
GPIO_writePin(39, 1);//enable write protect
return NO_ERROR;
}
The code is sometimes getting stuck in the while loop at line 66, waiting for the STP bit to go low. Please suggest a way to write proper read and write functions for I2C without using interrupts. All example codes I saw were with interrupt or were with loophole (BootROM example code). Where did i go wrong? And once the STP bit stays high, how do I recover from ths state if I put a timeout inside the loop?
Also, this link is broken: https://processors.wiki.ti.com/index.php/I2C_Tips



