Tool/software:
The MSPM0's I2C RD_ON_TXEMPTY feature works as advertised, and makes Repeated-Start very easy.
However, when using Driverlib, there is a hazard in the interaction between:
a) The MCTR transaction bits -- notably BURSTRUN -- don't auto-clear after a transaction is complete [Observed behavior].
b) The Driverlib function DL_I2C_enableControllerReadOnTXEmpty() sets RD_ON_TXEMPTY=1 using a read-modify-write operation.
The result is that using that function re-writes BURSTRUN, thus restarting the previous operation. [Awkwardness ensues.] The same happens when using DL_I2C_disableControllerReadOnTXEmpty() to set RD_ON_TXEMPTY=0.
The fix is one of:
1) Set RD_ON_TXEMPTY (=0 or =1) as part of starting every new transaction, i.e. in the same MCTR write as the (new) BURSTRUN. This is what my (non-Driverlib) drivers do, but neither of the DL_I2C_startControllerTransfer functions provides for this.
2) Set MCTR=0 (i.e. BURSTRUN=0) before calling this function.
3) But if you're writing MCTR anyway you might as well set RD_ON_TXEMPTY at the same time, so I ended up with:
#if RS_WA // Hazard workaround i2c->MASTER.MCTR = I2C_MCTR_RD_ON_TXEMPTY_ENABLE;// Set repeat-start, clear others #else // RS_WA DL_I2C_enableControllerReadOnTXEmpty(i2c); // Write then read #endif // RS_WA #if RS_WA // Hazard workaround i2c->MASTER.MCTR = 0*I2C_MCTR_RD_ON_TXEMPTY_ENABLE; // Clear repeat-start, clear others #else // RS_WA DL_I2C_disableControllerReadOnTXEmpty(i2c); #endif // RS_WA
It's not obvious how this might be remedied (compatibly) in Driverlib. One could argue that, since it's never appropriate to change RD_ON_TXEMPTY while a transaction is running, implementing enableControllerReadOnTXEmpty() using a write (=) to MCTR as above rather than a RMW (|= or &=) would be acceptable since any side-effects are benign.
[Edit: Added something for "disable" as well.]