/** * @brief Low level ADC driver initialization. * * @notapi */ void adc_lld_init(void) { #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; ADCD1.dmastp = STM32_DMA1_STREAM1; ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* The shared vector is initialized on driver initialization and never disabled.*/ nvicEnableVector(12, STM32_ADC_IRQ_PRIORITY); /* Calibration procedure.*/ rccEnableADC1(FALSE); osalDbgAssert(ADC1->CR == 0, "invalid register state"); ADC1->CR |= ADC_CR_ADCAL; while (ADC1->CR & ADC_CR_ADCAL) ; rccDisableADC1(FALSE); }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { bool b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); #if STM32_ADCSW == STM32_ADCSW_HSI14 /* Clock from HSI14, no need for jitter removal.*/ ADC1->CFGR2 = 0x00001000; #else #if STM32_ADCPRE == STM32_ADCPRE_DIV2 ADC1->CFGR2 = 0x00001000 | ADC_CFGR2_JITOFFDIV2; #else ADC1->CFGR2 = 0x00001000 | ADC_CFGR2_JITOFFDIV4; #endif #endif } #endif /* STM32_ADC_USE_ADC1 */ /* ADC initial setup, starting the analog part here in order to reduce the latency when starting a conversion.*/ adcp->adc->CR = ADC_CR_ADEN; while (!(adcp->adc->ISR & ADC_ISR_ADRDY)) ; } }
/** * @brief Low level ADC driver initialization. * * @notapi */ void adc_lld_init(void) { #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; ADCD1.dmastp = STM32_DMA1_STREAM1; ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE; /* Temporary activation.*/ rccEnableADC1(FALSE); ADC1->CR1 = 0; ADC1->CR2 = ADC_CR2_ADON; /* Reset calibration just to be safe.*/ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL; while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0) ; /* Calibration.*/ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL; while ((ADC1->CR2 & ADC_CR2_CAL) != 0) ; /* Return the ADC in low power mode.*/ ADC1->CR2 = 0; rccDisableADC1(FALSE); #endif }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { bool b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); /* Clock settings.*/ adcp->adc->CFGR2 = STM32_ADC_CKMODE; } #endif /* STM32_ADC_USE_ADC1 */ /* ADC initial setup, starting the analog part here in order to reduce the latency when starting a conversion.*/ adcp->adc->CR = ADC_CR_ADEN; while (!(adcp->adc->ISR & ADC_ISR_ADRDY)) ; } }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { bool b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); } #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_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR); rccEnableADC2(FALSE); } #endif /* STM32_ADC_USE_ADC2 */ #if STM32_ADC_USE_ADC3 if (&ADCD3 == adcp) { bool b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC3_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR); rccEnableADC3(FALSE); } #endif /* STM32_ADC_USE_ADC3 */ /* This is a common register but apparently it requires that at least one of the ADCs is clocked in order to allow writing, see bug 3575297.*/ ADC->CCR = (ADC->CCR & (ADC_CCR_TSVREFE | ADC_CCR_VBATE)) | (STM32_ADC_ADCPRE << 16); /* ADC initial setup, starting the analog part here in order to reduce the latency when starting a conversion.*/ adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; adcp->adc->CR2 = ADC_CR2_ADON; } }
void Adc_t::Init() { rccEnableADC1(FALSE); // Enable digital clock SetupClk(adcDiv4); // Setup ADCCLK SetChannelCount(ADC_CHANNEL_CNT); for(uint8_t i = 0; i < ADC_CHANNEL_CNT; i++) ChannelConfig(AdcChannels[i]); // ==== DMA ==== // Here only unchanged parameters of the DMA are configured. dmaStreamAllocate (ADC_DMA, IRQ_PRIO_LOW, AdcTxIrq, NULL); dmaStreamSetPeripheral(ADC_DMA, &ADC1->DR); dmaStreamSetMode (ADC_DMA, ADC_DMA_MODE); }
/* initialise ADC capture */ void adc_init(void) { adc_lld_init(); rccEnableADC1(true); /* set channels 4 and 5 for 28.5us sample time */ ADC1->SMPR2 = ADC_SMPR2_SMP_AN4(ADC_SAMPLE_28P5) | ADC_SMPR2_SMP_AN5(ADC_SAMPLE_28P5); /* capture a single sample at a time */ ADC1->SQR1 = 0; ADC1->SQR2 = 0; }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { bool_t b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); } #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_ADC2 if (&ADCD2 == adcp) { bool_t b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC2_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #2", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR); rccEnableADC2(FALSE); } #endif /* STM32_ADC_USE_ADC2 */ #if STM32_ADC_USE_ADC3 if (&ADCD3 == adcp) { bool_t b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC3_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #3", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR); rccEnableADC3(FALSE); } #endif /* STM32_ADC_USE_ADC3 */ /* ADC initial setup, starting the analog part here in order to reduce the latency when starting a conversion.*/ adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; adcp->adc->CR2 = ADC_CR2_ADON; } }
void Adc_t::Init() { rccEnableADC1(FALSE); // Enable digital clock SetupClk(ADC_CLK_DIVIDER); // Setup ADCCLK // Setup channels SetSequenceLength(ADC_SEQ_LEN); uint8_t SeqIndx = 1; // First sequence item is 1, not 0 for(uint8_t i=0; i < ADC_CHANNEL_CNT; i++) { SetChannelSampleTime(AdcChannels[i], ADC_SAMPLE_TIME); for(uint8_t j=0; j<ADC_SAMPLE_CNT; j++) SetSequenceItem(SeqIndx++, AdcChannels[i]); } // ==== 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) { /* If in stopped state then enables the ADC and DMA clocks.*/ if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { bool b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); osalDbgAssert(!b, "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); } #endif /* ADC setup, the calibration procedure has already been performed during initialization.*/ adcp->adc->CR1 = 0; adcp->adc->CR2 = 0; } }
/** * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start(ADCDriver *adcp) { if (adcp->config == NULL) adcp->config = &adc_lld_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) { bool_t b; b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_ADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); rccEnableADC1(FALSE); } #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_SDADC1 if (&SDADCD1 == adcp) { bool_t b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_SDADC1_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #2", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &SDADC1->JDATAR); rccEnableSDADC1(FALSE); PWR->CR |= PWR_CR_SDADC1EN; adcp->sdadc->CR2 = 0; adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) & ~SDADC_FORBIDDEN_CR1_FLAGS; adcp->sdadc->CR2 = SDADC_CR2_ADON; } #endif /* STM32_ADC_USE_SDADC1 */ #if STM32_ADC_USE_SDADC2 if (&SDADCD2 == adcp) { bool_t b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_SDADC2_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #3", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &SDADC2->JDATAR); rccEnableSDADC2(FALSE); PWR->CR |= PWR_CR_SDADC2EN; adcp->sdadc->CR2 = 0; adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) & ~SDADC_FORBIDDEN_CR1_FLAGS; adcp->sdadc->CR2 = SDADC_CR2_ADON; } #endif /* STM32_ADC_USE_SDADC2 */ #if STM32_ADC_USE_SDADC3 if (&SDADCD3 == adcp) { bool_t b = dmaStreamAllocate(adcp->dmastp, STM32_ADC_SDADC3_DMA_IRQ_PRIORITY, (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, (void *)adcp); chDbgAssert(!b, "adc_lld_start(), #4", "stream already allocated"); dmaStreamSetPeripheral(adcp->dmastp, &SDADC3->JDATAR); rccEnableSDADC3(FALSE); PWR->CR |= PWR_CR_SDADC3EN; adcp->sdadc->CR2 = 0; adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) & ~SDADC_FORBIDDEN_CR1_FLAGS; adcp->sdadc->CR2 = SDADC_CR2_ADON; } #endif /* STM32_ADC_USE_SDADC3 */ } adc_lld_reconfig(adcp); }