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