From 5129d249e9893b3bcae58b2e655b3e5693e1b760 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 19 Aug 2022 15:18:41 +0200 Subject: [PATCH] cpu/nrf52: add locking for shared peripherals --- cpu/nrf52/include/periph_cpu.h | 28 ++++++++++++++++++++++++++++ cpu/nrf52/spi_twi_irq.c | 27 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/cpu/nrf52/include/periph_cpu.h b/cpu/nrf52/include/periph_cpu.h index 7f3bef6051..d888c0a55c 100644 --- a/cpu/nrf52/include/periph_cpu.h +++ b/cpu/nrf52/include/periph_cpu.h @@ -264,6 +264,34 @@ void spi_twi_irq_register_spi(NRF_SPIM_Type *bus, void spi_twi_irq_register_i2c(NRF_TWIM_Type *bus, spi_twi_irq_cb_t cb, void *arg); +/** + * @brief Acquire the shared I2C/SPI peripheral in I2C mode + * + * @param bus bus to acquire exclusive access on + */ +void nrf5x_i2c_acquire(NRF_TWIM_Type *bus); + +/** + * @brief Release the shared I2C/SPI peripheral in I2C mode + * + * @param bus bus to release exclusive access on + */ +void nrf5x_i2c_release(NRF_TWIM_Type *bus); + +/** + * @brief Acquire the shared I2C/SPI peripheral in SPI mode + * + * @param bus bus to acquire exclusive access on + */ +void nrf5x_spi_release(NRF_SPIM_Type *bus); + +/** + * @brief Acquire the shared I2C/SPI peripheral in SPI mode + * + * @param bus bus to release exclusive access on + */ +void nrf5x_spi_acquire(NRF_SPIM_Type *bus); + /** * @brief USBDEV buffers must be word aligned because of DMA restrictions */ diff --git a/cpu/nrf52/spi_twi_irq.c b/cpu/nrf52/spi_twi_irq.c index 73fa24751d..6db7b0065f 100644 --- a/cpu/nrf52/spi_twi_irq.c +++ b/cpu/nrf52/spi_twi_irq.c @@ -24,6 +24,7 @@ #include #include "cpu.h" +#include "mutex.h" #include "periph_cpu.h" #if NRF_SPIM0_BASE != NRF_TWIM0_BASE @@ -59,6 +60,8 @@ static spi_twi_irq_cb_t _irq[SPIM_COUNT]; static void *_irq_arg[SPIM_COUNT]; +static mutex_t _locks[SPIM_COUNT]; + /* I2C and SPI share peripheral addresses */ static size_t _spi_dev2num(void *dev) { @@ -140,6 +143,30 @@ void spi_twi_irq_register_i2c(NRF_TWIM_Type *bus, NVIC_EnableIRQ(_isr[num]); } +void nrf5x_i2c_acquire(NRF_TWIM_Type *bus) +{ + size_t num = _i2c_dev2num(bus); + mutex_lock(&_locks[num]); +} + +void nrf5x_spi_acquire(NRF_SPIM_Type *bus) +{ + size_t num = _spi_dev2num(bus); + mutex_lock(&_locks[num]); +} + +void nrf5x_i2c_release(NRF_TWIM_Type *bus) +{ + size_t num = _i2c_dev2num(bus); + mutex_unlock(&_locks[num]); +} + +void nrf5x_spi_release(NRF_SPIM_Type *bus) +{ + size_t num = _spi_dev2num(bus); + mutex_unlock(&_locks[num]); +} + void ISR_SPIM0(void) { _irq[0](_irq_arg[0]);