This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 0a23b0c14e arch/stm32{f0l0g0|f7|h5|h7|l4}/stm32_adc.c: add support for batch DMA transfer 0a23b0c14e is described below commit 0a23b0c14ed4dfd9ff173f3cb30f404ac38833a1 Author: raiden00pl <raide...@railab.me> AuthorDate: Sun Jun 15 08:45:48 2025 +0200 arch/stm32{f0l0g0|f7|h5|h7|l4}/stm32_adc.c: add support for batch DMA transfer Add an option that configure the number of regular group conversions that will trigger a DMA callback transfering data to the upper-half driver. By default this value is 1 and the driver behaves the same as before the change. Increasing this value allows to reduce the number of DMA interrupts and achieve higher sampling rates. DMA support for H5 and H7 is not complete so this change has no effect, but for consistency they have also been modified. The naming between ports has also been unified: - dmabuffer -> r_dmabuffer - nchannels -> rnchannels - chanlist -> r_chanlist - jchanlist -> j_chanlist Signed-off-by: raiden00pl <raide...@railab.me> --- arch/arm/src/stm32/Kconfig | 50 ++++++++++++++++++++ arch/arm/src/stm32/stm32_adc.c | 41 +++++++++++++++-- arch/arm/src/stm32f0l0g0/Kconfig | 10 ++++ arch/arm/src/stm32f0l0g0/stm32_adc.c | 17 +++++-- arch/arm/src/stm32f7/Kconfig | 30 ++++++++++++ arch/arm/src/stm32f7/stm32_adc.c | 27 ++++++++++- arch/arm/src/stm32h5/Kconfig | 43 +++++++++++++++++ arch/arm/src/stm32h5/stm32_adc.c | 41 +++++++++++------ arch/arm/src/stm32h7/Kconfig | 62 +++++++++++++++++++++++++ arch/arm/src/stm32h7/stm32_adc.c | 61 ++++++++++++++++-------- arch/arm/src/stm32l4/Kconfig | 30 ++++++++++++ arch/arm/src/stm32l4/stm32l4_adc.c | 89 +++++++++++++++++++++++------------- 12 files changed, 428 insertions(+), 73 deletions(-) diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index cdc7177f7d..1065c16d69 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 ee4cff346d..62e519e27e 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 fe2b96e8ad..e0bf1b64fb 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 9f03792aa9..603d211815 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 84d8ca5fbc..fbb52a5cd9 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 8068d52479..8b2198c751 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 b348a77668..758a12d095 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 17a6e93c06..a60c3bb19a 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 a0b9f60c26..b155642d89 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 44808044e8..ffe6b28401 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 29433a89d8..a48daa716b 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 5c2212d730..e92aac79c9 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