diff --git a/cpu/nrf52/Kconfig b/cpu/nrf52/Kconfig index 13893255f9..21fa0544ba 100644 --- a/cpu/nrf52/Kconfig +++ b/cpu/nrf52/Kconfig @@ -14,6 +14,7 @@ config CPU_FAM_NRF52 select HAS_BLE_NIMBLE_NETIF select HAS_CORTEXM_MPU select HAS_CPU_NRF52 + select HAS_PERIPH_I2C_RECONFIGURE ## CPU Models config CPU_MODEL_NRF52805XXAA diff --git a/cpu/nrf52/Makefile.features b/cpu/nrf52/Makefile.features index a37f2a28de..3bcda9ceca 100644 --- a/cpu/nrf52/Makefile.features +++ b/cpu/nrf52/Makefile.features @@ -20,4 +20,6 @@ FEATURES_PROVIDED += ble_nimble_netif # all nrf52 have an MPU FEATURES_PROVIDED += cortexm_mpu +FEATURES_PROVIDED += periph_i2c_reconfigure + include $(RIOTCPU)/nrf5x_common/Makefile.features diff --git a/cpu/nrf52/include/periph_cpu.h b/cpu/nrf52/include/periph_cpu.h index 5d76239463..850c8b1888 100644 --- a/cpu/nrf52/include/periph_cpu.h +++ b/cpu/nrf52/include/periph_cpu.h @@ -137,6 +137,14 @@ typedef struct { #define PERIPH_I2C_NEED_WRITE_REG /** @} */ +/** + * @name Define macros for sda and scl pin to be able to reinitialize them + * @{ + */ +#define i2c_pin_sda(dev) i2c_config[dev].sda +#define i2c_pin_scl(dev) i2c_config[dev].scl +/** @} */ + /** * @name The PWM unit on the nRF52 supports 4 channels per device */ diff --git a/cpu/nrf52/periph/i2c.c b/cpu/nrf52/periph/i2c.c index cabdedd797..9888f8a68e 100644 --- a/cpu/nrf52/periph/i2c.c +++ b/cpu/nrf52/periph/i2c.c @@ -87,6 +87,14 @@ static int finish(i2c_t dev) return 0; } +static void _init_pins(i2c_t dev) +{ + gpio_init(i2c_config[dev].scl, GPIO_IN_OD_PU); + gpio_init(i2c_config[dev].sda, GPIO_IN_OD_PU); + bus(dev)->PSEL.SCL = i2c_config[dev].scl; + bus(dev)->PSEL.SDA = i2c_config[dev].sda; +} + void i2c_init(i2c_t dev) { assert(dev < I2C_NUMOF); @@ -99,22 +107,42 @@ void i2c_init(i2c_t dev) /* disable device during initialization, will be enabled when acquire is * called */ bus(dev)->ENABLE = TWIM_ENABLE_ENABLE_Disabled; + /* configure pins */ - gpio_init(i2c_config[dev].scl, GPIO_IN_OD_PU); - gpio_init(i2c_config[dev].sda, GPIO_IN_OD_PU); - bus(dev)->PSEL.SCL = i2c_config[dev].scl; - bus(dev)->PSEL.SDA = i2c_config[dev].sda; + _init_pins(dev); + /* configure dev clock speed */ bus(dev)->FREQUENCY = i2c_config[dev].speed; spi_twi_irq_register_i2c(bus(dev), i2c_isr_handler, (void *)dev); - /* re-enable the device. We expect that the device was being acquired before + /* We expect that the device was being acquired before * the i2c_init_master() function is called, so it should be enabled when * exiting this function. */ bus(dev)->ENABLE = TWIM_ENABLE_ENABLE_Enabled; } +#ifdef MODULE_PERIPH_I2C_RECONFIGURE +void i2c_init_pins(i2c_t dev) +{ + assert(dev < I2C_NUMOF); + + _init_pins(dev); + + bus(dev)->ENABLE = TWIM_ENABLE_ENABLE_Enabled; + + mutex_unlock(&locks[dev]); +} + +void i2c_deinit_pins(i2c_t dev) +{ + assert(dev < I2C_NUMOF); + + mutex_lock(&locks[dev]); + bus(dev)->ENABLE = TWIM_ENABLE_ENABLE_Disabled; +} +#endif /* MODULE_PERIPH_I2C_RECONFIGURE */ + int i2c_acquire(i2c_t dev) { assert(dev < I2C_NUMOF);