aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-12-11 09:46:10 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-12-11 09:46:10 +0000
commitf1386e0a146b6475c3559dd7db655969732c134c (patch)
tree3d0122c306a0bf93fc61a8cf8256525fe4a90736
parentc22bbe5104ebe05820dfbeb40b128596300bbbfc (diff)
downloadChibiOS-f1386e0a146b6475c3559dd7db655969732c134c.tar.gz
ChibiOS-f1386e0a146b6475c3559dd7db655969732c134c.tar.bz2
ChibiOS-f1386e0a146b6475c3559dd7db655969732c134c.zip
More ADCv3 code.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8579 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/ports/STM32/LLD/ADCv3/adc_lld.c184
-rw-r--r--os/hal/ports/STM32/LLD/ADCv3/adc_lld.h65
-rw-r--r--os/hal/ports/STM32/LLD/ADCv3/notes.txt18
-rw-r--r--testhal/STM32/STM32L4xx/GPT-ADC/mcuconf.h2
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