From c5d8ffef581fe83ccec276d0bfa8fcc15e9f9524 Mon Sep 17 00:00:00 2001 From: Tobias Badertscher Date: Tue, 8 Dec 2015 15:41:47 +0100 Subject: [PATCH] stmhal: Extend SPI support to fully support all SPI devices on STM32F429. This includes SPI4, SPI5 and SPI6. --- stmhal/boards/STM32F429DISC/mpconfigboard.h | 28 +++++ stmhal/dma.h | 18 +++ stmhal/spi.c | 125 ++++++++++++++++++-- stmhal/spi.h | 3 + 4 files changed, 162 insertions(+), 12 deletions(-) diff --git a/stmhal/boards/STM32F429DISC/mpconfigboard.h b/stmhal/boards/STM32F429DISC/mpconfigboard.h index dc4059d030..33dd507d51 100644 --- a/stmhal/boards/STM32F429DISC/mpconfigboard.h +++ b/stmhal/boards/STM32F429DISC/mpconfigboard.h @@ -1,3 +1,5 @@ +#include STM32_HAL_H + #define MICROPY_HW_BOARD_NAME "F429I-DISCO" #define MICROPY_HW_MCU_NAME "STM32F429" @@ -29,6 +31,32 @@ #define MICROPY_HW_I2C1_SCL (pin_A8) #define MICROPY_HW_I2C1_SDA (pin_C9) +// SPI busses +//#define MICROPY_HW_SPI1_NSS (pin_A4) +//#define MICROPY_HW_SPI1_SCK (pin_A5) +//#define MICROPY_HW_SPI1_MISO (pin_A6) +//#define MICROPY_HW_SPI1_MOSI (pin_A7) +#if defined(USE_USB_HS_IN_FS) +// The HS USB uses B14 & B15 for D- and D+ +#else +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) +#endif +//#define MICROPY_HW_SPI4_NSS (pin_E11) +//#define MICROPY_HW_SPI4_SCK (pin_E12) +//#define MICROPY_HW_SPI4_MISO (pin_E13) +//#define MICROPY_HW_SPI4_MOSI (pin_E14) +#define MICROPY_HW_SPI5_NSS (pin_F6) +#define MICROPY_HW_SPI5_SCK (pin_F7) +#define MICROPY_HW_SPI5_MISO (pin_F8) +#define MICROPY_HW_SPI5_MOSI (pin_F9) +//#define MICROPY_HW_SPI6_NSS (pin_G8) +//#define MICROPY_HW_SPI6_SCK (pin_G13) +//#define MICROPY_HW_SPI6_MISO (pin_G12) +//#define MICROPY_HW_SPI6_MOSI (pin_G14) + // USRSW is pulled low. Pressing the button makes the input go high. #define MICROPY_HW_USRSW_PIN (pin_A0) #define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) diff --git a/stmhal/dma.h b/stmhal/dma.h index 0e751757fd..9561d1b529 100644 --- a/stmhal/dma.h +++ b/stmhal/dma.h @@ -74,12 +74,30 @@ #define DMA_STREAM_SPI1_RX DMA2_Stream2 #define DMA_CHANNEL_SPI1_RX DMA_CHANNEL_3 +#define DMA_STREAM_SPI5_RX DMA2_Stream3 +#define DMA_CHANNEL_SPI5_RX DMA_CHANNEL_2 + #define DMA_STREAM_SDIO_RX DMA2_Stream3 #define DMA_CHANNEL_SDIO_RX DMA_CHANNEL_4 +#define DMA_STREAM_SPI4_RX DMA2_Stream3 +#define DMA_CHANNEL_SPI4_RX DMA_CHANNEL_5 + +#define DMA_STREAM_SPI5_TX DMA2_Stream4 +#define DMA_CHANNEL_SPI5_TX DMA_CHANNEL_2 + +#define DMA_STREAM_SPI4_TX DMA2_Stream4 +#define DMA_CHANNEL_SPI4_TX DMA_CHANNEL_5 + +#define DMA_STREAM_SPI6_TX DMA2_Stream5 +#define DMA_CHANNEL_SPI6_TX DMA_CHANNEL_1 + #define DMA_STREAM_SPI1_TX DMA2_Stream5 #define DMA_CHANNEL_SPI1_TX DMA_CHANNEL_3 +#define DMA_STREAM_SPI6_RX DMA2_Stream6 +#define DMA_CHANNEL_SPI6_RX DMA_CHANNEL_1 + #define DMA_STREAM_SDIO_TX DMA2_Stream6 #define DMA_CHANNEL_SDIO_TX DMA_CHANNEL_4 diff --git a/stmhal/spi.c b/stmhal/spi.c index f2036aadd7..d9bc7ec42f 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -68,6 +68,12 @@ // SPI2_RX: DMA1_Stream3.CHANNEL_0 // SPI3_TX: DMA1_Stream5.CHANNEL_0 or DMA1_Stream7.CHANNEL_0 // SPI3_RX: DMA1_Stream0.CHANNEL_0 or DMA1_Stream2.CHANNEL_0 +// SPI4_TX: DMA2_Stream4.CHANNEL_5 or DMA2_Stream1.CHANNEL_4 +// SPI4_RX: DMA2_Stream3.CHANNEL_5 or DMA2_Stream0.CHANNEL_4 +// SPI5_TX: DMA2_Stream4.CHANNEL_2 or DMA2_Stream6.CHANNEL_7 +// SPI5_RX: DMA2_Stream3.CHANNEL_2 or DMA2_Stream5.CHANNEL_7 +// SPI6_TX: DMA2_Stream5.CHANNEL_1 +// SPI6_RX: DMA2_Stream6.CHANNEL_1 typedef struct _pyb_spi_obj_t { mp_obj_base_t base; @@ -87,6 +93,15 @@ SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL}; #if defined(MICROPY_HW_SPI3_SCK) SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL}; #endif +#if defined(MICROPY_HW_SPI4_SCK) +SPI_HandleTypeDef SPIHandle4 = {.Instance = NULL}; +#endif +#if defined(MICROPY_HW_SPI5_SCK) +SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL}; +#endif +#if defined(MICROPY_HW_SPI6_SCK) +SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL}; +#endif STATIC const pyb_spi_obj_t pyb_spi_obj[] = { #if defined(MICROPY_HW_SPI1_SCK) @@ -104,6 +119,21 @@ STATIC const pyb_spi_obj_t pyb_spi_obj[] = { #else {{&pyb_spi_type}, NULL, NULL, 0, NULL, 0}, #endif + #if defined(MICROPY_HW_SPI4_SCK) + {{&pyb_spi_type}, &SPIHandle4, DMA_STREAM_SPI4_TX, DMA_CHANNEL_SPI4_TX, DMA_STREAM_SPI4_RX, DMA_CHANNEL_SPI4_RX}, + #else + {{&pyb_spi_type}, NULL, NULL, 0, NULL, 0}, + #endif + #if defined(MICROPY_HW_SPI5_SCK) + {{&pyb_spi_type}, &SPIHandle5, DMA_STREAM_SPI5_TX, DMA_CHANNEL_SPI5_TX, DMA_STREAM_SPI5_RX, DMA_CHANNEL_SPI5_RX}, + #else + {{&pyb_spi_type}, NULL, NULL, 0, NULL, 0}, + #endif + #if defined(MICROPY_HW_SPI6_SCK) + {{&pyb_spi_type}, &SPIHandle6, DMA_STREAM_SPI6_TX, DMA_CHANNEL_SPI6_TX, DMA_STREAM_SPI6_RX, DMA_CHANNEL_SPI6_RX}, + #else + {{&pyb_spi_type}, NULL, NULL, 0, NULL, 0}, + #endif }; void spi_init0(void) { @@ -120,6 +150,18 @@ void spi_init0(void) { memset(&SPIHandle3, 0, sizeof(SPI_HandleTypeDef)); SPIHandle3.Instance = SPI3; #endif + #if defined(MICROPY_HW_SPI4_SCK) + memset(&SPIHandle4, 0, sizeof(SPI_HandleTypeDef)); + SPIHandle4.Instance = SPI4; + #endif + #if defined(MICROPY_HW_SPI5_SCK) + memset(&SPIHandle5, 0, sizeof(SPI_HandleTypeDef)); + SPIHandle5.Instance = SPI5; + #endif + #if defined(MICROPY_HW_SPI6_SCK) + memset(&SPIHandle6, 0, sizeof(SPI_HandleTypeDef)); + SPIHandle6.Instance = SPI6; + #endif } // TODO allow to take a list of pins to use @@ -167,6 +209,39 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) { // enable the SPI clock __SPI3_CLK_ENABLE(); #endif + #if defined(MICROPY_HW_SPI4_SCK) + } else if (spi->Instance == SPI4) { + self = &pyb_spi_obj[3]; + pins[0] = &MICROPY_HW_SPI4_NSS; + pins[1] = &MICROPY_HW_SPI4_SCK; + pins[2] = &MICROPY_HW_SPI4_MISO; + pins[3] = &MICROPY_HW_SPI4_MOSI; + GPIO_InitStructure.Alternate = GPIO_AF5_SPI4; + // enable the SPI clock + __SPI4_CLK_ENABLE(); + #endif + #if defined(MICROPY_HW_SPI5_SCK) + } else if (spi->Instance == SPI5) { + self = &pyb_spi_obj[4]; + pins[0] = &MICROPY_HW_SPI5_NSS; + pins[1] = &MICROPY_HW_SPI5_SCK; + pins[2] = &MICROPY_HW_SPI5_MISO; + pins[3] = &MICROPY_HW_SPI5_MOSI; + GPIO_InitStructure.Alternate = GPIO_AF5_SPI5; + // enable the SPI clock + __SPI5_CLK_ENABLE(); + #endif + #if defined(MICROPY_HW_SPI6_SCK) + } else if (spi->Instance == SPI6) { + self = &pyb_spi_obj[5]; + pins[0] = &MICROPY_HW_SPI6_NSS; + pins[1] = &MICROPY_HW_SPI6_SCK; + pins[2] = &MICROPY_HW_SPI6_MISO; + pins[3] = &MICROPY_HW_SPI6_MOSI; + GPIO_InitStructure.Alternate = GPIO_AF5_SPI6; + // enable the SPI clock + __SPI6_CLK_ENABLE(); + #endif } else { // SPI does not exist for this board (shouldn't get here, should be checked by caller) return; @@ -215,6 +290,24 @@ void spi_deinit(SPI_HandleTypeDef *spi) { __SPI3_RELEASE_RESET(); __SPI3_CLK_DISABLE(); #endif + #if defined(MICROPY_HW_SPI4_SCK) + } else if (spi->Instance == SPI4) { + __SPI4_FORCE_RESET(); + __SPI4_RELEASE_RESET(); + __SPI4_CLK_DISABLE(); + #endif + #if defined(MICROPY_HW_SPI5_SCK) + } else if (spi->Instance == SPI5) { + __SPI5_FORCE_RESET(); + __SPI5_RELEASE_RESET(); + __SPI5_CLK_DISABLE(); + #endif + #if defined(MICROPY_HW_SPI6_SCK) + } else if (spi->Instance == SPI6) { + __SPI6_FORCE_RESET(); + __SPI6_RELEASE_RESET(); + __SPI6_CLK_DISABLE(); + #endif } } @@ -245,10 +338,18 @@ SPI_HandleTypeDef *spi_get_handle(mp_obj_t o) { STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_spi_obj_t *self = self_in; - uint spi_num; - if (self->spi->Instance == SPI1) { spi_num = 1; } - else if (self->spi->Instance == SPI2) { spi_num = 2; } - else { spi_num = 3; } + uint spi_num = 1; // default to SPI1 + if (self->spi->Instance == SPI2) { spi_num = 2; } + else if (self->spi->Instance == SPI3) { spi_num = 3; } + #if defined(SPI4) + else if (self->spi->Instance == SPI4) { spi_num = 4; } + #endif + #if defined(SPI5) + else if (self->spi->Instance == SPI5) { spi_num = 5; } + #endif + #if defined(SPI6) + else if (self->spi->Instance == SPI6) { spi_num = 6; } + #endif if (self->spi->State == HAL_SPI_STATE_RESET) { mp_printf(print, "SPI(%u)", spi_num); @@ -256,12 +357,12 @@ STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki if (self->spi->Init.Mode == SPI_MODE_MASTER) { // compute baudrate uint spi_clock; - if (self->spi->Instance == SPI1) { - // SPI1 is on APB2 - spi_clock = HAL_RCC_GetPCLK2Freq(); - } else { + if (self->spi->Instance == SPI2 || self->spi->Instance == SPI3) { // SPI2 and SPI3 are on APB1 spi_clock = HAL_RCC_GetPCLK1Freq(); + } else { + // SPI1, SPI4, SPI5 and SPI6 are on APB2 + spi_clock = HAL_RCC_GetPCLK2Freq(); } uint log_prescaler = (self->spi->Init.BaudRatePrescaler >> 3) + 1; uint baudrate = spi_clock >> log_prescaler; @@ -311,12 +412,12 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, mp_uint_t n_args, if (br_prescale == 0xffffffff) { // prescaler not given, so select one that yields at most the requested baudrate mp_uint_t spi_clock; - if (self->spi->Instance == SPI1) { - // SPI1 is on APB2 - spi_clock = HAL_RCC_GetPCLK2Freq(); - } else { + if (self->spi->Instance == SPI2 || self->spi->Instance == SPI3) { // SPI2 and SPI3 are on APB1 spi_clock = HAL_RCC_GetPCLK1Freq(); + } else { + // SPI1, SPI4, SPI5 and SPI6 are on APB2 + spi_clock = HAL_RCC_GetPCLK2Freq(); } br_prescale = spi_clock / args[1].u_int; } diff --git a/stmhal/spi.h b/stmhal/spi.h index 9f81552525..bf9eabfcab 100644 --- a/stmhal/spi.h +++ b/stmhal/spi.h @@ -27,6 +27,9 @@ extern SPI_HandleTypeDef SPIHandle1; extern SPI_HandleTypeDef SPIHandle2; extern SPI_HandleTypeDef SPIHandle3; +extern SPI_HandleTypeDef SPIHandle4; +extern SPI_HandleTypeDef SPIHandle5; +extern SPI_HandleTypeDef SPIHandle6; extern const mp_obj_type_t pyb_spi_type; void spi_init0(void);