From ff91156d3495c3583dd4ced85ceea6243a1377a2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 20 Apr 2014 19:06:15 +0100 Subject: [PATCH] stmhal: Improved configurability for I2C and SPI busses. The HAL handles for the I2C/SPI objects are rather large, so we don't want to unnecessarily include them. --- stmhal/accel.c | 4 ++ stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h | 5 +- stmhal/boards/PYBV10/mpconfigboard.h | 3 + stmhal/boards/PYBV3/mpconfigboard.h | 3 + stmhal/boards/PYBV4/mpconfigboard.h | 5 +- stmhal/boards/STM32F4DISC/mpconfigboard.h | 3 + stmhal/i2c.c | 30 +++++--- stmhal/spi.c | 70 +++++++++++-------- 8 files changed, 80 insertions(+), 43 deletions(-) diff --git a/stmhal/accel.c b/stmhal/accel.c index 339a93ea40..47c7a1a494 100644 --- a/stmhal/accel.c +++ b/stmhal/accel.c @@ -12,6 +12,8 @@ #include "i2c.h" #include "accel.h" +#if MICROPY_HW_HAS_MMA7660 + #define MMA_ADDR (0x98) #define MMA_REG_X (0) #define MMA_REG_Y (1) @@ -174,3 +176,5 @@ const mp_obj_type_t pyb_accel_type = { .make_new = pyb_accel_make_new, .locals_dict = (mp_obj_t)&pyb_accel_locals_dict, }; + +#endif // MICROPY_HW_HAS_MMA7660 diff --git a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h index a626f4534b..b70b56d9ce 100644 --- a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h +++ b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h @@ -17,8 +17,9 @@ #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (0) -#define MICROPU_HW_ENABLE_I2C1 (0) -#define MICROPU_HW_ENABLE_SPI1 (0) +#define MICROPY_HW_ENABLE_I2C1 (0) +#define MICROPY_HW_ENABLE_SPI1 (0) +#define MICROPY_HW_ENABLE_SPI3 (0) // USRSW is pulled low. Pressing the button makes the input go high. #define MICROPY_HW_USRSW_PIN (pin_B11) diff --git a/stmhal/boards/PYBV10/mpconfigboard.h b/stmhal/boards/PYBV10/mpconfigboard.h index 9386c04a2d..00c6a1acfc 100644 --- a/stmhal/boards/PYBV10/mpconfigboard.h +++ b/stmhal/boards/PYBV10/mpconfigboard.h @@ -13,6 +13,9 @@ #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_I2C1 (1) +#define MICROPY_HW_ENABLE_SPI1 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) // USRSW has no pullup or pulldown, and pressing the switch makes the input go low #define MICROPY_HW_USRSW_PIN (pin_B3) diff --git a/stmhal/boards/PYBV3/mpconfigboard.h b/stmhal/boards/PYBV3/mpconfigboard.h index f47a01bc4c..02ad78a64c 100644 --- a/stmhal/boards/PYBV3/mpconfigboard.h +++ b/stmhal/boards/PYBV3/mpconfigboard.h @@ -13,6 +13,9 @@ #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (0) +#define MICROPY_HW_ENABLE_I2C1 (1) +#define MICROPY_HW_ENABLE_SPI1 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) // USRSW has no pullup or pulldown, and pressing the switch makes the input go low #define MICROPY_HW_USRSW_PIN (pin_A13) diff --git a/stmhal/boards/PYBV4/mpconfigboard.h b/stmhal/boards/PYBV4/mpconfigboard.h index 1846491c3a..550f1633f9 100644 --- a/stmhal/boards/PYBV4/mpconfigboard.h +++ b/stmhal/boards/PYBV4/mpconfigboard.h @@ -13,6 +13,9 @@ #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_I2C1 (1) +#define MICROPY_HW_ENABLE_SPI1 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) // USRSW has no pullup or pulldown, and pressing the switch makes the input go low #define MICROPY_HW_USRSW_PIN (pin_B3) @@ -20,7 +23,7 @@ #define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) -// LEDs +// The pyboard has 4 LEDs #define MICROPY_HW_LED1 (pin_A13) // red #define MICROPY_HW_LED2 (pin_A14) // green #define MICROPY_HW_LED3 (pin_A15) // yellow diff --git a/stmhal/boards/STM32F4DISC/mpconfigboard.h b/stmhal/boards/STM32F4DISC/mpconfigboard.h index 3bfdfbfb80..c83bb162bb 100644 --- a/stmhal/boards/STM32F4DISC/mpconfigboard.h +++ b/stmhal/boards/STM32F4DISC/mpconfigboard.h @@ -13,6 +13,9 @@ #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_ENABLE_SERVO (0) #define MICROPY_HW_ENABLE_DAC (0) +#define MICROPY_HW_ENABLE_I2C1 (1) +#define MICROPY_HW_ENABLE_SPI1 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) // USRSW is pulled low. Pressing the button makes the input go high. #define MICROPY_HW_USRSW_PIN (pin_A0) diff --git a/stmhal/i2c.c b/stmhal/i2c.c index 4d2710d8e5..e1dd83d2f8 100644 --- a/stmhal/i2c.c +++ b/stmhal/i2c.c @@ -13,17 +13,17 @@ #include "genhdr/pins.h" #include "i2c.h" -#if !defined(MICROPU_HW_ENABLE_I2C1) -#define MICROPY_HW_ENABLE_I2C1 (1) -#endif - +#if MICROPY_HW_ENABLE_I2C1 I2C_HandleTypeDef I2CHandle1 = {.Instance = NULL}; +#endif I2C_HandleTypeDef I2CHandle2 = {.Instance = NULL}; void i2c_init0(void) { // reset the I2C1 handles +#if MICROPY_HW_ENABLE_I2C1 memset(&I2CHandle1, 0, sizeof(I2C_HandleTypeDef)); I2CHandle1.Instance = I2C1; +#endif memset(&I2CHandle2, 0, sizeof(I2C_HandleTypeDef)); I2CHandle2.Instance = I2C2; } @@ -36,23 +36,26 @@ void i2c_init(I2C_HandleTypeDef *i2c) { GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines const pin_obj_t *pins[2]; + if (0) { #if MICROPY_HW_ENABLE_I2C1 - if (i2c == &I2CHandle1) { + } else if (i2c == &I2CHandle1) { // X-skin: X9=PB6=SCL, X10=PB7=SDA pins[0] = &pin_B6; pins[1] = &pin_B7; GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; // enable the I2C clock __I2C1_CLK_ENABLE(); - } else #endif - if (i2c == &I2CHandle2) { + } else if (i2c == &I2CHandle2) { // Y-skin: Y9=PB10=SCL, Y10=PB11=SDA pins[0] = &pin_B10; pins[1] = &pin_B11; GPIO_InitStructure.Alternate = GPIO_AF4_I2C2; // enable the I2C clock __I2C2_CLK_ENABLE(); + } else { + // I2C does not exist for this board (shouldn't get here, should be checked by caller) + return; } // init the GPIO lines @@ -73,6 +76,8 @@ void i2c_init(I2C_HandleTypeDef *i2c) { if (HAL_I2C_Init(i2c) != HAL_OK) { // init error + // TODO should raise an exception, but this function is not necessarily going to be + // called via Python, so may not be properly wrapped in an NLR handler printf("HardwareError: HAL_I2C_Init failed\n"); return; } @@ -81,17 +86,20 @@ void i2c_init(I2C_HandleTypeDef *i2c) { /******************************************************************************/ /* Micro Python bindings */ -#define PYB_NUM_I2C (2) - typedef struct _pyb_i2c_obj_t { mp_obj_base_t base; I2C_HandleTypeDef *i2c; } pyb_i2c_obj_t; -STATIC const pyb_i2c_obj_t pyb_i2c_obj[PYB_NUM_I2C] = { +STATIC const pyb_i2c_obj_t pyb_i2c_obj[] = { +#if MICROPY_HW_ENABLE_I2C1 {{&pyb_i2c_type}, &I2CHandle1}, +#else + {{&pyb_i2c_type}, NULL}, +#endif {{&pyb_i2c_type}, &I2CHandle2} }; +#define PYB_NUM_I2C (sizeof(pyb_i2c_obj) / sizeof(pyb_i2c_obj[0])) STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments @@ -101,7 +109,7 @@ STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const machine_int_t i2c_id = mp_obj_get_int(args[0]) - 1; // check i2c number - if (!(0 <= i2c_id && i2c_id < PYB_NUM_I2C)) { + if (!(0 <= i2c_id && i2c_id < PYB_NUM_I2C && pyb_i2c_obj[i2c_id].i2c != NULL)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "I2C bus %d does not exist", i2c_id + 1)); } diff --git a/stmhal/spi.c b/stmhal/spi.c index 5e5049bef9..b16cd83c8b 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -13,22 +13,26 @@ #include "genhdr/pins.h" #include "spi.h" -#if !defined(MICROPU_HW_ENABLE_SPI1) -#define MICROPY_HW_ENABLE_SPI1 (1) -#endif - +#if MICROPY_HW_ENABLE_SPI1 SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL}; +#endif SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL}; +#if MICROPY_HW_ENABLE_SPI3 SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL}; +#endif void spi_init0(void) { // reset the SPI handles +#if MICROPY_HW_ENABLE_SPI1 memset(&SPIHandle1, 0, sizeof(SPI_HandleTypeDef)); SPIHandle1.Instance = SPI1; +#endif memset(&SPIHandle2, 0, sizeof(SPI_HandleTypeDef)); SPIHandle2.Instance = SPI2; +#if MICROPY_HW_ENABLE_SPI3 memset(&SPIHandle3, 0, sizeof(SPI_HandleTypeDef)); SPIHandle3.Instance = SPI3; +#endif } // TODO allow to take a list of pins to use @@ -40,36 +44,40 @@ void spi_init(SPI_HandleTypeDef *spi) { GPIO_InitStructure.Pull = GPIO_PULLUP; // ST examples use PULLUP const pin_obj_t *pins[4]; + if (0) { #if MICROPY_HW_ENABLE_SPI1 - if (spi->Instance == SPI1) { + } else if (spi->Instance == SPI1) { // X-skin: X5=PA4=SPI1_NSS, X6=PA5=SPI1_SCK, X7=PA6=SPI1_MISO, X8=PA7=SPI1_MOSI pins[0] = &pin_A4; pins[1] = &pin_A5; pins[2] = &pin_A6; pins[3] = &pin_A7; GPIO_InitStructure.Alternate = GPIO_AF5_SPI1; - } else + // enable the SPI clock + __SPI1_CLK_ENABLE(); #endif - if (spi->Instance == SPI2) { + } else if (spi->Instance == SPI2) { // Y-skin: Y5=PB12=SPI2_NSS, Y6=PB13=SPI2_SCK, Y7=PB14=SPI2_MISO, Y8=PB15=SPI2_MOSI pins[0] = &pin_B12; pins[1] = &pin_B13; pins[2] = &pin_B14; pins[3] = &pin_B15; GPIO_InitStructure.Alternate = GPIO_AF5_SPI2; - } else + // enable the SPI clock + __SPI2_CLK_ENABLE(); #if MICROPY_HW_ENABLE_SPI3 - if (spi->Instance == SPI3) { + } else if (spi->Instance == SPI3) { pins[0] = &pin_A4; pins[1] = &pin_B3; pins[2] = &pin_B4; pins[3] = &pin_B5; GPIO_InitStructure.Alternate = GPIO_AF6_SPI3; - } else + // enable the SPI clock + __SPI3_CLK_ENABLE(); #endif - { - // SPI does not exist for this board - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "SPI bus does not exist")); + } else { + // SPI does not exist for this board (shouldn't get here, should be checked by caller) + return; } for (uint i = 0; i < 4; i++) { @@ -77,16 +85,7 @@ void spi_init(SPI_HandleTypeDef *spi) { HAL_GPIO_Init(pins[i]->gpio, &GPIO_InitStructure); } - // enable the SPI clock - if (spi->Instance == SPI1) { - __SPI1_CLK_ENABLE(); - } else if (spi->Instance == SPI2) { - __SPI2_CLK_ENABLE(); - } else if (spi->Instance == SPI3) { - __SPI3_CLK_ENABLE(); - } - - // init the I2C device + // init the SPI device if (HAL_SPI_Init(spi) != HAL_OK) { // init error // TODO should raise an exception, but this function is not necessarily going to be @@ -98,29 +97,42 @@ void spi_init(SPI_HandleTypeDef *spi) { void spi_deinit(SPI_HandleTypeDef *spi) { HAL_SPI_DeInit(spi); - if (spi->Instance == SPI1) { + if (0) { +#if MICROPY_HW_ENABLE_SPI1 + } else if (spi->Instance == SPI1) { __SPI1_CLK_DISABLE(); +#endif } else if (spi->Instance == SPI2) { __SPI2_CLK_DISABLE(); +#if MICROPY_HW_ENABLE_SPI3 } else if (spi->Instance == SPI3) { __SPI3_CLK_DISABLE(); +#endif } } /******************************************************************************/ /* Micro Python bindings */ -#define PYB_NUM_SPI (2) - typedef struct _pyb_spi_obj_t { mp_obj_base_t base; SPI_HandleTypeDef *spi; } pyb_spi_obj_t; -STATIC const pyb_spi_obj_t pyb_spi_obj[PYB_NUM_SPI] = { +STATIC const pyb_spi_obj_t pyb_spi_obj[] = { +#if MICROPY_HW_ENABLE_SPI1 {{&pyb_spi_type}, &SPIHandle1}, - {{&pyb_spi_type}, &SPIHandle2} +#else + {{&pyb_spi_type}, NULL}, +#endif + {{&pyb_spi_type}, &SPIHandle2}, +#if MICROPY_HW_ENABLE_SPI3 + {{&pyb_spi_type}, &SPIHandle3}, +#else + {{&pyb_spi_type}, NULL}, +#endif }; +#define PYB_NUM_SPI (sizeof(pyb_spi_obj) / sizeof(pyb_spi_obj[0])) STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pyb_spi_obj_t *self = self_in; @@ -223,7 +235,7 @@ STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const machine_int_t spi_id = mp_obj_get_int(args[0]) - 1; // check SPI number - if (!(0 <= spi_id && spi_id < PYB_NUM_SPI)) { + if (!(0 <= spi_id && spi_id < PYB_NUM_SPI && pyb_spi_obj[spi_id].spi != NULL)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "SPI bus %d does not exist", spi_id + 1)); }