Skip to main content
Visitor II
June 22, 2005
Question

i2c function call

  • June 22, 2005
  • 11 replies
  • 1740 views
Posted on June 22, 2005 at 23:56

i2c function call

    This topic has been closed for replies.

    11 replies

    ongth60Author
    Visitor II
    May 16, 2005
    Posted on May 16, 2005 at 12:22

    Is this function ,I2C_FlagStatus (I2C0,DIRECT,I2C_AF) suppose to return the flag status of the Acknowledege return by the receiver?

    What is the AF flag status if the receiver didnt acknowledge the bytes sent by the MCU(master),where the receiver pulling the SDA low during the ninth clock pulse.

    My problem is that when i use the scope to probe the signal of the ACK signal, the ACK is high(means tht the receiver did not acknowledege my byte sent, but the value return by the I2C_FlagStatus (I2C0,DIRECT,I2C_AF) function returns RESET, which means the receiver acknowledge my signal sent.

    Any idea?

    ongth60Author
    Visitor II
    May 17, 2005
    Posted on May 17, 2005 at 04:26

    Hi,

    Any other suggestions?

    How will you do it?Could you include some codes?

    Rgrds.

    Visitor II
    May 18, 2005
    Posted on May 18, 2005 at 07:48

    The str7 libs do not handle the AF correctly, have a look at the following:

    http://mcu.st.com/mcu/modules.php?mop=modload&name=Splatt_Forums&file=viewtopic&topic=2561&forum=17

    Regards

    sjo

    ongth60Author
    Visitor II
    May 18, 2005
    Posted on May 19, 2005 at 01:19

    Hi,

    I've read the below forum link, and I've tried the code from sjo and it works. It detect the acknowledge bit that I cant previously detect. What acutually is the problem behind it?

    Also, the code from sjo below works:

    do{

    I2C_STARTGenerate( I2C0, ENABLE );

    while( I2C_FlagStatus( I2C0, DIRECT, I2C_SB) == RESET );

    I2C_AddressSend( I2C0, 0xA0, I2C_Mode7, I2C_TX );

    do{

    I2CStatus = I2C_GetStatus( I2C0 );

    }while(!( I2CStatus & I2C_EVF ));

    while( I2C_FlagStatus( I2C0, DIRECT, I2C_ENDAD ) ==RESET );

    I2C_FlagClear( I2C0, I2C_ENDAD );

    }while( I2CStatus & I2C_AF );

    while the one I wrote doesnt work:

    do{

    I2C_STARTGenerate (I2C0, ENABLE);

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_SB) == RESET);

    I2C_AddressSend (I2C0, 0xa0, I2C_Mode7, I2C_TX);

    do{

    I2C0_SR1_EVF = (I2C0->SR1) & 0x80;

    }while(I2C0_SR1_EVF == 0x00);

    (void)I2C0->SR1; //To clear EVF bit.

    while((I2C0->SR2) & 0x20 == 0x00);

    (void)I2C0->SR2; //To clear ENDAD bit.

    I2C0->CR|=0x20; //To clear ENDAD bit.

    }while((I2C0->SR2)&0x10 == 0x10);

    Pls advise.

    Rgrds.

    ongth60Author
    Visitor II
    May 21, 2005
    Posted on May 21, 2005 at 03:47

    Hi,

    Im not using ST EEPROM but of ohter type. However, the routines are very useful as Im am able to understand the way the routines are called.

    Currently, im able to read byte and write byte and also do acknowledge polling to check if the write operation is complete.

    int main()

    {

    ....

    while(1)

    {

    receive = EEPROM_byte_read(1,0xf000);

    }

    }

    u8 EEPROM_byte_read(u8 chip_select, u16 address)

    {

    u8 I2C_Rx_byte,control_byte;

    u16 I2CStatus;

    I2C_STARTGenerate (I2C0, ENABLE); //START bit.

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_SB) == RESET);

    control_byte = 0xa0 | (0x0f &(((0x03 & chip_select) << 1)|((address & 0x8000) >> 12)));

    I2C_AddressSend (I2C0, control_byte, I2C_Mode7, I2C_TX);

    do{

    I2CStatus = I2C_GetStatus(I2C0);

    }while(!( I2CStatus & I2C_EVF ));

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_ENDAD )==RESET);

    I2C_FlagClear (I2C0, I2C_ENDAD);

    I2C_ByteSend (I2C0, address >> 8);

    I2C_ByteSend (I2C0, address);

    I2C_STARTGenerate (I2C0, ENABLE);

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_SB) == RESET);

    I2C_AddressSend (I2C0, control_byte, I2C_Mode7, I2C_RX);

    do{

    I2CStatus = I2C_GetStatus( I2C0 );

    }while(!( I2CStatus & I2C_EVF ));

    while( I2C_FlagStatus( I2C0, DIRECT, I2C_ENDAD ) == RESET );

    I2C_FlagClear( I2C0, I2C_ENDAD );

    if( !(I2CStatus & I2C_AF) );

    {

    do{

    I2CStatus = I2C_GetStatus( I2C0 );

    }while(!(I2CStatus & I2C_EVF));

    I2C_Rx_byte = I2C_ByteReceive(I2C0);

    }

    I2C_STOPGenerate (I2C0, ENABLE);

    return I2C_Rx_byte;

    }

    However, currently Im facing a problem that in the EEPROM read byte routine function, if Im to run it, the program will run the function EEPROM_byte_read once, then the next time it runs the function, it will hang on the

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_SB) == RESET);

    in the EEPROM_byte_read() function.

    But when I step thru it , it can detect the ST bit, the it will go out from the while loop. So, if I run the program it will hang there but if step thru it, it will run smoothly.

    Pls advise.

    Rgrds,

    ongth60

    ongth60Author
    Visitor II
    May 24, 2005
    Posted on May 24, 2005 at 11:07

    Hi,

    I actually disabled the acknowledge return of the master at the beginning of the initialisation.

    Anyway, Ive tried out the codes and the same thing still happens. When I probe, I see that I couldnt generate the STOP bit, which might cause me the problem that Im facing right now.

    Rgrds.

    ongth60Author
    Visitor II
    May 26, 2005
    Posted on May 26, 2005 at 06:24

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6Xa&d=%2Fa%2F0X0000000bqE%2FAO8pRPc0gHtbpckdGiw_5tXee0ZeBb7cixQvJpIRekE&asPdf=false
    ongth60Author
    Visitor II
    May 26, 2005
    Posted on May 27, 2005 at 00:53

    Hi,

    Attached are the data captured on the scope. Pls combine sheet 1,2 and 3 to see the whole picture. This is what I got when I put a break point on the EEPROM_byte_read(0,0x0067) function and step through it. Before stepping through it, I need to go the Register pane to look at the registers of IC0. If I dont go to the Register pane and when I step through them the function run the EEPROM_byte_read(0,0x0067) twice and will loop at the

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_ENDAD )==RESET);

    without able to detect the I2C_ENDAD bit set when the control byte is sent.

    u8 EEPROM_byte_read(u8 chip_select, u16 address)

    {

    ...;

    ...;

    ...;

    I2C_AddressSend (I2C0, control_byte, I2C_Mode7, I2C_TX);

    while (I2C_FlagStatus (I2C0,DIRECT,I2C_ENDAD )==RESET);

    I2C_FlagClear (I2C0, I2C_ENDAD); ...;

    ...;

    }

    The above function is to read a byte using random read.

    So , according to the EEPROM spec(24AA515 Serial EEPROM pages 11 and 12), I need to

    1.Send a Start bit

    2.Send a Control byte to transmit.

    3.Send Upper address of the EEPROM.

    4.Send Lower address of the EEPROM.

    5.Send a Restart bit.

    6.Send a Control byte to receive.

    7.Receive Data from the EEPROM.

    8.CPU dont ACknowledge data byte received from the EEPROM.

    9.Sent STOP bit to end operation.

    I did all that in the above Read_byte function. What I've got is an extra 9 clockpulses data after the byte is received. This might be the problem that causes the read_byte function to hang.

    Pls advise.

    Rgrds,

    Ong

    ongth60Author
    Visitor II
    June 22, 2005
    Posted on June 22, 2005 at 13:47

    HI RISC,

    It works!! Thanks alot. I thought I need to capture the data first before sending the STOP bit but why is it the opposite around? Pls explain .Thanks again for the effort and trouble to solve my problem!

    Rgrds,

    ongth60 :-]