diff --git a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c index e1513a9b98..796ef485a9 100644 --- a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c +++ b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c @@ -79,6 +79,9 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA, this could help only if the DMA tries to access an unmapped address space or violates alignment rules.*/ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); + } else if ((flags & STM32_DMA_ISR_FEIF) != 0) { + /* FIFO error (overrun, underrun or FIFO level error) */ + _adc_isr_error_code(adcp, ADC_ERR_DMAFIFOERROR); } else { /* It is possible that the conversion group has already be reset by the @@ -197,6 +200,9 @@ void adc_lld_init(void) { ADCD1.adc = ADC1; ADCD1.dmastp = NULL; ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) | + #if (STM32_DMA_ADVANCED == TRUE) + STM32_DMA_CR_MBURST_INCR4 | + #endif STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | @@ -210,6 +216,9 @@ void adc_lld_init(void) { ADCD2.adc = ADC2; ADCD2.dmastp = NULL; ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) | + #if (STM32_DMA_ADVANCED == TRUE) + STM32_DMA_CR_MBURST_INCR4 | + #endif STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | @@ -223,6 +232,9 @@ void adc_lld_init(void) { ADCD3.adc = ADC3; ADCD3.dmastp = NULL; ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) | + #if (STM32_DMA_ADVANCED == TRUE) + STM32_DMA_CR_MBURST_INCR4 | + #endif STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | @@ -365,6 +377,9 @@ void adc_lld_start_conversion(ADCDriver *adcp) { dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * (uint32_t)adcp->depth); dmaStreamSetMode(adcp->dmastp, mode); +#if (STM32_DMA_ADVANCED == TRUE) + dmaStreamSetFIFO(adcp->dmastp, STM32_DMA_FCR_FEIE | STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_HALF); +#endif dmaStreamEnable(adcp->dmastp); /* ADC setup.*/ @@ -381,9 +396,12 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; /* Enforcing the mandatory bits in CR2.*/ - cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON; + if (grpp->circular) { + cr2 |= ADC_CR2_DDS; + } - /* The start method is different dependign if HW or SW triggered, the + /* The start method is different depending if HW or SW triggered, the start is performed using the method specified in the CR2 configuration.*/ if ((cr2 & ADC_CR2_SWSTART) != 0) { /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/ @@ -407,8 +425,9 @@ void adc_lld_stop_conversion(ADCDriver *adcp) { dmaStreamDisable(adcp->dmastp); adcp->adc->CR1 = 0; - /* Because ticket #822, preserving injected conversions.*/ - adcp->adc->CR2 &= ~(ADC_CR2_SWSTART); + if ((adcp->adc->CR2 & ADC_CR2_CONT) != 0U) { + adcp->adc->CR2 = 0U; + } adcp->adc->CR2 = ADC_CR2_ADON; } diff --git a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h index 9db5da9600..3d83617cad 100644 --- a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h +++ b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h @@ -319,8 +319,9 @@ typedef uint16_t adc_channels_num_t; */ typedef enum { ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ - ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */ - ADC_ERR_WATCHDOG = 2 /**< ADC watchdog condition. */ + ADC_ERR_DMAFIFOERROR = 1, /**< DMA FIFO error. */ + ADC_ERR_OVERFLOW = 2, /**< ADC overflow condition. */ + ADC_ERR_WATCHDOG = 3 /**< ADC watchdog condition. */ } adcerror_t; /*===========================================================================*/