diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index cdc7177f7df..1065c16d698 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -8594,6 +8594,16 @@ config STM32_ADC1_DMA_CFG ---help--- 0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode +config STM32_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32_ADC1 && STM32_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32_ADC1_ANIOC_TRIGGER int "ADC1 software trigger (ANIOC_TRIGGER) configuration" depends on STM32_ADC1 @@ -8627,6 +8637,16 @@ config STM32_ADC2_DMA_CFG ---help--- 0 - ADC2 DMA in One Shot Mode, 1 - ADC2 DMA in Circular Mode +config STM32_ADC2_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32_ADC2 && STM32_ADC2_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32_ADC2_ANIOC_TRIGGER int "ADC2 software trigger (ANIOC_TRIGGER) configuration" depends on STM32_ADC2 @@ -8660,6 +8680,16 @@ config STM32_ADC3_DMA_CFG ---help--- 0 - ADC3 DMA in One Shot Mode, 1 - ADC3 DMA in Circular Mode +config STM32_ADC3_DMA_BATCH + int "ADC3 DMA number of conversions" + depends on STM32_ADC3 && STM32_ADC3_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32_ADC3_ANIOC_TRIGGER int "ADC3 software trigger (ANIOC_TRIGGER) configuration" depends on STM32_ADC3 @@ -8687,6 +8717,16 @@ config STM32_ADC4_DMA_CFG ---help--- 0 - ADC4 DMA in One Shot Mode, 1 - ADC4 DMA in Circular Mode +config STM32_ADC4_DMA_BATCH + int "ADC4 DMA number of conversions" + depends on STM32_ADC4 && STM32_ADC4_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32_ADC4_ANIOC_TRIGGER int "ADC4 software trigger (ANIOC_TRIGGER) configuration" depends on STM32_ADC4 @@ -8714,6 +8754,16 @@ config STM32_ADC5_DMA_CFG ---help--- 0 - ADC5 DMA in One Shot Mode, 1 - ADC5 DMA in Circular Mode +config STM32_ADC5_DMA_BATCH + int "ADC5 DMA number of conversions" + depends on STM32_ADC5 && STM32_ADC5_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32_ADC1_INJECTED_CHAN int "ADC1 injected channels" depends on STM32_ADC1 diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index ee4cff346d5..62e519e27e9 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -420,6 +420,7 @@ struct stm32_dev_s uint8_t dmacfg; /* DMA channel configuration, only for ADC IPv2 */ # endif bool hasdma; /* True: This channel supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif #ifdef ADC_HAVE_SCAN bool scan; /* True: Scan mode */ @@ -456,7 +457,7 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t r_dmabuffer[CONFIG_STM32_ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ @@ -745,6 +746,12 @@ struct adccmn_data_s g_adc34_cmn = /* ADC1 state */ #ifdef CONFIG_STM32_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[CONFIG_STM32_ADC_MAX_SAMPLES * + CONFIG_STM32_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { #ifdef CONFIG_STM32_ADC_LL_OPS @@ -792,6 +799,8 @@ static struct stm32_dev_s g_adcpriv1 = .dmacfg = CONFIG_STM32_ADC1_DMA_CFG, # endif .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32_ADC1_DMA_BATCH, #endif #ifdef ADC_HAVE_SCAN .scan = CONFIG_STM32_ADC1_SCAN, @@ -808,6 +817,12 @@ static struct adc_dev_s g_adcdev1 = /* ADC2 state */ #ifdef CONFIG_STM32_ADC2 + +#ifdef ADC2_HAVE_DMA +static uint16_t g_adc2_dmabuffer[CONFIG_STM32_ADC_MAX_SAMPLES * + CONFIG_STM32_ADC2_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv2 = { #ifdef CONFIG_STM32_ADC_LL_OPS @@ -852,6 +867,8 @@ static struct stm32_dev_s g_adcpriv2 = .dmacfg = CONFIG_STM32_ADC2_DMA_CFG, # endif .hasdma = true, + .r_dmabuffer = g_adc2_dmabuffer, + .dmabatch = CONFIG_STM32_ADC2_DMA_BATCH, #endif #ifdef ADC_HAVE_SCAN .scan = CONFIG_STM32_ADC2_SCAN, @@ -868,6 +885,12 @@ static struct adc_dev_s g_adcdev2 = /* ADC3 state */ #ifdef CONFIG_STM32_ADC3 + +#ifdef ADC3_HAVE_DMA +static uint16_t g_adc3_dmabuffer[CONFIG_STM32_ADC_MAX_SAMPLES * + CONFIG_STM32_ADC3_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv3 = { #ifdef CONFIG_STM32_ADC_LL_OPS @@ -912,6 +935,8 @@ static struct stm32_dev_s g_adcpriv3 = .dmacfg = CONFIG_STM32_ADC3_DMA_CFG, # endif .hasdma = true, + .r_dmabuffer = g_adc3_dmabuffer, + .dmabatch = CONFIG_STM32_ADC3_DMA_BATCH, #endif #ifdef ADC_HAVE_SCAN .scan = CONFIG_STM32_ADC3_SCAN, @@ -928,6 +953,12 @@ static struct adc_dev_s g_adcdev3 = /* ADC4 state */ #ifdef CONFIG_STM32_ADC4 + +#ifdef ADC4_HAVE_DMA +static uint16_t g_adc4_dmabuffer[CONFIG_STM32_ADC_MAX_SAMPLES * + CONFIG_STM32_ADC4_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv4 = { #ifdef CONFIG_STM32_ADC_LL_OPS @@ -965,6 +996,8 @@ static struct stm32_dev_s g_adcpriv4 = .dmacfg = CONFIG_STM32_ADC4_DMA_CFG, # endif .hasdma = true, + .r_dmabuffer = g_adc4_dmabuffer, + .dmabatch = CONFIG_STM32_ADC4_DMA_BATCH #endif }; @@ -2254,10 +2287,10 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, { DEBUGASSERT(priv->cb->au_receive != NULL); - for (i = 0; i < priv->rnchannels; i++) + for (i = 0; i < priv->rnchannels * priv->dmabatch; i++) { priv->cb->au_receive(dev, priv->r_chanlist[priv->current], - priv->r_dmabuffer[priv->current]); + priv->r_dmabuffer[i]); priv->current++; if (priv->current >= priv->rnchannels) { @@ -2689,7 +2722,7 @@ static void adc_dma_start(struct adc_dev_s *dev) stm32_dmasetup(priv->dma, priv->base + STM32_ADC_DR_OFFSET, (uint32_t)priv->r_dmabuffer, - priv->rnchannels, + priv->rnchannels * priv->dmabatch, ADC_DMA_CONTROL_WORD); stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); diff --git a/arch/arm/src/stm32f0l0g0/Kconfig b/arch/arm/src/stm32f0l0g0/Kconfig index fe2b96e8ad5..e0bf1b64fb2 100644 --- a/arch/arm/src/stm32f0l0g0/Kconfig +++ b/arch/arm/src/stm32f0l0g0/Kconfig @@ -3419,6 +3419,16 @@ config STM32F0L0G0_ADC1_DMA_CFG ---help--- 0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode +config STM32F0L0G0_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32F0L0G0_ADC1 && STM32F0L0G0_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32F0L0G0_ADC1_EXTSEL bool "ADC1 external trigger for regular group" depends on STM32F0L0G0_ADC1 && !STM32F0L0G0_HAVE_ADC1_TIMER diff --git a/arch/arm/src/stm32f0l0g0/stm32_adc.c b/arch/arm/src/stm32f0l0g0/stm32_adc.c index 9f03792aa9b..603d2118157 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_adc.c +++ b/arch/arm/src/stm32f0l0g0/stm32_adc.c @@ -208,6 +208,7 @@ struct stm32_dev_s uint8_t dmacfg; /* DMA channel configuration, only for ADC IPv2 */ # endif bool hasdma; /* True: This channel supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif #ifdef CONFIG_STM32F0L0G0_ADC_CHANGE_SAMPLETIME /* Sample time selection. These bits must be written only when ADON=0. @@ -238,7 +239,7 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t r_dmabuffer[ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ @@ -399,6 +400,12 @@ static const struct stm32_adc_ops_s g_adc_llops = /* ADC1 state */ #ifdef CONFIG_STM32F0L0G0_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32F0L0G0_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { #ifdef CONFIG_STM32F0L0G0_ADC_LL_OPS @@ -431,6 +438,8 @@ static struct stm32_dev_s g_adcpriv1 = .dmacfg = CONFIG_STM32F0L0G0_ADC1_DMA_CFG, # endif .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32F0L0G0_ADC1_DMA_BATCH #endif }; @@ -1282,10 +1291,10 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, { DEBUGASSERT(priv->cb->au_receive != NULL); - for (i = 0; i < priv->rnchannels; i++) + for (i = 0; i < priv->rnchannels * priv->dmabatch; i++) { priv->cb->au_receive(dev, priv->r_chanlist[priv->current], - priv->r_dmabuffer[priv->current]); + priv->r_dmabuffer[i]); priv->current++; if (priv->current >= priv->rnchannels) { @@ -1535,7 +1544,7 @@ static void adc_dma_start(struct adc_dev_s *dev) stm32_dmasetup(priv->dma, priv->base + STM32_ADC_DR_OFFSET, (uint32_t)priv->r_dmabuffer, - priv->rnchannels, + priv->rnchannels * priv->dmabatch, ADC_DMA_CONTROL_WORD); stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 84d8ca5fbca..fbb52a5cd99 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -6376,6 +6376,16 @@ config STM32F7_ADC1_DMA_CFG ---help--- 0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode +config STM32F7_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32F7_ADC1 && STM32F7_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32F7_ADC1_ANIOC_TRIGGER int "ADC1 software trigger (ANIOC_TRIGGER) configuration" depends on STM32F7_ADC1 @@ -6408,6 +6418,16 @@ config STM32F7_ADC2_DMA_CFG ---help--- 0 - ADC2 DMA in One Shot Mode, 1 - ADC2 DMA in Circular Mode +config STM32F7_ADC2_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32F7_ADC2 && STM32F7_ADC2_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32F7_ADC2_ANIOC_TRIGGER int "ADC2 software trigger (ANIOC_TRIGGER) configuration" depends on STM32F7_ADC2 @@ -6440,6 +6460,16 @@ config STM32F7_ADC3_DMA_CFG ---help--- 0 - ADC3 DMA in One Shot Mode, 1 - ADC3 DMA in Circular Mode +config STM32F7_ADC3_DMA_BATCH + int "ADC3 DMA number of conversions" + depends on STM32F7_ADC3 && STM32F7_ADC3_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32F7_ADC3_ANIOC_TRIGGER int "ADC3 software trigger (ANIOC_TRIGGER) configuration" depends on STM32F7_ADC3 diff --git a/arch/arm/src/stm32f7/stm32_adc.c b/arch/arm/src/stm32f7/stm32_adc.c index 8068d524799..8b2198c751b 100644 --- a/arch/arm/src/stm32f7/stm32_adc.c +++ b/arch/arm/src/stm32f7/stm32_adc.c @@ -207,6 +207,7 @@ struct stm32_dev_s uint8_t dmachan; /* DMA channel needed by this ADC */ uint8_t dmacfg; /* DMA channel configuration, only for ADC IPv2 */ bool hasdma; /* True: This channel supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif bool scan; /* True: Scan mode */ #ifdef CONFIG_STM32F7_ADC_CHANGE_SAMPLETIME @@ -246,7 +247,7 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t r_dmabuffer[CONFIG_STM32F7_ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ @@ -454,6 +455,12 @@ struct adccmn_data_s g_adc123_cmn = /* ADC1 state */ #ifdef CONFIG_STM32F7_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[CONFIG_STM32F7_ADC_MAX_SAMPLES * + CONFIG_STM32F7_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { #ifdef CONFIG_STM32F7_ADC_LL_OPS @@ -485,6 +492,8 @@ static struct stm32_dev_s g_adcpriv1 = .dmachan = ADC1_DMA_CHAN, .dmacfg = CONFIG_STM32F7_ADC1_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32F7_ADC1_DMA_BATCH, #endif .scan = CONFIG_STM32F7_ADC1_SCAN, #ifdef CONFIG_PM @@ -505,6 +514,12 @@ static struct adc_dev_s g_adcdev1 = /* ADC2 state */ #ifdef CONFIG_STM32F7_ADC2 + +#ifdef ADC2_HAVE_DMA +static uint16_t g_adc2_dmabuffer[CONFIG_STM32F7_ADC_MAX_SAMPLES * + CONFIG_STM32F7_ADC2_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv2 = { #ifdef CONFIG_STM32F7_ADC_LL_OPS @@ -536,6 +551,8 @@ static struct stm32_dev_s g_adcpriv2 = .dmachan = ADC2_DMA_CHAN, .dmacfg = CONFIG_STM32F7_ADC2_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc2_dmabuffer, + .dmabatch = CONFIG_STM32F7_ADC2_DMA_BATCH, #endif .scan = CONFIG_STM32F7_ADC2_SCAN, #ifdef CONFIG_PM @@ -556,6 +573,12 @@ static struct adc_dev_s g_adcdev2 = /* ADC3 state */ #ifdef CONFIG_STM32F7_ADC3 + +#ifdef ADC3_HAVE_DMA +static uint16_t g_adc3_dmabuffer[CONFIG_STM32F7_ADC_MAX_SAMPLES * + CONFIG_STM32F7_ADC3_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv3 = { #ifdef CONFIG_STM32F7_ADC_LL_OPS @@ -587,6 +610,8 @@ static struct stm32_dev_s g_adcpriv3 = .dmachan = ADC3_DMA_CHAN, .dmacfg = CONFIG_STM32F7_ADC3_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc3_dmabuffer, + .dmabatch = CONFIG_STM32F7_ADC3_DMA_BATCH, #endif .scan = CONFIG_STM32F7_ADC3_SCAN, #ifdef CONFIG_PM diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig index b348a776689..758a12d0958 100644 --- a/arch/arm/src/stm32h5/Kconfig +++ b/arch/arm/src/stm32h5/Kconfig @@ -4550,6 +4550,49 @@ endif # STM32H5_SERIALDRIVER endmenu # U[S]ART Configuration +menu "ADC Configuration" + depends on STM32H5_ADC + +config STM32H5_ADC1_DMA + bool "ADC1 DMA (not supported yet)" + depends on STM32H5_ADC1 && EXPERIMENTAL + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32H5_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32H5_ADC1 && STM32H5_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + +config STM32H5_ADC2_DMA + bool "ADC2 DMA (not supported yet)" + depends on STM32H5_ADC2 && EXPERIMENTAL + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32H5_ADC2_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32H5_ADC2 && STM32H5_ADC2_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + +endmenu + menu "Ethernet MAC Configuration" depends on STM32H5_ETHMAC diff --git a/arch/arm/src/stm32h5/stm32_adc.c b/arch/arm/src/stm32h5/stm32_adc.c index 17a6e93c06e..a60c3bb19a0 100644 --- a/arch/arm/src/stm32h5/stm32_adc.c +++ b/arch/arm/src/stm32h5/stm32_adc.c @@ -110,13 +110,14 @@ struct stm32_dev_s { const struct adc_callback_s *cb; uint8_t irq; /* Interrupt generated by this ADC block */ - uint8_t nchannels; /* Number of channels */ + uint8_t rnchannels; /* Number of channels */ uint8_t cchannels; /* Number of configured channels */ uint8_t intf; /* ADC interface number */ uint8_t current; /* Current ADC channel being converted */ #ifdef ADC_HAVE_DMA uint8_t dmachan; /* DMA channel needed by this ADC */ bool hasdma; /* True: This ADC supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif #ifdef ADC_HAVE_TIMER uint8_t trigger; /* Timer trigger channel: 0=CC1, 1=CC2, 2=CC3, @@ -147,7 +148,7 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t dmabuffer[ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ @@ -229,6 +230,12 @@ static const struct adc_ops_s g_adcops = /* ADC1 state */ #ifdef CONFIG_STM32H5_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32H5_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { .irq = STM32_IRQ_ADC1, @@ -246,6 +253,12 @@ static struct stm32_dev_s g_adcpriv1 = .pclck = ADC1_TIMER_PCLK_FREQUENCY, .freq = CONFIG_STM32H5_ADC1_SAMPLE_FREQUENCY, #endif +#ifdef ADC1_HAVE_DMA + .dmachan = ADC1_DMA_CHAN, + .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32H5_ADC1_DMA_BATCH +#endif }; static struct adc_dev_s g_adcdev1 = @@ -902,10 +915,10 @@ static int adc_setup(struct adc_dev_s *dev) priv->dma = stm32_dmachannel(priv->dmachan); stm32_dmasetup(priv->dma, - priv->base + STM32_ADC_DR_OFFSET, - (uint32_t)priv->dmabuffer, - priv->nchannels, - ADC_DMA_CONTROL_WORD); + priv->base + STM32_ADC_DR_OFFSET, + (uint32_t)priv->r_dmabuffer, + priv->rnchannels * priv->dmabatch, + ADC_DMA_CONTROL_WORD); stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); } @@ -966,7 +979,7 @@ static uint32_t adc_sqrbits(struct stm32_dev_s *priv, int first, int i; for (i = first - 1; - i < priv->nchannels && i < last; + i < priv->rnchannels && i < last; i++, offset += ADC_SQ_OFFSET) { bits |= (uint32_t)priv->chanlist[i] << offset; @@ -986,7 +999,7 @@ static bool adc_internal(struct stm32_dev_s * priv, uint32_t *adc_ccr) if (priv->intf == 1) { - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels; i++) { switch (priv->chanlist[i]) { @@ -1004,7 +1017,7 @@ static bool adc_internal(struct stm32_dev_s * priv, uint32_t *adc_ccr) } else if (priv->intf == 2) { - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels; i++) { switch (priv->chanlist[i]) { @@ -1051,7 +1064,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) if (ch == 0) { priv->current = 0; - priv->nchannels = priv->cchannels; + priv->rnchannels = priv->cchannels; } else { @@ -1063,10 +1076,10 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) } priv->current = i; - priv->nchannels = 1; + priv->rnchannels = 1; } - DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES); + DEBUGASSERT(priv->rnchannels <= ADC_MAX_SAMPLES); bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST, ADC_SQR4_SQ_OFFSET); @@ -1080,7 +1093,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) ADC_SQR2_SQ_OFFSET); adc_modifyreg(priv, STM32_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits); - bits = ((uint32_t)priv->nchannels - 1) << ADC_SQR1_L_SHIFT | + bits = ((uint32_t)priv->rnchannels - 1) << ADC_SQR1_L_SHIFT | adc_sqrbits(priv, ADC_SQR1_FIRST, ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET); adc_modifyreg(priv, STM32_ADC_SQR1_OFFSET, ~ADC_SQR1_RESERVED, bits); @@ -1300,7 +1313,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) priv->current++; - if (priv->current >= priv->nchannels) + if (priv->current >= priv->rnchannels) { /* Restart the conversion sequence from the beginning */ diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig index a0b9f60c26e..b155642d891 100644 --- a/arch/arm/src/stm32h7/Kconfig +++ b/arch/arm/src/stm32h7/Kconfig @@ -1827,6 +1827,68 @@ config STM32H7_PM_SERIAL_ACTIVITY endif # PM endmenu # U[S]ART Configuration +menu "ADC Configuration" + depends on STM32H7_ADC + +config STM32H7_ADC1_DMA + bool "ADC1 DMA (not supported yet)" + depends on STM32H7_ADC1 && EXPERIMENTAL + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32H7_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32H7_ADC1 && STM32H7_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + +config STM32H7_ADC2_DMA + bool "ADC2 DMA (not supported yet)" + depends on STM32H7_ADC2 && EXPERIMENTAL + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32H7_ADC2_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32H7_ADC2 && STM32H7_ADC2_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + +config STM32H7_ADC3_DMA + bool "ADC3 DMA (not supported yet)" + depends on STM32H7_ADC3 && EXPERIMENTAL + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32H7_ADC3_DMA_BATCH + int "ADC3 DMA number of conversions" + depends on STM32H7_ADC3 && STM32H7_ADC3_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + +endmenu + menu "SD/MMC Configuration" depends on STM32H7_SDMMC diff --git a/arch/arm/src/stm32h7/stm32_adc.c b/arch/arm/src/stm32h7/stm32_adc.c index 44808044e82..ffe6b284012 100644 --- a/arch/arm/src/stm32h7/stm32_adc.c +++ b/arch/arm/src/stm32h7/stm32_adc.c @@ -159,13 +159,14 @@ struct stm32_dev_s { const struct adc_callback_s *cb; uint8_t irq; /* Interrupt generated by this ADC block */ - uint8_t nchannels; /* Number of channels */ + uint8_t rnchannels; /* Number of channels */ uint8_t cchannels; /* Number of configured channels */ uint8_t intf; /* ADC interface number */ uint8_t current; /* Current ADC channel being converted */ #ifdef ADC_HAVE_DMA uint8_t dmachan; /* DMA channel needed by this ADC */ bool hasdma; /* True: This ADC supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif #ifdef ADC_HAVE_DFSDM bool hasdfsdm; /* True: This ADC routes its output to DFSDM */ @@ -199,7 +200,7 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t dmabuffer[ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ @@ -303,6 +304,12 @@ static const struct adc_ops_s g_adcops = /* ADC1 state */ #ifdef CONFIG_STM32H7_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32H7_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { .irq = STM32_IRQ_ADC12, @@ -323,6 +330,8 @@ static struct stm32_dev_s g_adcpriv1 = #ifdef ADC1_HAVE_DMA .dmachan = ADC1_DMA_CHAN, .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32H7_ADC1_DMA_BATCH, #endif #ifdef ADC1_HAVE_DFSDM .hasdfsdm = true, @@ -345,6 +354,12 @@ static struct adc_dev_s g_adcdev1 = /* ADC2 state */ #ifdef CONFIG_STM32H7_ADC2 + +#ifdef ADC2_HAVE_DMA +static uint16_t g_adc2_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32H7_ADC2_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv2 = { .irq = STM32_IRQ_ADC12, @@ -365,6 +380,8 @@ static struct stm32_dev_s g_adcpriv2 = #ifdef ADC2_HAVE_DMA .dmachan = ADC2_DMA_CHAN, .hasdma = true, + .r_dmabuffer = g_adc2_dmabuffer, + .dmabatch = CONFIG_STM32H7_ADC2_DMA_BATCH, #endif #ifdef ADC2_HAVE_DFSDM .hasdfsdm = true, @@ -387,6 +404,12 @@ static struct adc_dev_s g_adcdev2 = /* ADC3 state */ #ifdef CONFIG_STM32H7_ADC3 + +#ifdef ADC3_HAVE_DMA +static uint16_t g_adc3_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32H7_ADC3_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv3 = { .irq = STM32_IRQ_ADC3, @@ -407,6 +430,8 @@ static struct stm32_dev_s g_adcpriv3 = #ifdef ADC3_HAVE_DMA .dmachan = ADC3_DMA_CHAN, .hasdma = true, + .r_dmabuffer = g_adc3_dmabuffer, + .dmabatch = CONFIG_STM32H7_ADC3_DMA_BATCH, #endif #ifdef ADC3_HAVE_DFSDM .hasdfsdm = true, @@ -1468,10 +1493,10 @@ static int adc_setup(struct adc_dev_s *dev) priv->dma = stm32_dmachannel(priv->dmachan); stm32_dmasetup(priv->dma, - priv->base + STM32_ADC_DR_OFFSET, - (uint32_t)priv->dmabuffer, - priv->nchannels, - ADC_DMA_CONTROL_WORD); + priv->base + STM32_ADC_DR_OFFSET, + (uint32_t)priv->r_dmabuffer, + priv->rnchannels * priv->dmabatch, + ADC_DMA_CONTROL_WORD); stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); } @@ -1755,7 +1780,7 @@ static uint32_t adc_sqrbits(struct stm32_dev_s *priv, int first, int i; for (i = first - 1; - i < priv->nchannels && i < last; + i < priv->rnchannels && i < last; i++, offset += ADC_SQ_OFFSET) { bits |= (uint32_t)priv->chanlist[i] << offset; @@ -1775,7 +1800,7 @@ static bool adc_internal(struct stm32_dev_s * priv, uint32_t *adc_ccr) if (priv->intf == 3) { - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels; i++) { if (priv->chanlist[i] > ADC_EXTERNAL_CHAN_MAX) { @@ -1854,7 +1879,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) if (ch == 0) { priv->current = 0; - priv->nchannels = priv->cchannels; + priv->rnchannels = priv->cchannels; } else { @@ -1866,10 +1891,10 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) } priv->current = i; - priv->nchannels = 1; + priv->rnchannels = 1; } - DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES); + DEBUGASSERT(priv->rnchannels <= ADC_MAX_SAMPLES); bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST, ADC_SQR4_SQ_OFFSET); @@ -1883,7 +1908,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) ADC_SQR2_SQ_OFFSET); adc_modifyreg(priv, STM32_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits); - bits = ((uint32_t)priv->nchannels - 1) << ADC_SQR1_L_SHIFT | + bits = ((uint32_t)priv->rnchannels - 1) << ADC_SQR1_L_SHIFT | adc_sqrbits(priv, ADC_SQR1_FIRST, ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET); adc_modifyreg(priv, STM32_ADC_SQR1_OFFSET, ~ADC_SQR1_RESERVED, bits); @@ -2122,7 +2147,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) priv->current++; - if (priv->current >= priv->nchannels) + if (priv->current >= priv->rnchannels) { /* Restart the conversion sequence from the beginning */ @@ -2239,12 +2264,12 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, { DEBUGASSERT(priv->cb->au_receive != NULL); - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels * priv->dmabatch; i++) { - priv->cb->au_receive(dev, priv->chanlist[priv->current], - priv->dmabuffer[priv->current]); + priv->cb->au_receive(dev, priv->r_chanlist[priv->current], + priv->r_dmabuffer[i]); priv->current++; - if (priv->current >= priv->nchannels) + if (priv->current >= priv->rnchannels) { /* Restart the conversion sequence from the beginning */ @@ -2278,7 +2303,7 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, * chanlist[15]-> ADC_SQR1_SQ16 * * up to - * chanlist[nchannels] + * chanlist[rnchannels] * * Input Parameters: * intf - Could be {1,2,3} for ADC1, ADC2, or ADC3 diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig index 29433a89d8a..a48daa716b9 100644 --- a/arch/arm/src/stm32l4/Kconfig +++ b/arch/arm/src/stm32l4/Kconfig @@ -5273,6 +5273,16 @@ config STM32L4_ADC1_DMA_CFG ---help--- 0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode +config STM32L4_ADC1_DMA_BATCH + int "ADC1 DMA number of conversions" + depends on STM32L4_ADC1 && STM32L4_ADC1_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32L4_ADC2_DMA bool "ADC2 DMA" depends on STM32L4_ADC2 @@ -5290,6 +5300,16 @@ config STM32L4_ADC2_DMA_CFG ---help--- 0 - ADC2 DMA in One Shot Mode, 1 - ADC2 DMA in Circular Mode +config STM32L4_ADC2_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32L4_ADC2 && STM32L4_ADC2_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32L4_ADC3_DMA bool "ADC3 DMA" depends on STM32L4_ADC3 @@ -5307,6 +5327,16 @@ config STM32L4_ADC3_DMA_CFG ---help--- 0 - ADC3 DMA in One Shot Mode, 1 - ADC3 DMA in Circular Mode +config STM32L4_ADC3_DMA_BATCH + int "ADC2 DMA number of conversions" + depends on STM32L4_ADC3 && STM32L4_ADC3_DMA + default 1 + ---help--- + This option allows you to select the number of regular group conversions + that will trigger a DMA callback transerring data to the upper-half driver. + By default, this value is 1, which means that data is transferred after + each group conversion. + config STM32L4_ADC1_INJ_CHAN int "ADC1 configured injected channels" depends on STM32L4_ADC1 diff --git a/arch/arm/src/stm32l4/stm32l4_adc.c b/arch/arm/src/stm32l4/stm32l4_adc.c index 5c2212d730f..e92aac79c99 100644 --- a/arch/arm/src/stm32l4/stm32l4_adc.c +++ b/arch/arm/src/stm32l4/stm32l4_adc.c @@ -182,7 +182,7 @@ struct stm32_dev_s const struct adc_callback_s *cb; uint8_t irq; /* Interrupt generated by this ADC block */ #endif - uint8_t nchannels; /* Number of regular channels */ + uint8_t rnchannels; /* Number of regular channels */ uint8_t cchannels; /* Number of configured regular channels */ #ifdef ADC_HAVE_INJECTED uint8_t cjchannels; /* Number of configured injected channels */ @@ -196,6 +196,7 @@ struct stm32_dev_s uint8_t dmachan; /* DMA channel needed by this ADC */ uint8_t dmacfg; /* DMA channel configuration */ bool hasdma; /* True: This ADC supports DMA */ + uint16_t dmabatch; /* Number of conversions for DMA batch */ #endif #ifdef ADC_HAVE_DFSDM bool hasdfsdm; /* True: This ADC routes its output to DFSDM */ @@ -227,17 +228,17 @@ struct stm32_dev_s /* DMA transfer buffer */ - uint16_t dmabuffer[ADC_MAX_SAMPLES]; + uint16_t *r_dmabuffer; #endif /* List of selected ADC channels to sample */ - uint8_t chanlist[ADC_MAX_SAMPLES]; + uint8_t r_chanlist[ADC_MAX_SAMPLES]; #ifdef ADC_HAVE_INJECTED /* List of selected ADC injected channels to sample */ - uint8_t jchanlist[ADC_INJ_MAX_SAMPLES]; + uint8_t j_chanlist[ADC_INJ_MAX_SAMPLES]; #endif }; @@ -426,6 +427,12 @@ static const struct stm32_adc_ops_s g_adc_llops = /* ADC1 state */ #ifdef CONFIG_STM32L4_ADC1 + +#ifdef ADC1_HAVE_DMA +static uint16_t g_adc1_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32L4_ADC1_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv1 = { #ifdef CONFIG_STM32L4_ADC_LL_OPS @@ -456,6 +463,8 @@ static struct stm32_dev_s g_adcpriv1 = .dmachan = ADC1_DMA_CHAN, .dmacfg = CONFIG_STM32L4_ADC1_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc1_dmabuffer, + .dmabatch = CONFIG_STM32L4_ADC1_DMA_BATCH #endif #ifdef ADC1_HAVE_DFSDM .hasdfsdm = true, @@ -478,6 +487,12 @@ static struct adc_dev_s g_adcdev1 = /* ADC2 state */ #ifdef CONFIG_STM32L4_ADC2 + +#ifdef ADC2_HAVE_DMA +static uint16_t g_adc2_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32L4_ADC2_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv2 = { #ifdef CONFIG_STM32L4_ADC_LL_OPS @@ -508,6 +523,8 @@ static struct stm32_dev_s g_adcpriv2 = .dmachan = ADC2_DMA_CHAN, .dmacfg = CONFIG_STM32L4_ADC2_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc2_dmabuffer, + .dmabatch = CONFIG_STM32L4_ADC2_DMA_BATCH #endif #ifdef ADC2_HAVE_DFSDM .hasdfsdm = true, @@ -530,6 +547,12 @@ static struct adc_dev_s g_adcdev2 = /* ADC3 state */ #ifdef CONFIG_STM32L4_ADC3 + +#ifdef ADC3_HAVE_DMA +static uint16_t g_adc3_dmabuffer[ADC_MAX_SAMPLES * + CONFIG_STM32L4_ADC3_DMA_BATCH]; +#endif + static struct stm32_dev_s g_adcpriv3 = { #ifdef CONFIG_STM32L4_ADC_LL_OPS @@ -560,6 +583,8 @@ static struct stm32_dev_s g_adcpriv3 = .dmachan = ADC3_DMA_CHAN, .dmacfg = CONFIG_STM32L4_ADC3_DMA_CFG, .hasdma = true, + .r_dmabuffer = g_adc3_dmabuffer, + .dmabatch = CONFIG_STM32L4_ADC3_DMA_BATCH #endif #ifdef ADC3_HAVE_DFSDM .hasdfsdm = true, @@ -1754,10 +1779,10 @@ static uint32_t adc_sqrbits(struct stm32_dev_s *priv, int i; for (i = first - 1; - i < priv->nchannels && i < last; + i < priv->rnchannels && i < last; i++, offset += ADC_SQ_OFFSET) { - bits |= (uint32_t)priv->chanlist[i] << offset; + bits |= (uint32_t)priv->r_chanlist[i] << offset; } return bits; @@ -1774,13 +1799,13 @@ static bool adc_internal(struct stm32_dev_s * priv, uint32_t *adc_ccr) if (priv->intf == 1 || priv->intf == 3) { - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels; i++) { - if (priv->chanlist[i] < ADC_EXTERNAL_CHAN_MIN || \ - priv->chanlist[i] > ADC_EXTERNAL_CHAN_MAX) + if (priv->r_chanlist[i] < ADC_EXTERNAL_CHAN_MIN || \ + priv->r_chanlist[i] > ADC_EXTERNAL_CHAN_MAX) { internal = true; - switch (priv->chanlist[i]) + switch (priv->r_chanlist[i]) { case 0: if (priv->intf == 1) @@ -1867,11 +1892,11 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) if (ch == 0) { priv->current = 0; - priv->nchannels = priv->cchannels; + priv->rnchannels = priv->cchannels; } else { - for (i = 0; i < priv->cchannels && priv->chanlist[i] != ch - 1; i++); + for (i = 0; i < priv->cchannels && priv->r_chanlist[i] != ch - 1; i++); if (i >= priv->cchannels) { @@ -1879,10 +1904,10 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) } priv->current = i; - priv->nchannels = 1; + priv->rnchannels = 1; } - DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES); + DEBUGASSERT(priv->rnchannels <= ADC_MAX_SAMPLES); bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST, ADC_SQR4_SQ_OFFSET); @@ -1899,7 +1924,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) adc_modifyreg(priv, STM32L4_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits); - bits = ((uint32_t)priv->nchannels - 1) << ADC_SQR1_L_SHIFT | + bits = ((uint32_t)priv->rnchannels - 1) << ADC_SQR1_L_SHIFT | adc_sqrbits(priv, ADC_SQR1_FIRST, ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET); adc_modifyreg(priv, @@ -1914,7 +1939,7 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch) { for (i = 0; i < priv->cchannels; i++) { - adc_setoffset(priv, priv->chanlist[i], i, 0x800); + adc_setoffset(priv, priv->r_chanlist[i], i, 0x800); } } else @@ -1949,7 +1974,7 @@ static int adc_inj_set_ch(struct adc_dev_s *dev, uint8_t ch) for (i = 0 ; i < priv->cjchannels; i += 1) { - setbits |= priv->jchanlist[i] << (ADC_JSQR_JSQ1_SHIFT + + setbits |= priv->j_chanlist[i] << (ADC_JSQR_JSQ1_SHIFT + ADC_JSQR_JSQ_SHIFT * i); } @@ -2163,7 +2188,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) */ DEBUGASSERT(priv->cb->au_receive != NULL); - priv->cb->au_receive(dev, priv->chanlist[priv->current], value); + priv->cb->au_receive(dev, priv->r_chanlist[priv->current], value); } /* Set the channel number of the next channel that will complete @@ -2172,7 +2197,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) priv->current++; - if (priv->current >= priv->nchannels) + if (priv->current >= priv->rnchannels) { /* Restart the conversion sequence from the beginning */ @@ -2193,7 +2218,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) if (priv->cb != NULL) { DEBUGASSERT(priv->cb->au_receive != NULL); - priv->cb->au_receive(dev, priv->jchanlist[i], value); + priv->cb->au_receive(dev, priv->j_chanlist[i], value); } } } @@ -2352,8 +2377,8 @@ static void adc_dma_start(struct adc_dev_s *dev) #ifndef CONFIG_STM32L4_ADC_NOIRQ stm32l4_dmasetup(priv->dma, priv->base + STM32L4_ADC_DR_OFFSET, - (uint32_t)priv->dmabuffer, - priv->nchannels, + (uint32_t)priv->r_dmabuffer, + priv->rnchannels * priv->dmabatch, ADC_DMA_CONTROL_WORD); stm32l4_dmastart(priv->dma, adc_dmaconvcallback, dev, false); @@ -2391,12 +2416,12 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, { DEBUGASSERT(priv->cb->au_receive != NULL); - for (i = 0; i < priv->nchannels; i++) + for (i = 0; i < priv->rnchannels * priv->dmabatch; i++) { - priv->cb->au_receive(dev, priv->chanlist[priv->current], - priv->dmabuffer[priv->current]); + priv->cb->au_receive(dev, priv->r_chanlist[priv->current], + priv->r_dmabuffer[i]); priv->current++; - if (priv->current >= priv->nchannels) + if (priv->current >= priv->rnchannels) { /* Restart the conversion sequence from the beginning */ @@ -2723,7 +2748,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, uint8_t crchannels = 0; uint8_t cjchannels = 0; #ifdef ADC_HAVE_INJECTED - uint8_t *jchanlist = NULL; + uint8_t *j_chanlist = NULL; #endif switch (intf) @@ -2738,7 +2763,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, # ifdef ADC_HAVE_INJECTED if (cjchannels > 0) { - jchanlist = (uint8_t *)chanlist + crchannels; + j_chanlist = (uint8_t *)chanlist + crchannels; } # endif @@ -2757,7 +2782,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, # ifdef ADC_HAVE_INJECTED if (cjchannels > 0) { - jchanlist = (uint8_t *)chanlist + crchannels; + j_chanlist = (uint8_t *)chanlist + crchannels; } # endif @@ -2776,7 +2801,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, # ifdef ADC_HAVE_INJECTED if (cjchannels > 0) { - jchanlist = (uint8_t *)chanlist + crchannels; + j_chanlist = (uint8_t *)chanlist + crchannels; } # endif @@ -2801,7 +2826,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, } priv->cchannels = crchannels; - memcpy(priv->chanlist, chanlist, crchannels); + memcpy(priv->r_chanlist, chanlist, crchannels); #ifdef ADC_HAVE_INJECTED /* Configure injected channels */ @@ -2809,7 +2834,7 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, DEBUGASSERT(cjchannels <= ADC_INJ_MAX_SAMPLES); priv->cjchannels = cjchannels; - memcpy(priv->jchanlist, jchanlist, cjchannels); + memcpy(priv->j_chanlist, jchanlist, cjchannels); #endif