Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pio/i2c/i2c.pio
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ do_nack:

do_byte:
set x, 7 ; Loop 8 times
mov isr, null ; Set ISR and input shift counter to zero. This
; helps fix a race condition when autopush is
; disabled and re-enabled, which can leave the
; counter in an inconsistent state.
bitloop:
out pindirs, 1 [7] ; Serialise write data (all-ones if reading)
nop side 1 [2] ; SCL rising edge
Expand Down
5 changes: 5 additions & 0 deletions pio/i2c/pio_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ void pio_i2c_resume_after_error(PIO pio, uint sm) {
pio_interrupt_clear(pio, sm);
}

// Disable autopush of read I2C bytes, which is useful when only writing to
// the I2C bus and we don't want to bother with cleaning the RX FIFO. But be
// careful because this isn't synchronized to the state machine program and in
// a race condition can leave its input shift counter in an unexpected state,
// shifting any subsequently read bytes by an unexpected number of bits.
void pio_i2c_rx_enable(PIO pio, uint sm, bool en) {
if (en)
hw_set_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_AUTOPUSH_BITS);
Expand Down