Skip to content

Commit f9e6afc

Browse files
authored
Merge pull request #10933 from FoamyGuy/rpi_i2c_fixes
Rpi port i2ctarget fixes
2 parents 2a4ccc2 + e376e24 commit f9e6afc

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) {
8585
}
8686

8787
int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) {
88+
// Interrupt bits must be cleared by software. Clear the STOP and
89+
// RESTART interrupt bits after an I2C transaction finishes.
90+
if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) {
91+
self->peripheral->hw->clr_stop_det;
92+
self->peripheral->hw->clr_restart_det;
93+
}
94+
8895
if (!((self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) || (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS))) {
8996
return 0;
9097
}
@@ -98,12 +105,20 @@ int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *sel
98105
}
99106

100107
int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) {
101-
if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) {
102-
*data = (uint8_t)self->peripheral->hw->data_cmd;
103-
return 1;
104-
} else {
105-
return 0;
108+
// Wait for data to arrive or a STOP condition indicating the transfer is over.
109+
// Without this wait, the CPU can drain the FIFO faster than bytes arrive on the
110+
// I2C bus, causing transfers to be split into multiple partial reads.
111+
for (int t = 0; t < 100; t++) {
112+
if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) {
113+
*data = (uint8_t)self->peripheral->hw->data_cmd;
114+
return 1;
115+
}
116+
if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) {
117+
break;
118+
}
119+
mp_hal_delay_us(10);
106120
}
121+
return 0;
107122
}
108123

109124
int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) {

0 commit comments

Comments
 (0)