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