ACK
Many, if not all Application Notes and PowerPoint presentations by Microchip tell the user to check for an ACK from the slave. In fact, there is some emphasis on polling the ACKSTAT bit. However, the sample code from Microchip does not always do that. Here's one example:
Code:
TX
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
movf datao,W ; Copy datao to WREG
movwf SSPBUF ; Write byte out to device
tx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto tx_wait ; If not, keep checking
; bsf STATUS,RP0 ; Select Bank 01
; btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received
; goto ackfailed ; This executes if no ACK received
retlw 0
Checking for an ACK is commented out as being optional, but no advice is rendered to help the reader decide whether checking for an ACK is advised. In line with that, could one substitute just checking ACKSTAT instead of checking SSPIF (assuming an interrupt is not enabled for SSPIF)?
Recover after a Reset
There is a need to have the slave(s) in a known state after a reset or other mess-up. On the Microchip forums, there is this suggestion:
"Send a START condition, then clock out nine 1's, send another START, then send a STOP." An alternative from the DS3231 datasheet is: "Toggle SCL until SDA is observed to go high, then generate a START condition."
Since I will be using the DS3231, my inclination is to use the latter protocol. Is that an alternative, generally applicable protocol, or is there even such a thing as a generally applicable protocol?
All I know is.... If you implement a software I2C... You need to tristate the port pins and let the pullup do the work..
This way high is never given..... Both pins are logic 0 and all that should be done is the pin is tristated to make it a high!!! That way there should never be a conflict!! Most hardware implementations are done like this...
In hardware I2C with Microchip Assembly, SCL and SDA are also tristated (set as inputs) with pull-up resistors. For 100kHz, 4k7 resistors are recommended. Thus, the MCU pulls the bus low and it floats high, just like you describe. That is another reason the second option I gave appeals to me. Waiting for the bus to go high means no one is active on it.
I have the code pretty much done. Nice to know you guarantee my RTC won't lock up on me. I do have two spares, just in case.