aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/rt/RT-STM32F429-DISCOVERY/mcuconf.h25
-rw-r--r--os/hal/ports/STM32/SPIv1/spi_lld.c153
-rw-r--r--os/hal/ports/STM32/SPIv1/spi_lld.h180
-rw-r--r--os/hal/ports/STM32F0xx/stm32_registry.h3
-rw-r--r--os/hal/ports/STM32F1xx/stm32_registry.h24
-rw-r--r--os/hal/ports/STM32F30x/stm32_registry.h4
-rw-r--r--os/hal/ports/STM32F37x/stm32_registry.h4
-rw-r--r--os/hal/ports/STM32F4xx/stm32_rcc.h128
-rw-r--r--os/hal/ports/STM32F4xx/stm32_registry.h36
-rw-r--r--os/hal/ports/STM32L1xx/stm32_registry.h3
10 files changed, 553 insertions, 7 deletions
diff --git a/demos/rt/RT-STM32F429-DISCOVERY/mcuconf.h b/demos/rt/RT-STM32F429-DISCOVERY/mcuconf.h
index 289f0f95f..cacfa1ff3 100644
--- a/demos/rt/RT-STM32F429-DISCOVERY/mcuconf.h
+++ b/demos/rt/RT-STM32F429-DISCOVERY/mcuconf.h
@@ -151,9 +151,9 @@
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_I2C3_DMA_PRIORITY 3
-#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_I2C_I2C1_DMA_ERROR_HOOK() osalSysHalt("DMA failure")
+#define STM32_I2C_I2C2_DMA_ERROR_HOOK() osalSysHalt("DMA failure")
+#define STM32_I2C_I2C3_DMA_ERROR_HOOK() osalSysHalt("DMA failure")
/*
* ICU driver system settings.
@@ -225,19 +225,34 @@
#define STM32_SPI_USE_SPI1 FALSE
#define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_USE_SPI3 FALSE
+#define STM32_SPI_USE_SPI4 FALSE
+#define STM32_SPI_USE_SPI5 FALSE
+#define STM32_SPI_USE_SPI6 FALSE
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
+#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6)
+#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
#define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_DMA_PRIORITY 1
#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#define STM32_SPI_SPI4_DMA_PRIORITY 1
+#define STM32_SPI_SPI5_DMA_PRIORITY 1
+#define STM32_SPI_SPI6_DMA_PRIORITY 1
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
+#define STM32_SPI_SPI4_IRQ_PRIORITY 10
+#define STM32_SPI_SPI5_IRQ_PRIORITY 10
+#define STM32_SPI_SPI6_IRQ_PRIORITY 10
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
/*
* UART driver system settings.
@@ -272,7 +287,7 @@
#define STM32_UART_UART4_DMA_PRIORITY 0
#define STM32_UART_UART5_DMA_PRIORITY 0
#define STM32_UART_USART6_DMA_PRIORITY 0
-#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
/*
* USB driver system settings.
diff --git a/os/hal/ports/STM32/SPIv1/spi_lld.c b/os/hal/ports/STM32/SPIv1/spi_lld.c
index 2c8231086..048ad5743 100644
--- a/os/hal/ports/STM32/SPIv1/spi_lld.c
+++ b/os/hal/ports/STM32/SPIv1/spi_lld.c
@@ -54,6 +54,30 @@
STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \
STM32_SPI3_TX_DMA_CHN)
+#define SPI4_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \
+ STM32_SPI4_RX_DMA_CHN)
+
+#define SPI4_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \
+ STM32_SPI4_TX_DMA_CHN)
+
+#define SPI5_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \
+ STM32_SPI5_RX_DMA_CHN)
+
+#define SPI5_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \
+ STM32_SPI5_TX_DMA_CHN)
+
+#define SPI6_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \
+ STM32_SPI6_RX_DMA_CHN)
+
+#define SPI6_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \
+ STM32_SPI6_TX_DMA_CHN)
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -73,6 +97,21 @@ SPIDriver SPID2;
SPIDriver SPID3;
#endif
+/** @brief SPI4 driver identifier.*/
+#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
+SPIDriver SPID4;
+#endif
+
+/** @brief SPI5 driver identifier.*/
+#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
+SPIDriver SPID5;
+#endif
+
+/** @brief SPI6 driver identifier.*/
+#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
+SPIDriver SPID6;
+#endif
+
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
@@ -200,6 +239,60 @@ void spi_lld_init(void) {
STM32_DMA_CR_DMEIE |
STM32_DMA_CR_TEIE;
#endif
+
+#if STM32_SPI_USE_SPI4
+ spiObjectInit(&SPID4);
+ SPID4.spi = SPI4;
+ SPID4.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM);
+ SPID4.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM);
+ SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI5
+ spiObjectInit(&SPID5);
+ SPID5.spi = SPI5;
+ SPID5.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM);
+ SPID5.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM);
+ SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI6
+ spiObjectInit(&SPID6);
+ SPID6.spi = SPI6;
+ SPID6.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI6_RX_DMA_STREAM);
+ SPID6.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI6_TX_DMA_STREAM);
+ SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
}
/**
@@ -261,6 +354,54 @@ void spi_lld_start(SPIDriver *spip) {
rccEnableSPI3(FALSE);
}
#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip) {
+ bool b;
+ b = dmaStreamAllocate(spip->dmarx,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ b = dmaStreamAllocate(spip->dmatx,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ rccEnableSPI4(FALSE);
+ }
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip) {
+ bool b;
+ b = dmaStreamAllocate(spip->dmarx,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ b = dmaStreamAllocate(spip->dmatx,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ rccEnableSPI5(FALSE);
+ }
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip) {
+ bool b;
+ b = dmaStreamAllocate(spip->dmarx,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ b = dmaStreamAllocate(spip->dmatx,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "stream already allocated");
+ rccEnableSPI6(FALSE);
+ }
+#endif
/* DMA setup.*/
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
@@ -320,6 +461,18 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID3 == spip)
rccDisableSPI3(FALSE);
#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip)
+ rccDisableSPI4(FALSE);
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip)
+ rccDisableSPI5(FALSE);
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip)
+ rccDisableSPI6(FALSE);
+#endif
}
}
diff --git a/os/hal/ports/STM32/SPIv1/spi_lld.h b/os/hal/ports/STM32/SPIv1/spi_lld.h
index 53a7607ff..fe31daeff 100644
--- a/os/hal/ports/STM32/SPIv1/spi_lld.h
+++ b/os/hal/ports/STM32/SPIv1/spi_lld.h
@@ -67,6 +67,33 @@
#endif
/**
+ * @brief SPI4 driver enable switch.
+ * @details If set to @p TRUE the support for SPI4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI4 FALSE
+#endif
+
+/**
+ * @brief SPI5 driver enable switch.
+ * @details If set to @p TRUE the support for SPI5 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI5 FALSE
+#endif
+
+/**
+ * @brief SPI6 driver enable switch.
+ * @details If set to @p TRUE the support for SPI6 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI6 FALSE
+#endif
+
+/**
* @brief SPI1 interrupt priority level setting.
*/
#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
@@ -88,6 +115,27 @@
#endif
/**
+ * @brief SPI4 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI5 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI6 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_IRQ_PRIORITY 10
+#endif
+
+/**
* @brief SPI1 DMA priority (0..3|lowest..highest).
* @note The priority level is used for both the TX and RX DMA streams but
* because of the streams ordering the RX stream has always priority
@@ -118,6 +166,36 @@
#endif
/**
+ * @brief SPI4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_DMA_PRIORITY 1
+#endif
+
+/**
* @brief SPI DMA error hook.
*/
#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
@@ -141,7 +219,20 @@
#error "SPI3 not present in the selected device"
#endif
-#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3
+#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
+#error "SPI4 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
+#error "SPI5 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
+#error "SPI6 not present in the selected device"
+#endif
+
+#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
+ !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
#error "SPI driver activated but no SPI peripheral assigned"
#endif
@@ -160,6 +251,21 @@
#error "Invalid IRQ priority assigned to SPI3"
#endif
+#if STM32_SPI_USE_SPI4 && \
+ !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI6"
+#endif
+
#if STM32_SPI_USE_SPI1 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
#error "Invalid DMA priority assigned to SPI1"
@@ -175,6 +281,21 @@
#error "Invalid DMA priority assigned to SPI3"
#endif
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI6"
+#endif
+
/* The following checks are only required when there is a DMA able to
reassign streams to different channels.*/
#if STM32_ADVANCED_DMA
@@ -194,6 +315,21 @@
#error "SPI3 DMA streams not defined"
#endif
+#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
+#error "SPI4 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
+#error "SPI5 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI6_TX_DMA_STREAM))
+#error "SPI6 DMA streams not defined"
+#endif
+
/* Check on the validity of the assigned DMA channels.*/
#if STM32_SPI_USE_SPI1 && \
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
@@ -224,6 +360,36 @@
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
#error "invalid DMA stream associated to SPI3 TX"
#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 RX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 TX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 RX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 TX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 RX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 TX"
+#endif
#endif /* STM32_ADVANCED_DMA */
#if !defined(STM32_DMA_REQUIRED)
@@ -340,6 +506,18 @@ extern SPIDriver SPID2;
extern SPIDriver SPID3;
#endif
+#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
+extern SPIDriver SPID4;
+#endif
+
+#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
+extern SPIDriver SPID5;
+#endif
+
+#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
+extern SPIDriver SPID6;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/os/hal/ports/STM32F0xx/stm32_registry.h b/os/hal/ports/STM32F0xx/stm32_registry.h
index 0b12f7bb0..599e7acfe 100644
--- a/os/hal/ports/STM32F0xx/stm32_registry.h
+++ b/os/hal/ports/STM32F0xx/stm32_registry.h
@@ -97,6 +97,9 @@
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_HAS_TIM1 TRUE
diff --git a/os/hal/ports/STM32F1xx/stm32_registry.h b/os/hal/ports/STM32F1xx/stm32_registry.h
index d03894d40..46ce6e297 100644
--- a/os/hal/ports/STM32F1xx/stm32_registry.h
+++ b/os/hal/ports/STM32F1xx/stm32_registry.h
@@ -98,6 +98,9 @@
#define STM32_HAS_SPI2 FALSE
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -242,6 +245,9 @@
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -386,6 +392,9 @@
#define STM32_HAS_SPI2 FALSE
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -515,6 +524,9 @@
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -653,6 +665,10 @@
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -823,6 +839,10 @@
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
@@ -993,6 +1013,10 @@
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
diff --git a/os/hal/ports/STM32F30x/stm32_registry.h b/os/hal/ports/STM32F30x/stm32_registry.h
index 75c72d396..5ab6aa3f2 100644
--- a/os/hal/ports/STM32F30x/stm32_registry.h
+++ b/os/hal/ports/STM32F30x/stm32_registry.h
@@ -106,6 +106,10 @@
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 6
diff --git a/os/hal/ports/STM32F37x/stm32_registry.h b/os/hal/ports/STM32F37x/stm32_registry.h
index 3a7cdfaf2..61bde9281 100644
--- a/os/hal/ports/STM32F37x/stm32_registry.h
+++ b/os/hal/ports/STM32F37x/stm32_registry.h
@@ -106,6 +106,10 @@
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 4
diff --git a/os/hal/ports/STM32F4xx/stm32_rcc.h b/os/hal/ports/STM32F4xx/stm32_rcc.h
index 25a9bb037..9178f67da 100644
--- a/os/hal/ports/STM32F4xx/stm32_rcc.h
+++ b/os/hal/ports/STM32F4xx/stm32_rcc.h
@@ -387,6 +387,29 @@
/** @} */
/**
+ * @name BKPSRAM specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the BKPSRAM peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableBKPSRAM(lp) rccEnableAHB1(RCC_AHB1ENR_BKPSRAMEN, lp)
+
+/**
+ * @brief Disables the BKPSRAM peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableBKPSRAM(lp) rccDisableAHB1(RCC_AHB1ENR_BKPSRAMEN, lp)
+/** @} */
+
+/**
* @name PWR interface specific RCC operations
* @{
*/
@@ -754,6 +777,81 @@
* @api
*/
#define rccResetSPI3() rccResetAPB1(RCC_APB1RSTR_SPI3RST)
+
+/**
+ * @brief Enables the SPI4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI4(lp) rccEnableAPB2(RCC_APB2ENR_SPI4EN, lp)
+
+/**
+ * @brief Disables the SPI4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableSPI4(lp) rccDisableAPB2(RCC_APB2ENR_SPI4EN, lp)
+
+/**
+ * @brief Resets the SPI4 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI4() rccResetAPB2(RCC_APB2RSTR_SPI4RST)
+
+/**
+ * @brief Enables the SPI5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI5(lp) rccEnableAPB2(RCC_APB2ENR_SPI5EN, lp)
+
+/**
+ * @brief Disables the SPI5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableSPI5(lp) rccDisableAPB2(RCC_APB2ENR_SPI5EN, lp)
+
+/**
+ * @brief Resets the SPI5 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI5() rccResetAPB2(RCC_APB2RSTR_SPI5RST)
+
+/**
+ * @brief Enables the SPI6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI6(lp) rccEnableAPB2(RCC_APB2ENR_SPI6EN, lp)
+
+/**
+ * @brief Disables the SPI6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableSPI6(lp) rccDisableAPB2(RCC_APB2ENR_SPI6EN, lp)
+
+/**
+ * @brief Resets the SPI6 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI6() rccResetAPB2(RCC_APB2RSTR_SPI6RST)
/** @} */
/**
@@ -1238,6 +1336,36 @@
#define rccResetUSART6() rccResetAPB2(RCC_APB2RSTR_USART6RST)
/** @} */
+/**
+ * @name LTDC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the LTDC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLTDC(lp) rccEnableAPB2(RCC_APB2ENR_LTDCEN, lp)
+
+/**
+ * @brief Disables the LTDC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableLTDC(lp) rccDisableAPB2(RCC_APB2ENR_LTDCEN, lp)
+
+/**
+ * @brief Resets the LTDC peripheral.
+ *
+ * @api
+ */
+#define rccResetLTDC() rccResetAPB2(RCC_APB2RSTR_LTDCRST)
+/** @} */
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32F4xx/stm32_registry.h
index 5edcaad15..7c14455ca 100644
--- a/os/hal/ports/STM32F4xx/stm32_registry.h
+++ b/os/hal/ports/STM32F4xx/stm32_registry.h
@@ -81,10 +81,16 @@
#define STM32_HAS_GPIOC TRUE
#define STM32_HAS_GPIOD TRUE
#define STM32_HAS_GPIOE TRUE
+#define STM32_HAS_GPIOH TRUE
+#if !defined(STM32F401xx)
#define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
#define STM32_HAS_GPIOI TRUE
+#else
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOI FALSE
+#endif
/* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE
@@ -146,6 +152,34 @@
STM32_DMA_STREAM_ID_MSK(1, 7))
#define STM32_SPI3_TX_DMA_CHN 0x00000000
+#if defined(STM32F429_439xx)
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI4_RX_DMA_CHN 0x00005004
+#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI4_TX_DMA_CHN 0x00050040
+
+#define STM32_HAS_SPI5 TRUE
+#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) | \
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SPI5_RX_DMA_CHN 0x00702000
+#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) | \
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SPI5_TX_DMA_CHN 0x07020000
+
+#define STM32_HAS_SPI6 TRUE
+#define STM32_SPI6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SPI6_RX_DMA_CHN 0x01000000
+#define STM32_SPI6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SPI6_TX_DMA_CHN 0x00100000
+#else /* !defined(STM32F429_439xx) */
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+#endif /* !defined(STM32F429_439xx) */
+
/* TIM attributes.*/
#define STM32_HAS_TIM1 TRUE
#define STM32_TIM1_IS_32BITS FALSE
diff --git a/os/hal/ports/STM32L1xx/stm32_registry.h b/os/hal/ports/STM32L1xx/stm32_registry.h
index 23d5d3264..ab679e19f 100644
--- a/os/hal/ports/STM32L1xx/stm32_registry.h
+++ b/os/hal/ports/STM32L1xx/stm32_registry.h
@@ -99,6 +99,9 @@
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
#define STM32_TIM_MAX_CHANNELS 6