@@ -79,20 +79,54 @@ void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
79
79
}
80
80
}
81
81
82
+ #define TWI_TWIM_PIN_CONFIGURE (_pin ) nrf_gpio_cfg((_pin), \
83
+ NRF_GPIO_PIN_DIR_OUTPUT, \
84
+ NRF_GPIO_PIN_INPUT_CONNECT, \
85
+ NRF_GPIO_PIN_PULLUP, \
86
+ NRF_GPIO_PIN_S0D1, \
87
+ NRF_GPIO_PIN_NOSENSE)
88
+
89
+ static nrfx_err_t _safe_twim_enable (busio_i2c_obj_t * self ) {
90
+ // check to see if bus is in sensible state before enabling twim
91
+ nrfx_err_t recover_result ;
92
+ nrf_gpio_cfg_input (self -> scl_pin_number , NRF_GPIO_PIN_PULLDOWN );
93
+ nrf_gpio_cfg_input (self -> sda_pin_number , NRF_GPIO_PIN_PULLDOWN );
94
+
95
+ common_hal_mcu_delay_us (10 );
96
+
97
+ nrf_gpio_cfg_input (self -> scl_pin_number , NRF_GPIO_PIN_NOPULL );
98
+ nrf_gpio_cfg_input (self -> sda_pin_number , NRF_GPIO_PIN_NOPULL );
99
+
100
+ // We must pull up within 3us to achieve 400khz.
101
+ common_hal_mcu_delay_us (3 );
102
+
103
+ if (!nrf_gpio_pin_read (self -> sda_pin_number ) || !nrf_gpio_pin_read (self -> scl_pin_number )) {
104
+ // bus not in a sane state - try to recover
105
+ recover_result = nrfx_twim_bus_recover (self -> scl_pin_number , self -> sda_pin_number );
106
+ if (NRFX_SUCCESS != recover_result ) {
107
+ // return error message if unable to recover the bus
108
+ return recover_result ;
109
+ }
110
+ }
111
+
112
+ nrfx_twim_enable (& self -> twim_peripheral -> twim );
113
+ return NRFX_SUCCESS ;
114
+ }
115
+
82
116
static uint8_t twi_error_to_mp (const nrfx_err_t err ) {
83
117
switch (err ) {
84
118
case NRFX_ERROR_DRV_TWI_ERR_ANACK :
85
119
return MP_ENODEV ;
86
120
case NRFX_ERROR_BUSY :
87
121
return MP_EBUSY ;
122
+ case NRFX_SUCCESS :
123
+ return 0 ;
88
124
case NRFX_ERROR_DRV_TWI_ERR_DNACK :
89
125
case NRFX_ERROR_INVALID_ADDR :
90
- return MP_EIO ;
126
+ case NRFX_ERROR_INTERNAL :
91
127
default :
92
- break ;
128
+ return MP_EIO ;
93
129
}
94
-
95
- return 0 ;
96
130
}
97
131
98
132
void common_hal_busio_i2c_construct (busio_i2c_obj_t * self , const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
@@ -188,7 +222,9 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
188
222
NRF_TWIM_Type * reg = self -> twim_peripheral -> twim .p_twim ;
189
223
bool found = true;
190
224
191
- nrfx_twim_enable (& self -> twim_peripheral -> twim );
225
+ if (NRFX_SUCCESS != _safe_twim_enable (self )) {
226
+ return false;
227
+ }
192
228
193
229
nrf_twim_address_set (reg , addr );
194
230
nrf_twim_tx_buffer_set (reg , NULL , 0 );
@@ -246,7 +282,10 @@ STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
246
282
247
283
nrfx_err_t err = NRFX_SUCCESS ;
248
284
249
- nrfx_twim_enable (& self -> twim_peripheral -> twim );
285
+ err = _safe_twim_enable (self );
286
+ if (NRFX_SUCCESS != err ) {
287
+ return twi_error_to_mp (err );
288
+ }
250
289
251
290
// break into MAX_XFER_LEN transaction
252
291
while (len ) {
@@ -278,7 +317,10 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
278
317
279
318
nrfx_err_t err = NRFX_SUCCESS ;
280
319
281
- nrfx_twim_enable (& self -> twim_peripheral -> twim );
320
+ err = _safe_twim_enable (self );
321
+ if (NRFX_SUCCESS != err ) {
322
+ return twi_error_to_mp (err );
323
+ }
282
324
283
325
// break into MAX_XFER_LEN transaction
284
326
while (len ) {
0 commit comments