@@ -280,15 +280,16 @@ static void dma_mcux_edma_multi_channels_irq_handler(const struct device *dev, u
280
280
281
281
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT ) && FSL_FEATURE_SOC_DMAMUX_COUNT
282
282
static void edma_configure_dmamux (const struct device * dev , uint32_t channel ,
283
- struct dma_config * config , edma_transfer_type_t transfer_type )
283
+ struct dma_config * config )
284
284
{
285
+ uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL (dev , channel );
286
+ uint8_t dmamux_idx = DEV_DMAMUX_IDX (dev , channel );
285
287
uint32_t slot = config -> dma_slot ;
286
- uint8_t dmamux_idx , dmamux_channel ;
287
-
288
- dmamux_idx = DEV_DMAMUX_IDX (dev , channel );
289
- dmamux_channel = DEV_DMAMUX_CHANNEL (dev , channel );
290
288
291
289
#if DT_INST_PROP (0 , nxp_a_on )
290
+ edma_transfer_type_t transfer_type = data -> transfer_settings .transfer_type ;
291
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
292
+
292
293
if (config -> source_handshake || config -> dest_handshake ||
293
294
transfer_type == kEDMA_MemoryToMemory ) {
294
295
/*software trigger make the channel always on*/
@@ -317,6 +318,22 @@ static void edma_log_dmamux(const struct device *dev, uint32_t channel)
317
318
#define edma_log_dmamux (...)
318
319
#endif /* FSL_FEATURE_SOC_DMA_MUX_COUNT */
319
320
321
+ static inline void dma_mcux_edma_configure_muxes (const struct device * dev , uint32_t channel ,
322
+ struct dma_config * config )
323
+ {
324
+ edma_configure_dmamux (dev , channel , config );
325
+
326
+ #if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX ) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
327
+ uint32_t slot = config -> dma_slot ;
328
+ uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
329
+
330
+ /* First release any peripheral previously associated with this channel */
331
+ EDMA_SetChannelMux (DEV_BASE (dev ), hw_channel , 0 );
332
+ EDMA_SetChannelMux (DEV_BASE (dev ), hw_channel , slot );
333
+ #endif
334
+ }
335
+
336
+
320
337
static int dma_mcux_edma_configure_sg_loop (const struct device * dev ,
321
338
uint32_t channel ,
322
339
struct dma_config * config ,
@@ -471,24 +488,52 @@ static int dma_mcux_edma_configure_basic(const struct device *dev,
471
488
return ret ;
472
489
}
473
490
474
- /* Configure a channel */
475
- static int dma_mcux_edma_configure (const struct device * dev , uint32_t channel ,
476
- struct dma_config * config )
491
+ static void dma_mcux_edma_configure_hardware (const struct device * dev , uint32_t channel ,
492
+ struct dma_config * config )
493
+ {
494
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
495
+ edma_transfer_type_t transfer_type = data -> transfer_settings .transfer_type ;
496
+ struct dma_block_config * block_config = config -> head_block ;
497
+ bool sg_mode = block_config -> source_gather_en || block_config -> dest_scatter_en ;
498
+ uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
499
+
500
+ dma_mcux_edma_configure_muxes (dev , channel , config );
501
+
502
+ if (sg_mode && config -> cyclic ) {
503
+ dma_mcux_edma_configure_sg_loop (dev , channel , config , transfer_type );
504
+ } else if (sg_mode ) {
505
+ dma_mcux_edma_configure_sg_dynamic (dev , channel , config , transfer_type );
506
+ } else {
507
+ dma_mcux_edma_configure_basic (dev , channel , config , transfer_type );
508
+ }
509
+
510
+ if (config -> dest_chaining_en ) {
511
+ LOG_DBG ("link major channel %d" , config -> linked_channel );
512
+ EDMA_SetChannelLink (DEV_BASE (dev ), channel , kEDMA_MajorLink ,
513
+ config -> linked_channel );
514
+ }
515
+ if (config -> source_chaining_en ) {
516
+ LOG_DBG ("link minor channel %d" , config -> linked_channel );
517
+ EDMA_SetChannelLink (DEV_BASE (dev ), channel , kEDMA_MinorLink ,
518
+ config -> linked_channel );
519
+ }
520
+
521
+ EDMA_EnableChannelInterrupts (DEV_BASE (dev ), hw_channel , kEDMA_ErrorInterruptEnable );
522
+ }
523
+
524
+ static inline int dma_mcux_edma_validate_cfg (const struct device * dev ,
525
+ uint32_t channel ,
526
+ struct dma_config * config )
477
527
{
478
528
/* Check for invalid parameters before dereferencing them. */
479
529
if (NULL == dev || NULL == config ) {
480
530
return - EINVAL ;
481
531
}
482
532
483
- uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
484
- edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
485
533
struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
486
534
struct dma_block_config * block_config = config -> head_block ;
487
- bool sg_mode = block_config -> source_gather_en || block_config -> dest_scatter_en ;
488
535
uint32_t slot = config -> dma_slot ;
489
- edma_transfer_type_t transfer_type ;
490
- unsigned int key ;
491
- int ret = 0 ;
536
+ edma_transfer_type_t * type = & data -> transfer_settings .transfer_type ;
492
537
493
538
if (slot >= DEV_CFG (dev )-> dma_requests ) {
494
539
LOG_ERR ("source number is out of scope %d" , slot );
@@ -499,27 +544,10 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
499
544
LOG_ERR ("out of DMA channel %d" , channel );
500
545
return - EINVAL ;
501
546
}
547
+ LOG_DBG ("channel is %d" , channel );
502
548
503
549
data -> transfer_settings .valid = false;
504
550
505
- switch (config -> channel_direction ) {
506
- case MEMORY_TO_MEMORY :
507
- transfer_type = kEDMA_MemoryToMemory ;
508
- break ;
509
- case MEMORY_TO_PERIPHERAL :
510
- transfer_type = kEDMA_MemoryToPeripheral ;
511
- break ;
512
- case PERIPHERAL_TO_MEMORY :
513
- transfer_type = kEDMA_PeripheralToMemory ;
514
- break ;
515
- case PERIPHERAL_TO_PERIPHERAL :
516
- transfer_type = kEDMA_PeripheralToPeripheral ;
517
- break ;
518
- default :
519
- LOG_ERR ("not support transfer direction" );
520
- return - EINVAL ;
521
- }
522
-
523
551
if (!data_size_valid (config -> source_data_size )) {
524
552
LOG_ERR ("Source unit size error, %d" , config -> source_data_size );
525
553
return - EINVAL ;
@@ -537,60 +565,88 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
537
565
}
538
566
}
539
567
540
- data -> transfer_settings .source_data_size = config -> source_data_size ;
541
- data -> transfer_settings .dest_data_size = config -> dest_data_size ;
542
- data -> transfer_settings .source_burst_length = config -> source_burst_length ;
543
- data -> transfer_settings .dest_burst_length = config -> dest_burst_length ;
544
- data -> transfer_settings .direction = config -> channel_direction ;
545
- data -> transfer_settings .transfer_type = transfer_type ;
546
- data -> transfer_settings .valid = true;
547
- data -> transfer_settings .cyclic = config -> cyclic ;
568
+ switch (config -> channel_direction ) {
569
+ case MEMORY_TO_MEMORY :
570
+ * type = kEDMA_MemoryToMemory ;
571
+ break ;
572
+ case MEMORY_TO_PERIPHERAL :
573
+ * type = kEDMA_MemoryToPeripheral ;
574
+ break ;
575
+ case PERIPHERAL_TO_MEMORY :
576
+ * type = kEDMA_PeripheralToMemory ;
577
+ break ;
578
+ case PERIPHERAL_TO_PERIPHERAL :
579
+ * type = kEDMA_PeripheralToPeripheral ;
580
+ break ;
581
+ default :
582
+ LOG_ERR ("not support transfer direction" );
583
+ return - EINVAL ;
584
+ }
548
585
549
- /* Lock and page in the channel configuration */
550
- key = irq_lock ();
586
+ return 0 ;
587
+ }
588
+
589
+ /* fills out transfer settings struct based on api config */
590
+ static inline void dma_mcux_edma_set_xfer_settings (const struct device * dev , uint32_t channel ,
591
+ struct dma_config * config )
592
+ {
593
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
594
+ struct dma_mcux_channel_transfer_edma_settings * xfer_settings = & data -> transfer_settings ;
595
+
596
+ xfer_settings -> source_burst_length = config -> source_burst_length ;
597
+ xfer_settings -> dest_burst_length = config -> dest_burst_length ;
598
+ xfer_settings -> source_data_size = config -> source_data_size ;
599
+ xfer_settings -> dest_data_size = config -> dest_data_size ;
600
+ xfer_settings -> direction = config -> channel_direction ;
601
+ xfer_settings -> valid = true;
602
+ xfer_settings -> cyclic = config -> cyclic ;
603
+ }
551
604
552
- edma_configure_dmamux (dev , channel , config , transfer_type );
605
+ /* stops, resets, and creates new MCUX SDK handle for a channel */
606
+ static inline void dma_mcux_edma_reset_channel (const struct device * dev , uint32_t channel )
607
+ {
608
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
609
+ edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
610
+ uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
553
611
554
612
if (data -> busy ) {
555
613
EDMA_AbortTransfer (p_handle );
556
614
}
615
+
557
616
EDMA_ResetChannel (DEV_BASE (dev ), hw_channel );
558
617
EDMA_CreateHandle (p_handle , DEV_BASE (dev ), hw_channel );
559
618
EDMA_SetCallback (p_handle , nxp_edma_callback , (void * )data );
619
+ }
560
620
561
- #if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX ) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
562
- /* First release any peripheral previously associated with this channel */
563
- EDMA_SetChannelMux (DEV_BASE (dev ), hw_channel , 0 );
564
- EDMA_SetChannelMux (DEV_BASE (dev ), hw_channel , slot );
565
- #endif
566
621
567
- LOG_DBG ("channel is %d" , channel );
568
- EDMA_EnableChannelInterrupts (DEV_BASE (dev ), hw_channel , kEDMA_ErrorInterruptEnable );
622
+ /* Configure a channel */
623
+ static int dma_mcux_edma_configure (const struct device * dev , uint32_t channel ,
624
+ struct dma_config * config )
625
+ {
626
+ unsigned int key ;
627
+ int ret = 0 ;
628
+
629
+ ret = dma_mcux_edma_validate_cfg (dev , channel , config );
630
+ if (ret ) {
631
+ return ret ;
632
+ }
633
+
634
+ dma_mcux_edma_set_xfer_settings (dev , channel , config );
635
+
636
+ /* Lock and page in the channel configuration */
637
+ key = irq_lock ();
638
+
639
+ dma_mcux_edma_reset_channel (dev , channel );
569
640
570
641
/* Initialize all TCD pool as 0*/
571
642
for (int i = 0 ; i < CONFIG_DMA_TCD_QUEUE_SIZE ; i ++ ) {
572
643
memset (& DEV_CFG (dev )-> tcdpool [channel ][i ], 0 ,
573
644
sizeof (DEV_CFG (dev )-> tcdpool [channel ][i ]));
574
645
}
575
646
576
- if (sg_mode && config -> cyclic ) {
577
- dma_mcux_edma_configure_sg_loop (dev , channel , config , transfer_type );
578
- } else if (sg_mode ) {
579
- dma_mcux_edma_configure_sg_dynamic (dev , channel , config , transfer_type );
580
- } else {
581
- dma_mcux_edma_configure_basic (dev , channel , config , transfer_type );
582
- }
647
+ dma_mcux_edma_configure_hardware (dev , channel , config );
583
648
584
- if (config -> dest_chaining_en ) {
585
- LOG_DBG ("link major channel %d" , config -> linked_channel );
586
- EDMA_SetChannelLink (DEV_BASE (dev ), channel , kEDMA_MajorLink ,
587
- config -> linked_channel );
588
- }
589
- if (config -> source_chaining_en ) {
590
- LOG_DBG ("link minor channel %d" , config -> linked_channel );
591
- EDMA_SetChannelLink (DEV_BASE (dev ), channel , kEDMA_MinorLink ,
592
- config -> linked_channel );
593
- }
649
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
594
650
595
651
data -> busy = false;
596
652
if (config -> dma_callback ) {
@@ -602,7 +658,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
602
658
603
659
irq_unlock (key );
604
660
605
- return ret ;
661
+ return 0 ;
606
662
}
607
663
608
664
static int dma_mcux_edma_start (const struct device * dev , uint32_t channel )
0 commit comments