So i've got my i2c driver 99% functional but i've stumbled over a problem that is bugging me.
It appears to me that in order to issue repeated starts to a bus, repeat mode has to be on. I've done a fair amount of testing and no matter what I try, if repeat mode isn't on setting the start bit doesn't generate a repeated start even when we've finished everything we were doing previously. That's fine, I can live with that. What I can't live with is erroneous documentation.
Page 2257 of the TRM:
*Ahem...* "Only applicable when the I2C module is a master transmitter". That is 100% incorrect as far as I can tell. Setting the RM bit when in master receive, allows a repeated start to be generated on the bus. If I don't have RM set, I cannot generate a new start while I have control of the bus. Would you disagree with my above assertion?
Another thing.... The TRM discusses what a repeated start is in section 25.3.5.4 but never really tells the user how to do it. If my observations that it is only allowed when RM is set are correct, this should be explicitly spelled out in the TRM. The documentation for the RM bit make it seem like its behavior is only tied to the CNT register and repeated data transmission.
OOOoookkkkk.....now that brings me to the main point of this post. Assuming my observations are accurate and I'm not doing something dumb in my software, the above raises a small but IMO significant issue. How do I clock in an accurate number of bytes? Let's run through an example:
- Ack poll the slave - Setup master transmit repeat mode, send a start condition, look for the ADRY bit to be set, test the nack bit to determine if slave is ready
- Setup slave read address - Setup master transmit repeat mode, send a repeated start condition, send the address in the memory of the slave device (eeprom), interrupt on ARDY
- Read slave data - Configure master receive repeat mode, send a repeated start condition, interrupt on the RXFF, copy data in, when I've read all the bytes requested by the higher level application, send a stop condition
In the above case, because I'm sending the stop in software I don't have deterministic control of the number of bytes that are shifted in. My two choices are to send it after I've received the last requested byte which results in at least one additional unwanted data byte being shifted in. Alternatively, I can try to send the stop at n-1 and hope the timing is right that I get my last byte in before stop is sent.
Ultimately I guess my point is the peripheral should be able to send repeated starts when not in repeat mode. This would allow me to use the count register to shift in an accurate amount of data. So am I crazy? Have you ever been able to send a repeated start when RM isn't set?