cancel
Showing results for 
Search instead for 
Did you mean: 

Error interrupt I2C Example1

jordi
Associate II
Posted on September 04, 2009 at 17:24

Error interrupt I2C Example1

11 REPLIES 11
jordi
Associate II
Posted on May 17, 2011 at 12:31

Hi,

I want to add error handling in the I2C example 1. So I've add the error interrupt:

I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, ENABLE );

If I don't connect the master & slave, I expect an Acknowledge failure Interrupt after sending the slave address, but this doesn't happen.

By contrast, if I monitor the I2C_FLAG_AF with the I2C_GetFlagStatus(I2C1,I2C_FLAG_AF) function in the main loop, I can see that the AF Flag is really set after a short time. Why isn't also fired the I2C1_ER_IRQHandler interrupt?

Thanks

[ This message was edited by: jordi.pallisanunez on 25-04-2008 16:15 ]

daniels2
Associate
Posted on May 17, 2011 at 12:31

Hi

I've tried the same thing when I get an Acknowledge failure the appropriate error handling interrupt is not fired yet if I force an AF high it is reset transparently in uvision. This seems to be an intermittent problem also i can get locked into an infinite loop where the interrupt functio is called but the AF trap is not executed.

/*******************************************************************************

* Function Name : I2C1_EV_IRQHandler

* Description : This function handles I2C1 Event interrupt request.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void I2C1_EV_IRQHandler(void)

{

uint8_t tbuff;

switch (I2C_GetLastEvent(I2C1))

{

/* Test on I2C1 EV1 and clear it */

case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:

ResetRxTx_Buffers();

break;

/* Test on I2C1 EV2 and clear it */

case I2C_EVENT_SLAVE_BYTE_RECEIVED:

tbuff = I2C_ReceiveData(I2C1);

i2c_Rx_Decode(&tbuff);

break;

case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:

ResetTxBuffer();

i2c_Tx_encode();

break;

/* Test on I2C1 EV4 and clear it */

case I2C_EVENT_SLAVE_STOP_DETECTED:

/* Clear STOPF flag */

I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);

ResetRxTx_Buffers();

/* Disable I2C2 interrupts */

break;

case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:

i2c_Tx_encode();

break;

case I2C_EVENT_SLAVE_ACK_FAILURE:

I2C_ClearFlag(I2C1, I2C_IT_AF);

ResetRxTx_Buffers();

break;

default:

//clock held low by

break;

}

}

stephan2399
Associate II
Posted on May 17, 2011 at 12:31

Hello,

I have the same problem. Have anybody solved it?

Thanks

guyvo67
Associate II
Posted on May 17, 2011 at 12:31

Guys,

Yes I encountered also hang behaviour in the I2C IRQ handler. (receiver)

My priority is put highest 0 and I send 84 bytes from one cortex to another. This works perfect but as soon there's some charge on my free RTOS tasks the interrupt on the receiver side starts to hang. Moreover this holds the cortex in the I2C int (highest priority) routine so the RTOS systick gets no feed and my system is dead.

I put a break point on this line:

evt = I2C_GetLastEvent(I2C2);

switch (evt){

.....

And the event assigned was 0x20054. This value is even not defined in the ST header. So I added a case default line like:

default:

I2C_ClearITPendingBit(I2C2, I2C_IT_EVT);

break;

I tried to clear I2C_IT_EVT , which i'm not sure I can do, but still the same unknown event value. And I can confirm that I get no error in that case as well. So I still can't get a comfortable feeling when I use I2C on the cortex. I saw other threads as well pointing to hang on EVs. So is there something critical even a small detail that we don't know here?

So my questions to you guys:

Did you tested the I2C in loop/charge or with other interrupts going on at the same time ?

Did you tested the I2C using a RTOS of some kind with tasks charge at same time ?

Cheers

-G

guyvo67
Associate II
Posted on May 17, 2011 at 12:31

Daniels,

Quote:

/* Test on I2C1 EV4 and clear it */

case I2C_EVENT_SLAVE_STOP_DETECTED:

/* Clear STOPF flag */

I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);

ResetRxTx_Buffers();

/* Disable I2C2 interrupts */

break;

Be aware that you have to do an extra read for the stop like:

I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);

I2C_CMD(I2C1,ENABLE)

Maybe you do this in your ResetRxTx_Buffers routine but I can't see that.

To all guys suffering on I2C hangs,

I did some further testing still no exact cause but if the I2C interrupt enters the blocked state the order of events on the slave receiver just before the hang I capture are:

1. evt = 0x50

2. evt = 0x200052

3. evt = 0x200054 (always that value and hang)

--> SCL is pulled low

All these events are not described in the ST header. Of course I can break this endless looping with my watchdog. So i'm still suspecting a software cause corrupting the GetEvent routine. I continue in my tests. Maybe I check even further with logic analyzer.

-G

[ This message was edited by: guyvo67 on 03-09-2009 08:45 ]

jvaque
Associate II
Posted on May 17, 2011 at 12:31

Hi all!

I can't offer you a solution, but I had lots of problems with I2C with STM32 in the past. After discussions with ST support, I realized that the events defined on the libraries (the ones used on the examples) do not cover all the possible cases, just the ''ideal cases''.

The best way to work with I2C is to read the reference manual RM0008, and treat the events as described in figures 232 to 235. These figures on the same time define exactly the possible events (keep in mind that in the real world one can have combinations of different events, so take care when implementing, I wouldn't follow the way the examples implement it with switch and case ).

Ah, and try to use DMA, because when a I2C DMA transfer is started, one doesn't have to bother with interrupts and events until a STOP is received or has to be sent!

Regards,

[ This message was edited by: jvaque on 03-09-2009 10:05 ]

dmatheis
Associate II
Posted on May 17, 2011 at 12:31

Quote:

Be aware that you have to do an extra read for the stop like:

I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);

I2C_CMD(I2C1,ENABLE)

Hi guyvo67,

why should I (re)enable the I2C interface? I thought after reading the stop-flag there is no communication on the bus and I could disable it.

[ This message was edited by: dmatheis on 04-09-2009 10:52 ]

guyvo67
Associate II
Posted on May 17, 2011 at 12:31

dmatheis,

why should I (re)enable the I2C interface?

In rm0008 on page 647:

–Cleared by software readingthe SR1 register followed by a write in the CR1 register

So this sequence is needed to clear the STOPF flag.

-G

dmatheis
Associate II
Posted on May 17, 2011 at 12:31

Thank you,

I'm using I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)); to clear the STOPF Flag. 😉