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;
#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;
#else /* !STM32_ADC_DUAL_MODE */
isr = ADC1->ISR;
ADC1->ISR = isr;
#endif /* !STM32_ADC_DUAL_MODE */
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();
}
@ -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);
#if STM32_ADC_DUAL_MODE
nvicEnableVector(ADC4_IRQn, STM32_ADC_ADC34_IRQ_PRIORITY);
#endif
#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 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
}
}

View File

@ -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)

View File

@ -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).

View File

@ -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