summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal/spi.c')
-rw-r--r--stmhal/spi.c125
1 files changed, 113 insertions, 12 deletions
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;
}