28
28
*/
29
29
30
30
#include "shared-bindings/busio/I2C.h"
31
+ #include "shared-bindings/microcontroller/__init__.h"
31
32
#include "py/mperrno.h"
32
33
#include "py/runtime.h"
33
34
#include "supervisor/shared/translate.h"
34
35
35
36
#include "nrfx_twim.h"
36
- #include "nrf_gpio.h"
37
-
38
37
#include "nrfx_spim.h"
39
38
#include "nrf_gpio.h"
40
39
@@ -107,7 +106,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
107
106
for (size_t i = 0 ; i < MP_ARRAY_SIZE (twim_peripherals ); i ++ ) {
108
107
if (!twim_peripherals [i ].in_use ) {
109
108
self -> twim_peripheral = & twim_peripherals [i ];
110
- self -> twim_peripheral -> in_use = true;
109
+ // Mark it as in_use later after other validation is finished.
111
110
break ;
112
111
}
113
112
}
@@ -116,10 +115,27 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
116
115
mp_raise_ValueError (translate ("All I2C peripherals are in use" ));
117
116
}
118
117
118
+ // Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
119
+ nrf_gpio_cfg_input (scl -> number , NRF_GPIO_PIN_PULLDOWN );
120
+ nrf_gpio_cfg_input (sda -> number , NRF_GPIO_PIN_PULLDOWN );
121
+
122
+ common_hal_mcu_delay_us (10 );
123
+
124
+ nrf_gpio_cfg_input (scl -> number , NRF_GPIO_PIN_NOPULL );
125
+ nrf_gpio_cfg_input (sda -> number , NRF_GPIO_PIN_NOPULL );
126
+
127
+ // We must pull up within 3us to achieve 400khz.
128
+ common_hal_mcu_delay_us (3 );
129
+
130
+ if (!nrf_gpio_pin_read (sda -> number ) || !nrf_gpio_pin_read (scl -> number )) {
131
+ reset_pin_number (sda -> number );
132
+ reset_pin_number (scl -> number );
133
+ mp_raise_RuntimeError (translate ("SDA or SCL needs a pull up" ));
134
+ }
135
+
119
136
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG ;
120
137
config .scl = scl -> number ;
121
138
config .sda = sda -> number ;
122
-
123
139
// change freq. only if it's less than the default 400K
124
140
if (frequency < 100000 ) {
125
141
config .frequency = NRF_TWIM_FREQ_100K ;
@@ -132,6 +148,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
132
148
claim_pin (sda );
133
149
claim_pin (scl );
134
150
151
+ // About to init. If we fail after this point, common_hal_busio_i2c_deinit() will set in_use to false.
152
+ self -> twim_peripheral -> in_use = true;
135
153
nrfx_err_t err = nrfx_twim_init (& self -> twim_peripheral -> twim , & config , NULL , NULL );
136
154
137
155
// A soft reset doesn't uninit the driver so we might end up with a invalid state
@@ -152,8 +170,9 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
152
170
}
153
171
154
172
void common_hal_busio_i2c_deinit (busio_i2c_obj_t * self ) {
155
- if (common_hal_busio_i2c_deinited (self ))
173
+ if (common_hal_busio_i2c_deinited (self )) {
156
174
return ;
175
+ }
157
176
158
177
nrfx_twim_uninit (& self -> twim_peripheral -> twim );
159
178
0 commit comments