Skip to content
Snippets Groups Projects
Commit c5d8ffef authored by Tobias Badertscher's avatar Tobias Badertscher Committed by Damien George
Browse files

stmhal: Extend SPI support to fully support all SPI devices on STM32F429.

This includes SPI4, SPI5 and SPI6.
parent 130fde81
No related branches found
No related tags found
No related merge requests found
#include STM32_HAL_H
#define MICROPY_HW_BOARD_NAME "F429I-DISCO" #define MICROPY_HW_BOARD_NAME "F429I-DISCO"
#define MICROPY_HW_MCU_NAME "STM32F429" #define MICROPY_HW_MCU_NAME "STM32F429"
...@@ -29,6 +31,32 @@ ...@@ -29,6 +31,32 @@
#define MICROPY_HW_I2C1_SCL (pin_A8) #define MICROPY_HW_I2C1_SCL (pin_A8)
#define MICROPY_HW_I2C1_SDA (pin_C9) #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. // USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN (pin_A0) #define MICROPY_HW_USRSW_PIN (pin_A0)
#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) #define MICROPY_HW_USRSW_PULL (GPIO_NOPULL)
......
...@@ -74,12 +74,30 @@ ...@@ -74,12 +74,30 @@
#define DMA_STREAM_SPI1_RX DMA2_Stream2 #define DMA_STREAM_SPI1_RX DMA2_Stream2
#define DMA_CHANNEL_SPI1_RX DMA_CHANNEL_3 #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_STREAM_SDIO_RX DMA2_Stream3
#define DMA_CHANNEL_SDIO_RX DMA_CHANNEL_4 #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_STREAM_SPI1_TX DMA2_Stream5
#define DMA_CHANNEL_SPI1_TX DMA_CHANNEL_3 #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_STREAM_SDIO_TX DMA2_Stream6
#define DMA_CHANNEL_SDIO_TX DMA_CHANNEL_4 #define DMA_CHANNEL_SDIO_TX DMA_CHANNEL_4
......
...@@ -68,6 +68,12 @@ ...@@ -68,6 +68,12 @@
// SPI2_RX: DMA1_Stream3.CHANNEL_0 // SPI2_RX: DMA1_Stream3.CHANNEL_0
// SPI3_TX: DMA1_Stream5.CHANNEL_0 or DMA1_Stream7.CHANNEL_0 // SPI3_TX: DMA1_Stream5.CHANNEL_0 or DMA1_Stream7.CHANNEL_0
// SPI3_RX: DMA1_Stream0.CHANNEL_0 or DMA1_Stream2.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 { typedef struct _pyb_spi_obj_t {
mp_obj_base_t base; mp_obj_base_t base;
...@@ -87,6 +93,15 @@ SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL}; ...@@ -87,6 +93,15 @@ SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL};
#if defined(MICROPY_HW_SPI3_SCK) #if defined(MICROPY_HW_SPI3_SCK)
SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL}; SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL};
#endif #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[] = { STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
#if defined(MICROPY_HW_SPI1_SCK) #if defined(MICROPY_HW_SPI1_SCK)
...@@ -104,6 +119,21 @@ STATIC const pyb_spi_obj_t pyb_spi_obj[] = { ...@@ -104,6 +119,21 @@ STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
#else #else
{{&pyb_spi_type}, NULL, NULL, 0, NULL, 0}, {{&pyb_spi_type}, NULL, NULL, 0, NULL, 0},
#endif #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) { void spi_init0(void) {
...@@ -120,6 +150,18 @@ void spi_init0(void) { ...@@ -120,6 +150,18 @@ void spi_init0(void) {
memset(&SPIHandle3, 0, sizeof(SPI_HandleTypeDef)); memset(&SPIHandle3, 0, sizeof(SPI_HandleTypeDef));
SPIHandle3.Instance = SPI3; SPIHandle3.Instance = SPI3;
#endif #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 // TODO allow to take a list of pins to use
...@@ -167,6 +209,39 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) { ...@@ -167,6 +209,39 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
// enable the SPI clock // enable the SPI clock
__SPI3_CLK_ENABLE(); __SPI3_CLK_ENABLE();
#endif #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 { } else {
// SPI does not exist for this board (shouldn't get here, should be checked by caller) // SPI does not exist for this board (shouldn't get here, should be checked by caller)
return; return;
...@@ -215,6 +290,24 @@ void spi_deinit(SPI_HandleTypeDef *spi) { ...@@ -215,6 +290,24 @@ void spi_deinit(SPI_HandleTypeDef *spi) {
__SPI3_RELEASE_RESET(); __SPI3_RELEASE_RESET();
__SPI3_CLK_DISABLE(); __SPI3_CLK_DISABLE();
#endif #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) { ...@@ -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) { 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; pyb_spi_obj_t *self = self_in;
uint spi_num; uint spi_num = 1; // default to SPI1
if (self->spi->Instance == SPI1) { spi_num = 1; } if (self->spi->Instance == SPI2) { spi_num = 2; }
else if (self->spi->Instance == SPI2) { spi_num = 2; } else if (self->spi->Instance == SPI3) { spi_num = 3; }
else { 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) { if (self->spi->State == HAL_SPI_STATE_RESET) {
mp_printf(print, "SPI(%u)", spi_num); 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 ...@@ -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) { if (self->spi->Init.Mode == SPI_MODE_MASTER) {
// compute baudrate // compute baudrate
uint spi_clock; uint spi_clock;
if (self->spi->Instance == SPI1) { if (self->spi->Instance == SPI2 || self->spi->Instance == SPI3) {
// SPI1 is on APB2
spi_clock = HAL_RCC_GetPCLK2Freq();
} else {
// SPI2 and SPI3 are on APB1 // SPI2 and SPI3 are on APB1
spi_clock = HAL_RCC_GetPCLK1Freq(); 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 log_prescaler = (self->spi->Init.BaudRatePrescaler >> 3) + 1;
uint baudrate = spi_clock >> log_prescaler; 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, ...@@ -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) { if (br_prescale == 0xffffffff) {
// prescaler not given, so select one that yields at most the requested baudrate // prescaler not given, so select one that yields at most the requested baudrate
mp_uint_t spi_clock; mp_uint_t spi_clock;
if (self->spi->Instance == SPI1) { if (self->spi->Instance == SPI2 || self->spi->Instance == SPI3) {
// SPI1 is on APB2
spi_clock = HAL_RCC_GetPCLK2Freq();
} else {
// SPI2 and SPI3 are on APB1 // SPI2 and SPI3 are on APB1
spi_clock = HAL_RCC_GetPCLK1Freq(); 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; br_prescale = spi_clock / args[1].u_int;
} }
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
extern SPI_HandleTypeDef SPIHandle1; extern SPI_HandleTypeDef SPIHandle1;
extern SPI_HandleTypeDef SPIHandle2; extern SPI_HandleTypeDef SPIHandle2;
extern SPI_HandleTypeDef SPIHandle3; 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; extern const mp_obj_type_t pyb_spi_type;
void spi_init0(void); void spi_init0(void);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment