The attached code works fine accessing an attached EEPROM (CAT24C512-D). I can write/read but only with band-aids because I cannot get the CNT register to decrement which effects the status register (I have NEVER seen ARDY active). I scope the lines and the signals are good (scope decoder shows correct data.
What am I doing wrong here? why can't i get CNT to decrement?
#include "includes.h" #include "HL_i2c.h" #include "HL_reg_i2c.h" static void EEDebugMsg(char *sMsg); static void i2cSetFreeRun(i2cBASE_t *i2c, bool bTrue); #define EEPROM i2cREG1 void EEInit() { i2cInit(); i2cSetSlaveAdd(EEPROM, '\x50'); // EEPROM at Addr=1001_000 } #define I2C_RX (0) #define I2C_TX (1) int I2C_Read_M(short Slave_Add, short Read_Add, short Count, uint8 *buff); static bool eeWriteByte(UINT16 uAddr, UINT8 uData); static bool eeReadByte(UINT16 uAddr, UINT8 *uData); // TEST FUNCTIONS static bool EERandomAccessTest(); bool EETest() { UINT8 uTestWr[] = {"\x01\x23\x55"}; UINT16 uAddrs[5] = {0x0000, 0x09de, 0x6E50, 0xFFFA, 0x0555}; UINT8 uData[5] = {0x44, 0x22, 0x10, 0x32, 0x77}; UINT8 uReadback[10]; char sBuf[256]; BOOL bPass=true; BOOL bErr = false; if (EERandomAccessTest()) EEDebugMsg("\nRANDOM ACCESS TEST PASSED"); else EEDebugMsg("\n************ RANDOM ACCESS TEST FAILED **************"); } #define EE_I2C_ADDRESS ('\x50') static bool eeReadByte(UINT16 uAddr, UINT8 *uData) { UINT8 uTx[3]; bool bNoAck = false; // Build 3-byte packet <ADDR><DATA> memcpy(uTx, &uAddr, 2); UINT16 STR = EEPROM->STR; UINT16 CNT = EEPROM->CNT; while (!i2cIsTxReady(EEPROM)); // Wait for finish before checking for NACK EEPROM->STR |= (uint32)I2C_NACK_INT; // Clear NACK flag i2cSetSlaveAdd(EEPROM, EE_I2C_ADDRESS); // EEPROM at Addr=1001_000 (x50) i2cSetMode(EEPROM, I2C_MASTER); // Must be set again after every STOP condition i2cSetDirection(i2cREG1, I2C_TRANSMITTER); i2cSetCount(i2cREG1, 2); // Send 2 address bytes i2cSetStart(EEPROM); // Sets MDR.STT. Generates Start + I2C Address i2cSend(EEPROM, 2, uTx); // send address x123 (no STOP) if((i2cREG1->STR & I2C_NACK) == 0) // Check for Positive Acknoledge { i2cSetMode(i2cREG1, I2C_MASTER); // Switch to Master Receiver i2cSetDirection(i2cREG1, I2C_RECEIVER); i2cSetCount(i2cREG1, 0x01); // read in 1 byte i2cSetStart(i2cREG1); //I2C BUS: Start--Slave Addr *uData = i2cReceiveByte(i2cREG1); // Read incoming data and store in array } if (EEPROM->STR & I2C_NACK_INT) bNoAck = true; return bNoAck; } static bool eeWriteByte(UINT16 uAddr, UINT8 uData) { UINT8 uTx[3]; bool bNoAck = false; // Build 3-byte packet <ADDR><DATA> memcpy(uTx, &uAddr, 2); uTx[2] = uData; // I2C Setup EEPROM->STR |= (uint32)I2C_NACK_INT; // Clear NACK flag i2cSetSlaveAdd(EEPROM, EE_I2C_ADDRESS); // EEPROM at Addr=1001_000 (x50) i2cSetMode(EEPROM, I2C_MASTER); // Must be set again after every STOP condition i2cSetDirection(EEPROM, I2C_TRANSMITTER); // MDR.TRX = 1 // Transmit device address + WR i2cSetCount(EEPROM, 3); // CNT = 3 (Transmit 3 bytes) i2cSetStart(EEPROM); // Sets MDR.STT. Generates Start + I2C Address while (!i2cIsTxReady(EEPROM)); // wait for end of tx // Transmit Packet i2cSetStop(EEPROM); // Transmit STOP after CNT=0 i2cSend(EEPROM, 3, uTx); // Send <ADDR><DATA> while (!i2cIsTxReady(EEPROM)); // Wait for finish before checking for NACK if (EEPROM->STR & I2C_NACK_INT) bNoAck = true; return bNoAck; } void i2cSetFreeRun(i2cBASE_t *i2c, bool bTrue) { uint32 temp_mdr; temp_mdr = (i2c->MDR & (~I2C_FD_FORMAT)); if (bTrue) temp_mdr |= I2C_FD_FORMAT; i2c->MDR = temp_mdr; } static bool EERandomAccessTest() { UINT16 uAddrs[5] = {0x0000, 0x09de, 0x6E50, 0xF3FA, 0x0555}; UINT8 uData[5] = {0x54, 0x25, 0x15, 0x52, 0x75}; UINT8 uReadback[10]; char sBuf[256]; BOOL bPass=true; BOOL bErr = false; EEDebugMsg("\n\nEE RANDOM ACCESS TEST"); debugText("\n\n\rTest @ 10 Pseudo-Random Addresses:\n\t\r"); debugText("\n\rWrite: "); #if 1 UINT16 uAO1=299, uAO2=1024; UINT8 uDO1=0x13, uDO2=0xd3; for (UINT8 i=0; i<5; i++) { sprintf(sBuf," %04x:%02x", uAddrs[i]+uAO1, i+uDO1); debugText(sBuf); sprintf(sBuf," %04x:%02x", uAddrs[i]+uAO2, i+uDO2); debugText(sBuf); } for (uint8 i=0; i<5; i++) { bErr |= eeWriteByte(uAddrs[i]+uAO1, i+uDO1); debugWaitMs(10); bErr |= eeWriteByte(uAddrs[i]+uAO2, i+uDO2); debugWaitMs(10); } debugText("\n\rRead: "); for (uint8 i=0; i<5; i++) { bErr |= eeReadByte(uAddrs[i]+uAO1, &uReadback[i]); debugWaitMs(10); bErr |= eeReadByte(uAddrs[i]+uAO2,&uReadback[i+5]); debugWaitMs(10); } for (uint8 i=0; i<5; i++) { sprintf(sBuf," %04x:%02x", uAddrs[i]+uAO1, uReadback[i]); debugText(sBuf); debugWaitMs(5); sprintf(sBuf," %04x:%02x", uAddrs[i]+uAO2, uReadback[i+5]); debugText(sBuf); debugWaitMs(5); } for (uint8 i=0; i<5; i++) { if (uReadback[i] != i+uDO1) bPass=false; if (uReadback[i+5] != i+uDO2) bPass=false; } #else /* WORKS */ UINT8 v1=0x16, v2 = 0x22; for (int i=0; i<5; i++) { sprintf(sBuf,"\n\rWriting 0x%02x to Address 0x%04x", i+v1, uAddrs[i]); debugText(sBuf); bErr |= eeWriteByte(uAddrs[i], i+v1); debugWaitMs(10); // Delay needed for write to finish bErr |= eeReadByte(uAddrs[i], &uReadback[i]); debugWaitMs(10); sprintf(sBuf," ***** Readback Address 0x%04x = 0x%02x",uAddrs[i], uReadback[i]); debugText(sBuf); } for (int i=0; i<5; i++) if (uReadback[i] != i+v1) bPass=false; for (int i=0; i<5; i++) { sprintf(sBuf,"\n\rWriting 0x%02x to Address 0x%04x", i+v2, uAddrs[i]+5); debugText(sBuf); bErr |= eeWriteByte(uAddrs[i]+5, i+v2); debugWaitMs(10); bErr |= eeReadByte(uAddrs[i]+5, &uReadback[i+5]); debugWaitMs(10); sprintf(sBuf," ***** Readback Address 0x%04x = 0x%02x",uAddrs[i]+5, uReadback[i+5]); debugText(sBuf); } for (int i=0; i<5; i++) if (uReadback[i+5] != i+v2) bPass=false; #endif return bPass; } static void EEDebugMsg(char *sMsg) { #ifdef DRIVER_DEBUG const char sPfx[] = {"\n\reeDRV.c: "}; debugText((uint8 *)sPfx, strlen(sPfx)); debugText((uint8 *)sMsg, strnlen(sMsg,255)); #endif }