More ADCv3 code.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8579 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2015-12-11 09:46:10 +00:00
parent c22bbe5104
commit f1386e0a14
4 changed files with 222 additions and 55 deletions

View File

@ -64,11 +64,21 @@
ADCDriver ADCD1; ADCDriver ADCD1;
#endif #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__) #if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
ADCDriver ADCD3; ADCDriver ADCD3;
#endif #endif
/** @brief ADC4 driver identifier.*/
#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__)
ADCDriver ADCD4;
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver local variables and types. */ /* Driver local variables and types. */
/*===========================================================================*/ /*===========================================================================*/
@ -77,31 +87,12 @@ static const ADCConfig default_config = {
difsel: 0 difsel: 0
}; };
static uint32_t clkmask;
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* 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. * @brief Enables the ADC voltage regulator.
* *
@ -317,13 +308,13 @@ static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
/* Driver interrupt handlers. */ /* 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. * @brief ADC1/ADC2 interrupt handler.
* *
* @isr * @isr
*/ */
OSAL_IRQ_HANDLER(Vector88) { OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
uint32_t isr; uint32_t isr;
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
@ -333,12 +324,22 @@ OSAL_IRQ_HANDLER(Vector88) {
isr |= ADC2->ISR; isr |= ADC2->ISR;
ADC1->ISR = isr; ADC1->ISR = isr;
ADC2->ISR = isr; ADC2->ISR = isr;
#else /* !STM32_ADC_DUAL_MODE */
isr = ADC1->ISR;
ADC1->ISR = isr;
#endif /* !STM32_ADC_DUAL_MODE */
adc_lld_serve_interrupt(&ADCD1, isr); adc_lld_serve_interrupt(&ADCD1, isr);
#else /* !STM32_ADC_DUAL_MODE */
#if STM32_ADC_USE_ADC1
isr = ADC1->ISR;
ADC1->ISR = isr;
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(); OSAL_IRQ_EPILOGUE();
} }
@ -350,7 +351,7 @@ OSAL_IRQ_HANDLER(Vector88) {
* *
* @isr * @isr
*/ */
OSAL_IRQ_HANDLER(VectorFC) { OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) {
uint32_t isr; uint32_t isr;
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
@ -369,7 +370,7 @@ OSAL_IRQ_HANDLER(VectorFC) {
* *
* @isr * @isr
*/ */
OSAL_IRQ_HANDLER(Vector134) { OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) {
uint32_t isr; uint32_t isr;
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
@ -384,6 +385,26 @@ OSAL_IRQ_HANDLER(Vector134) {
#endif /* STM32_ADC_DUAL_MODE */ #endif /* STM32_ADC_DUAL_MODE */
#endif /* STM32_ADC_USE_ADC3 */ #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. */ /* Driver exported functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -395,6 +416,8 @@ OSAL_IRQ_HANDLER(Vector134) {
*/ */
void adc_lld_init(void) { void adc_lld_init(void) {
clkmask = 0;
#if STM32_ADC_USE_ADC1 #if STM32_ADC_USE_ADC1
/* Driver initialization.*/ /* Driver initialization.*/
adcObjectInit(&ADCD1); adcObjectInit(&ADCD1);
@ -409,7 +432,6 @@ void adc_lld_init(void) {
STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_DIR_P2M |
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
nvicEnableVector(ADC1_2_IRQn, STM32_ADC_ADC12_IRQ_PRIORITY);
#endif /* STM32_ADC_USE_ADC1 */ #endif /* STM32_ADC_USE_ADC1 */
#if STM32_ADC_USE_ADC3 #if STM32_ADC_USE_ADC3
@ -426,12 +448,23 @@ void adc_lld_init(void) {
STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_DIR_P2M |
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
nvicEnableVector(ADC3_IRQn, STM32_ADC_ADC34_IRQ_PRIORITY);
#if STM32_ADC_DUAL_MODE
nvicEnableVector(ADC4_IRQn, STM32_ADC_ADC34_IRQ_PRIORITY);
#endif
#endif /* STM32_ADC_USE_ADC3 */ #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(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
/* ADC units pre-initializations.*/
#if defined(STM32F3XX) #if defined(STM32F3XX)
#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 #if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
rccEnableADC12(FALSE); rccEnableADC12(FALSE);
@ -479,15 +512,30 @@ void adc_lld_start(ADCDriver *adcp) {
(stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
(void *)adcp); (void *)adcp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
clkmask |= (1 << 0);
#if defined(STM32F3XX) #if defined(STM32F3XX)
rccEnableADC12(FALSE); rccEnableADC12(FALSE);
#endif
#if defined(STM32L4XX)
rccEnableADC123(FALSE);
#endif #endif
} }
#endif /* STM32_ADC_USE_ADC1 */ #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 STM32_ADC_USE_ADC3
if (&ADCD3 == adcp) { if (&ADCD3 == adcp) {
bool b; bool b;
@ -496,14 +544,33 @@ void adc_lld_start(ADCDriver *adcp) {
(stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
(void *)adcp); (void *)adcp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
clkmask |= (1 << 2);
#if defined(STM32F3XX) #if defined(STM32F3XX)
rccEnableADC34(FALSE); rccEnableADC34(FALSE);
#endif #endif
}
#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_ADC4 */
#if defined(STM32L4XX) #if defined(STM32L4XX)
rccEnableADC123(FALSE); rccEnableADC123(FALSE);
#endif #endif
}
#endif /* STM32_ADC_USE_ADC2 */
/* Setting DMA peripheral-side pointer.*/ /* Setting DMA peripheral-side pointer.*/
#if STM32_ADC_DUAL_MODE #if STM32_ADC_DUAL_MODE
@ -551,7 +618,44 @@ void adc_lld_stop(ADCDriver *adcp) {
adc_lld_analog_off(adcp); adc_lld_analog_off(adcp);
adc_lld_vreg_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
} }
} }

View File

@ -249,10 +249,17 @@
#endif #endif
/** /**
* @brief ADC3/ADC4 interrupt priority level setting. * @brief ADC3 interrupt priority level setting.
*/ */
#if !defined(STM32_ADC34_IRQ_PRIORITY) || defined(__DOXYGEN__) #if !defined(STM32_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_ADC34_IRQ_PRIORITY 5 #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 #endif
/** /**
@ -319,6 +326,40 @@
#error "ADCv3 only supports F3 and L4 STM32 devices" #error "ADCv3 only supports F3 and L4 STM32 devices"
#endif #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.*/ /* Units checks.*/
#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1 #if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
#error "ADC1 not present in the selected device" #error "ADC1 not present in the selected device"
@ -359,17 +400,33 @@
#error "ADC driver activated but no ADC peripheral assigned" #error "ADC driver activated but no ADC peripheral assigned"
#endif #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.*/ /* ADC IRQ priority tests.*/
#if STM32_ADC_USE_ADC1 && \ #if STM32_ADC_USE_ADC1 && \
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY) !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC1" #error "Invalid IRQ priority assigned to ADC1"
#endif #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 && \ #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" #error "Invalid IRQ priority assigned to ADC3"
#endif #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.*/ /* DMA IRQ priority tests.*/
#if STM32_ADC_USE_ADC1 && \ #if STM32_ADC_USE_ADC1 && \
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)

View File

@ -1,4 +1,4 @@
STM32 ADCv2 driver. STM32 ADCv3 driver.
Driver capability: Driver capability:
@ -6,8 +6,14 @@ Driver capability:
The file registry must export: The file registry must export:
STM32_HAS_ADCx - ADCx presence flag (1..3). STM32_HAS_ADCx - ADCx presence flag (1..4).
STM32_ADC_HANDLER - IRQ vector name for ADCs (shared). STM32_ADC1_HANDLER - IRQ vector name for ADC1.
STM32_ADC_NUMBER - IRQ vector number for ADCs (shared). STM32_ADC1_NUMBER - IRQ vector number for ADC1.
STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels. STM32_ADC2_HANDLER - IRQ vector name for ADC2.
STM32_ADCx_DMA_CHN - Mask of the channels mapping. 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).

View File

@ -103,7 +103,7 @@
#define STM32_ADC_ADC2_DMA_PRIORITY 2 #define STM32_ADC_ADC2_DMA_PRIORITY 2
#define STM32_ADC_ADC3_DMA_PRIORITY 2 #define STM32_ADC_ADC3_DMA_PRIORITY 2
#define STM32_ADC_ADC12_IRQ_PRIORITY 5 #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_ADC1_DMA_IRQ_PRIORITY 5
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5