@@ -79,20 +79,54 @@ void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
7979 }
8080}
8181
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+
82116static uint8_t twi_error_to_mp (const nrfx_err_t err ) {
83117 switch (err ) {
84118 case NRFX_ERROR_DRV_TWI_ERR_ANACK :
85119 return MP_ENODEV ;
86120 case NRFX_ERROR_BUSY :
87121 return MP_EBUSY ;
122+ case NRFX_SUCCESS :
123+ return 0 ;
88124 case NRFX_ERROR_DRV_TWI_ERR_DNACK :
89125 case NRFX_ERROR_INVALID_ADDR :
90- return MP_EIO ;
126+ case NRFX_ERROR_INTERNAL :
91127 default :
92- break ;
128+ return MP_EIO ;
93129 }
94-
95- return 0 ;
96130}
97131
98132void 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) {
188222 NRF_TWIM_Type * reg = self -> twim_peripheral -> twim .p_twim ;
189223 bool found = true;
190224
191- nrfx_twim_enable (& self -> twim_peripheral -> twim );
225+ if (NRFX_SUCCESS != _safe_twim_enable (self )) {
226+ return false;
227+ }
192228
193229 nrf_twim_address_set (reg , addr );
194230 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,
246282
247283 nrfx_err_t err = NRFX_SUCCESS ;
248284
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+ }
250289
251290 // break into MAX_XFER_LEN transaction
252291 while (len ) {
@@ -278,7 +317,10 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
278317
279318 nrfx_err_t err = NRFX_SUCCESS ;
280319
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+ }
282324
283325 // break into MAX_XFER_LEN transaction
284326 while (len ) {
0 commit comments