ArduinoCore-samd
ArduinoCore-samd copied to clipboard
Check for loss of arbitration
When initiating an I2C communication as master, there is a chance of losing arbitration of the bus if there are other masters on the bus. This is a perfectly normal scenario and it is handled by trying to start the communication again. If arbitration was lost during the first try, now the bus state is busy so the second call to startTransmissionWIRE will wait until the bus is idle again before retrying. I made this change on my MKRZERO over a month ago and since then I didn't have any more errors. I have a system with 7 masters on the same I2C bus sending messages at about 10Hz each, so loss of arbitration happens frequently (2 masters starting to communicate at the same time). One of the 2 gets priority over the other while the other loses arbitration. The loser simply retries the communication when loss of arbitration is detected, and everything works smoothly without data loss. Without this check we can't be aware of any loss of arbitration and the library would detect the NACK without understanding that it was not a real NACK from the slave.
LGTM, need to test it a bit before merging. @agdl can you take care of it?
@agdl It's me, Alberto :) if you guys need some code to test it I have already something ready
@lupalby yes please paste the code here. Anyway Did I miss something? Alberto Who? :D
To sum up, unfortunately I found that the code I have cannot be shared easily. In general, you can easily test it having 2 or more Arduino as masters on the same I2C bus trying to perform a read operation with one or more slave devices, possibly as frequently as you can. You will notice that some of the operations will fail if you don't apply the fix I am proposing. The problem is not present when only one master is talking on the bus.