seneral limitations: state machine locks up under various circumstances master mode limitations: requires transfer length be specified before starting transfer stop condition must be requested *before* last data byte is transferred therefore cannot perform 0-byte transfers doesn't handle NACKs well slave mode limitations: always ACKs its slave address(es), every data byte written only stalls if requested before slave address is recognized or on fifo overrun/underrun always ACKs general call, cannot stall except by fifo full AL, NACK, ARDY, AERR, BF, AAS are events. AAS also auto-clears at stop or repeated start, but I get the impression this isn't reliable. RRDY is sticky: it is forced high by a level status, needs manual clearing but this will not succeed unless the level is low. XRDY is sticky in master mode but a normal event in slave mode. BB is level and cannot be enabled. It is nevertheless shown in irqstatus. XUDF and ROVR are level but also have sticky versions. If they are enabled, the sticky version is visible in both irqrawstatus and irqstatus. If they are disabled, the level is visible in both irqrawstatus and irqstatus. Manual set and clear acts on the sticky event even if not enabled (but clearing will only succeed if the level is low). Notation for I²C bus: < = SDA falling with SCL high > = SDA rising with SCL high . = SCL falling 0 = SCL rising with SDA low 1 = SCL rising with SDA high x = 0 or 1 hence <. = start condition 1<. = repeated start condition x. = data bit 0. = data bit: 0 1. = data bit: 1 0> = stop condition Notation for irqs/events: +FOO = level status set (sticky event set and can't be cleared) -FOO = level status unset (sticky event can now be cleared) ^FOO = event pulsed (set but can be cleared) +addr/-addr refers to a bit being set/cleared in ACTOA register slave transmitter: < +BB .x.x.x.x.x.x.x. 1 +addr ^AAS +XUDF (if fifo empty) .0. ^XRDY (if fifo empty) (waits until stall bit is cleared) +XUDF (waits until fifo non-empty) -XUDF data written, tx-bufstat decremented (mod 64) x.x.x.x.x.x.x.x . +XUDF 0. ^XRDY -XUDF data written, tx-bufstat decremented (mod 64) x.x.x.x.x.x.x.x . +XUDF 1. ^NACK 0> -XUDF ^ARDY tx-bufstat is reset to count -addr -BB ^BF slave transmitter with stall bit set and stray data in tx fifo: < +BB (even in the presence of arbitrary delays). .x.x.x.x.x.x.x. 1 +addr ^AAS .0. (stalling begins) (fifo cleared) +XUDF (stall bit cleared, may be immediately set again) -XUDF (data written) (continues as before) restart: 1< -XUDF ^ARDY tx-bufstat reset to count .x.x.x.x.x.x.x. 1 ±addr ^AAS slave receiver: < +BB .x.x.x.x.x.x.x. 0 +addr ^AAS .0. (waits until stall bit is cleared) x.x.x.x.x.x.x. x +RRDY rx-bufstat incremented -RRDY data read, bufstats decremented .0.x.x.x.x.x.x.x. x +RRDY rx-bufstat incremented .0.x.x.x.x.x.x.x. x +RRDY rx-bufstat incremented .0.0> -addr -BB ^BF data read, bufstats decremented -RRDY data read, ^ARDY bufstats reset filling the rx fifo: x rx-bufstat incremented to FIFO size - 1 .0.x.x.x.x.x.x.x. x rx-bufstat incremented (mod FIFO size) to 0 .0.x.x.x.x.x.x.x. x +ROVR .0. (stalling begins) -ROVR data read, tx-bufstat decremented data read, bufstats decremented slave receiver + restart to transmitter: x +RRDY rx-bufstat incremented .0. 1< (no ARDY due to data in rx fifo) .x.x.x.x.x.x.x. 1 ^AAS +XUDF .0. ^XRDY (stalling) -RRDY data read, bufstats decremented master transmitter: set count, tx-bufstat resets +MST +WRITE +S +XRDY (waits until bus free) -S -XRDY <. +BB repeat{ +XRDY write data, tx-bufstat decremented to nonzero -XRDY write data, tx-bufstat decremented to zero x.x.x.x.x.x.x.0. repeat{ 0. +XUDF if tx fifo empty +P if stop desired, set before last byte written -XUDF +XRDY write data, tx-bufstat decremented to nonzero -XUDF -XRDY write data, tx-bufstat decremented to zero x.x.x.x.x.x.x.x. } if P bit not set: 0. ^ARDY tx-bufstat resets (set count, tx-bufstat resets) +MST +WRITE +S +XRDY 1<. -S -XRDY } if P bit set: 0> -P -MST ^ARDY bufstats reset -BB ^BF XUDF is never set if the tx fifo is non-empty. in slave mode can write into the fifo at any time. threshold is ignored, the counter in buffer stat decrements mod 64 on every read or write and is reset to count when ARDY is generated. stall bit needs to be set before address is recognized to be effective. clearing the still bit, even momentarily, after AAS will release the stall. if data in rx fifo (+RRDY), ARDY event and bufstat reset is deferred. master transmitter with threshold = 2 +MST +S +P +XRDY (5 remaining) <. +BB -S -XRDY x.x.x.x.x.x.x.0.0 . +XUDF (write) -XUDF +XRDY (4 remaining) (write) (3 remaining) (write) -XRDY +XDR (2 remaining) (write) (1 remaining) (write) -XDR (0 remaining)