cancel
Showing results for 
Search instead for 
Did you mean: 

Problem on I2C bus

fabricepeden
Associate II
Posted on February 28, 2013 at 18:40

Hi everybody,

I've got a problem on the I2C bus. I'm trying to read/write an EEPROM (24AA1025 from microchip). When I'm writing into the EEPROM, I can see I2C sentences on my oscillscope. They're looking good. To read the EEPROM, I need to do : Start / Control Byte / High Address / Low Address / Start / Control byte / read data. When I do :Start / Control Byte / High Address / Low Address, I can see sentences from write and read. But when I'm doing the read entire procedure (two starts + two control bytes), nothing is now happening. On the oscilloscope, it seems that the last STOP instruction doesn't work, because I have a 0V voltage. And about the program it's seems to be stopped in the ''while (!I2C_CheckEvent(I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))'' of read operation. If you have any idea that could help me, thank you in advance.

/* Enable the I2C peripheral */
I2C_GenerateSTART(I2C, ENABLE);
/* Test on SB Flag */
TimeOut = 100;//TIMEOUT_MAX;
while (I2C_GetFlagStatus(I2C,I2C_FLAG_SB) == RESET) 
{
if(TimeOut-- == 0)
{
NOP; 
}
}
/* Send device address for write */
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS, I2C_Direction_Transmitter);
/* Test on ADDR Flag */
TimeOut = 100;//TIMEOUT_MAX;
while (!I2C_CheckEvent(I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
{
if (TimeOut-- == 0)
{
NOP;
}
}
I2C_SendData(I2C, adr >> 8);
TimeOut = 100;
while ((!I2C_GetFlagStatus(I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(I2C,I2C_FLAG_BTF))) 
{
if (TimeOut-- == 0)
{
NOP;
}
}
I2C_SendData(I2C, adr & 0x00FF);
TimeOut = 100;
while ((!I2C_GetFlagStatus(I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(I2C,I2C_FLAG_BTF))) 
{
if (TimeOut-- == 0)
{
NOP;
}
}
/* Send START condition a second time */ 
I2C_GenerateSTART(I2C, ENABLE);
/* Test on SB Flag */
TimeOut = 100;//TIMEOUT_MAX;
while (I2C_GetFlagStatus(I2C,I2C_FLAG_SB) == RESET) 
{
if(TimeOut-- == 0)
{
NOP; 
}
}
/* Send IOExpander address for read */
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS, I2C_Direction_Receiver);
/* Test on ADDR Flag */
TimeOut = 100;
while (!I2C_CheckEvent(I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) 
{
if (TimeOut-- == 0)
{
return; 
}
}*
/* Lecture de 128 octets max */
if(size > 0)
{
for(i=0;i<size;i++)
{ 
tab[i] = I2C_ReceiveData(I2C);
}
}
/* Envoi du signal de Stop */
I2C_GenerateSTOP(I2C, ENABLE);

2 REPLIES 2
fabricepeden
Associate II
Posted on April 10, 2013 at 17:12

I come back with my problem on my EEPROM.

Now, it's better, I managed to read and write bytes in it. I need to write 47 bytes (always the same) into my EEPROM. At the @0, it works. Then, when I write to the @ 47, it seems to work, but when I read the memory zone, I got data, but wrong data. More explanations : @0 : ABCDEFGH... @47 : ABCDIJKLM, so the beginning is good, but it seems that I got something like a rollover, but I don't understand. I've checked the address, the data at the oscilloscope, and everything seems to be good. My read function :

/* Déclarations et initialisations des variables */
uint8_t i = 0;
uint16_t nop = 0;
uint16_t TimeOut = 0;
/*!< 
While
the bus is busy */
TimeOut
= 
1000
;
while(I2C_GetFlagStatus(I2C, I2C_FLAG_BUSY))
{
if(TimeOut-- == 0)
{
NOP; 
}
}
/* Enable the I2C peripheral */
I2C_GenerateSTART(I2C, ENABLE);
/* Test on SB Flag */
TimeOut
= 
1000
;
while(I2C_CheckEvent(I2C, I2C_EVENT_MASTER_MODE_SELECT) == 0)
{
if(TimeOut-- == 0)
{
NOP; 
}
}
/* Send device address for write */
if(adr > 65535)
{
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS | 0x08, I2C_Direction_Transmitter);
}
else
{
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS, I2C_Direction_Transmitter);
}
/* Test on ADDR Flag */
TimeOut = 1000;
while (I2C_CheckEvent(I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == 0) 
{
if (TimeOut-- == 0)
{
NOP;
}
}
I2C_SendData(I2C, (adr > 65535) ? (((adr - 65535) & 0xFF00) >> 8) : ((adr & 0xFF00) >> 8));
TimeOut = 1000;
while(I2C_CheckEvent(I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING) == 0)
{
if (TimeOut-- == 0)
{
NOP;
}
}
I2C_SendData(I2C, (adr > 65535) ? ((adr - 65535) & 0x00FF) : (adr & 0x00FF));
TimeOut = 1000;
while(I2C_GetFlagStatus(I2C, I2C_FLAG_BTF) == RESET)
{
if (TimeOut-- == 0)
{
NOP;
}
}
/* Send START condition a second time */ 
I2C_GenerateSTART(I2C, ENABLE);
/* Test on SB Flag */
TimeOut = 1000;//TIMEOUT_MAX;
while(I2C_CheckEvent(I2C, I2C_EVENT_MASTER_MODE_SELECT) == 0)
{
if(TimeOut-- == 0)
{
NOP; 
}
}
/* Send IOExpander address for read */
if(adr > 65535)
{
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS | 0x08, I2C_Direction_Receiver);
}
else
{
I2C_Send7bitAddress(I2C, I2C_EEPROM_ADDRESS, I2C_Direction_Receiver);
}
/* Test on ADDR Flag */
TimeOut = 1000;
while(I2C_GetFlagStatus(I2C, I2C_FLAG_ADDR) == RESET)
{
if (TimeOut-- == 0)
{
NOP; 
}
}
/* Lecture de 128 octets max */
if(size > 0)
{
for(i=0;i<
size
;i++)
{ 
if(i == (size-1))
{
/* Envoi du signal de Stop */
I2C_GenerateSTOP(I2C, ENABLE);
/*!< Disable Acknowledgment */
I2C_AcknowledgeConfig(I2C, DISABLE); 
(void)I2C->SR2;
TimeOut = 1000;
while(I2C_GetFlagStatus(I2C, I2C_FLAG_RXNE) == RESET)
{
if (TimeOut-- == 0)
{
NOP; 
}
}
/* Lecture de 128 octets max */ 
tab[i] = I2C_ReceiveData(I2C);
TimeOut = 1000;
while(I2C->CR1 & I2C_CR1_STOP)
{
if (TimeOut-- == 0)
{
NOP; 
}
} 
/*!< 
Re-Enable
Acknowledgment to be ready for another reception */
I2C_AcknowledgeConfig(I2C, ENABLE); 
}
else
{
(void)I2C->SR2;
TimeOut = 1000;
while(I2C_GetFlagStatus(I2C, I2C_FLAG_RXNE) == RESET)
{
if (TimeOut-- == 0)
{
NOP; 
}
}
tab[i] = I2C_ReceiveData(I2C);
}
}
}

fabricepeden
Associate II
Posted on April 12, 2013 at 10:17

I have found my answer about my problem.

If you are using a 24AA1025 EEPROM, you must write into a page of 128 bytes, so be careful ! 

So if you write bytes on two different pages (ex : 4 bytes between @ 124,125,126,127 and 4 bytes between @ 128, 129, 130, 131, be careful it's two different pages, so you can have a risk of rollover).