From 85a55d87b54ce2c4e6404d7bcfade6b631d42e0d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 27 Jun 2016 13:09:03 +0000 Subject: SDMMC2 support, removed a duplicated comment in ADCv3. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9671 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h | 1 - os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c | 119 ++++++++++++++++++++++----- os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h | 90 ++++++++++++++++++-- 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. */ @@ -48,6 +48,15 @@ #define STM32_SDC_USE_SDMMC1 FALSE #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. @@ -84,26 +93,67 @@ #define STM32_SDC_SDMMC1_DMA_PRIORITY 3 #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 -- cgit v1.2.3