@@ -145,7 +145,8 @@ struct stm32_dev_s
145145
146146#ifdef ADC_HAVE_DMA
147147 DMA_HANDLE dma ; /* Allocated DMA channel */
148- uint16_t * r_dmabuffer ; /* DMA transfer buffer */
148+ uint32_t * r_dmabuffer ; /* DMA transfer buffer */
149+ uint8_t * r_chanbuffer ; /* DMA channel buffer */
149150#endif
150151
151152 bool wdg1_enable ; /* True - Analog Watchdog 1 Enabled */
@@ -218,6 +219,7 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t status,
218219 void * arg );
219220static void adc_dmacfg (struct stm32_dev_s * priv ,
220221 struct stm32_gpdma_cfg_s * cfg );
222+ static void adc_dma_init_chanbuf (struct stm32_dev_s * priv );
221223static void adc_reset_dma (struct adc_dev_s * dev );
222224#endif
223225
@@ -267,17 +269,20 @@ static const struct adc_ops_s g_adcops =
267269 */
268270
269271#ifdef ADC1_HAVE_DMA
272+ # define ADC1_CHAN_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
273+ CONFIG_STM32H5_ADC1_DMA_BATCH)
274+
270275# ifdef CONFIG_STM32H5_ADC1_DMA_CFG
271- # define ADC1_DMA_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
272- CONFIG_STM32H5_ADC1_DMA_BATCH * 2)
276+ # define ADC1_DMA_BUFFER_SIZE (ADC1_CHAN_BUFFER_SIZE * 2)
273277# else
274- # define ADC1_DMA_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
275- CONFIG_STM32H5_ADC1_DMA_BATCH)
278+ # define ADC1_DMA_BUFFER_SIZE (ADC1_CHAN_BUFFER_SIZE)
276279# endif
277280
278- static uint16_t g_adc1_dmabuffer [ ADC1_DMA_BUFFER_SIZE ]
281+ static uint8_t g_adc1_chanbuffer [ ADC1_CHAN_BUFFER_SIZE ]
279282__attribute__((aligned (32 )));
280283
284+ static uint32_t g_adc1_dmabuffer [ADC1_DMA_BUFFER_SIZE ]
285+ __attribute__((aligned (32 )));
281286#endif
282287
283288static struct stm32_dev_s g_adcpriv1 =
@@ -318,16 +323,17 @@ static struct stm32_dev_s g_adcpriv1 =
318323#endif
319324
320325#ifdef ADC1_HAVE_DMA
321- .hasdma = true,
322- .r_dmabuffer = g_adc1_dmabuffer ,
323- .dmabatch = CONFIG_STM32H5_ADC1_DMA_BATCH ,
326+ .hasdma = true,
327+ .r_chanbuffer = g_adc1_chanbuffer ,
328+ .r_dmabuffer = g_adc1_dmabuffer ,
329+ .dmabatch = CONFIG_STM32H5_ADC1_DMA_BATCH ,
324330# ifdef CONFIG_STM32H5_ADC1_DMA_CFG
325- .circular = true,
331+ .circular = true,
326332# else
327- .circular = false,
333+ .circular = false,
328334# endif
329335#else
330- .hasdma = false,
336+ .hasdma = false,
331337#endif
332338
333339#ifdef ADC1_HAVE_OVERSAMPLE
@@ -343,7 +349,7 @@ static struct stm32_dev_s g_adcpriv1 =
343349 .oversample = false,
344350#endif
345351
346- #ifdef ADC1_HAVE_WDG1
352+ #ifdef CONFIG_STM32H5_ADC1_WDG1
347353 .wdg1_enable = true,
348354 .wdg1_flt = CONFIG_STM32H5_ADC1_WDG1_FLT ,
349355 .wdg1_low_thresh = CONFIG_STM32H5_ADC1_WDG1_LOWTHRESH ,
@@ -372,15 +378,19 @@ static struct adc_dev_s g_adcdev1 =
372378#ifdef CONFIG_STM32H5_ADC2
373379
374380#ifdef ADC2_HAVE_DMA
381+ # define ADC2_CHAN_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
382+ CONFIG_STM32H5_ADC2_DMA_BATCH)
383+
375384# ifdef CONFIG_STM32H5_ADC2_DMA_CFG
376- # define ADC2_DMA_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
377- CONFIG_STM32H5_ADC2_DMA_BATCH * 2)
385+ # define ADC2_DMA_BUFFER_SIZE (ADC2_CHAN_BUFFER_SIZE * 2)
378386# else
379- # define ADC2_DMA_BUFFER_SIZE (CONFIG_STM32H5_ADC_MAX_SAMPLES *\
380- CONFIG_STM32H5_ADC2_DMA_BATCH)
387+ # define ADC2_DMA_BUFFER_SIZE (ADC2_CHAN_BUFFER_SIZE)
381388# endif
382389
383- static uint16_t g_adc2_dmabuffer [ADC2_DMA_BUFFER_SIZE ]
390+ static uint8_t g_adc2_chanbuffer [ADC2_CHAN_BUFFER_SIZE ]
391+ __attribute__((aligned (32 )));
392+
393+ static uint32_t g_adc2_dmabuffer [ADC2_DMA_BUFFER_SIZE ]
384394__attribute__((aligned (32 )));
385395#endif
386396
@@ -422,16 +432,17 @@ static struct stm32_dev_s g_adcpriv2 =
422432#endif
423433
424434#ifdef ADC2_HAVE_DMA
425- .hasdma = true,
426- .r_dmabuffer = g_adc2_dmabuffer ,
427- .dmabatch = CONFIG_STM32H5_ADC2_DMA_BATCH ,
435+ .hasdma = true,
436+ .r_chanbuffer = g_adc2_chanbuffer ,
437+ .r_dmabuffer = g_adc2_dmabuffer ,
438+ .dmabatch = CONFIG_STM32H5_ADC2_DMA_BATCH ,
428439# ifdef CONFIG_STM32H5_ADC2_DMA_CFG
429- .circular = true,
440+ .circular = true,
430441# else
431- .circular = false,
442+ .circular = false,
432443# endif
433444#else
434- .hasdma = false,
445+ .hasdma = false,
435446#endif
436447
437448#ifdef ADC2_HAVE_OVERSAMPLE
@@ -447,7 +458,7 @@ static struct stm32_dev_s g_adcpriv2 =
447458 .oversample = false,
448459#endif
449460
450- #ifdef ADC2_HAVE_WDG1
461+ #ifdef CONFIG_STM32H5_ADC2_WDG1
451462 .wdg1_enable = true,
452463 .wdg1_flt = CONFIG_STM32H5_ADC2_WDG1_FLT ,
453464 .wdg1_low_thresh = CONFIG_STM32H5_ADC2_WDG1_LOWTHRESH ,
@@ -1180,9 +1191,8 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t status, void *arg)
11801191 struct adc_dev_s * dev = (struct adc_dev_s * )arg ;
11811192 struct stm32_dev_s * priv = (struct stm32_dev_s * )dev -> ad_priv ;
11821193
1183- uint16_t conversion_count ;
1184- uint16_t buffer_offset ;
1185- int i ;
1194+ uint32_t conversion_count ;
1195+ uint32_t buffer_offset ;
11861196
11871197 /* About Circular Mode
11881198 * The size of r_dmabuffer and transfer size is doubled
@@ -1195,7 +1205,7 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t status, void *arg)
11951205
11961206 if (priv -> cb != NULL )
11971207 {
1198- DEBUGASSERT (priv -> cb -> au_receive != NULL );
1208+ DEBUGASSERT (priv -> cb -> au_receive_batch != NULL );
11991209
12001210 if (status & DMA_STATUS_FATAL )
12011211 {
@@ -1237,22 +1247,18 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t status, void *arg)
12371247
12381248 if (status & DMA_STATUS_HTF && priv -> circular )
12391249 {
1240- for (i = 0 ; i < conversion_count ; i ++ )
1241- {
1242- priv -> cb -> au_receive (dev ,
1243- priv -> chanlist [i % priv -> rnchannels ],
1244- priv -> r_dmabuffer [i ]);
1245- }
1250+ priv -> cb -> au_receive_batch (dev ,
1251+ priv -> r_chanbuffer ,
1252+ priv -> r_dmabuffer ,
1253+ conversion_count );
12461254 }
12471255
12481256 if (status & DMA_STATUS_TCF )
12491257 {
1250- for (i = 0 ; i < conversion_count ; i ++ )
1251- {
1252- priv -> cb -> au_receive (dev ,
1253- priv -> chanlist [i % priv -> rnchannels ],
1254- priv -> r_dmabuffer [buffer_offset + i ]);
1255- }
1258+ priv -> cb -> au_receive_batch (dev ,
1259+ priv -> r_chanbuffer ,
1260+ & priv -> r_dmabuffer [buffer_offset ],
1261+ conversion_count );
12561262 }
12571263 }
12581264
@@ -1283,7 +1289,8 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t status, void *arg)
12831289static void adc_dmacfg (struct stm32_dev_s * priv ,
12841290 struct stm32_gpdma_cfg_s * cfg )
12851291{
1286- const uint32_t sdw_log2 = 1 ; /* Always 16-bit half-word for ADC_DR */
1292+ const uint32_t src_sdw_log2 = 1 ; /* Always 16-bit half-word for ADC_DR */
1293+ const uint32_t dst_sdw_log2 = 2 ; /* 32-bit word for dmabuffer */
12871294
12881295 cfg -> src_addr = priv -> base + STM32_ADC_DR_OFFSET ;
12891296 cfg -> dest_addr = (uintptr_t )priv -> r_dmabuffer ;
@@ -1296,13 +1303,64 @@ static void adc_dmacfg(struct stm32_dev_s *priv,
12961303
12971304 cfg -> mode = priv -> circular ? GPDMACFG_MODE_CIRC : 0 ;
12981305
1299- cfg -> ntransfers = (priv -> cchannels * priv -> dmabatch ) << sdw_log2 ;
1306+ cfg -> ntransfers = (priv -> cchannels * priv -> dmabatch ) << src_sdw_log2 ;
13001307 cfg -> ntransfers <<= (priv -> circular ? 1 : 0 );
13011308
1302- cfg -> tr1 = (sdw_log2 << GPDMA_CXTR1_SDW_LOG2_SHIFT )
1303- | (sdw_log2 << GPDMA_CXTR1_DDW_LOG2_SHIFT )
1309+ cfg -> tr1 = (src_sdw_log2 << GPDMA_CXTR1_SDW_LOG2_SHIFT )
1310+ | (dst_sdw_log2 << GPDMA_CXTR1_DDW_LOG2_SHIFT )
13041311 | GPDMA_CXTR1_DINC ; /* dest-inc, source fixed */
13051312}
1313+
1314+ /****************************************************************************
1315+ * Name: adc_dma_init_chanbuf
1316+ *
1317+ * Description:
1318+ * Initialize the channel buffer for use with au_receive_batch.
1319+ *
1320+ * Input Parameters:
1321+ * priv - ADC instance structure
1322+ *
1323+ * Returned Value:
1324+ * None
1325+ ****************************************************************************/
1326+
1327+ static void adc_dma_init_chanbuf (struct stm32_dev_s * priv )
1328+ {
1329+ const uint32_t channels = priv -> cchannels ;
1330+ const uint32_t conversions = channels * priv -> dmabatch ; /* total entries in r_chanbuffer */
1331+ uint8_t * dst = priv -> r_chanbuffer ;
1332+ uint32_t filled = 0 ; /* number of valid bytes in dst */
1333+ uint32_t remain ;
1334+ uint32_t chunk ;
1335+
1336+ if (channels == 0 || conversions == 0 )
1337+ {
1338+ return ;
1339+ }
1340+
1341+ /* Fast path: single-channel scan ==> fill with one byte */
1342+
1343+ if (channels == 1 )
1344+ {
1345+ memset (dst , priv -> chanlist [0 ], conversions );
1346+ return ;
1347+ }
1348+
1349+ /* Seed the first frame (one copy of chanlist) */
1350+
1351+ memcpy (dst , priv -> chanlist , channels * sizeof (dst [0 ]));
1352+ filled = channels ;
1353+
1354+ /* Exponentially replicate: copy the filled prefix onto the tail */
1355+
1356+ while (filled < conversions )
1357+ {
1358+ remain = conversions - filled ;
1359+ chunk = (filled < remain ) ? filled : remain ;
1360+ memcpy (dst + filled , dst , chunk );
1361+ filled += chunk ;
1362+ }
1363+ }
13061364#endif
13071365
13081366/****************************************************************************
@@ -1457,6 +1515,8 @@ static int adc_setup(struct adc_dev_s *dev)
14571515
14581516 priv -> dma = stm32_dmachannel (GPDMA_TTYPE_P2M );
14591517
1518+ adc_dma_init_chanbuf (priv );
1519+
14601520 adc_dmacfg (priv , & dmacfg );
14611521
14621522 stm32_dmasetup (priv -> dma , & dmacfg );
0 commit comments