I2C busy flag not cleared immediately after stop condition

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C busy flag not cleared immediately after stop condition

Jump to solution
4,294 Views
errorek123
Contributor III

Hello,

I noticed that my function to send data sometimes fails at busy flag check but every write/read ends up with stop condition so next one shouldn't get BUSY FLAG(it's  not multimaster), seems like burning some cycles(around 20 NOPS) after stop condition helps and then it never happens that function fails on busy flag check.

Is it possible that update of the busy flag is somehow delayed(queued in some kind of pipeline) and another function call will check busy flag before it actually gets updated? Is there any solution to this problem other than burning some cycles after generating stop condition?

1 Solution
3,631 Views
mjbcswitzerland
Specialist V

Brian

In a single master system dead-lock recovery is done only once - the first time the bus is used. It can generally be assumed that slaves will behave and in case of difficulties it means that there is a slave failure and so needs repair. I never has a dead-lock in normal operation (only after a reset that left the slave driving the bus).

In a multi-master environment one can call a status check for busy before attempting to send (and one needs to try again later) and if it is busy when a transfer is actually attempted it can immediately return since it means that another master took the bus between the check and the transfer start. It is also possible to lose arbitration during the start of the transfer (even when the bus was not busy) so they all more or less fall into the same pot of needing to repeat after a delay and a timeout is redundant.

Personally I stay away from multi-master I2C designs - there are other multi-master buses if needed.This is due to experience in a project based on multi-master I2C communication involving also ASICs which had some flaws in the (I2C) design, requiring various workarounds, lots of lost time and probably a hundred thousand dollars of additional project costs (it dragged on, involved several companies/departments all pointing the finger at each other and the I2C solution was inefficient anyway - a later re-design scrapped it for a multi-drop HDLC bus which was much faster and gave no problem).

Regards

Mark

View solution in original post

0 Kudos
8 Replies
3,631 Views
mjbcswitzerland
Specialist V

Brian

When code commands the transmission of the stop condition it initiates the process in the controller but the time that it takes for it to complete depends on the synchronisation of the clock domains used by the I2C controller and the CPU's clocks, the speed of the I2C bus (eg. whether 20kHz, 100kHm 400kHz etc.) plus bus loading (capacitance and pull-up strength). Therefore it is normal that there is a delay between initiating a stop condition and the bus becoming free (i.e. not busy).

When you complete sending a transmission over the bus (as master) you don't really need to do anything (like checking the busy state) since you can "assume" that the command will operate [once you are sure it is correctly commanded] and that after this delay the bus will be free (not busy) again - the exact delay is then not of any real concern.

When you "need" to check busy is when you perform any subsequent operations since if a subsequent operation is started very quickly after the previous it may be that the stop condition hasn't completed and the bus is still "busy" from the previous transaction. Therefore the bus busy check should be performed before every new transfer (rather than after each transfer termination) where is will generally be free immediately. If it is still busy you can 'spin' on the busy state rather than adding a random delay (as you could have done on the end of transfer - but less efficient as method).

For general I2C dead-lock recovery (which should be performed after every reset) I wrote this some 5 years ago: I2C device dead-lock recovery 

Regards

Mark

Complete Kinetis solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market
Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html

3,631 Views
errorek123
Contributor III

Well seems like it depends on the application if it's better to put blocking while loop at the start of sending or at the end of sending. If i want to check if it's busy and just skip the send if it is, the while loop would be better after sending stop condition, but if i want to make sure every transfer i command is send out no matter how long it will have to wait, while loop at the start would be more suitable. The best way i think would be to make function which returns status of the I2C so i can decide in every place i put sending function if i want to retry untill send is complete or not.

0 Kudos
3,631 Views
mjbcswitzerland
Specialist V

Brian

The aim should be to have a driver that is application independent and an application that doesn't need to concern itself about the driver. Then there will be no problems when using the same in the next project with I2C. Don't ignore the dead-lock recovery requirement (it can be transparent to the application) because it can and does happen when the board is reset and the slave (usually without reset line) continuously holds the bus in a busy state.

If ignored, expect the occasional irate customer call when it blocks and be prepared to do the "Have you tried turning it off and on again...?" bit.

Regards

Mark

3,631 Views
errorek123
Contributor III

I'm not ignoring dead-lock recovery, i know it's necessary in i2c communication, i'm just not sure about putting blocking while loop at the start of every transfer as it will block the whole program untill it can actually send(that might be problematic in multi-master where another master is taking bus for a long time). Maybe some kind of timeout on that while loop would be good solution connected with dead-lock recovery in single master communication? I read your post about deadlock and seems like You got no timeout so there is possibility that dead-lock recovery mechanism is fired even it's not really required(fast sends,  trying to send before bus becomes free again) unless dead-lock recovery is only on i2c initialization.

Every time driver needs to check if i2c is deadlocked, pins need to be reconfigurated for GPIO right?

Is there any way to tell if bus is dead-locked in multi-master?

0 Kudos
3,632 Views
mjbcswitzerland
Specialist V

Brian

In a single master system dead-lock recovery is done only once - the first time the bus is used. It can generally be assumed that slaves will behave and in case of difficulties it means that there is a slave failure and so needs repair. I never has a dead-lock in normal operation (only after a reset that left the slave driving the bus).

In a multi-master environment one can call a status check for busy before attempting to send (and one needs to try again later) and if it is busy when a transfer is actually attempted it can immediately return since it means that another master took the bus between the check and the transfer start. It is also possible to lose arbitration during the start of the transfer (even when the bus was not busy) so they all more or less fall into the same pot of needing to repeat after a delay and a timeout is redundant.

Personally I stay away from multi-master I2C designs - there are other multi-master buses if needed.This is due to experience in a project based on multi-master I2C communication involving also ASICs which had some flaws in the (I2C) design, requiring various workarounds, lots of lost time and probably a hundred thousand dollars of additional project costs (it dragged on, involved several companies/departments all pointing the finger at each other and the I2C solution was inefficient anyway - a later re-design scrapped it for a multi-drop HDLC bus which was much faster and gave no problem).

Regards

Mark

0 Kudos
3,631 Views
berndsirozynski
Contributor III

Hello Brian,
i dont not know which controller you use and which library for the I2C bus
but the most controllers use the same status maschine for the I2C Bus,
if you set a stop condition, it needs a little bit time
the time is specified as 4,7µs in standard mode and 1,3 µs in Fast Mode

only after that time the bus is free.

i think you can try to read the I2CSTAT register.
If all is ready, the status is 0xF8 else the last shift out (STOP condition) is not ready

i have not tested this, but maybe this can solve the problem.

have you the right Pullups on SCL und SDA ?
if the Pullups are to big you can have problems with the rising edge of SDA Line
you can also try the behavier with 1K Ohm Pullup  

Bernd

0 Kudos
3,631 Views
errorek123
Contributor III

Thanks for informations, could u please tell me where did u find such information about timings? I'm using FRDM-K22F at this moment to test i2c. I'm using my own simple drivers but i just chcked NXP driver and i found intresting line of code which will wait untill bus becomes avaiable after generating stop condition.

0 Kudos
3,631 Views
berndsirozynski
Contributor III

Here ist a good information:

https://www.analog.com/en/technical-articles/i2c-timing-definition-and-specification-guide-part-2.ht...

maybe a slave Device holds the SDA Line low,
i have found this with some chips if i scan the I2C bus.
So i must generate 3 or 8 clock pulses and the Slave give the bus free.
Analog Devices recommends 9 clock cycles

i have problems found with these chips:
#define BMP180_ADDRESS  0x77  // Barometer problem bei Read dann 8 clocks
#define BMP280_ADDRESS  0x76  // Barometer problem bei raed dann 8 clocks
#define ADS1110_ADDRESS 0x48  // AD Converter  problem bei read dann 8 clocks
#define PCA9685_LED_ALL 0x70  // problem bei Read dann 3 clocks

the problems only occured if scan the bus with a read operation but read no data.

if i read one ore more data there is no problem.

if you want to scan the bus it is better to do this with a write operation.

problems can also occure if you set breakpoints and restart the CPU.

Sometimes you must power off the Slaves to eleminate the error.

sorry, now, i look in your datasheet, this I2C controller is not the same as in my controller in the LPC-Serie.

0 Kudos