Skip to main content
fabricepeden
Associate III
February 28, 2013
Question

Problem on I2C bus

  • February 28, 2013
  • 2 replies
  • 843 views
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);

    This topic has been closed for replies.

    2 replies

    fabricepeden
    Associate III
    April 10, 2013
    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 III
    April 12, 2013
    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).