cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 what is the best I2C Comunication Method?

Bogdan
Senior
Posted on October 18, 2014 at 09:13

Hello guys,

a few months ago i started to work with discoveryF4 board and some sensors in i2c mode.

But my inconvenient was that after several minutes or several hours the code just STONED...

So in the last couple of days i did some experiments using/not using i2c

After using the i2c comunication in my program it got stoned/halt

I`m not using the interrupt features of the i2c module, so i was wondering to build a i2c driver based on the interrupt event and error handlers.

But i said to ask you whats the best/stable lets say... solution to use the i2c feature.

The idea is that if i get a error on the i2c buss at some point, i dont want my code to get stuck

Thanks

1 REPLY 1
Danish1
Lead II
Posted on October 18, 2014 at 12:43

Because computers are so very predictable, much programming we do is ''fragile'' for example in that the program waits forever for something we have asked to happen to actually happen. That's fine for a PC where we occasionally have to resort to ctrl-alt-del but should not occur in an embedded device.

In my opinion, the right thing to do is to have a scheme to recover and return to normal operation if something seems to be taking excessively long.

One way to do this is is with a watchdog timer that will reset your processor. Another way is for each of your wait loops to also monitor how long they have been waiting for*, and give up (throwing an exception) if they wait too long.

If/when a wait takes too long, you should record enough information to help you find out the circumstances of the time-out. It might be that you are writing to an EEPROM that needs time to complete the write cycle, and your code does not allow for the ''busy'' message that your EEPROM sometimes sends back. Or it might be that you are pushing the I2C bus faster than either the peripherals are designed for, or than the combination of stray-capacitance in the lines and the pull-up-resistors can cope with and you are getting random corruption of data on there.

It doesn't matter whether you use interrupts or explicit wait loops. If something unexpected happens you have to cope with it. And you also should try to understand why and how it happened and how it might be avoided.

As to coping with it, you might not know but if the I2C bus is stopped part-way through a data transfer, a slave might be left driving the SDA line. As part of your error-recovery code, you might try to manually send pulses on the SCL line (while not driving SDA) to ''clock-out'' this state.

*Note that I disapprove of using a loop-count for this timing because the average time to go round the loop changes if there are many interrupts to service, or you change the frequency of the clock.

As to answering your specific question of ''best'', I have to ask best judged by what criteria?

Eventually you need to end up with code that works, and works sufficiently reliably for your needs. But a key part of this is having code that you understand well enough to be able to fix. Which might compromise its efficiency in terms of the processor power it needs, or the data-rate you can send over the bus**.

**For example, going back to EEPROMs, some of them have ''page-write'' features, where if you are writing data within one e.g. 16-byte page, it can all be written in one hit with a single I2C write command. But if you are doing random writes that might straddle the boundary between two different pages then the EEPROM will get confused and probably not update the locations you expect. So you either have complicated code that knows where these boundaries are, or you have much simpler code that only allows you to write one byte at a time and has to wait the few milliseconds before doing the next read or write.

Hope this helps,

Danish