Skip to content

Commit 85a6482

Browse files
committed
Check for no pullups on I2C on nrf; give arduino nano 33 ble two I2C devices
1 parent 43b8d5e commit 85a6482

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

ports/atmel-samd/common-hal/busio/I2C.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
116116
if (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) {
117117
reset_pin_number(sda->number);
118118
reset_pin_number(scl->number);
119+
common_hal_busio_i2c_deinit(self);
119120
mp_raise_ValueError(translate("Unsupported baudrate"));
120121
}
121122

ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ endif
2222
NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
2323

2424
INTERNAL_FLASH_FILESYSTEM = 1
25+
26+
# Allocate two, not just one I2C peripheral, so that we have both
27+
# on-board and off-board I2C available.
28+
# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
29+
# We use a CFLAGS define here because there are include order issues
30+
# if we try to include "mpconfigport.h" into nrfx_config.h .
31+
CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2

ports/nrf/common-hal/busio/I2C.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@
2828
*/
2929

3030
#include "shared-bindings/busio/I2C.h"
31+
#include "shared-bindings/microcontroller/__init__.h"
3132
#include "py/mperrno.h"
3233
#include "py/runtime.h"
3334
#include "supervisor/shared/translate.h"
3435

3536
#include "nrfx_twim.h"
36-
#include "nrf_gpio.h"
37-
3837
#include "nrfx_spim.h"
3938
#include "nrf_gpio.h"
4039

@@ -107,7 +106,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
107106
for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
108107
if (!twim_peripherals[i].in_use) {
109108
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.
111110
break;
112111
}
113112
}
@@ -116,10 +115,27 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
116115
mp_raise_ValueError(translate("All I2C peripherals are in use"));
117116
}
118117

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+
119136
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG;
120137
config.scl = scl->number;
121138
config.sda = sda->number;
122-
123139
// change freq. only if it's less than the default 400K
124140
if (frequency < 100000) {
125141
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 *
132148
claim_pin(sda);
133149
claim_pin(scl);
134150

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;
135153
nrfx_err_t err = nrfx_twim_init(&self->twim_peripheral->twim, &config, NULL, NULL);
136154

137155
// 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) {
152170
}
153171

154172
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)) {
156174
return;
175+
}
157176

158177
nrfx_twim_uninit(&self->twim_peripheral->twim);
159178

0 commit comments

Comments
 (0)