@@ -77,6 +77,7 @@ typedef struct _machine_i2c_target_obj_t {
7777 mp_hal_pin_obj_t sda ;
7878 uint8_t state ;
7979 bool stop_pending ;
80+ bool irq_active ;
8081} machine_i2c_target_obj_t ;
8182
8283static machine_i2c_target_data_t i2c_target_data [4 ];
@@ -89,11 +90,26 @@ static machine_i2c_target_obj_t machine_i2c_target_obj[] = {
8990/******************************************************************************/
9091// RP2xxx hardware bindings
9192
93+ static void check_stop_pending (machine_i2c_target_obj_t * self ) {
94+ if (self -> irq_active ) {
95+ return ;
96+ }
97+ if (self -> stop_pending && !(self -> i2c_inst -> hw -> status & I2C_IC_STATUS_RFNE_BITS )) {
98+ unsigned int i2c_id = self - & machine_i2c_target_obj [0 ];
99+ machine_i2c_target_data_t * data = & i2c_target_data [i2c_id ];
100+ self -> stop_pending = false;
101+ self -> state = STATE_IDLE ;
102+ machine_i2c_target_data_restart_or_stop (data );
103+ }
104+ }
105+
92106static void i2c_target_handler (i2c_inst_t * i2c ) {
93107 unsigned int i2c_id = i2c == i2c0 ? 0 : 1 ;
94108 machine_i2c_target_obj_t * self = & machine_i2c_target_obj [i2c_id ];
95109 machine_i2c_target_data_t * data = & i2c_target_data [i2c_id ];
96110
111+ self -> irq_active = true;
112+
97113 // Get the interrupt status.
98114 uint32_t intr_stat = i2c -> hw -> intr_stat ;
99115
@@ -102,6 +118,16 @@ static void i2c_target_handler(i2c_inst_t *i2c) {
102118 (void )i2c -> hw -> clr_tx_abrt ;
103119 }
104120
121+ if (intr_stat & I2C_IC_INTR_STAT_R_START_DET_BITS ) {
122+ // Controller sent a start condition.
123+ // Reset all state machines in case something went wrong.
124+ (void )i2c -> hw -> clr_start_det ;
125+ if (self -> state != STATE_IDLE ) {
126+ machine_i2c_target_data_reset_helper (data );
127+ self -> state = STATE_IDLE ;
128+ }
129+ }
130+
105131 if (intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS ) {
106132 // Data from controller is available for reading.
107133 // Mask interrupt until I2C_DATA_CMD is read from.
@@ -138,6 +164,9 @@ static void i2c_target_handler(i2c_inst_t *i2c) {
138164 self -> state = STATE_IDLE ;
139165 }
140166 }
167+
168+ self -> irq_active = false;
169+ check_stop_pending (self );
141170}
142171
143172static void i2c_slave_irq_handler (void ) {
@@ -160,10 +189,12 @@ static void i2c_slave_init(i2c_inst_t *i2c, uint16_t addr, bool addr_10bit) {
160189 i2c -> hw -> sar = addr ;
161190 i2c -> hw -> tx_tl = 1 ;
162191 i2c -> hw -> rx_tl = 0 ; // interrupt when at least 1 byte is available
192+ (void )i2c -> hw -> clr_intr ;
163193
164194 // Enable interrupts.
165195 i2c -> hw -> intr_mask =
166- I2C_IC_INTR_MASK_M_STOP_DET_BITS
196+ I2C_IC_INTR_MASK_M_START_DET_BITS
197+ | I2C_IC_INTR_MASK_M_STOP_DET_BITS
167198 | I2C_IC_INTR_MASK_M_RX_DONE_BITS
168199 | I2C_IC_INTR_MASK_M_TX_ABRT_BITS
169200 | I2C_IC_INTR_MASK_M_RD_REQ_BITS
@@ -187,6 +218,7 @@ static void i2c_slave_deinit(i2c_inst_t *i2c) {
187218
188219 i2c -> hw -> intr_mask = 0 ;
189220 i2c -> hw -> enable = 0 ;
221+ i2c -> hw -> con = I2C_IC_CON_IC_SLAVE_DISABLE_BITS ;
190222}
191223
192224/******************************************************************************/
@@ -199,39 +231,36 @@ static void mp_machine_i2c_target_event_callback(machine_i2c_target_irq_obj_t *i
199231 mp_irq_handler (& irq -> base );
200232}
201233
202- static mp_int_t mp_machine_i2c_target_read_bytes (machine_i2c_target_obj_t * self , size_t len , uint8_t * buf ) {
234+ static size_t mp_machine_i2c_target_read_bytes (machine_i2c_target_obj_t * self , size_t len , uint8_t * buf ) {
203235 i2c_hw_t * i2c_hw = self -> i2c_inst -> hw ;
204236
205237 // Read from the RX FIFO.
206- mp_int_t i = 0 ;
238+ size_t i = 0 ;
207239 while (i < len && (i2c_hw -> status & I2C_IC_STATUS_RFNE_BITS )) {
208240 buf [i ++ ] = i2c_hw -> data_cmd ;
209241 }
210242
211243 // Re-enable RX_FULL interrupt.
212244 i2c_hw -> intr_mask |= I2C_IC_INTR_MASK_M_RX_FULL_BITS ;
213245
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- }
246+ check_stop_pending (self );
221247
222248 return i ;
223249}
224250
225- static mp_int_t mp_machine_i2c_target_write_bytes (machine_i2c_target_obj_t * self , size_t len , const uint8_t * buf ) {
251+ static size_t mp_machine_i2c_target_write_bytes (machine_i2c_target_obj_t * self , size_t len , const uint8_t * buf ) {
226252 i2c_hw_t * i2c_hw = self -> i2c_inst -> hw ;
227253
228254 // Write to the TX FIFO.
229- i2c_hw -> data_cmd = buf [0 ];
255+ size_t i = 0 ;
256+ while (i < len && (i2c_hw -> status & I2C_IC_STATUS_TFNF_BITS )) {
257+ i2c_hw -> data_cmd = buf [i ++ ];
258+ }
230259
231260 // Re-enable RD_REQ interrupt.
232261 i2c_hw -> intr_mask |= I2C_IC_INTR_MASK_M_RD_REQ_BITS ;
233262
234- return 1 ;
263+ return i ;
235264}
236265
237266static void mp_machine_i2c_target_irq_config (machine_i2c_target_obj_t * self , unsigned int trigger ) {
@@ -271,6 +300,7 @@ static mp_obj_t mp_machine_i2c_target_make_new(const mp_obj_type_t *type, size_t
271300 // Initialise data.
272301 self -> state = STATE_IDLE ;
273302 self -> stop_pending = false;
303+ self -> irq_active = false;
274304 MP_STATE_PORT (i2c_target_mem_obj )[i2c_id ] = args [ARG_mem ].u_obj ;
275305 machine_i2c_target_data_t * data = & i2c_target_data [i2c_id ];
276306 machine_i2c_target_data_init (data , args [ARG_mem ].u_obj , args [ARG_mem_addrsize ].u_int );
@@ -310,5 +340,7 @@ static void mp_machine_i2c_target_print(const mp_print_t *print, mp_obj_t self_i
310340}
311341
312342static void mp_machine_i2c_target_deinit (machine_i2c_target_obj_t * self ) {
343+ gpio_set_function (self -> scl , GPIO_FUNC_SIO );
344+ gpio_set_function (self -> sda , GPIO_FUNC_SIO );
313345 i2c_slave_deinit (self -> i2c_inst );
314346}
0 commit comments