Skip to content

Commit e376e24

Browse files
committed
refactor to remove common_hal_i2ctarget_i2c_target_is_stop(). Fix separate issue with read_byte returning early.
1 parent 05fae5d commit e376e24

File tree

2 files changed

+19
-21
lines changed

2 files changed

+19
-21
lines changed

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

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,12 @@ 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-
common_hal_i2ctarget_i2c_target_is_stop(self);
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+
}
8994

9095
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))) {
9196
return 0;
@@ -100,12 +105,20 @@ int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *sel
100105
}
101106

102107
int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) {
103-
if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) {
104-
*data = (uint8_t)self->peripheral->hw->data_cmd;
105-
return 1;
106-
} else {
107-
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);
108120
}
121+
return 0;
109122
}
110123

111124
int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) {
@@ -125,19 +138,6 @@ int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self,
125138
}
126139
}
127140

128-
int common_hal_i2ctarget_i2c_target_is_stop(i2ctarget_i2c_target_obj_t *self) {
129-
// Interrupt bits must be cleared by software. Clear the STOP and
130-
// RESTART interrupt bits after an I2C transaction finishes.
131-
if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) {
132-
self->peripheral->hw->clr_stop_det;
133-
self->peripheral->hw->clr_restart_det;
134-
return 1;
135-
} else {
136-
return 0;
137-
}
138-
139-
}
140-
141141
void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) {
142142
return;
143143
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,3 @@ typedef struct {
2121
uint8_t scl_pin;
2222
uint8_t sda_pin;
2323
} i2ctarget_i2c_target_obj_t;
24-
25-
int common_hal_i2ctarget_i2c_target_is_stop(i2ctarget_i2c_target_obj_t *self);

0 commit comments

Comments
 (0)