void Adc_t::Init() { rccEnableADC123(FALSE); // Enable AHB clock // Setup ADC clock: PLLSAI1 "R" selected as ADC clk MODIFY_REG(RCC->CCIPR, RCC_CCIPR_ADCSEL, RCC_CCIPR_ADCSEL_0); // Setup PLL if(Clk.SetupPllSai1(16, 8) != OK) return; Clk.EnableSai1ROut(); // Power-on ADC CLEAR_BIT(ADC1->CR, ADC_CR_DEEPPWD); // Exit deep power-down mode SET_BIT(ADC1->CR, ADC_CR_ADVREGEN); // Enable ADC internal voltage regulator chThdSleepMicroseconds(20); // Setup channels SetSequenceLength(ADC_SEQ_LEN); for(uint8_t i=0; i < ADC_CHANNEL_CNT; i++) { SetChannelSampleTime(AdcChannels[i], ADC_SAMPLE_TIME); SetSequenceItem(i+1, AdcChannels[i]); // First sequence item is 1, not 0 } // ==== DMA ==== dmaStreamAllocate (ADC_DMA, IRQ_PRIO_LOW, AdcTxIrq, NULL); dmaStreamSetPeripheral(ADC_DMA, &ADC1->DR); dmaStreamSetMode (ADC_DMA, ADC_DMA_MODE); }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { /* Handling the default configuration.*/ if (adcp->config == NULL) { adcp->config = &default_config; } /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); clkmask |= (1 << 0); #if defined(STM32F3XX) rccEnableADC12(true); #endif #if defined(STM32L4XX) || defined(STM32L4XXP) rccEnableADC123(true); #endif #if STM32_DMA_SUPPORTS_DMAMUX dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1); #endif } #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_ADC2 if (&ADCD2 == adcp) { adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC_ADC2_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); clkmask |= (1 << 1); #if defined(STM32F3XX) rccEnableADC12(true); #endif #if defined(STM32L4XX) || defined(STM32L4XXP) rccEnableADC123(true); #endif #if STM32_DMA_SUPPORTS_DMAMUX dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC2); #endif } #endif /* STM32_ADC_USE_ADC2 */ #if STM32_ADC_USE_ADC3 if (&ADCD3 == adcp) { adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC_ADC3_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); clkmask |= (1 << 2); #if defined(STM32F3XX) rccEnableADC34(true); #endif #if defined(STM32L4XX) || defined(STM32L4XXP) rccEnableADC123(true); #endif #if STM32_DMA_SUPPORTS_DMAMUX dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC3); #endif } #endif /* STM32_ADC_USE_ADC3 */ #if STM32_ADC_USE_ADC4 if (&ADCD4 == adcp) { adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC4_DMA_STREAM, STM32_ADC_ADC4_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); clkmask |= (1 << 3); #if defined(STM32F3XX) rccEnableADC34(true); #endif #if defined(STM32L4XX) || defined(STM32L4XXP) rccEnableADC123(true); #endif #if STM32_DMA_SUPPORTS_DMAMUX dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC4); #endif } #endif /* STM32_ADC_USE_ADC4 */ /* Setting DMA peripheral-side pointer.*/ #if STM32_ADC_DUAL_MODE dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR); #else dmaStreamSetPeripheral(adcp->dmastp, &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 /* Master ADC calibration.*/ adc_lld_vreg_on(adcp); adc_lld_calibrate(adcp); /* Master ADC enabled here in order to reduce conversions latencies.*/ adc_lld_analog_on(adcp); } }
/** * @brief Low level ADC driver initialization. * * @notapi */ void adc_lld_init(void) { clkmask = 0; #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); #if defined(ADC1_2_COMMON) ADCD1.adcc = ADC1_2_COMMON; #elif defined(ADC123_COMMON) ADCD1.adcc = ADC123_COMMON; #else ADCD1.adcc = ADC1_COMMON; #endif ADCD1.adcm = ADC1; #if STM32_ADC_DUAL_MODE ADCD1.adcs = ADC2; #endif #if STM32_DMA_SUPPORTS_DMAMUX ADCD1.dmastp = NULL; #else ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM); #endif ADCD1.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_ADC2 /* Driver initialization.*/ adcObjectInit(&ADCD2); #if defined(ADC1_2_COMMON) ADCD2.adcc = ADC1_2_COMMON; #elif defined(ADC123_COMMON) ADCD2.adcc = ADC123_COMMON; #endif ADCD2.adcm = ADC2; #if STM32_DMA_SUPPORTS_DMAMUX ADCD2.dmastp = NULL; #else ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); #endif ADCD2.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC2 */ #if STM32_ADC_USE_ADC3 /* Driver initialization.*/ adcObjectInit(&ADCD3); #if defined(ADC3_4_COMMON) ADCD3.adcc = ADC3_4_COMMON; #elif defined(ADC123_COMMON) ADCD3.adcc = ADC123_COMMON; #else ADCD3.adcc = ADC3_COMMON; #endif ADCD3.adcm = ADC3; #if STM32_ADC_DUAL_MODE ADCD3.adcs = ADC4; #endif #if STM32_DMA_SUPPORTS_DMAMUX ADCD3.dmastp = NULL; #else ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); #endif 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; #endif /* STM32_ADC_USE_ADC3 */ #if STM32_ADC_USE_ADC4 /* Driver initialization.*/ adcObjectInit(&ADCD4); ADCD4.adcc = ADC3_4_COMMON; ADCD4.adcm = ADC4; #if STM32_DMA_SUPPORTS_DMAMUX ADCD4.dmastp = NULL; #else ADCD4.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC4_DMA_STREAM); #endif ADCD4.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC4_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC4 */ /* 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_HAS_ADC1 && STM32_HAS_ADC2 #if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 rccEnableADC12(true); rccResetADC12(); ADC1_2_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC12(); #endif #else #if STM32_ADC_USE_ADC1 rccEnableADC12(true); rccResetADC12(); ADC1_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC12(); #endif #endif #if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4 rccEnableADC34(true); rccResetADC34(); ADC3_4_COMMON->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC34(); #endif #endif #if defined(STM32L4XX) || defined(STM32L4XXP) rccEnableADC123(true); rccResetADC123(); #if defined(ADC1_2_COMMON) ADC1_2_COMMON->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; #elif defined(ADC123_COMMON) ADC123_COMMON->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; #else ADC1_COMMON->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; #endif rccDisableADC123(); #endif }