2013-02-28 09:40 AM
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);
2013-04-10 08:12 AM
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);
}
}
}
2013-04-12 01:17 AM
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).