aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h1
-rw-r--r--os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c119
-rw-r--r--os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h90
3 files changed, 181 insertions, 29 deletions
diff --git a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
index d9ccea7cf..f71d438c9 100644
--- a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
@@ -426,7 +426,6 @@
#error "Invalid IRQ priority assigned to ADC1"
#endif
-/* ADC IRQ priority tests.*/
#if STM32_ADC_USE_ADC2 && \
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC2"
diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
index d5f74b735..b545634b6 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
+++ b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
@@ -63,16 +63,27 @@
(((STM32_SDMMCCLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
STM32_SDC_SDMMC_READ_TIMEOUT)
-#define DMA_CHANNEL \
+#define SDMMC1_DMA_CHANNEL \
STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC1_DMA_STREAM, \
STM32_SDC_SDMMC1_DMA_CHN)
+#define SDMMC2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC2_DMA_STREAM, \
+ STM32_SDC_SDMMC2_DMA_CHN)
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief SDCD1 driver identifier.*/
+#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
SDCDriver SDCD1;
+#endif
+
+/** @brief SDCD2 driver identifier.*/
+#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
+SDCDriver SDCD2;
+#endif
/*===========================================================================*/
/* Driver local variables and types. */
@@ -320,17 +331,14 @@ static void sdc_lld_error_cleanup(SDCDriver *sdcp,
/* Driver interrupt handlers. */
/*===========================================================================*/
-#if !defined(STM32_SDMMC1_HANDLER)
-#error "STM32_SDMMC1_HANDLER not defined"
-#endif
-
/**
- * @brief SDIO IRQ handler.
- * @details It just wakes transaction thread. All error handling performs in
- * that thread.
+ * @brief SDMMC1 IRQ handler.
+ * @details It just wakes transaction thread, errors handling is performed in
+ * there.
*
* @isr
*/
+#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) {
OSAL_IRQ_PROLOGUE();
@@ -347,6 +355,33 @@ OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
+#endif
+
+/**
+ * @brief SDMMC2 IRQ handler.
+ * @details It just wakes transaction thread, errors handling is performed in
+ * there.
+ *
+ * @isr
+ */
+#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
+OSAL_IRQ_HANDLER(STM32_SDMMC2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ osalSysLockFromISR();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions needs to check them.*/
+ SDMMC2->MASK = 0;
+
+ osalThreadResumeI(&SDCD2.thread, MSG_OK);
+
+ osalSysUnlockFromISR();
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
/*===========================================================================*/
/* Driver exported functions. */
@@ -359,10 +394,21 @@ OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) {
*/
void sdc_lld_init(void) {
+#if STM32_SDC_USE_SDMMC1
sdcObjectInit(&SDCD1);
SDCD1.thread = NULL;
SDCD1.dma = STM32_DMA_STREAM(STM32_SDC_SDMMC1_DMA_STREAM);
SDCD1.sdmmc = SDMMC1;
+ nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY);
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ sdcObjectInit(&SDCD2);
+ SDCD2.thread = NULL;
+ SDCD2.dma = STM32_DMA_STREAM(STM32_SDC_SDMMC2_DMA_STREAM);
+ SDCD2.sdmmc = SDMMC2;
+ nvicEnableVector(STM32_SDMMC2_NUMBER, STM32_SDC_SDMMC2_IRQ_PRIORITY);
+#endif
}
/**
@@ -379,7 +425,7 @@ void sdc_lld_start(SDCDriver *sdcp) {
sdcp->config = &sdc_default_cfg;
}
- sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) |
+ sdcp->dmamode = STM32_DMA_CR_CHSEL(SDMMC1_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_SDC_SDMMC1_DMA_PRIORITY) |
STM32_DMA_CR_PSIZE_WORD |
STM32_DMA_CR_MSIZE_WORD |
@@ -391,17 +437,39 @@ void sdc_lld_start(SDCDriver *sdcp) {
STM32_DMA_CR_MBURST_INCR4;
#endif
+ /* If in stopped state then clocks are enabled and DMA initialized.*/
if (sdcp->state == BLK_STOP) {
- /* Note, the DMA must be enabled before the IRQs.*/
- bool b;
- b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDMMC1_IRQ_PRIORITY, NULL, NULL);
- osalDbgAssert(!b, "stream already allocated");
- dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ bool b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDMMC1_IRQ_PRIORITY,
+ NULL, NULL);
+
+ osalDbgAssert(!b, "stream already allocated");
+
+ dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
#if STM32_DMA_ADVANCED
- dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL);
+ dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
+ STM32_DMA_FCR_FTH_FULL);
#endif
- nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY);
- rccEnableSDMMC1(FALSE);
+ rccEnableSDMMC1(FALSE);
+ }
+#endif /* STM32_SDC_USE_SDMMC1 */
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ bool b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDMMC2_IRQ_PRIORITY,
+ NULL, NULL);
+
+ osalDbgAssert(!b, "stream already allocated");
+
+ dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
+#if STM32_DMA_ADVANCED
+ dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
+ STM32_DMA_FCR_FTH_FULL);
+#endif
+ rccEnableSDMMC2(FALSE);
+ }
+#endif /* STM32_SDC_USE_SDMMC2 */
}
/* Configuration, card clock is initially stopped.*/
@@ -428,10 +496,21 @@ void sdc_lld_stop(SDCDriver *sdcp) {
sdcp->sdmmc->DCTRL = 0;
sdcp->sdmmc->DTIMER = 0;
- /* Clock deactivation.*/
- nvicDisableVector(STM32_SDMMC1_NUMBER);
+ /* DMA stream released.*/
dmaStreamRelease(sdcp->dma);
- rccDisableSDMMC1(FALSE);
+
+ /* Clock deactivation.*/
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ rccDisableSDMMC1(FALSE);
+ }
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ rccDisableSDMMC2(FALSE);
+ }
+#endif
}
}
diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
index 1b09d6862..4479a1c5b 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
+++ b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
@@ -40,7 +40,7 @@
* @{
*/
/**
- * @brief SDMMC driver enable switch.
+ * @brief SDMMC1 driver enable switch.
* @details If set to @p TRUE the support for SDMMC1 is included.
* @note The default is @p FALSE.
*/
@@ -49,6 +49,15 @@
#endif
/**
+ * @brief SDMMC2 driver enable switch.
+ * @details If set to @p TRUE the support for SDMMC2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SDC_USE_SDMMC2) || defined(__DOXYGEN__)
+#define STM32_SDC_USE_SDMMC2 FALSE
+#endif
+
+/**
* @brief Support for unaligned transfers.
* @note Unaligned transfers are much slower.
*/
@@ -85,25 +94,66 @@
#endif
/**
+ * @brief SDMMC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDMMC2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC2_DMA_PRIORITY 3
+#endif
+
+/**
* @brief SDMMC1 interrupt priority level setting.
*/
#if !defined(STM32_SDC_SDMMC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9
#endif
+
+/**
+ * @brief SDMMC2 interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDMMC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC2_IRQ_PRIORITY 9
+#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
+/* Registry checks.*/
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_HANDLER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_HANDLER))
+#error "STM32_SDMMCx_HANDLER not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_NUMBER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_NUMBER))
+#error "STM32_ADCx_NUMBER not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_MSK)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_MSK))
+#error "STM32_SDC_SDMMCx_DMA_MSK not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_CHN)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_CHN))
+#error "STM32_SDC_SDMMCx_DMA_CHN not defined in registry"
+#endif
+
+/* Units checks.*/
#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1
#error "SDMMC1 not present in the selected device"
#endif
-#if !STM32_SDC_USE_SDMMC1
+#if STM32_SDC_USE_SDMMC2 && !STM32_HAS_SDMMC2
+#error "SDMMC2 not present in the selected device"
+#endif
+
+#if !STM32_SDC_USE_SDMMC1 && !STM32_SDC_USE_SDMMC2
#error "SDC driver activated but no SDMMC peripheral assigned"
#endif
+/* Clock related tests.*/
#if !defined(STM32_SDMMCCLK)
#error "STM32_SDMMCCLK not defined"
#endif
@@ -112,28 +162,48 @@
#error "STM32_HCLK not defined"
#endif
-#if STM32_SDC_USE_SDMMC1 * 10 > STM32_HCLK * 7
+#if STM32_SDMMCCLK * 10 > STM32_HCLK * 7
#error "STM32_SDC_USE_SDMMC1 must not exceed STM32_HCLK * 0.7"
#endif
+/* SDMMC IRQ priority tests.*/
#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDIO"
+#error "Invalid IRQ priority assigned to SDMMC1"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDMMC2"
#endif
+/* DMA priority tests.*/
#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDIO"
+#error "Invalid DMA priority assigned to SDMMC1"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDMMC2"
#endif
/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if !defined(STM32_SDC_SDMMC1_DMA_STREAM)
+#if STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_STREAM)
#error "SDMMC1 DMA streams not defined"
#endif
+#if STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_STREAM)
+#error "SDMMC2 DMA streams not defined"
+#endif
+
/* Check on the validity of the assigned DMA channels.*/
-#if !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC1_DMA_STREAM, STM32_SDC_SDMMC1_DMA_MSK)
+#if STM32_SDC_USE_SDMMC1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC1_DMA_STREAM, STM32_SDC_SDMMC1_DMA_MSK)
#error "invalid DMA stream associated to SDMMC1"
#endif
+#if STM32_SDC_USE_SDMMC2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC2_DMA_STREAM, STM32_SDC_SDMMC2_DMA_MSK)
+#error "invalid DMA stream associated to SDMMC2"
+#endif
+
#if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED
#endif
@@ -246,10 +316,14 @@ struct SDCDriver {
/* External declarations. */
/*===========================================================================*/
-#if !defined(__DOXYGEN__)
+#if STM32_SDC_USE_SDMMC1 && !defined(__DOXYGEN__)
extern SDCDriver SDCD1;
#endif
+#if STM32_SDC_USE_SDMMC2 && !defined(__DOXYGEN__)
+extern SDCDriver SDCD2;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif