mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #19798
19798: cpu/nrf53: add I2C and SPI support r=benpicco a=dylad ### Contribution description This PR provides support for nRF53 SPI and I2C. It also moves common structs from each nRF CPU folder to `cpu/nrf5x_common` to avoid duplication. Moreover, since nRF9160 and nRF5340 have shared IRQ for UART/SPI/I2C. Both this families now use a common file to register and manage these interrupts. Note that nRF9160 have different name for its interrupts than nRF5340 but they have the same purpose. ### Testing procedure Since some structs were moved around, I think this PR should be carefully tested against nRF52, nRF53 and nRF9160 to avoid any issues. On nRF5340DK-APP, SPI can be tested with its onboard SPI flash. ### Issues/PRs references Co-authored-by: Dylan Laduranty <dylan.laduranty@mesotic.com>
This commit is contained in:
commit
0f50a8fa00
@ -11,11 +11,15 @@ config BOARD_NRF5340DK_APP
|
||||
bool
|
||||
default y
|
||||
select CPU_MODEL_NRF5340_APP
|
||||
select HAS_PERIPH_I2C
|
||||
select HAS_PERIPH_SPI
|
||||
select HAS_PERIPH_SPI_GPIO_MODE
|
||||
select HAS_PERIPH_PWM
|
||||
select HAS_PERIPH_RTT
|
||||
select HAS_PERIPH_TIMER
|
||||
select HAS_PERIPH_UART
|
||||
select HAS_PERIPH_UART_HW_FC
|
||||
select HAS_PERIPH_USBDEV
|
||||
select HAVE_MTD_SPI_NOR
|
||||
|
||||
# Put other features for this board (in alphabetical order)
|
||||
|
9
boards/nrf5340dk-app/Makefile.dep
Normal file
9
boards/nrf5340dk-app/Makefile.dep
Normal file
@ -0,0 +1,9 @@
|
||||
ifneq (,$(filter mtd,$(USEMODULE)))
|
||||
USEMODULE += mtd_spi_nor
|
||||
endif
|
||||
|
||||
# default to using littlefs2 on the external flash
|
||||
ifneq (,$(filter vfs_default,$(USEMODULE)))
|
||||
USEPKG += littlefs2
|
||||
USEMODULE += mtd
|
||||
endif
|
@ -2,8 +2,10 @@ CPU_MODEL = nrf5340_app
|
||||
CPU = nrf53
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
FEATURES_PROVIDED += periph_rtt
|
||||
FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
FEATURES_PROVIDED += periph_uart_hw_fc
|
||||
|
58
boards/nrf5340dk-app/board.c
Normal file
58
boards/nrf5340dk-app/board.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Mesotic SAS
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_nrf5340dk-app
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Board specific implementations for the Nordic nRF5340DK board
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "timex.h"
|
||||
#ifdef MODULE_VFS_DEFAULT
|
||||
#include "vfs_default.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_MTD_SPI_NOR
|
||||
#include "mtd_spi_nor.h"
|
||||
/* MX25R64 */
|
||||
static const mtd_spi_nor_params_t _nrf5340_nor_params = {
|
||||
.opcode = &mtd_spi_nor_opcode_default,
|
||||
.wait_chip_erase = 240 * US_PER_SEC,
|
||||
.wait_64k_erase = 800 * US_PER_MS,
|
||||
.wait_sector_erase = 240 * US_PER_MS,
|
||||
.wait_chip_wake_up = 1 * US_PER_MS,
|
||||
.clk = MHZ(54),
|
||||
.flag = SPI_NOR_F_SECT_4K | SPI_NOR_F_SECT_64K,
|
||||
.spi = SPI_DEV(0),
|
||||
.mode = SPI_MODE_0,
|
||||
.cs = BOARD_QSPI_PIN_CS,
|
||||
.wp = BOARD_QSPI_PIN_WP,
|
||||
.hold = BOARD_QSPI_PIN_HOLD,
|
||||
};
|
||||
|
||||
static mtd_spi_nor_t nrf5340_nor_dev = {
|
||||
.base = {
|
||||
.driver = &mtd_spi_nor_driver,
|
||||
.page_size = 256,
|
||||
.pages_per_sector = 16,
|
||||
},
|
||||
.params = &_nrf5340_nor_params,
|
||||
};
|
||||
mtd_dev_t *mtd0 = (mtd_dev_t *)&nrf5340_nor_dev;
|
||||
|
||||
#ifdef MODULE_VFS_DEFAULT
|
||||
VFS_AUTO_MOUNT(littlefs2, VFS_MTD(nrf5340_nor_dev), VFS_DEFAULT_NVM(0), 0);
|
||||
#endif
|
||||
#endif /* MODULE_MTD_SPI_NOR */
|
@ -20,6 +20,7 @@
|
||||
#define BOARD_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mtd.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -95,6 +96,19 @@ extern "C" {
|
||||
#define BTN3_MODE GPIO_IN_PU /**< BTN3 default mode */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MTD configuration
|
||||
* @{
|
||||
*/
|
||||
extern mtd_dev_t *mtd0;
|
||||
#define MTD_0 mtd0
|
||||
#define MTD_NUMOF 1
|
||||
|
||||
#define BOARD_QSPI_PIN_CS GPIO_PIN(0, 18) /**< SPI Flash Chip Select */
|
||||
#define BOARD_QSPI_PIN_WP GPIO_PIN(0, 15) /**< SPI Flash Write Protect */
|
||||
#define BOARD_QSPI_PIN_HOLD GPIO_PIN(0, 16) /**< SPI Flash Hold pin */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -70,8 +70,6 @@ static const uart_conf_t uart_config[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_0_ISR (isr_serial0) /**< SERIAL0_IRQn */
|
||||
|
||||
#define UART_NUMOF ARRAY_SIZE(uart_config) /**< UART configuration NUMOF */
|
||||
/** @} */
|
||||
|
||||
@ -112,6 +110,37 @@ static const pwm_conf_t pwm_config[] = {
|
||||
#define PWM_NUMOF ARRAY_SIZE(pwm_config)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SPI configuration
|
||||
* @{
|
||||
*/
|
||||
static const spi_conf_t spi_config[] = {
|
||||
{
|
||||
.dev = NRF_SPIM1_S,
|
||||
.sclk = GPIO_PIN(0, 17),
|
||||
.mosi = GPIO_PIN(0, 13),
|
||||
.miso = GPIO_PIN(0, 14),
|
||||
}
|
||||
};
|
||||
|
||||
#define SPI_NUMOF ARRAY_SIZE(spi_config)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* * @name I2C configuration
|
||||
* * @{
|
||||
* */
|
||||
static const i2c_conf_t i2c_config[] = {
|
||||
{
|
||||
.dev = NRF_TWIM2_S,
|
||||
.scl = GPIO_PIN(1, 3),
|
||||
.sda = GPIO_PIN(1, 2),
|
||||
.speed = I2C_SPEED_NORMAL
|
||||
}
|
||||
};
|
||||
#define I2C_NUMOF ARRAY_SIZE(i2c_config)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -113,9 +113,6 @@ static const uart_conf_t uart_config[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_0_ISR (isr_uarte0_spim0_spis0_twim0_twis0) /**< UART0_IRQ */
|
||||
#define UART_1_ISR (isr_uarte1_spim1_spis1_twim1_twis1) /**< UART1_IRQ */
|
||||
|
||||
#define UART_NUMOF ARRAY_SIZE(uart_config) /**< UART configuration NUMOF */
|
||||
/** @} */
|
||||
|
||||
|
@ -27,14 +27,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the workaround for the SPI single byte transmit errata (No.
|
||||
* 58 on the nrf52832)
|
||||
*/
|
||||
#ifdef CPU_MODEL_NRF52832XXAA
|
||||
#define ERRATA_SPI_SINGLE_BYTE_WORKAROUND (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System core clock speed, fixed to 64MHz for all NRF52x CPUs
|
||||
*/
|
||||
@ -45,18 +37,6 @@ extern "C" {
|
||||
*/
|
||||
#define PERIPH_CLOCK (16000000U)
|
||||
|
||||
/**
|
||||
* @brief Redefine some peripheral names to unify them between nRF51 and 52
|
||||
* @{
|
||||
*/
|
||||
#define SPI_SCKSEL (dev(bus)->PSEL.SCK)
|
||||
#define SPI_MOSISEL (dev(bus)->PSEL.MOSI)
|
||||
#define SPI_MISOSEL (dev(bus)->PSEL.MISO)
|
||||
#ifdef CPU_MODEL_NRF52832XXAA
|
||||
#define UART_IRQN (UARTE0_UART0_IRQn)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief The nRF52 family of CPUs provides a fixed number of 9 ADC lines
|
||||
*/
|
||||
@ -66,14 +46,6 @@ extern "C" {
|
||||
#define ADC_NUMOF (9U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI temporary buffer size for storing const data in RAM before
|
||||
* initiating DMA transfer
|
||||
*/
|
||||
#ifndef CONFIG_SPI_MBUF_SIZE
|
||||
#define CONFIG_SPI_MBUF_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief nRF52 specific naming of ADC lines (for convenience)
|
||||
*/
|
||||
@ -109,50 +81,6 @@ typedef enum {
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Override I2C speed settings
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_I2C_SPEED_T
|
||||
typedef enum {
|
||||
I2C_SPEED_LOW = 0xff, /**< not supported */
|
||||
I2C_SPEED_NORMAL = TWIM_FREQUENCY_FREQUENCY_K100, /**< 100kbit/s */
|
||||
I2C_SPEED_FAST = TWIM_FREQUENCY_FREQUENCY_K400, /**< 400kbit/s */
|
||||
I2C_SPEED_FAST_PLUS = 0xfe, /**< not supported */
|
||||
I2C_SPEED_HIGH = 0xfd, /**< not supported */
|
||||
} i2c_speed_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief I2C (TWI) configuration options
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_TWIM_Type *dev; /**< TWIM hardware device */
|
||||
gpio_t scl; /**< SCL pin */
|
||||
gpio_t sda; /**< SDA pin */
|
||||
i2c_speed_t speed; /**< Bus speed */
|
||||
} i2c_conf_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Use shared I2C functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_I2C_NEED_READ_REG
|
||||
#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
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Size of the UART TX buffer for non-blocking mode.
|
||||
*/
|
||||
@ -160,19 +88,6 @@ typedef struct {
|
||||
#define UART_TXBUF_SIZE (64)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI configuration values
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_SPIM_Type *dev; /**< SPI device used */
|
||||
gpio_t sclk; /**< CLK pin */
|
||||
gpio_t mosi; /**< MOSI pin */
|
||||
gpio_t miso; /**< MISO pin */
|
||||
#if ERRATA_SPI_SINGLE_BYTE_WORKAROUND
|
||||
uint8_t ppi; /**< PPI channel */
|
||||
#endif
|
||||
} spi_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Common SPI/I2C interrupt callback
|
||||
*
|
||||
|
@ -7,16 +7,6 @@
|
||||
|
||||
if TEST_KCONFIG
|
||||
|
||||
config MODULE_PERIPH_UART_NONBLOCKING
|
||||
depends on HAS_PERIPH_UART_NONBLOCKING
|
||||
depends on MODULE_PERIPH_UART
|
||||
select MODULE_TSRB
|
||||
|
||||
config MODULE_PERIPH_SPI
|
||||
depends on HAS_PERIPH_SPI
|
||||
select MODULE_PERIPH_GPIO_IRQ if CPU_MODEL_NRF52832XXAA && HAS_PERIPH_GPIO_IRQ
|
||||
select MODULE_PERIPH_SPI_GPIO_MODE if MODULE_PERIPH_SPI && HAS_PERIPH_SPI_GPIO_MODE
|
||||
|
||||
config MODULE_SAUL_NRF_VDDH
|
||||
bool "Internal Voltage Sensor"
|
||||
depends on HAS_PERIPH_ADC
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define SPIM_COUNT 2
|
||||
#endif
|
||||
|
||||
static spi_twi_irq_cb_t _irq[SPIM_COUNT];
|
||||
static shared_irq_cb_t _irq[SPIM_COUNT];
|
||||
static void *_irq_arg[SPIM_COUNT];
|
||||
|
||||
static mutex_t _locks[SPIM_COUNT];
|
||||
@ -123,8 +123,8 @@ static const IRQn_Type _isr[] = {
|
||||
#endif /* CPU_MODEL_NRF52840XXAA */
|
||||
};
|
||||
|
||||
void spi_twi_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
void shared_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
|
||||
@ -133,8 +133,8 @@ void spi_twi_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void spi_twi_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
void shared_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
|
||||
@ -145,7 +145,7 @@ void spi_twi_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
}
|
||||
|
||||
void nrf5x_i2c_acquire(NRF_TWIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
@ -154,7 +154,7 @@ void nrf5x_i2c_acquire(NRF_TWIM_Type *bus,
|
||||
}
|
||||
|
||||
void nrf5x_spi_acquire(NRF_SPIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
|
@ -19,6 +19,7 @@ config CPU_FAM_NRF53
|
||||
select HAS_PERIPH_UART_MODECFG
|
||||
select HAS_PERIPH_WDT
|
||||
select HAS_PERIPH_WDT_CB
|
||||
select MODULE_NRF_SHARED_SERIAL_IRQ
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_NRF5340_APP
|
||||
|
@ -1,4 +1,9 @@
|
||||
USEMODULE += nrf53_vectors
|
||||
USEMODULE += nrf_shared_serial_irq
|
||||
|
||||
ifneq (,$(filter periph_spi,$(USEMODULE)))
|
||||
USEMODULE += periph_spi_gpio_mode
|
||||
endif
|
||||
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.dep
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.dep
|
||||
|
@ -1,4 +1,6 @@
|
||||
CPU_CORE = cortex-m33
|
||||
CPU_FAM = nrf53
|
||||
|
||||
FEATURES_PROVIDED += periph_spi_gpio_mode
|
||||
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.features
|
||||
|
@ -53,6 +53,11 @@ config HAS_VDD_LC_FILTER_REG1
|
||||
Indicates that a board is equipped with an external LC filter circuit
|
||||
attached to the CPUs voltage regulator stage 1.
|
||||
|
||||
config MODULE_NRF_SHARED_SERIAL_IRQ
|
||||
bool
|
||||
depends on CPU_FAM_NRF53 || CPU_FAM_NRF9160
|
||||
help
|
||||
Indicates that the MCU used shared IRQ for UART/I2C/SPI.
|
||||
|
||||
config MODULE_CPU_COMMON
|
||||
bool
|
||||
|
@ -1,6 +1,9 @@
|
||||
MODULE = cpu_common
|
||||
DIRS = periph
|
||||
|
||||
ifneq (,$(filter nrf_shared_serial_irq,$(USEMODULE)))
|
||||
DIRS += shared_irq
|
||||
endif
|
||||
# build one of the radio drivers, if enabled
|
||||
ifneq (,$(filter nrfble,$(USEMODULE)))
|
||||
DIRS += radio/nrfble
|
||||
|
@ -31,6 +31,15 @@ extern "C" {
|
||||
#ifdef NRF_FICR_S
|
||||
#define NRF_FICR NRF_FICR_S
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the workaround for the SPI single byte transmit errata (No.
|
||||
* 58 on the nrf52832)
|
||||
*/
|
||||
#ifdef CPU_MODEL_NRF52832XXAA
|
||||
#define ERRATA_SPI_SINGLE_BYTE_WORKAROUND (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Power management configuration
|
||||
* @{
|
||||
@ -136,6 +145,38 @@ typedef enum {
|
||||
} gpio_pull_t;
|
||||
#endif /* END: GPIO LL overwrites */
|
||||
|
||||
#if !defined(DOXYGEN) && (defined(CPU_NRF53) || defined(CPU_NRF9160))
|
||||
/**
|
||||
* @brief Wrapper to fix differences between nRF families vendor files
|
||||
*/
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud1200 UARTE_BAUDRATE_BAUDRATE_Baud1200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud2400 UARTE_BAUDRATE_BAUDRATE_Baud2400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud4800 UARTE_BAUDRATE_BAUDRATE_Baud4800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud9600 UARTE_BAUDRATE_BAUDRATE_Baud9600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud14400 UARTE_BAUDRATE_BAUDRATE_Baud14400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud19200 UARTE_BAUDRATE_BAUDRATE_Baud19200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud28800 UARTE_BAUDRATE_BAUDRATE_Baud28800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud31250 UARTE_BAUDRATE_BAUDRATE_Baud31250
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud38400 UARTE_BAUDRATE_BAUDRATE_Baud38400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud56000 UARTE_BAUDRATE_BAUDRATE_Baud56000
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud57600 UARTE_BAUDRATE_BAUDRATE_Baud57600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud76800 UARTE_BAUDRATE_BAUDRATE_Baud76800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud115200 UARTE_BAUDRATE_BAUDRATE_Baud115200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud230400 UARTE_BAUDRATE_BAUDRATE_Baud230400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud250000 UARTE_BAUDRATE_BAUDRATE_Baud250000
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud460800 UARTE_BAUDRATE_BAUDRATE_Baud460800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud921600 UARTE_BAUDRATE_BAUDRATE_Baud921600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud1M UARTE_BAUDRATE_BAUDRATE_Baud1M
|
||||
|
||||
#define SPI_FREQUENCY_FREQUENCY_K125 SPIM_FREQUENCY_FREQUENCY_K125
|
||||
#define SPI_FREQUENCY_FREQUENCY_K500 SPIM_FREQUENCY_FREQUENCY_K500
|
||||
#define SPI_FREQUENCY_FREQUENCY_M1 SPIM_FREQUENCY_FREQUENCY_M1
|
||||
#define SPI_FREQUENCY_FREQUENCY_M4 SPIM_FREQUENCY_FREQUENCY_M4
|
||||
#define SPI_FREQUENCY_FREQUENCY_M8 SPIM_FREQUENCY_FREQUENCY_M8
|
||||
#define SPI_CONFIG_CPHA_Msk SPIM_CONFIG_CPHA_Msk
|
||||
#define SPI_CONFIG_CPOL_Msk SPIM_CONFIG_CPOL_Msk
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief No support for HW chip select...
|
||||
*/
|
||||
@ -221,7 +262,6 @@ typedef struct {
|
||||
* @brief Override SPI mode values
|
||||
* @{
|
||||
*/
|
||||
#if !defined(CPU_FAM_NRF9160) && !defined(CPU_FAM_NRF53)
|
||||
#define HAVE_SPI_MODE_T
|
||||
typedef enum {
|
||||
SPI_MODE_0 = 0, /**< CPOL=0, CPHA=0 */
|
||||
@ -244,7 +284,6 @@ typedef enum {
|
||||
SPI_CLK_10MHZ = SPI_FREQUENCY_FREQUENCY_M8 /**< 10MHz */
|
||||
} spi_clk_t;
|
||||
/** @} */
|
||||
#endif /* ndef CPU_FAM_NRF9160 */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
@ -360,6 +399,159 @@ typedef struct {
|
||||
} pwm_conf_t;
|
||||
#endif
|
||||
#endif /* ndef CPU_FAM_NRF51 */
|
||||
#ifndef CPU_NRF51
|
||||
|
||||
/**
|
||||
* @brief Redefine some peripheral names to unify them across nRF families
|
||||
*/
|
||||
#define SPI_SCKSEL (dev(bus)->PSEL.SCK) /**< Macro for SPI clk */
|
||||
#define SPI_MOSISEL (dev(bus)->PSEL.MOSI) /**< Macro for SPI mosi */
|
||||
#define SPI_MISOSEL (dev(bus)->PSEL.MISO) /**< Macro for SPI miso */
|
||||
#ifdef CPU_MODEL_NRF52832XXAA
|
||||
#define UART_IRQN (UARTE0_UART0_IRQn)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI configuration values
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_SPIM_Type *dev; /**< SPI device used */
|
||||
gpio_t sclk; /**< CLK pin */
|
||||
gpio_t mosi; /**< MOSI pin */
|
||||
gpio_t miso; /**< MISO pin */
|
||||
#if ERRATA_SPI_SINGLE_BYTE_WORKAROUND
|
||||
uint8_t ppi; /**< PPI channel */
|
||||
#endif
|
||||
} spi_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Common UART/SPI/I2C interrupt callback
|
||||
*
|
||||
* @param arg Opaque context pointer
|
||||
*/
|
||||
typedef void (*shared_irq_cb_t)(void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register a SPI IRQ handler for a shared UART/I2C/SPI irq vector
|
||||
*
|
||||
* @param bus bus to register the IRQ handler on
|
||||
* @param cb callback to call on IRQ
|
||||
* @param arg Argument to pass to the handler
|
||||
*/
|
||||
void shared_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register an I2C IRQ handler for a shared UART/I2C/SPI irq vector
|
||||
*
|
||||
* @param bus bus to register the IRQ handler on
|
||||
* @param cb callback to call on IRQ
|
||||
* @param arg Argument to pass to the handler
|
||||
*/
|
||||
void shared_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register an UART IRQ handler for a shared UART/I2C/SPI irq vector
|
||||
*
|
||||
* @param bus bus to register the IRQ handler on
|
||||
* @param cb callback to call on IRQ
|
||||
* @param arg Argument to pass to the handler
|
||||
*/
|
||||
void shared_irq_register_uart(NRF_UARTE_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Acquire the shared I2C/SPI peripheral in I2C mode
|
||||
*
|
||||
* @param bus bus to acquire exclusive access on
|
||||
* @param cb ISR handler to call on IRQ
|
||||
* @param arg ISR handler argument
|
||||
*/
|
||||
void nrf5x_i2c_acquire(NRF_TWIM_Type *bus, shared_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @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 release exclusive access on
|
||||
* @param cb ISR handler to call on IRQ
|
||||
* @param arg ISR handler argument
|
||||
*/
|
||||
void nrf5x_spi_acquire(NRF_SPIM_Type *bus, shared_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Acquire the shared I2C/SPI peripheral in SPI mode
|
||||
*
|
||||
* @param bus bus to release exclusive access on
|
||||
*/
|
||||
void nrf5x_spi_release(NRF_SPIM_Type *bus);
|
||||
|
||||
/**
|
||||
* @brief Size of the UART TX buffer for non-blocking mode.
|
||||
*/
|
||||
#ifndef UART_TXBUF_SIZE
|
||||
#define UART_TXBUF_SIZE (64)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI temporary buffer size for storing const data in RAM before
|
||||
* initiating DMA transfer
|
||||
*/
|
||||
#ifndef CONFIG_SPI_MBUF_SIZE
|
||||
#define CONFIG_SPI_MBUF_SIZE 64
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Override I2C speed settings
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_I2C_SPEED_T
|
||||
typedef enum {
|
||||
I2C_SPEED_LOW = 0xff, /**< not supported */
|
||||
I2C_SPEED_NORMAL = TWIM_FREQUENCY_FREQUENCY_K100, /**< 100kbit/s */
|
||||
I2C_SPEED_FAST = TWIM_FREQUENCY_FREQUENCY_K400, /**< 400kbit/s */
|
||||
I2C_SPEED_FAST_PLUS = 0xfe, /**< not supported */
|
||||
I2C_SPEED_HIGH = 0xfd, /**< not supported */
|
||||
} i2c_speed_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief I2C (TWI) configuration options
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_TWIM_Type *dev; /**< TWIM hardware device */
|
||||
gpio_t scl; /**< SCL pin */
|
||||
gpio_t sda; /**< SDA pin */
|
||||
i2c_speed_t speed; /**< Bus speed */
|
||||
} i2c_conf_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Use shared I2C functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_I2C_NEED_READ_REG
|
||||
#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 /**< Macro for getting SDA pin */
|
||||
#define i2c_pin_scl(dev) i2c_config[dev].scl /**< Macro for getting SCL pin */
|
||||
/** @} */
|
||||
#endif /* ndef CPU_NRF51 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -33,4 +33,14 @@ config MODULE_VDD_LC_FILTER_REG1
|
||||
help
|
||||
Use the LC filter attached to the CPUs voltage regulator
|
||||
|
||||
config MODULE_PERIPH_UART_NONBLOCKING
|
||||
depends on HAS_PERIPH_UART_NONBLOCKING
|
||||
depends on MODULE_PERIPH_UART
|
||||
select MODULE_TSRB
|
||||
|
||||
config MODULE_PERIPH_SPI
|
||||
depends on HAS_PERIPH_SPI
|
||||
select MODULE_PERIPH_GPIO_IRQ if CPU_MODEL_NRF52832XXAA && HAS_PERIPH_GPIO_IRQ
|
||||
select MODULE_PERIPH_SPI_GPIO_MODE if MODULE_PERIPH_SPI && HAS_PERIPH_SPI_GPIO_MODE
|
||||
|
||||
endif # TEST_KCONFIG
|
||||
|
@ -2,7 +2,7 @@ MODULE = nrf5x_common_periph
|
||||
|
||||
# Select the specific implementation for `periph_i2c`
|
||||
ifneq (,$(filter periph_i2c,$(USEMODULE)))
|
||||
ifneq (,$(filter $(CPU_FAM),nrf52 nrf9160))
|
||||
ifneq (,$(filter $(CPU_FAM),nrf52 nrf53 nrf9160))
|
||||
SRC += i2c_nrf52_nrf9160.c
|
||||
endif
|
||||
endif
|
||||
@ -17,7 +17,7 @@ endif
|
||||
|
||||
# Select the specific implementation for `periph_spi`
|
||||
ifneq (,$(filter periph_spi,$(USEMODULE)))
|
||||
ifneq (,$(filter $(CPU_FAM),nrf52 nrf9160))
|
||||
ifneq (,$(filter $(CPU_FAM),nrf52 nrf53 nrf9160))
|
||||
SRC += spi_nrf52_nrf9160.c
|
||||
endif
|
||||
endif
|
||||
|
@ -134,7 +134,7 @@ void i2c_init(i2c_t dev)
|
||||
/* configure shared periphal speed */
|
||||
_setup_shared_peripheral(dev);
|
||||
|
||||
spi_twi_irq_register_i2c(bus(dev), i2c_isr_handler, (void *)(uintptr_t)dev);
|
||||
shared_irq_register_i2c(bus(dev), i2c_isr_handler, (void *)(uintptr_t)dev);
|
||||
|
||||
/* We expect that the device was being acquired before
|
||||
* the i2c_init_master() function is called, so it should be enabled when
|
||||
|
@ -178,7 +178,7 @@ void spi_init_pins(spi_t bus)
|
||||
|
||||
/* select pins for the SPI device */
|
||||
_setup_workaround_for_ftpan_58(bus);
|
||||
spi_twi_irq_register_spi(dev(bus), spi_isr_handler, (void *)(uintptr_t)bus);
|
||||
shared_irq_register_spi(dev(bus), spi_isr_handler, (void *)(uintptr_t)bus);
|
||||
}
|
||||
|
||||
void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
|
@ -76,6 +76,11 @@ static tsrb_t uart_tx_rb[UART_NUMOF];
|
||||
static uint8_t uart_tx_rb_buf[UART_NUMOF][UART_TXBUF_SIZE];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Shared IRQ Callback for UART on nRF53/nRF9160
|
||||
*/
|
||||
void uart_isr_handler(void *arg);
|
||||
|
||||
static inline NRF_UARTE_Type *dev(uart_t uart)
|
||||
{
|
||||
return uart_config[uart].dev;
|
||||
@ -239,7 +244,11 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
}
|
||||
|
||||
if (rx_cb || IS_USED(MODULE_PERIPH_UART_NONBLOCKING)) {
|
||||
#if defined(CPU_NRF53) || defined(CPU_NRF9160)
|
||||
shared_irq_register_uart(dev(uart), uart_isr_handler, (void *)(uintptr_t)uart);
|
||||
#else
|
||||
NVIC_EnableIRQ(UART_IRQN);
|
||||
#endif
|
||||
}
|
||||
return UART_OK;
|
||||
}
|
||||
@ -489,6 +498,14 @@ static inline void irq_handler(uart_t uart)
|
||||
|
||||
#endif /* !CPU_MODEL_NRF52832XXAA && !CPU_FAM_NRF51 */
|
||||
|
||||
#if defined(CPU_NRF53) || defined(CPU_NRF9160)
|
||||
void uart_isr_handler(void *arg)
|
||||
{
|
||||
uart_t uart = (uart_t)(uintptr_t)arg;
|
||||
|
||||
irq_handler(uart);
|
||||
}
|
||||
#else
|
||||
#ifdef UART_0_ISR
|
||||
void UART_0_ISR(void)
|
||||
{
|
||||
@ -502,3 +519,4 @@ void UART_1_ISR(void)
|
||||
irq_handler(UART_DEV(1));
|
||||
}
|
||||
#endif
|
||||
#endif /* def CPU_NRF53 || CPU_NRF9160 */
|
||||
|
11
cpu/nrf5x_common/shared_irq/Kconfig
Normal file
11
cpu/nrf5x_common/shared_irq/Kconfig
Normal file
@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2023 Mesotic SAS
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config MODULE_NRF_SHARED_SERIAL_IRQ
|
||||
bool
|
||||
depends on TEST_KCONFIG
|
||||
default y
|
7
cpu/nrf5x_common/shared_irq/Makefile
Normal file
7
cpu/nrf5x_common/shared_irq/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
MODULE = nrf_shared_serial_irq
|
||||
|
||||
SRC_FILE = shared_serial_irq.c
|
||||
|
||||
SRCS += $(SRC_FILE)
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
209
cpu/nrf5x_common/shared_irq/shared_serial_irq.c
Normal file
209
cpu/nrf5x_common/shared_irq/shared_serial_irq.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Mesotic SAS
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_nrf5x_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Shared IRQ handling between UART, SPI and TWI peripherals
|
||||
* on the nRF53/9160 devices
|
||||
*
|
||||
* I2C is called TWI (Two Wire Interface) in Nordic's documentation
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
static shared_irq_cb_t _irq[SPIM_COUNT];
|
||||
static void *_irq_arg[SPIM_COUNT];
|
||||
|
||||
static mutex_t _locks[SPIM_COUNT];
|
||||
|
||||
/* UART, I2C and SPI share peripheral addresses */
|
||||
static size_t _spi_dev2num(void *dev)
|
||||
{
|
||||
if (dev == NRF_SPIM0_S) {
|
||||
return 0;
|
||||
}
|
||||
else if (dev == NRF_SPIM1_S) {
|
||||
return 1;
|
||||
}
|
||||
else if (dev == NRF_SPIM2_S) {
|
||||
return 2;
|
||||
}
|
||||
else if (dev == NRF_SPIM3_S) {
|
||||
return 3;
|
||||
}
|
||||
#ifdef NRF_SPIM4_S
|
||||
else if (dev == NRF_SPIM4_S) {
|
||||
return 4;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t _i2c_dev2num(void *dev)
|
||||
{
|
||||
if (dev == NRF_SPIM0_S) {
|
||||
return 0;
|
||||
}
|
||||
else if (dev == NRF_SPIM1_S) {
|
||||
return 1;
|
||||
}
|
||||
else if (dev == NRF_SPIM2_S) {
|
||||
return 2;
|
||||
}
|
||||
else if (dev == NRF_SPIM3_S) {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t _uart_dev2num(void *dev)
|
||||
{
|
||||
/* I2C and UART have the same amount of instances */
|
||||
return _i2c_dev2num(dev);
|
||||
}
|
||||
|
||||
#ifdef CPU_MODEL_NRF5340_APP
|
||||
static const IRQn_Type _isr[] = {
|
||||
SERIAL0_IRQn,
|
||||
SERIAL1_IRQn,
|
||||
SERIAL2_IRQn,
|
||||
SERIAL3_IRQn,
|
||||
SPIM4_IRQn
|
||||
};
|
||||
#define SERIAL0_ISR isr_serial0
|
||||
#define SERIAL1_ISR isr_serial1
|
||||
#define SERIAL2_ISR isr_serial2
|
||||
#define SERIAL3_ISR isr_serial3
|
||||
#define SERIAL4_ISR isr_spim4
|
||||
#elif defined(CPU_NRF9160)
|
||||
static const IRQn_Type _isr[] = {
|
||||
UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQn,
|
||||
UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQn,
|
||||
UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQn,
|
||||
UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQn
|
||||
};
|
||||
#define SERIAL0_ISR isr_uarte0_spim0_spis0_twim0_twis0
|
||||
#define SERIAL1_ISR isr_uarte1_spim1_spis1_twim1_twis1
|
||||
#define SERIAL2_ISR isr_uarte2_spim2_spis2_twim2_twis2
|
||||
#define SERIAL3_ISR isr_uarte3_spim3_spis3_twim3_twis3
|
||||
#else
|
||||
#error "Missing shared IRQ configuration for this MCU."asm
|
||||
#endif
|
||||
|
||||
void shared_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void shared_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void shared_irq_register_uart(NRF_UARTE_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _uart_dev2num(bus);
|
||||
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void nrf5x_i2c_acquire(NRF_TWIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
}
|
||||
|
||||
void nrf5x_spi_acquire(NRF_SPIM_Type *bus,
|
||||
shared_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
/* ISR Routines */
|
||||
void SERIAL0_ISR(void)
|
||||
{
|
||||
_irq[0](_irq_arg[0]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
||||
void SERIAL1_ISR(void)
|
||||
{
|
||||
_irq[1](_irq_arg[1]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
||||
void SERIAL2_ISR(void)
|
||||
{
|
||||
_irq[2](_irq_arg[2]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
||||
void SERIAL3_ISR(void)
|
||||
{
|
||||
_irq[3](_irq_arg[3]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
||||
#ifdef SERIAL4_ISR
|
||||
void serial4_isr(void)
|
||||
{
|
||||
_irq[4](_irq_arg[4]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif
|
@ -21,6 +21,7 @@ config CPU_FAM_NRF9160
|
||||
select HAS_PERIPH_SPI_GPIO_MODE
|
||||
select HAS_PERIPH_WDT
|
||||
select HAS_PERIPH_WDT_CB
|
||||
select MODULE_NRF_SHARED_SERIAL_IRQ
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_NRF9160
|
||||
|
@ -1,4 +1,5 @@
|
||||
USEMODULE += nrf9160_vectors
|
||||
USEMODULE += nrf_shared_serial_irq
|
||||
|
||||
ifneq (,$(filter periph_spi,$(USEMODULE)))
|
||||
USEMODULE += periph_spi_gpio_mode
|
||||
|
@ -36,189 +36,6 @@ extern "C" {
|
||||
*/
|
||||
#define PERIPH_CLOCK MHZ(16)
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Wrapper to fix differences between nRF9160 and
|
||||
* nRF52 vendor files
|
||||
*/
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud1200 UARTE_BAUDRATE_BAUDRATE_Baud1200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud2400 UARTE_BAUDRATE_BAUDRATE_Baud2400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud4800 UARTE_BAUDRATE_BAUDRATE_Baud4800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud9600 UARTE_BAUDRATE_BAUDRATE_Baud9600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud14400 UARTE_BAUDRATE_BAUDRATE_Baud14400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud19200 UARTE_BAUDRATE_BAUDRATE_Baud19200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud28800 UARTE_BAUDRATE_BAUDRATE_Baud28800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud31250 UARTE_BAUDRATE_BAUDRATE_Baud31250
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud38400 UARTE_BAUDRATE_BAUDRATE_Baud38400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud56000 UARTE_BAUDRATE_BAUDRATE_Baud56000
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud57600 UARTE_BAUDRATE_BAUDRATE_Baud57600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud76800 UARTE_BAUDRATE_BAUDRATE_Baud76800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud115200 UARTE_BAUDRATE_BAUDRATE_Baud115200
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud230400 UARTE_BAUDRATE_BAUDRATE_Baud230400
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud250000 UARTE_BAUDRATE_BAUDRATE_Baud250000
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud460800 UARTE_BAUDRATE_BAUDRATE_Baud460800
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud921600 UARTE_BAUDRATE_BAUDRATE_Baud921600
|
||||
#define UART_BAUDRATE_BAUDRATE_Baud1M UARTE_BAUDRATE_BAUDRATE_Baud1M
|
||||
|
||||
/**
|
||||
* @brief Override I2C speed settings
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_I2C_SPEED_T
|
||||
typedef enum {
|
||||
I2C_SPEED_LOW = 0xff, /**< not supported */
|
||||
I2C_SPEED_NORMAL = TWIM_FREQUENCY_FREQUENCY_K100, /**< 100kbit/s */
|
||||
I2C_SPEED_FAST = TWIM_FREQUENCY_FREQUENCY_K400, /**< 400kbit/s */
|
||||
I2C_SPEED_FAST_PLUS = 0xfe, /**< not supported */
|
||||
I2C_SPEED_HIGH = 0xfd, /**< not supported */
|
||||
} i2c_speed_t;
|
||||
/** @} */
|
||||
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief I2C (TWI) configuration options
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_TWIM_Type *dev; /**< TWIM hardware device */
|
||||
gpio_t scl; /**< SCL pin */
|
||||
gpio_t sda; /**< SDA pin */
|
||||
i2c_speed_t speed; /**< Bus speed */
|
||||
} i2c_conf_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Use shared I2C functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_I2C_NEED_READ_REG
|
||||
#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
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Defines macros for SPI pins initialization
|
||||
* @{
|
||||
*/
|
||||
#define SPI_SCKSEL (dev(bus)->PSEL.SCK)
|
||||
#define SPI_MOSISEL (dev(bus)->PSEL.MOSI)
|
||||
#define SPI_MISOSEL (dev(bus)->PSEL.MISO)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SPI temporary buffer size for storing const data in RAM before
|
||||
* initiating DMA transfer
|
||||
*/
|
||||
#ifndef CONFIG_SPI_MBUF_SIZE
|
||||
#define CONFIG_SPI_MBUF_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI configuration values
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_SPIM_Type *dev; /**< SPI device used */
|
||||
gpio_t sclk; /**< CLK pin */
|
||||
gpio_t mosi; /**< MOSI pin */
|
||||
gpio_t miso; /**< MISO pin */
|
||||
} spi_conf_t;
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Override SPI mode values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_MODE_T
|
||||
typedef enum {
|
||||
SPI_MODE_0 = 0, /**< CPOL=0, CPHA=0 */
|
||||
SPI_MODE_1 = SPIM_CONFIG_CPHA_Msk, /**< CPOL=0, CPHA=1 */
|
||||
SPI_MODE_2 = SPIM_CONFIG_CPOL_Msk, /**< CPOL=1, CPHA=0 */
|
||||
SPI_MODE_3 = (SPIM_CONFIG_CPOL_Msk | SPIM_CONFIG_CPHA_Msk) /**< CPOL=1, CPHA=1 */
|
||||
} spi_mode_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Override SPI clock values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CLK_T
|
||||
typedef enum {
|
||||
SPI_CLK_100KHZ = SPIM_FREQUENCY_FREQUENCY_K125, /**< 100KHz */
|
||||
SPI_CLK_400KHZ = SPIM_FREQUENCY_FREQUENCY_K500, /**< 400KHz */
|
||||
SPI_CLK_1MHZ = SPIM_FREQUENCY_FREQUENCY_M1, /**< 1MHz */
|
||||
SPI_CLK_5MHZ = SPIM_FREQUENCY_FREQUENCY_M4, /**< 5MHz */
|
||||
SPI_CLK_10MHZ = SPIM_FREQUENCY_FREQUENCY_M8 /**< 10MHz */
|
||||
} spi_clk_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Common SPI/I2C interrupt callback
|
||||
*
|
||||
* @param arg Opaque context pointer
|
||||
*/
|
||||
typedef void (*spi_twi_irq_cb_t)(void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register a SPI IRQ handler for a shared I2C/SPI irq vector
|
||||
*
|
||||
* @param bus bus to register the IRQ handler on
|
||||
* @param cb callback to call on IRQ
|
||||
* @param arg Argument to pass to the handler
|
||||
*/
|
||||
void spi_twi_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register a I2C IRQ handler for a shared I2C/SPI irq vector
|
||||
*
|
||||
* @param bus bus to register the IRQ handler on
|
||||
* @param cb callback to call on IRQ
|
||||
* @param arg Argument to pass to the handler
|
||||
*/
|
||||
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
|
||||
* @param cb ISR handler to call on IRQ
|
||||
* @param arg ISR handler argument
|
||||
*/
|
||||
void nrf5x_i2c_acquire(NRF_TWIM_Type *bus, spi_twi_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @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 release exclusive access on
|
||||
* @param cb ISR handler to call on IRQ
|
||||
* @param arg ISR handler argument
|
||||
*/
|
||||
void nrf5x_spi_acquire(NRF_SPIM_Type *bus, spi_twi_irq_cb_t cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Acquire the shared I2C/SPI peripheral in SPI mode
|
||||
*
|
||||
* @param bus bus to release exclusive access on
|
||||
*/
|
||||
void nrf5x_spi_release(NRF_SPIM_Type *bus);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Mesotic SAS
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_nrf9160
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Shared IRQ handling between SPI and TWI peripherals on the nRF52
|
||||
* devices
|
||||
*
|
||||
* I2C is called TWI (Two Wire Interface) in the datasheets from Nordic
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
static spi_twi_irq_cb_t _irq[TWIM_COUNT];
|
||||
static void *_irq_arg[TWIM_COUNT];
|
||||
|
||||
static mutex_t _locks[SPIM_COUNT];
|
||||
|
||||
#if TWIM_COUNT != SPIM_COUNT
|
||||
#error Possible configuration issue, please update this file
|
||||
#endif
|
||||
|
||||
/* I2C and SPI share peripheral addresses */
|
||||
static size_t _spi_dev2num(void *dev)
|
||||
{
|
||||
if (dev == NRF_SPIM0_S) {
|
||||
return 0;
|
||||
}
|
||||
else if (dev == NRF_SPIM1_S) {
|
||||
return 1;
|
||||
}
|
||||
else if (dev == NRF_SPIM2_S) {
|
||||
return 2;
|
||||
}
|
||||
else if (dev == NRF_SPIM3_S) {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t _i2c_dev2num(void *dev)
|
||||
{
|
||||
return _spi_dev2num(dev);
|
||||
}
|
||||
|
||||
static const IRQn_Type _isr[] = {
|
||||
UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQn,
|
||||
UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQn,
|
||||
UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQn,
|
||||
UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQn
|
||||
};
|
||||
|
||||
void spi_twi_irq_register_spi(NRF_SPIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void spi_twi_irq_register_i2c(NRF_TWIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
|
||||
NVIC_EnableIRQ(_isr[num]);
|
||||
}
|
||||
|
||||
void nrf5x_i2c_acquire(NRF_TWIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _i2c_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
}
|
||||
|
||||
void nrf5x_spi_acquire(NRF_SPIM_Type *bus,
|
||||
spi_twi_irq_cb_t cb, void *arg)
|
||||
{
|
||||
size_t num = _spi_dev2num(bus);
|
||||
mutex_lock(&_locks[num]);
|
||||
_irq[num] = cb;
|
||||
_irq_arg[num] = arg;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
/* Check if UART driver doesn't already use the same IRQ */
|
||||
#ifndef UART_0_ISR
|
||||
void isr_uarte0_spim0_spis0_twim0_twis0(void)
|
||||
{
|
||||
_irq[0](_irq_arg[0]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* ndef UART_0_ISR */
|
||||
|
||||
#ifndef UART_1_ISR
|
||||
void isr_uarte1_spim1_spis1_twim1_twis1(void)
|
||||
{
|
||||
_irq[1](_irq_arg[1]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* ndef UART_1_ISR */
|
||||
|
||||
#ifndef UART_2_ISR
|
||||
void isr_uarte2_spim2_spis2_twim2_twis2(void)
|
||||
{
|
||||
_irq[2](_irq_arg[2]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* ndef UART_2_ISR */
|
||||
|
||||
#ifndef UART_3_ISR
|
||||
void isr_uarte3_spim3_spis3_twim3_twis3(void)
|
||||
{
|
||||
_irq[3](_irq_arg[3]);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* ndef UART_3_ISR */
|
@ -8,7 +8,7 @@ INCLUDES += -I$(RIOTPKG)/mynewt-core/include \
|
||||
DIRS += $(RIOTPKG)/mynewt-core/contrib \
|
||||
#
|
||||
|
||||
ifneq (,$(filter nrf5%,$(CPU)))
|
||||
ifneq (,$(filter nrf51 nrf52,$(CPU)))
|
||||
# OS_CPUTIME is set to 32.767 Hz
|
||||
CFLAGS += -DMYNEWT_VAL_OS_CPUTIME_FREQ=32768
|
||||
else
|
||||
|
@ -3,7 +3,7 @@ MODULE = mynewt-core
|
||||
# exclude submodule sources from *.c wildcard source selection
|
||||
SRC := $(filter-out nrf5x_isr.c cputime.c,$(wildcard *.c))
|
||||
|
||||
ifneq (,$(filter nrf5%,$(CPU)))
|
||||
ifneq (,$(filter nrf51 nrf52,$(CPU)))
|
||||
SRC += nrf5x_isr.c
|
||||
else
|
||||
SRC += cputime.c
|
||||
|
@ -8,7 +8,7 @@ SRC := \
|
||||
os_cputime_pwr2.c \
|
||||
#
|
||||
|
||||
ifneq (,$(filter nrf5%,$(CPU)))
|
||||
ifneq (,$(filter nrf51 nrf52,$(CPU)))
|
||||
SRC += os_cputime.c
|
||||
endif
|
||||
|
||||
|
@ -53,7 +53,7 @@ endif
|
||||
|
||||
# nimble controller dependencies
|
||||
ifneq (,$(filter nimble_controller,$(USEMODULE)))
|
||||
ifneq (,$(filter nrf5%,$(CPU_FAM)))
|
||||
ifneq (,$(filter nrf51 nrf52,$(CPU_FAM)))
|
||||
USEMODULE += nimble_drivers_nrf5x
|
||||
endif
|
||||
endif
|
||||
|
@ -19,7 +19,8 @@ endif
|
||||
ifneq (,$(filter uwb-core_dpl,$(USEMODULE)))
|
||||
USEPKG += mynewt-core
|
||||
USEMODULE += mynewt-core_os
|
||||
ifneq (,$(filter nrf5%,$(CPU)))
|
||||
# don't pull nrf53 into the list
|
||||
ifneq (,$(filter nrf51 nrf52,$(CPU)))
|
||||
USEMODULE += mynewt-core_nrf5x_hal
|
||||
endif
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user