diff --git a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
index 9078ba95d..cebb1df45 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
@@ -32,25 +32,29 @@
#if STM32_ADC_DUAL_MODE == TRUE
#if STM32_ADC_COMPACT_SAMPLES == TRUE
-/* Compact type dual mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_HWORD
+/* Compact type dual mode, 2x8-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_BYTE
#else /* STM32_ADC_COMPACT_SAMPLES == FALSE */
-/* Large type dual mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_WORD
+/* Large type dual mode, 2x16bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_HWORD
#endif /* !STM32_ADC_COMPACT_SAMPLES */
#else /* STM32_ADC_DUAL_MODE == FALSE */
#if STM32_ADC_COMPACT_SAMPLES
-/* Compact type single mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
+/* Compact type single mode, 8-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
#else /* STM32_ADC_COMPACT_SAMPLES == FALSE */
-/* Large type single mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+/* Large type single mode, 16-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
#endif /* STM32_ADC_COMPACT_SAMPLES == FALSE */
#endif /* STM32_ADC_DUAL_MODE == FALSE */
@@ -90,7 +94,9 @@ static void adc_lld_vreg_on(ADCDriver *adcp) {
adcp->adcm->CR = ADC_CR_ADVREGEN;
#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR = ADC_CR_ADVREGEN;
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR = ADC_CR_ADVREGEN;
+ }
#endif
osalSysPolledDelayX(OSAL_US2RTC(STM32_SYS_CK, 10U));
}
@@ -104,7 +110,9 @@ static void adc_lld_vreg_off(ADCDriver *adcp) {
adcp->adcm->CR = ADC_CR_DEEPPWD;
#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR = ADC_CR_DEEPPWD;
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR = ADC_CR_DEEPPWD;
+ }
#endif
}
@@ -120,10 +128,12 @@ static void adc_lld_analog_on(ADCDriver *adcp) {
while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0U)
;
#if STM32_ADC_DUAL_MODE
- adcp->adcs->ISR = ADC_ISR_ADRDY;
- adcp->adcs->CR |= ADC_CR_ADEN;
- while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0U)
- ;
+ if (&ADCD1 == adcp) {
+ adcp->adcs->ISR = ADC_ISR_ADRDY;
+ adcp->adcs->CR |= ADC_CR_ADEN;
+ while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0U)
+ ;
+ }
#endif
}
@@ -138,9 +148,11 @@ static void adc_lld_analog_off(ADCDriver *adcp) {
while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0U)
;
#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR |= ADC_CR_ADDIS;
- while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0U)
- ;
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR |= ADC_CR_ADDIS;
+ while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0U)
+ ;
+ }
#endif
}
@@ -160,14 +172,16 @@ static void adc_lld_calibrate(ADCDriver *adcp) {
while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0U)
;
#if STM32_ADC_DUAL_MODE
- osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
+ if (&ADCD1 == adcp) {
+ osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
- adcp->adcs->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
- adcp->adcs->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
- ADC_CR_ADCALLIN);
- adcp->adcs->CR |= ADC_CR_ADCAL;
- while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0U)
- ;
+ adcp->adcs->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
+ adcp->adcs->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
+ ADC_CR_ADCALLIN);
+ adcp->adcs->CR |= ADC_CR_ADCAL;
+ while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0U)
+ ;
+ }
#endif
}
@@ -186,6 +200,7 @@ static void adc_lld_stop_adc(ADCDriver *adcp) {
adcp->adcm->PCSEL = 0U;
}
+#if (STM32_ADC_USE_ADC12 == TRUE) || defined(__DOXYGEN__)
/**
* @brief ADC DMA service routine.
*
@@ -215,7 +230,9 @@ static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
}
}
}
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+#if (STM32_ADC_USE_ADC3 == TRUE) || defined(__DOXYGEN__)
/**
* @brief ADC BDMA service routine.
*
@@ -245,6 +262,7 @@ static void adc_lld_serve_bdma_interrupt(ADCDriver *adcp, uint32_t flags) {
}
}
}
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
/**
* @brief ADC IRQ service routine.
@@ -295,11 +313,11 @@ OSAL_IRQ_HANDLER(STM32_ADC12_HANDLER) {
OSAL_IRQ_PROLOGUE();
isr = ADC1->ISR;
-#if STM32_ADC_DUAL_MODE == TRUE
+#if STM32_ADC_DUAL_MODE
isr |= ADC2->ISR;
#endif
ADC1->ISR = isr;
-#if STM32_ADC_DUAL_MODE == TRUE
+#if STM32_ADC_DUAL_MODE
ADC2->ISR = isr;
#endif
#if defined(STM32_ADC_ADC12_IRQ_HOOK)
@@ -353,7 +371,7 @@ void adc_lld_init(void) {
ADCD1.adcs = ADC2;
#endif
ADCD1.data.dma = NULL;
- ADCD1.dmamode = ADC_DMA_SIZE |
+ ADCD1.dmamode = ADC12_DMA_SIZE |
STM32_DMA_CR_PL(STM32_ADC_ADC12_DMA_PRIORITY) |
STM32_DMA_CR_DIR_P2M |
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
@@ -367,11 +385,11 @@ void adc_lld_init(void) {
ADCD3.adcc = ADC3_COMMON;
ADCD3.adcm = ADC3;
ADCD3.data.bdma = NULL;
- ADCD3.dmamode = ADC_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ ADCD3.dmamode = ADC3_BDMA_SIZE |
+ STM32_BDMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
+ STM32_BDMA_CR_DIR_P2M |
+ STM32_BDMA_CR_MINC | STM32_BDMA_CR_TCIE |
+ STM32_BDMA_CR_TEIE;
nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
#endif /* STM32_ADC_USE_ADC3 == TRUE */
@@ -386,7 +404,7 @@ void adc_lld_init(void) {
#if STM32_ADC_USE_ADC3 == TRUE
rccEnableADC3(true);
rccResetADC3();
- ADC3_COMMON->CCR = STM32_ADC_ADC3_CLOCK_MODE | ADC_DMA_DAMDF;
+ ADC3_COMMON->CCR = STM32_ADC_ADC3_CLOCK_MODE;
rccDisableADC3();
#endif
#endif
@@ -417,6 +435,21 @@ void adc_lld_start(ADCDriver *adcp) {
osalDbgAssert(adcp->data.dma != NULL, "unable to allocate stream");
rccEnableADC12(true);
dmaSetRequestSource(adcp->data.dma, STM32_DMAMUX1_ADC1);
+
+ /* Setting DMA peripheral-side pointer.*/
+#if STM32_ADC_DUAL_MODE
+ dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcc->CDR);
+#else
+ dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcm->DR);
+#endif
+
+ /* Differential channels setting.*/
+#if STM32_ADC_DUAL_MODE
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+ adcp->adcs->DIFSEL = adcp->config->difsel;
+#else
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+#endif
}
#endif /* STM32_ADC_USE_ADC12 == TRUE */
@@ -429,28 +462,35 @@ void adc_lld_start(ADCDriver *adcp) {
osalDbgAssert(adcp->data.bdma != NULL, "unable to allocate stream");
rccEnableADC3(true);
bdmaSetRequestSource(adcp->data.bdma, STM32_DMAMUX2_ADC3_REQ);
+
+ /* Setting DMA peripheral-side pointer.*/
+ bdmaStreamSetPeripheral(adcp->data.bdma, &adcp->adcm->DR);
+
+ /* Differential channels setting.*/
+ adcp->adcm->DIFSEL = adcp->config->difsel;
}
#endif /* STM32_ADC_USE_ADC3 == TRUE */
- /* Setting DMA peripheral-side pointer.*/
-#if STM32_ADC_DUAL_MODE == TRUE
- dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcc->CDR);
-#else
- dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcm->DR);
-#endif
-
- /* Differential channels setting.*/
-#if STM32_ADC_DUAL_MODE == TRUE
- adcp->adcm->DIFSEL = adcp->config->difsel;
- adcp->adcs->DIFSEL = adcp->config->difsel;
-#else
- adcp->adcm->DIFSEL = adcp->config->difsel;
-#endif
-
/* Master ADC calibration.*/
adc_lld_vreg_on(adcp);
adc_lld_calibrate(adcp);
+ /* Configure the ADC boost. */
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+ adcp->adcm->CR |= STM32_ADC12_BOOST;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR |= STM32_ADC12_BOOST;
+#endif
+ }
+#endif
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ adcp->adcm->CR |= STM32_ADC3_BOOST;
+ }
+#endif
+
/* Master ADC enabled here in order to reduce conversions latencies.*/
adc_lld_analog_on(adcp);
}
@@ -496,7 +536,7 @@ void adc_lld_stop(ADCDriver *adcp) {
adcp->data.bdma = NULL;
/* Resetting CCR options except default ones.*/
- adcp->adcc->CCR = STM32_ADC_ADC3_CLOCK_MODE | ADC_DMA_DAMDF;
+ adcp->adcc->CCR = STM32_ADC_ADC3_CLOCK_MODE;
rccDisableADC3();
}
#endif
@@ -513,104 +553,147 @@ void adc_lld_stop(ADCDriver *adcp) {
void adc_lld_start_conversion(ADCDriver *adcp) {
uint32_t dmamode, cfgr;
const ADCConversionGroup *grpp = adcp->grpp;
+
+#if STM32_ADC_USE_ADC12 == TRUE
#if STM32_ADC_DUAL_MODE
- uint32_t ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_DUAL_MASK);
+ uint32_t ccr;
+#endif
+ if (&ADCD1 == adcp) {
+#if STM32_ADC_DUAL_MODE
+ ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK);
+ osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
+ "odd number of channels in dual mode");
#endif
- osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
- "odd number of channels in dual mode");
-
- /* Calculating control registers values.*/
- dmamode = adcp->dmamode;
- if (grpp->circular) {
- dmamode |= STM32_DMA_CR_CIRC;
- cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- dmamode |= STM32_DMA_CR_HTIE;
+ /* Calculating control registers values.*/
+ dmamode = adcp->dmamode;
+ if (grpp->circular) {
+ dmamode |= STM32_DMA_CR_CIRC;
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ dmamode |= STM32_DMA_CR_HTIE;
+ }
}
else {
cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
}
- }
- /* DMA setup.*/
- dmaStreamSetMemory0(adcp->data.dma, adcp->samples);
+ /* DMA setup.*/
+ dmaStreamSetMemory0(adcp->data.dma, adcp->samples);
#if STM32_ADC_DUAL_MODE
- dmaStreamSetTransactionSize(adcp->data.dma, ((uint32_t)grpp->num_channels / 2U) *
- (uint32_t)adcp->depth);
+ dmaStreamSetTransactionSize(adcp->data.dma, ((uint32_t)grpp->num_channels / 2U) *
+ (uint32_t)adcp->depth);
#else
- dmaStreamSetTransactionSize(adcp->data.dma, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
+ dmaStreamSetTransactionSize(adcp->data.dma, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
#endif
- dmaStreamSetMode(adcp->data.dma, dmamode);
- dmaStreamEnable(adcp->data.dma);
+ dmaStreamSetMode(adcp->data.dma, dmamode);
+ dmaStreamEnable(adcp->data.dma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ /* Calculating control registers values.*/
+ dmamode = adcp->dmamode;
+ if (grpp->circular) {
+ dmamode |= STM32_BDMA_CR_CIRC;
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ dmamode |= STM32_BDMA_CR_HTIE;
+ }
+ }
+ else {
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
+ }
+
+ /* DMA setup.*/
+ bdmaStreamSetMemory(adcp->data.bdma, adcp->samples);
+ bdmaStreamSetTransactionSize(adcp->data.bdma, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ bdmaStreamSetMode(adcp->data.bdma, dmamode);
+ bdmaStreamEnable(adcp->data.bdma);
+ }
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
/* ADC setup, if it is defined a callback for the analog watch dog then it
is enabled.*/
adcp->adcm->ISR = adcp->adcm->ISR;
adcp->adcm->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE;
-#if STM32_ADC_DUAL_MODE
+#if STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE
+ /* Configuration for dual mode ADC12 */
+ if (&ADCD1 == adcp) {
+ /* Configuring the CCR register with the user-specified settings
+ in the conversion group configuration structure, static settings are
+ preserved.*/
+ adcp->adcc->CCR = (adcp->adcc->CCR &
+ (ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK)) | ccr;
- /* Configuring the CCR register with the user-specified settings
- in the conversion group configuration structure, static settings are
- preserved.*/
- adcp->adcc->CCR = (adcp->adcc->CCR &
- (ADC_CCR_CKMODE_MASK | ADC_CCR_DUAL_MASK)) | ccr;
+ adcp->adcm->CFGR2 = grpp->cfgr2;
+ adcp->adcm->PCSEL = grpp->pcsel;
+ adcp->adcm->LTR1 = grpp->ltr1;
+ adcp->adcm->HTR1 = grpp->htr1;
+ adcp->adcm->LTR1 = grpp->ltr2;
+ adcp->adcm->HTR1 = grpp->htr2;
+ adcp->adcm->LTR1 = grpp->ltr3;
+ adcp->adcm->HTR1 = grpp->htr3;
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
+ adcp->adcs->CFGR2 = grpp->cfgr2;
+ adcp->adcs->PCSEL = grpp->pcsel;
+ adcp->adcs->LTR1 = grpp->ltr1;
+ adcp->adcs->HTR1 = grpp->htr1;
+ adcp->adcs->LTR1 = grpp->ltr2;
+ adcp->adcs->HTR1 = grpp->htr2;
+ adcp->adcs->LTR1 = grpp->ltr3;
+ adcp->adcs->HTR1 = grpp->htr3;
+ adcp->adcs->SMPR1 = grpp->ssmpr[0];
+ adcp->adcs->SMPR2 = grpp->ssmpr[1];
+ adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcs->SQR2 = grpp->ssqr[1];
+ adcp->adcs->SQR3 = grpp->ssqr[2];
+ adcp->adcs->SQR4 = grpp->ssqr[3];
- adcp->adcm->CFGR2 = grpp->cfgr2;
- adcp->adcm->PCSEL = grpp->pcsel;
- adcp->adcm->LTR1 = grpp->ltr1;
- adcp->adcm->HTR1 = grpp->htr1;
- adcp->adcm->LTR1 = grpp->ltr2;
- adcp->adcm->HTR1 = grpp->htr2;
- adcp->adcm->LTR1 = grpp->ltr3;
- adcp->adcm->HTR1 = grpp->htr3;
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
- adcp->adcs->CFGR2 = grpp->cfgr2;
- adcp->adcs->PCSEL = grpp->pcsel;
- adcp->adcs->LTR1 = grpp->ltr1;
- adcp->adcs->HTR1 = grpp->htr1;
- adcp->adcs->LTR1 = grpp->ltr2;
- adcp->adcs->HTR1 = grpp->htr2;
- adcp->adcs->LTR1 = grpp->ltr3;
- adcp->adcs->HTR1 = grpp->htr3;
- adcp->adcs->SMPR1 = grpp->ssmpr[0];
- adcp->adcs->SMPR2 = grpp->ssmpr[1];
- adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcs->SQR2 = grpp->ssqr[1];
- adcp->adcs->SQR3 = grpp->ssqr[2];
- adcp->adcs->SQR4 = grpp->ssqr[3];
+ /* ADC configuration.*/
+ adcp->adcm->CFGR = cfgr;
+ adcp->adcs->CFGR = cfgr;
+ }
- /* ADC configuration.*/
- adcp->adcm->CFGR = cfgr;
- adcp->adcs->CFGR = cfgr;
+#endif /* STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE */
-#else /* !STM32_ADC_DUAL_MODE */
- adcp->adcm->CFGR2 = grpp->cfgr2;
- adcp->adcm->PCSEL = grpp->pcsel;
- adcp->adcm->LTR1 = grpp->ltr1;
- adcp->adcm->HTR1 = grpp->htr1;
- adcp->adcm->LTR1 = grpp->ltr2;
- adcp->adcm->HTR1 = grpp->htr2;
- adcp->adcm->LTR1 = grpp->ltr3;
- adcp->adcm->HTR1 = grpp->htr3;
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
+#if STM32_ADC_DUAL_MODE == FALSE || STM32_ADC_USE_ADC3 == TRUE
+ /* Configuration for ADC3 and single mode ADC1 */
+#if STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp)
+#endif
+ {
+ adcp->adcm->CFGR2 = grpp->cfgr2;
+ adcp->adcm->PCSEL = grpp->pcsel;
+ adcp->adcm->LTR1 = grpp->ltr1;
+ adcp->adcm->HTR1 = grpp->htr1;
+ adcp->adcm->LTR1 = grpp->ltr2;
+ adcp->adcm->HTR1 = grpp->htr2;
+ adcp->adcm->LTR1 = grpp->ltr3;
+ adcp->adcm->HTR1 = grpp->htr3;
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
- /* ADC configuration.*/
- adcp->adcm->CFGR = cfgr;
-#endif /* !STM32_ADC_DUAL_MODE */
+ /* ADC configuration.*/
+ adcp->adcm->CFGR = cfgr;
+ }
+#endif
/* Starting conversion.*/
adcp->adcm->CR |= ADC_CR_ADSTART;
@@ -625,7 +708,18 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
*/
void adc_lld_stop_conversion(ADCDriver *adcp) {
- dmaStreamDisable(adcp->data.dma);
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+ dmaStreamDisable(adcp->data.dma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ bdmaStreamDisable(adcp->data.bdma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
adc_lld_stop_adc(adcp);
}
diff --git a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
index 0e22517ba..690a404fa 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
@@ -54,6 +54,7 @@
#define ADC_CHANNEL_IN16 16U /**< @brief External analog input 16. */
#define ADC_CHANNEL_IN17 17U /**< @brief External analog input 17. */
#define ADC_CHANNEL_IN18 18U /**< @brief External analog input 18. */
+#define ADC_CHANNEL_IN19 19U /**< @brief External analog input 19. */
/** @} */
/**
@@ -79,6 +80,7 @@
#define ADC_SELMASK_IN16 (1U << ADC_CHANNEL_IN16)
#define ADC_SELMASK_IN17 (1U << ADC_CHANNEL_IN17)
#define ADC_SELMASK_IN18 (1U << ADC_CHANNEL_IN18)
+#define ADC_SELMASK_IN19 (1U << ADC_CHANNEL_IN19)
/** @} */
/**
@@ -109,10 +111,16 @@
#define ADC_CFGR_RES_MASK (7U << 2U)
#define ADC_CFGR_RES_16BITS (0U << 2U)
+#define ADC_CFGR_RES_10BITS (3U << 2U)
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+#define ADC_CFGR_RES_14BITS (5U << 2U)
+#define ADC_CFGR_RES_12BITS (6U << 2U)
+#define ADC_CFGR_RES_8BITS (7U << 2U)
+#else
#define ADC_CFGR_RES_14BITS (1U << 2U)
#define ADC_CFGR_RES_12BITS (2U << 2U)
-#define ADC_CFGR_RES_10BITS (3U << 2U)
#define ADC_CFGR_RES_8BITS (4U << 2U)
+#endif
#define ADC_CFGR_EXTSEL_MASK (15U << 5U)
#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 5U)
@@ -137,12 +145,20 @@
*/
#define ADC_CCR_DUAL_MASK (31U << 0U)
#define ADC_CCR_DUAL_FIELD(n) ((n) << 0U)
+#define ADC_CCR_DUAL_INDEPENDENT (0U << 0U) /**< @brief Independent, dual mode disabled. */
+#define ADC_CCR_DUAL_REG_SIMULT (6U << 0U) /**< @brief Regular simultaneous. */
+#define ADC_CCR_DUAL_REG_INTERL (7U << 0U) /**< @brief Regular interleaved. */
+#define ADC_CCR_DUAL_INJ_SIMULT (5U << 0U) /**< @brief Injected simultaneous. */
+#define ADC_CCR_DUAL_INJ_ALTERNATE (9U << 0U) /**< @brief Injected alternate trigger. */
+#define ADC_CCR_DUAL_REG_SIM_INJ_SIM (1U << 0U) /**< @brief Combined regular simultaneous + injected simultaneous. */
+#define ADC_CCR_DUAL_REG_SIM_INJ_ALT (2U << 0U) /**< @brief Combined regular simultaneous + injected alternate trigger. */
+#define ADC_CCR_DUAL_REG_INT_INJ_SIM (3U << 0U) /**< @brief Combined regular interleaved + injected simultaneous. */
#define ADC_CCR_DELAY_MASK (15U << 8U)
#define ADC_CCR_DELAY_FIELD(n) ((n) << 8U)
#define ADC_CCR_DAMDF_MASK (3U << 14U)
#define ADC_CCR_DAMDF_DISABLED (0U << 14U)
#define ADC_CCR_DAMDF_HWORD (2U << 14U)
-#define ADC_CCR_DAMDF_WORD (3U << 14U)
+#define ADC_CCR_DAMDF_BYTE (3U << 14U)
#define ADC_CCR_CKMODE_MASK (3U << 16U)
#define ADC_CCR_CKMODE_ADCCK (0U << 16U)
#define ADC_CCR_CKMODE_AHB_DIV1 (1U << 16U)
@@ -294,6 +310,11 @@
#error "ADC driver activated but no ADC peripheral assigned"
#endif
+/* Dual mode is only supported with ADC12.*/
+#if !STM32_ADC_USE_ADC12 && STM32_ADC_DUAL_MODE
+#error "STM32_ADC_DUAL_MODE only supported with ADC12"
+#endif
+
/* Check on the presence of the DMA streams settings in mcuconf.h.*/
#if STM32_ADC_USE_ADC12 && !defined(STM32_ADC_ADC12_DMA_STREAM)
#error "STM32_ADC_ADC12_DMA_STREAM not defined"
@@ -336,7 +357,42 @@
#error "Invalid IRQ priority assigned to ADC3"
#endif
+#if !defined(STM32_ENFORCE_H7_REV_XY)
/* ADC clock source checks.*/
+#if (STM32_D1HPRE == STM32_D1HPRE_DIV1)
+#define STM32_ADC_SCLK STM32_HCLK
+#else
+#define STM32_ADC_SCLK (STM32_HCLK / 2)
+#endif
+
+#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+/* CHTODO: also check ADC_CCR_PRESC.*/
+#define STM32_ADC12_CLOCK (STM32_ADCCLK / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 1 / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 2 / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 4 / 2)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
+#endif
+
+#if STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+/* CHTODO: also check ADC_CCR_PRESC.*/
+#define STM32_ADC3_CLOCK (STM32_ADCCLK / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 1 / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 2 / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 4 / 2)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
+#endif
+
+#else /* defined(STM32_ENFORCE_H7_REV_XY) */
+
#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
#define STM32_ADC12_CLOCK STM32_ADCCLK
#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
@@ -361,6 +417,8 @@
#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
#endif
+#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
+
#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
#endif
@@ -369,6 +427,44 @@
#error "STM32_ADC3_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
#endif
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+/* ADC boost checks.*/
+#if STM32_ADC12_CLOCK > 6250000
+#define STM32_ADC12_BOOST (1U << 8U)
+#elif STM32_ADC12_CLOCK > 12500000
+#define STM32_ADC12_BOOST (2U << 8U)
+#elif STM32_ADC12_CLOCK > 25000000
+#define STM32_ADC12_BOOST (3U << 8U)
+#else
+#define STM32_ADC12_BOOST (0U << 8U)
+#endif
+
+#if STM32_ADC3_CLOCK > 6250000
+#define STM32_ADC3_BOOST (1U << 8U)
+#elif STM32_ADC3_CLOCK > 12500000
+#define STM32_ADC3_BOOST (2U << 8U)
+#elif STM32_ADC3_CLOCK > 25000000
+#define STM32_ADC3_BOOST (3U << 8U)
+#else
+#define STM32_ADC3_BOOST (0U << 8U)
+#endif
+
+#else /* defined(STM32_ENFORCE_H7_REV_XY) */
+
+#if STM32_ADC12_CLOCK > 20000000
+#define STM32_ADC12_BOOST (1U << 8U)
+#else
+#define STM32_ADC12_BOOST (0U << 8U)
+#endif
+
+#if STM32_ADC3_CLOCK > 20000000
+#define STM32_ADC3_BOOST (1U << 8U)
+#else
+#define STM32_ADC3_BOOST (0U << 8U)
+#endif
+
+#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
+
#if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED
#endif
diff --git a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
index 47c54f47d..6ed63f11c 100644
--- a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
+++ b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
@@ -131,9 +131,9 @@
* @name Status flags passed to the ISR callbacks
* @{
*/
-#define STM32_BDMA_ISR_TEIF BDMA_ISR_TEIF1
-#define STM32_BDMA_ISR_HTIF BDMA_ISR_HTIF1
-#define STM32_BDMA_ISR_TCIF BDMA_ISR_TCIF1
+#define STM32_BDMA_ISR_TEIF BDMA_ISR_TEIF0
+#define STM32_BDMA_ISR_HTIF BDMA_ISR_HTIF0
+#define STM32_BDMA_ISR_TCIF BDMA_ISR_TCIF0
/** @} */
/*===========================================================================*/
@@ -272,15 +272,9 @@ typedef struct {
*
* @special
*/
-#if !defined(STM32_ENFORCE_H7_REV_XY) || defined(__DOXYGEN__)
#define bdmaStreamSetMemory(stp, addr) { \
(stp)->channel->CM0AR = (uint32_t)(addr); \
}
-#else
-#define bdmaStreamSetMemory(stp, addr) { \
- (stp)->channel->CMAR = (uint32_t)(addr); \
-}
-#endif
/**
* @brief Sets the number of transfers to be performed.
diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.h b/os/hal/ports/STM32/STM32H7xx/hal_lld.h
index 9867fa435..3dc31c512 100644
--- a/os/hal/ports/STM32/STM32H7xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.h
@@ -212,7 +212,7 @@
/**
* @brief Maximum ADC clock frequency.
*/
-#define STM32_ADCCLK_MAX 100000000
+#define STM32_ADCCLK_MAX 50000000
/** @} */
#else /* defined(STM32_ENFORCE_H7_REV_XY) */
diff --git a/testhal/STM32/multi/ADC/.cproject b/testhal/STM32/multi/ADC/.cproject
index f7b9378f0..e2ec9577c 100644
--- a/testhal/STM32/multi/ADC/.cproject
+++ b/testhal/STM32/multi/ADC/.cproject
@@ -285,4 +285,5 @@
+