forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 23
BackGround ESP32 Errata and Discoveries
chuck todd edited this page Nov 23, 2017
·
19 revisions
#I2C subsystems Enhancement
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.
- If an ACK error is detected (ACK value not what was expected), the ST will terminate the cmd[] queue and send a STOP on the bus.
- COMMAND[] queue
- an END command can only be the LAST element of the queue. All entries after END are not Executed. AND the END entry must not be changed when the queue is refilled. This means once an END is used, [15] can only be END.
- an END cannot be directly preceded by a START. If END exists in [15], a START cannot be placed in [14]. If this case is encountered, a prior READ or WRITE must be split to consume the unused position [14]. If this exception is not followed an a START is placed in [14], the SM will not execute the ctrl.trans_start=1. A TimeOut IRQ will happen.
- Register fields must not be updated with -= +=,
i2c->dev->command[i].byte_num -= 1; // will change other fields of command[]
// safe method to decrement byte_num
uint32_t temp = i2c->dev->command[i].val;
temp = (temp&0xFFFFFF00) | ((temp & 0xFF)-1);
i2c->dev->command[i].val = temp;
* dummy command can be created using a READ or WRITE command, just set the num_byte = 0.
- 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