@@ -24,6 +24,8 @@ LOG_MODULE_REGISTER(dma_stm32, CONFIG_DMA_LOG_LEVEL);
24
24
25
25
#define DT_DRV_COMPAT st_stm32u5_dma
26
26
27
+ #define STM32U5_DMA_LINKED_LIST_NODE_SIZE (2)
28
+
27
29
static const uint32_t table_src_size [] = {
28
30
LL_DMA_SRC_DATAWIDTH_BYTE ,
29
31
LL_DMA_SRC_DATAWIDTH_HALFWORD ,
@@ -354,14 +356,6 @@ static int dma_stm32_configure(const struct device *dev,
354
356
uint32_t ll_direction ;
355
357
int ret ;
356
358
357
- /* Linked list Node and structure initialization */
358
- static LL_DMA_LinkNodeTypeDef Node_GPDMA_Channel ;
359
- LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct ;
360
- LL_DMA_InitNodeTypeDef NodeConfig ;
361
-
362
- LL_DMA_ListStructInit (& DMA_InitLinkedListStruct );
363
- LL_DMA_NodeStructInit (& NodeConfig );
364
-
365
359
/* Give channel from index 0 */
366
360
id = id - STM32_DMA_STREAM_OFFSET ;
367
361
@@ -434,10 +428,6 @@ static int dma_stm32_configure(const struct device *dev,
434
428
LL_DMA_ConfigAddresses (dma , dma_stm32_id_to_stream (id ), config -> head_block -> source_address ,
435
429
config -> head_block -> dest_address );
436
430
437
- NodeConfig .SrcAddress = config -> head_block -> source_address ;
438
- NodeConfig .DestAddress = config -> head_block -> dest_address ;
439
- NodeConfig .BlkDataLength = config -> head_block -> block_size ;
440
-
441
431
ret = dma_stm32_get_priority (config -> channel_priority , & ll_priority );
442
432
if (ret < 0 ) {
443
433
return ret ;
@@ -502,30 +492,41 @@ static int dma_stm32_configure(const struct device *dev,
502
492
LL_DMA_SetPeriphRequest (dma , dma_stm32_id_to_stream (id ), config -> dma_slot );
503
493
504
494
if (config -> head_block -> source_reload_en == 0 ) {
495
+ LL_DMA_SetLinkStepMode (dma , dma_stm32_id_to_stream (id ), LL_DMA_LSM_1LINK_EXECUTION );
505
496
/* Initialize the DMA structure in non-cyclic mode only */
506
497
LL_DMA_SetLinkedListAddrOffset (dma , dma_stm32_id_to_stream (id ), 0 );
507
498
} else {/* cyclic mode */
508
- /* Setting GPDMA request */
509
- NodeConfig .DestDataWidth = table_dst_size [index ];
510
- NodeConfig .SrcDataWidth = table_src_size [index ];
511
- NodeConfig .DestIncMode = LL_DMA_GetDestIncMode (dma , dma_stm32_id_to_stream (id ));
512
- NodeConfig .SrcIncMode = LL_DMA_GetSrcIncMode (dma , dma_stm32_id_to_stream (id ));
513
- NodeConfig .Direction = ll_direction ;
514
- NodeConfig .Request = config -> dma_slot ;
499
+ uint32_t linked_list_flags = 0 ;
500
+ volatile uint32_t * linked_list_node =
501
+ & dev_config -> linked_list_buffer [id * STM32U5_DMA_LINKED_LIST_NODE_SIZE ];
502
+ /* We use "linked list" to emulate circular mode.
503
+ * The linked list can consists of just source and/or destination address.
504
+ * Other registers can remain the same. Linked list itself doesn't contain
505
+ * pointer to other item, since LLR register is not updated (ULL bit = 0).
506
+ */
507
+ if (config -> head_block -> source_addr_adj == config -> head_block -> dest_addr_adj ) {
508
+ /* We update both source and destination address */
509
+ linked_list_node [0 ] = config -> head_block -> source_address ;
510
+ linked_list_node [1 ] = config -> head_block -> dest_address ;
511
+ linked_list_flags = LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR ;
512
+ } else if (config -> head_block -> source_addr_adj == DMA_ADDR_ADJ_INCREMENT ) {
513
+ /* We update only source address */
514
+ linked_list_node [0 ] = config -> head_block -> source_address ;
515
+ linked_list_flags = LL_DMA_UPDATE_CSAR ;
516
+ } else if (config -> head_block -> dest_addr_adj == DMA_ADDR_ADJ_INCREMENT ) {
517
+ /* We update only destination address */
518
+ linked_list_node [0 ] = config -> head_block -> dest_address ;
519
+ linked_list_flags = LL_DMA_UPDATE_CDAR ;
520
+ }
521
+ /* We update only destination address */
522
+ LL_DMA_SetLinkedListBaseAddr (dma , dma_stm32_id_to_stream (id ),
523
+ (uint32_t )& linked_list_node [0 ]);
524
+ LL_DMA_ConfigLinkUpdate (dma , dma_stm32_id_to_stream (id ), linked_list_flags ,
525
+ (uint32_t )& linked_list_node [0 ]);
515
526
516
527
/* Continuous transfers with Linked List */
517
528
stream -> cyclic = true;
518
- LL_DMA_List_Init (dma , dma_stm32_id_to_stream (id ), & DMA_InitLinkedListStruct );
519
- LL_DMA_CreateLinkNode (& NodeConfig , & Node_GPDMA_Channel );
520
- LL_DMA_ConnectLinkNode (& Node_GPDMA_Channel , LL_DMA_CLLR_OFFSET5 ,
521
- & Node_GPDMA_Channel , LL_DMA_CLLR_OFFSET5 );
522
- LL_DMA_SetLinkedListBaseAddr (dma , dma_stm32_id_to_stream (id ),
523
- (uint32_t )& Node_GPDMA_Channel );
524
- LL_DMA_ConfigLinkUpdate (dma , dma_stm32_id_to_stream (id ),
525
- (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 |
526
- LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR |
527
- LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR ),
528
- (uint32_t )& Node_GPDMA_Channel );
529
+ LL_DMA_SetLinkStepMode (dma , dma_stm32_id_to_stream (id ), LL_DMA_LSM_FULL_EXECUTION );
529
530
530
531
LL_DMA_EnableIT_HT (dma , dma_stm32_id_to_stream (id ));
531
532
}
@@ -801,6 +802,11 @@ static struct dma_stm32_stream \
801
802
dma_stm32_streams_##index[DT_INST_PROP_OR(index, dma_channels, \
802
803
DT_NUM_IRQS(DT_DRV_INST(index)))]; \
803
804
\
805
+ static volatile uint32_t dma_stm32_linked_list_buffer##index \
806
+ [STM32U5_DMA_LINKED_LIST_NODE_SIZE * \
807
+ DT_INST_PROP_OR(index, dma_channels, \
808
+ DT_NUM_IRQS(DT_DRV_INST(index)))] __nocache_noinit; \
809
+ \
804
810
const struct dma_stm32_config dma_stm32_config_##index = { \
805
811
.pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus), \
806
812
.enr = DT_INST_CLOCKS_CELL(index, bits) }, \
@@ -810,6 +816,7 @@ const struct dma_stm32_config dma_stm32_config_##index = { \
810
816
DT_NUM_IRQS(DT_DRV_INST(index)) \
811
817
), \
812
818
.streams = dma_stm32_streams_##index, \
819
+ .linked_list_buffer = dma_stm32_linked_list_buffer##index \
813
820
}; \
814
821
\
815
822
static struct dma_stm32_data dma_stm32_data_##index = { \
0 commit comments