I’m writing an I2C slave on PIC16F1454. My slave uses a slave defined packet exchange algorithm with an unknown master (Command, Data Length, Data). My problem is deciding upon a decent deadlock detection and recovery scheme.
For instance:
--Master sends address with Read command
--Slave decodes address; sends ACK
-- slave loads SSPBUF with response data byte
-- Master fails to send any more clocks
In this deadlock situation, my slave is holding SDA low (can only change SDA on SCL low following falling edge of SCL), so even if the master can recover from whatever problem it had, it’s only possible chance at recovery is send enough clocks to clear my slave.
But (there’s always a but, isn’t there?), I can’t count on the master to do that, so my slave with its ACK holding the SDA low, will effectively lock up the I2C bus in perpetuity. My solution is to detect the deadlock and return the I2C bus to its idle state.
My thinking is to time each exchange between my slave and whatever master happens to be controlling the bus. If the exchange doesn’t complete within the allotted time, my slave should abandon the exchange and return the bus to its idle state.
That seems reasonable to me, but that leaves two questions: 1) What is a reasonable time to wait before abandoning the exchange and 2) what’s the best way to ‘reset’ the MSSP to return the I2C bus to its idle state?
I would think that a timeout period could be as low as tens of milliseconds up to a couple of seconds? Any suggestions and thoughts on this are welcome. Remember, I’m dealing with a potentially unknown master.
Second, what is a reliable method to ‘reset’ an MSSP slave? Is toggling SSPEN (low then back to high) good enough or is there a better way to do this?
Thanks for any help, ideas or thoughts you might have.