Hello, I am using a AT24C08 for store some datas and I'm having trouble. I am using code sample for I2C. The data is being written and read perfectly, but the function I2CStart() return always "timeout". This "problem" causes a delay in my routines of W/R. I believe it is necessary some modification in I2C0_IRQHandler() function. Someone could review my code?
I implemented a matricial keypad for tests of write and read.
=> but the function I2CStart() return always "timeout". Do you mean that I2CStart() returns FALSE due to timeout?
uint32_t I2CStart( void ) { uint32_t timeout = 0; uint32_t retVal = FALSE; /*--- Issue a start condition ---*/ LPC_I2C0->I2CONSET = I2CONSET_STA; /* Set Start flag */ /*--- Wait until START transmitted ---*/ while( 1 ) { if ( I2CMasterState == I2C_STARTED ) { retVal = TRUE; break; }
But it seems you never assign an I2C_STARTED to I2CMasterState.
Search "I2CMasterState" (10 hits in 1 files) new 1 (10 hits) Line 6: volatile uint32_t I2CMasterState = I2C_IDLE; Line 48: I2CMasterState = I2C_NO_DATA; Line 71: I2CMasterState = I2C_OK; Line 79: I2CMasterState = I2C_NACK_ON_DATA; Line 112: I2CMasterState = I2C_OK; Line 120: I2CMasterState = I2C_NACK_ON_ADDRESS; Line 127: I2CMasterState = I2C_ARBITRATION_LOST; Line 146: if ( I2CMasterState == I2C_STARTED ) Line 201: I2CMasterState = I2C_IDLE; Line 213: if ( I2CMasterState == DATA_NACK )
An old thread may be relevant: http://www.keil.com/forum/19195/
Yes, the I2CStart() returns FALSE. This code is a driver sample of NXP for PCA8581, but don't work with my 24C08. I tried using the code below, but don't work. There is some error in I2C0_IRQHandler() that I can't find.
void I2C0_IRQHandler(void) { uint8_t StatValue; /* this handler deals with master read and master write only */ StatValue = LPC_I2C0->I2STAT; switch ( StatValue ) { case 0x08: /* A Start condition is issued. */ LPC_I2C0->I2DAT = I2CMasterBuffer[0]; LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); I2CMasterState = I2C_STARTED; break; case 0x10: /* A repeated started is issued */ LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); I2CMasterState = I2C_RESTARTED; break; case 0x18: /* Regardless, it's a ACK */ if ( I2CMasterState == I2C_STARTED ) { LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex]; WrIndex++; I2CMasterState = DATA_ACK; } LPC_I2C0->I2CONCLR = I2CONCLR_SIC; break; case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */ case 0x30: if ( WrIndex != I2CWriteLength ) { LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */ WrIndex++; if ( WrIndex != I2CWriteLength ) { I2CMasterState = DATA_ACK; } else { I2CMasterState = DATA_NACK; if ( I2CReadLength != 0 ) { LPC_I2C0->I2CONSET = I2CONSET_STA; /* Set Repeated-start flag */ I2CMasterState = I2C_REPEATED_START; } } } else { if ( I2CReadLength != 0 ) { LPC_I2C0->I2CONSET = I2CONSET_STA; /* Set Repeated-start flag */ I2CMasterState = I2C_REPEATED_START; } else { I2CMasterState = DATA_NACK; LPC_I2C0->I2CONSET = I2CONSET_STO; /* Set Stop flag */ } } LPC_I2C0->I2CONCLR = I2CONCLR_SIC; break; case 0x40: /* Master Receive, SLA_R has been sent */ LPC_I2C0->I2CONSET = I2CONSET_AA; /* assert ACK after data is received */ LPC_I2C0->I2CONCLR = I2CONCLR_SIC; break; case 0x50: /* Data byte has been received, regardless following ACK or NACK */ case 0x58: I2CMasterBuffer[3+RdIndex] = LPC_I2C0->I2DAT; RdIndex++; if ( RdIndex != I2CReadLength ) { I2CMasterState = DATA_ACK; } else { RdIndex = 0; I2CMasterState = DATA_NACK; } LPC_I2C0->I2CONSET = I2CONSET_AA; /* assert ACK after data is received */ LPC_I2C0->I2CONCLR = I2CONCLR_SIC; break; case 0x20: /* regardless, it's a NACK */ case 0x48: LPC_I2C0->I2CONCLR = I2CONCLR_SIC; I2CMasterState = DATA_NACK; break; case 0x38: /* Arbitration lost, in this example, we don't deal with multiple master situation */ default: LPC_I2C0->I2CONCLR = I2CONCLR_SIC; break; } }
=> I tried using the code below, but don't work
What do you mean by [but don't work] in this case?