Skip to content

BackGround ESP32 Errata and Discoveries

chuck todd edited this page Nov 22, 2017 · 19 revisions

#I2C subsystems Enhancement

This arduino-esp32 fork is dedicated to enhancing the I2C support for the Espressif ESP32.

21Nov2017 Through trial and error some truths have been discovered about the ESP32 v1 chip:

  • The I2C StateMachine(SM) is unforgiving.
  • The SM enforces the I2C protocol rules.
    • All transactions must begin with a START and end with STOP. No exceptions.
    • SCL clock stretching must not exceed approximately 2**20 CPU clock cycles (about 12ms)
    • Ownership of the bus cannot be forced. This means that if the SM thinks it has lost an Arbitration it will not generate SCL pulses until it sees a STOP. If the Arbitration Loss was due to a unserviced END command it will never release BUS Busy error.
    • The SM enforces SCL TimeOuts. If the SCL signal is held low for longer than the programmed timeout, the SM will latchup into a state where the only recovery method is to reinit the hardware. The only proven recovery from this state is by Totally releasing the peripheral then re-attaching and reloading all configurations.
    • The SM monitors the i2c bus, It will generate state interrupts based on this monitoring.
      • The TimeOut interrupt will trigger repeatedly if another master mal-forms an I2C transaction. A low going SDA while SCL will be interpreted as a Start, if Timeout clock ticks happen without a SCL pulse, TimeOut is issued.
      • the master_trans (0x40) will be generated every 9 clock cycles.
      • and ACK mismatches will be reported as ACK interrupts.

Preliminary, not completely verified, still guessing!

  • The SM is semi-promiscuous, It monitors the I2C bus and triggers its interrupts as if the transactions were directed at it.
    • When configured as master ctrl.mode=1
    • Specifically, the 0x80 Interrupt (int_raw.trans_complete) what I call STOP interrupt
    • Specifically, the 0x40 interrupt (master_tran_comp) is issued for every byte that traverses the bus.
    • The status_reg.rx_fifo_cnt is increment for each of these bytes, up to 0x20
    • The fifo_st.rx_fifo_end_addr increment for each byte(Address and Data) and loops
    • When configured as Not Master (slave) ctr.ms_mode=0, interrupts not related to this slave will fire
      • any ACK error will be reflected 0x400 (int_raw.ack_error) event
      • the 0x80 Interrupt (int_raw.trans_complete) what I call STOP interrupt
    • When configured as not Master (slave) with slave.addr = 0 will respond to all data on bus
Clone this wiki locally