@@ -76,6 +76,7 @@ typedef struct _machine_i2c_target_obj_t {
7676 mp_hal_pin_obj_t scl ;
7777 mp_hal_pin_obj_t sda ;
7878 uint8_t state ;
79+ bool stop_pending ;
7980} machine_i2c_target_obj_t ;
8081
8182static machine_i2c_target_data_t i2c_target_data [4 ];
@@ -130,8 +131,12 @@ static void i2c_target_handler(i2c_inst_t *i2c) {
130131 if (self -> state == STATE_IDLE ) {
131132 machine_i2c_target_data_addr_match (data , false);
132133 }
133- machine_i2c_target_data_restart_or_stop (data );
134- self -> state = STATE_IDLE ;
134+ if (i2c -> hw -> status & I2C_IC_STATUS_RFNE_BITS ) {
135+ self -> stop_pending = true;
136+ } else {
137+ machine_i2c_target_data_restart_or_stop (data );
138+ self -> state = STATE_IDLE ;
139+ }
135140 }
136141}
137142
@@ -146,7 +151,9 @@ static void i2c_slave_init(i2c_inst_t *i2c, uint16_t addr, bool addr_10bit) {
146151
147152 // Note: The I2C slave does clock stretching implicitly after a RD_REQ, while the Tx FIFO is empty.
148153 // Clock stretching while the Rx FIFO is full is also enabled by default.
149- i2c -> hw -> con = I2C_IC_CON_STOP_DET_IFADDRESSED_BITS ;
154+ i2c -> hw -> con =
155+ I2C_IC_CON_RX_FIFO_FULL_HLD_CTRL_BITS
156+ | I2C_IC_CON_STOP_DET_IFADDRESSED_BITS ;
150157 if (addr_10bit ) {
151158 i2c -> hw -> con |= I2C_IC_CON_IC_10BITADDR_SLAVE_BITS ;
152159 }
@@ -204,6 +211,14 @@ static mp_int_t mp_machine_i2c_target_read_bytes(machine_i2c_target_obj_t *self,
204211 // Re-enable RX_FULL interrupt.
205212 i2c_hw -> intr_mask |= I2C_IC_INTR_MASK_M_RX_FULL_BITS ;
206213
214+ if (self -> stop_pending && !(i2c_hw -> status & I2C_IC_STATUS_RFNE_BITS )) {
215+ unsigned int i2c_id = self -> i2c_inst == i2c0 ? 0 : 1 ;
216+ machine_i2c_target_data_t * data = & i2c_target_data [i2c_id ];
217+ self -> stop_pending = false;
218+ self -> state = STATE_IDLE ;
219+ machine_i2c_target_data_restart_or_stop (data );
220+ }
221+
207222 return i ;
208223}
209224
@@ -255,6 +270,7 @@ static mp_obj_t mp_machine_i2c_target_make_new(const mp_obj_type_t *type, size_t
255270
256271 // Initialise data.
257272 self -> state = STATE_IDLE ;
273+ self -> stop_pending = false;
258274 MP_STATE_PORT (i2c_target_mem_obj )[i2c_id ] = args [ARG_mem ].u_obj ;
259275 machine_i2c_target_data_t * data = & i2c_target_data [i2c_id ];
260276 machine_i2c_target_data_init (data , args [ARG_mem ].u_obj , args [ARG_mem_addrsize ].u_int );
0 commit comments