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
 


Reply via email to