From 1e4e2644ecfd2cab5154a2ad95f3eb5aca545ba7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 3 Dec 2020 13:07:37 +1100 Subject: [PATCH] stm32: Add support for a board to reserve certain peripherals. Allows reserving CAN, I2C, SPI, Timer and UART peripherals. If reserved the peripheral cannot be accessed from Python. Signed-off-by: Damien George --- ports/stm32/i2c.c | 6 ++++++ ports/stm32/machine_uart.c | 5 +++++ ports/stm32/mpconfigboard_common.h | 25 ++++++++++++++++++++++++ ports/stm32/pyb_can.c | 5 +++++ ports/stm32/spi.c | 31 ++++++++++++++++++------------ ports/stm32/timer.c | 5 +++++ 6 files changed, 65 insertions(+), 12 deletions(-) diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c index d67201b714..0b7105344c 100644 --- a/ports/stm32/i2c.c +++ b/ports/stm32/i2c.c @@ -534,6 +534,12 @@ int i2c_find_peripheral(mp_obj_t id) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id); } } + + // check if the I2C is reserved for system use or not + if (MICROPY_HW_I2C_IS_RESERVED(i2c_id)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) is reserved"), i2c_id); + } + return i2c_id; } diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index 2862f4c0e7..31e6a1789e 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -345,6 +345,11 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size } } + // check if the UART is reserved for system use or not + if (MICROPY_HW_UART_IS_RESERVED(uart_id)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) is reserved"), uart_id); + } + pyb_uart_obj_t *self; if (MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] == NULL) { // create new UART object diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index a73a26b162..8890abc59b 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -127,6 +127,31 @@ #define MICROPY_HW_FLASH_FS_LABEL "pybflash" #endif +// Function to determine if the given can_id is reserved for system use or not. +#ifndef MICROPY_HW_CAN_IS_RESERVED +#define MICROPY_HW_CAN_IS_RESERVED(can_id) (false) +#endif + +// Function to determine if the given i2c_id is reserved for system use or not. +#ifndef MICROPY_HW_I2C_IS_RESERVED +#define MICROPY_HW_I2C_IS_RESERVED(i2c_id) (false) +#endif + +// Function to determine if the given spi_id is reserved for system use or not. +#ifndef MICROPY_HW_SPI_IS_RESERVED +#define MICROPY_HW_SPI_IS_RESERVED(spi_id) (false) +#endif + +// Function to determine if the given tim_id is reserved for system use or not. +#ifndef MICROPY_HW_TIM_IS_RESERVED +#define MICROPY_HW_TIM_IS_RESERVED(tim_id) (false) +#endif + +// Function to determine if the given uart_id is reserved for system use or not. +#ifndef MICROPY_HW_UART_IS_RESERVED +#define MICROPY_HW_UART_IS_RESERVED(uart_id) (false) +#endif + /*****************************************************************************/ // General configuration diff --git a/ports/stm32/pyb_can.c b/ports/stm32/pyb_can.c index 224b8f28b0..def66481cb 100644 --- a/ports/stm32/pyb_can.c +++ b/ports/stm32/pyb_can.c @@ -203,6 +203,11 @@ STATIC mp_obj_t pyb_can_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%d) doesn't exist"), can_idx); } + // check if the CAN is reserved for system use or not + if (MICROPY_HW_CAN_IS_RESERVED(can_idx)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%d) is reserved"), can_idx); + } + pyb_can_obj_t *self; if (MP_STATE_PORT(pyb_can_obj_all)[can_idx - 1] == NULL) { self = m_new_obj(pyb_can_obj_t); diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 5f9b1c1a28..07374d7a38 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -167,45 +167,52 @@ void spi_init0(void) { } int spi_find_index(mp_obj_t id) { + int spi_id; if (mp_obj_is_str(id)) { // given a string id const char *port = mp_obj_str_get_str(id); if (0) { #ifdef MICROPY_HW_SPI1_NAME } else if (strcmp(port, MICROPY_HW_SPI1_NAME) == 0) { - return 1; + spi_id = 1; #endif #ifdef MICROPY_HW_SPI2_NAME } else if (strcmp(port, MICROPY_HW_SPI2_NAME) == 0) { - return 2; + spi_id = 2; #endif #ifdef MICROPY_HW_SPI3_NAME } else if (strcmp(port, MICROPY_HW_SPI3_NAME) == 0) { - return 3; + spi_id = 3; #endif #ifdef MICROPY_HW_SPI4_NAME } else if (strcmp(port, MICROPY_HW_SPI4_NAME) == 0) { - return 4; + spi_id = 4; #endif #ifdef MICROPY_HW_SPI5_NAME } else if (strcmp(port, MICROPY_HW_SPI5_NAME) == 0) { - return 5; + spi_id = 5; #endif #ifdef MICROPY_HW_SPI6_NAME } else if (strcmp(port, MICROPY_HW_SPI6_NAME) == 0) { - return 6; + spi_id = 6; #endif + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%s) doesn't exist"), port); } - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%s) doesn't exist"), port); } else { // given an integer id - int spi_id = mp_obj_get_int(id); - if (spi_id >= 1 && spi_id <= MP_ARRAY_SIZE(spi_obj) - && spi_obj[spi_id - 1].spi != NULL) { - return spi_id; + spi_id = mp_obj_get_int(id); + if (spi_id < 1 || spi_id > MP_ARRAY_SIZE(spi_obj) || spi_obj[spi_id - 1].spi == NULL) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id); } - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id); } + + // check if the SPI is reserved for system use or not + if (MICROPY_HW_SPI_IS_RESERVED(spi_id)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) is reserved"), spi_id); + } + + return spi_id; } STATIC uint32_t spi_get_source_freq(SPI_HandleTypeDef *spi) { diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 9b8c14c0da..a34d2984da 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -896,6 +896,11 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Timer(%d) doesn't exist"), tim_id); } + // check if the timer is reserved for system use or not + if (MICROPY_HW_TIM_IS_RESERVED(tim_id)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Timer(%d) is reserved"), tim_id); + } + pyb_timer_obj_t *tim; if (MP_STATE_PORT(pyb_timer_obj_all)[tim_id - 1] == NULL) { // create new Timer object