forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 23
Slave Mode
chuck todd edited this page Mar 20, 2018
·
2 revisions
The ESP32 does not stretch SCL. When the peripherals are configured for SLAVE Mode, data for transmission must be in the fifo before the Master device requests it. If a Master device requests 4 bytes of data from a ESP32 that is configured as SLAVE, and there are only 3 bytes in the txFifo, the ESP32 will send the three bytes of valid data then continue to send 0xFF as long as the master clocks SCL.
-
int_status.tx_send_empty
whenever the contents of txFifo falls Belowfifo_conf.nonfifo_tx_thres
-
int_status.tx_fifo_empty
whenever the contents of txFifo is Equal or Belowfifo_conf.tx_fifo_empty_thrhd
But, neither of these interrupt will cause SCL to be stretched. So data must be added to the txFifo before it is needed else 0xFF with be emitted.
I can envision a couple of methods to work with this limitation:
- Trigger the
onRequest()
after the Master Read request, to fill the fifo for the next request. This would require a dummy read, then a full read of valid data. The dummy read equivalent toWire.requestFrom(id,0);
would trigger the SLAVE to flush it's txFifo, reload by callingonRequest()
. - Coordinate between a Master Write (
Wire.onReceive()
) and the Master Read (Wire.onRequest()
). The Master Write would be considered a command that would triggeronRequest()
to fill the txFifo with the 'requested' data. This method is similar to how most I2C devices work. AWrite()
command is issued to set an 'internal' device pointer. After the 'Write()' command completes,Wire.onReceive()
then process the address pointer adjustment, then executesWire.onRequest()
which reloads the txFifo. This pre-staged data is now waiting for the 'Read()' operation. 'Read()' operations could be of infinite length, each time the txFifo reached its threshold values theonRequest()
call-back would be executed to refill the txfifo. - Leave the txFifo empty which cause the peripheral to emit 0xFF, call
onRequest()
, hope the call returns soon enough to satisfy the Master, Personally I think this last idea is bonkers.
If a ESP32 is configured as SLAVE, the ISR will trigger during any Address NAK.
- The ISR will receive a 0x400 (ack_err).
- And 0x80 (trans_complete), Both Read and Write mode.
- 0x10 (slave_tran_comp), actually SLAVE_TRAN_START read or write can be detected by status_reg.slave_rw
This interrupt is generated after the address match has occurred, and the first data byte is moving into or out of the fifo. - 0x02 (tx_fifo_empty)
onRequest()
if fifo_conf.tx_fifo_empty_thrhd is reached. - 0x01 (rx_fifo_full)
onReceive()
if fifo_conf.rx_fifo_full_thrhd is reached. - 0x400 (ack_err) an last byte during onRequest()
- 0x80 (trans_complete) STOP signal