From f1386e0a146b6475c3559dd7db655969732c134c Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 11 Dec 2015 09:46:10 +0000 Subject: More ADCv3 code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8579 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/ADCv3/adc_lld.c | 184 +++++++++++++++++++++++------- os/hal/ports/STM32/LLD/ADCv3/adc_lld.h | 65 ++++++++++- os/hal/ports/STM32/LLD/ADCv3/notes.txt | 18 ++- testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h | 2 +- 4 files changed, 218 insertions(+), 51 deletions(-) diff --git a/os/hal/ports/STM32/LLD/ADCv3/adc_lld.c b/os/hal/ports/STM32/LLD/ADCv3/adc_lld.c index ff43998b1..36d3a320e 100644 --- a/os/hal/ports/STM32/LLD/ADCv3/adc_lld.c +++ b/os/hal/ports/STM32/LLD/ADCv3/adc_lld.c @@ -64,11 +64,21 @@ ADCDriver ADCD1; #endif -/** @brief ADC1 driver identifier.*/ +/** @brief ADC2 driver identifier.*/ +#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__) +ADCDriver ADCD2; +#endif + +/** @brief ADC3 driver identifier.*/ #if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__) ADCDriver ADCD3; #endif +/** @brief ADC4 driver identifier.*/ +#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__) +ADCDriver ADCD4; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -77,31 +87,12 @@ static const ADCConfig default_config = { difsel: 0 }; +static uint32_t clkmask; + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ -static void adc_lld_disable_clocks(void) { - bool disable; - -#if defined(STM32F3XX) -#endif - -#if defined(STM32L4XX) -#endif - -#if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) { - rccDisableADC12(FALSE); - } -#endif - -#if STM32_ADC_USE_ADC3 - if (&ADCD3 == adcp) - rccDisableADC34(FALSE); -#endif -} - /** * @brief Enables the ADC voltage regulator. * @@ -317,13 +308,13 @@ static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) { /* Driver interrupt handlers. */ /*===========================================================================*/ -#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) +#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || defined(__DOXYGEN__) /** * @brief ADC1/ADC2 interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(Vector88) { +OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) { uint32_t isr; OSAL_IRQ_PROLOGUE(); @@ -333,12 +324,22 @@ OSAL_IRQ_HANDLER(Vector88) { isr |= ADC2->ISR; ADC1->ISR = isr; ADC2->ISR = isr; + + adc_lld_serve_interrupt(&ADCD1, isr); #else /* !STM32_ADC_DUAL_MODE */ +#if STM32_ADC_USE_ADC1 isr = ADC1->ISR; ADC1->ISR = isr; -#endif /* !STM32_ADC_DUAL_MODE */ adc_lld_serve_interrupt(&ADCD1, isr); +#endif +#if STM32_ADC_USE_ADC2 + isr = ADC2->ISR; + ADC2->ISR = isr; + + adc_lld_serve_interrupt(&ADCD2, isr); +#endif +#endif /* !STM32_ADC_DUAL_MODE */ OSAL_IRQ_EPILOGUE(); } @@ -350,7 +351,7 @@ OSAL_IRQ_HANDLER(Vector88) { * * @isr */ -OSAL_IRQ_HANDLER(VectorFC) { +OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) { uint32_t isr; OSAL_IRQ_PROLOGUE(); @@ -369,7 +370,7 @@ OSAL_IRQ_HANDLER(VectorFC) { * * @isr */ -OSAL_IRQ_HANDLER(Vector134) { +OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) { uint32_t isr; OSAL_IRQ_PROLOGUE(); @@ -384,6 +385,26 @@ OSAL_IRQ_HANDLER(Vector134) { #endif /* STM32_ADC_DUAL_MODE */ #endif /* STM32_ADC_USE_ADC3 */ +#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__) +/** + * @brief ADC4 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) { + uint32_t isr; + + OSAL_IRQ_PROLOGUE(); + + isr = ADC4->ISR; + ADC4->ISR = isr; + + adc_lld_serve_interrupt(&ADCD4, isr); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_ADC_USE_ADC4 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -395,6 +416,8 @@ OSAL_IRQ_HANDLER(Vector134) { */ void adc_lld_init(void) { + clkmask = 0; + #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); @@ -409,7 +432,6 @@ void adc_lld_init(void) { STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; - nvicEnableVector(ADC1_2_IRQn, STM32_ADC_ADC12_IRQ_PRIORITY); #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_ADC3 @@ -426,12 +448,23 @@ void adc_lld_init(void) { STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; - nvicEnableVector(ADC3_IRQn, STM32_ADC_ADC34_IRQ_PRIORITY); +#endif /* STM32_ADC_USE_ADC3 */ + + /* IRQs setup.*/ +#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 + nvicEnableVector(STM32_ADC1_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY); +#endif +#if STM32_ADC_USE_ADC3 + nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); #if STM32_ADC_DUAL_MODE - nvicEnableVector(ADC4_IRQn, STM32_ADC_ADC34_IRQ_PRIORITY); + nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); +#endif +#endif +#if STM32_ADC_USE_ADC4 + nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); #endif -#endif /* STM32_ADC_USE_ADC3 */ + /* ADC units pre-initializations.*/ #if defined(STM32F3XX) #if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 rccEnableADC12(FALSE); @@ -479,15 +512,30 @@ void adc_lld_start(ADCDriver *adcp) { (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); + + clkmask |= (1 << 0); #if defined(STM32F3XX) rccEnableADC12(FALSE); -#endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); #endif } #endif /* STM32_ADC_USE_ADC1 */ +#if STM32_ADC_USE_ADC2 + if (&ADCD2 == adcp) { + bool b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC2_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, + (void *)adcp); + osalDbgAssert(!b, "stream already allocated"); + + clkmask |= (1 << 1); +#if defined(STM32F3XX) + rccEnableADC12(FALSE); +#endif + } +#endif /* STM32_ADC_USE_ADC2 */ + #if STM32_ADC_USE_ADC3 if (&ADCD3 == adcp) { bool b; @@ -496,20 +544,39 @@ void adc_lld_start(ADCDriver *adcp) { (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); + + clkmask |= (1 << 2); #if defined(STM32F3XX) rccEnableADC34(FALSE); #endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); + } +#endif /* STM32_ADC_USE_ADC3 */ + +#if STM32_ADC_USE_ADC4 + if (&ADCD4 == adcp) { + bool b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC4_DMA_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, + (void *)adcp); + osalDbgAssert(!b, "stream already allocated"); + + clkmask |= (1 << 3); +#if defined(STM32F3XX) + rccEnableADC34(FALSE); #endif } -#endif /* STM32_ADC_USE_ADC2 */ +#endif /* STM32_ADC_USE_ADC4 */ + +#if defined(STM32L4XX) + rccEnableADC123(FALSE); +#endif /* Setting DMA peripheral-side pointer.*/ #if STM32_ADC_DUAL_MODE - dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR); + dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR); #else - dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcm->DR); + dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcm->DR); #endif /* Differential channels setting.*/ @@ -551,7 +618,44 @@ void adc_lld_stop(ADCDriver *adcp) { adc_lld_analog_off(adcp); adc_lld_vreg_off(adcp); - adc_lld_disable_clocks(); +#if STM32_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + clkmask &= ~(1 << 0); + } +#endif + +#if STM32_ADC_USE_ADC2 + if (&ADCD1 == adcp) { + clkmask &= ~(1 << 1); + } +#endif + +#if STM32_ADC_USE_ADC3 + if (&ADCD1 == adcp) { + clkmask &= ~(1 << 2); + } +#endif + +#if STM32_ADC_USE_ADC4 + if (&ADCD1 == adcp) { + clkmask &= ~(1 << 3); + } +#endif + +#if defined(STM32F3XX) + if ((clkmask & 0x3) == 0) { + rccDisableADC12(FALSE); + } + if ((clkmask & 0xC) == 0) { + rccDisableADC34(FALSE); + } +#endif + +#if defined(STM32L4XX) + if ((clkmask & 0x7) == 0) { + rccDisableADC123(FALSE); + } +#endif } } diff --git a/os/hal/ports/STM32/LLD/ADCv3/adc_lld.h b/os/hal/ports/STM32/LLD/ADCv3/adc_lld.h index a5d639e1f..1e29c8508 100644 --- a/os/hal/ports/STM32/LLD/ADCv3/adc_lld.h +++ b/os/hal/ports/STM32/LLD/ADCv3/adc_lld.h @@ -249,10 +249,17 @@ #endif /** - * @brief ADC3/ADC4 interrupt priority level setting. + * @brief ADC3 interrupt priority level setting. */ -#if !defined(STM32_ADC34_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_ADC_ADC34_IRQ_PRIORITY 5 +#if !defined(STM32_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC3_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC4 interrupt priority level setting. + */ +#if !defined(STM32_ADC4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ADC_ADC4_IRQ_PRIORITY 5 #endif /** @@ -319,6 +326,40 @@ #error "ADCv3 only supports F3 and L4 STM32 devices" #endif +/* Registry checks.*/ +#if !defined(STM32_HAS_ADC1) || !defined(STM32_HAS_ADC2) || \ + !defined(STM32_HAS_ADC3) || !defined(STM32_HAS_ADC4) +#error "STM32_ADC_USE_ADCx not defined in registry" +#endif + +#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER)) || \ + (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_HANDLER)) || \ + (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_HANDLER)) || \ + (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_HANDLER)) +#error "STM32_ADCx_HANDLER not defined in registry" +#endif + +#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER)) || \ + (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_NUMBER)) || \ + (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_NUMBER)) || \ + (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_NUMBER)) +#error "STM32_ADCx_NUMBER not defined in registry" +#endif + +#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_MSK)) || \ + (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_MSK)) || \ + (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_MSK)) || \ + (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_MSK)) +#error "STM32_ADCx_DMA_MSK not defined in registry" +#endif + +#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_CHN)) || \ + (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_CHN)) || \ + (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_CHN)) || \ + (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_CHN)) +#error "STM32_ADCx_DMA_CHN not defined in registry" +#endif + /* Units checks.*/ #if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1 #error "ADC1 not present in the selected device" @@ -359,17 +400,33 @@ #error "ADC driver activated but no ADC peripheral assigned" #endif +/* ISR arrangments checks.*/ +#if STM32_ADC1_NUMBER != STM32_ADC2_NUMBER +#error "ADCv3 driver expects STM32_ADC1_NUMBER == STM32_ADC2_NUMBER from registry" +#endif + /* ADC IRQ priority tests.*/ #if STM32_ADC_USE_ADC1 && \ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY) #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" +#endif + #if STM32_ADC_USE_ADC3 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC34_IRQ_PRIORITY) + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_IRQ_PRIORITY) #error "Invalid IRQ priority assigned to ADC3" #endif +#if STM32_ADC_USE_ADC4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to ADC4" +#endif + /* DMA IRQ priority tests.*/ #if STM32_ADC_USE_ADC1 && \ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) diff --git a/os/hal/ports/STM32/LLD/ADCv3/notes.txt b/os/hal/ports/STM32/LLD/ADCv3/notes.txt index 2a8bf0137..360e02aca 100644 --- a/os/hal/ports/STM32/LLD/ADCv3/notes.txt +++ b/os/hal/ports/STM32/LLD/ADCv3/notes.txt @@ -1,4 +1,4 @@ -STM32 ADCv2 driver. +STM32 ADCv3 driver. Driver capability: @@ -6,8 +6,14 @@ Driver capability: The file registry must export: -STM32_HAS_ADCx - ADCx presence flag (1..3). -STM32_ADC_HANDLER - IRQ vector name for ADCs (shared). -STM32_ADC_NUMBER - IRQ vector number for ADCs (shared). -STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels. -STM32_ADCx_DMA_CHN - Mask of the channels mapping. +STM32_HAS_ADCx - ADCx presence flag (1..4). +STM32_ADC1_HANDLER - IRQ vector name for ADC1. +STM32_ADC1_NUMBER - IRQ vector number for ADC1. +STM32_ADC2_HANDLER - IRQ vector name for ADC2. +STM32_ADC2_NUMBER - IRQ vector number for ADC2. +STM32_ADC3_HANDLER - IRQ vector name for ADC3. +STM32_ADC3_NUMBER - IRQ vector number for ADC3. +STM32_ADC4_HANDLER - IRQ vector name for ADC4. +STM32_ADC4_NUMBER - IRQ vector number for ADC4. +STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels (1..4). +STM32_ADCx_DMA_CHN - Mask of the channels mapping (1..4). diff --git a/testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h b/testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h index 72c0c17cc..37c92b087 100644 --- a/testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h +++ b/testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h @@ -103,7 +103,7 @@ #define STM32_ADC_ADC2_DMA_PRIORITY 2 #define STM32_ADC_ADC3_DMA_PRIORITY 2 #define STM32_ADC_ADC12_IRQ_PRIORITY 5 -#define STM32_ADC_ADC34_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_IRQ_PRIORITY 5 #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 -- cgit v1.2.3