cancel
Showing results for 
Search instead for 
Did you mean: 

i2c function call

ongth60
Associate II
Posted on June 22, 2005 at 23:56

i2c function call

11 REPLIES 11
ongth60
Associate II
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?

ongth60
Associate II
Posted on May 17, 2005 at 04:26

Hi,

Any other suggestions?

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

Rgrds.

sjo
Associate II
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

ongth60
Associate II
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.

ongth60
Associate II
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

ongth60
Associate II
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.

ongth60
Associate II
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
ongth60
Associate II
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