@@ -28,11 +28,19 @@ LOG_MODULE_REGISTER(dma_sam_xdmac);
28
28
#define XDMAC_INT_ERR (XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE)
29
29
#define DMA_CHANNELS_MAX 31
30
30
31
+ enum dma_state {
32
+ DMA_STATE_INIT = 0 ,
33
+ DMA_STATE_CONFIGURED ,
34
+ DMA_STATE_RUNNING ,
35
+ DMA_STATE_SUSPENDED ,
36
+ };
37
+
31
38
/* DMA channel configuration */
32
39
struct sam_xdmac_channel_cfg {
33
40
void * user_data ;
34
41
dma_callback_t callback ;
35
42
uint32_t data_size ;
43
+ enum dma_state state ;
36
44
};
37
45
38
46
/* Device constant configuration parameters */
@@ -68,6 +76,7 @@ static void sam_xdmac_isr(const struct device *dev)
68
76
continue ;
69
77
}
70
78
79
+ dev_data -> dma_channels [channel ].state = DMA_STATE_CONFIGURED ;
71
80
channel_cfg = & dev_data -> dma_channels [channel ];
72
81
73
82
/* Get channel errors */
@@ -180,6 +189,8 @@ int sam_xdmac_transfer_configure(const struct device *dev, uint32_t channel,
180
189
/* Set next descriptor configuration */
181
190
xdmac -> XDMAC_CHID [channel ].XDMAC_CNDC = param -> ndc ;
182
191
192
+ dev_data -> dma_channels [channel ].state = DMA_STATE_CONFIGURED ;
193
+
183
194
return 0 ;
184
195
}
185
196
@@ -199,6 +210,12 @@ static int sam_xdmac_config(const struct device *dev, uint32_t channel,
199
210
return - EINVAL ;
200
211
}
201
212
213
+ if (dev_data -> dma_channels [channel ].state != DMA_STATE_INIT &&
214
+ dev_data -> dma_channels [channel ].state != DMA_STATE_CONFIGURED ) {
215
+ LOG_ERR ("Config Channel %d at invalidate state" , channel );
216
+ return - EINVAL ;
217
+ }
218
+
202
219
__ASSERT_NO_MSG (cfg -> source_data_size == cfg -> dest_data_size );
203
220
__ASSERT_NO_MSG (cfg -> source_burst_length == cfg -> dest_burst_length );
204
221
@@ -327,6 +344,12 @@ int sam_xdmac_transfer_start(const struct device *dev, uint32_t channel)
327
344
return - EINVAL ;
328
345
}
329
346
347
+ if (dev_data -> dma_channels [channel ].state != DMA_STATE_CONFIGURED &&
348
+ dev_data -> dma_channels [channel ].state != DMA_STATE_RUNNING ) {
349
+ LOG_ERR ("Start Channel %d at invalidate state" , channel );
350
+ return - EINVAL ;
351
+ }
352
+
330
353
/* Check if the channel is enabled */
331
354
if (xdmac -> XDMAC_GS & (XDMAC_GS_ST0 << channel )) {
332
355
LOG_DBG ("Channel %d already enabled" , channel );
@@ -338,6 +361,8 @@ int sam_xdmac_transfer_start(const struct device *dev, uint32_t channel)
338
361
/* Enable channel */
339
362
xdmac -> XDMAC_GE = XDMAC_GE_EN0 << channel ;
340
363
364
+ dev_data -> dma_channels [channel ].state = DMA_STATE_RUNNING ;
365
+
341
366
return 0 ;
342
367
}
343
368
@@ -354,6 +379,11 @@ int sam_xdmac_transfer_stop(const struct device *dev, uint32_t channel)
354
379
return - EINVAL ;
355
380
}
356
381
382
+ if (dev_data -> dma_channels [channel ].state == DMA_STATE_INIT ) {
383
+ LOG_ERR ("Channel %d not configured" , channel );
384
+ return - EINVAL ;
385
+ }
386
+
357
387
/* Check if the channel is enabled */
358
388
if (!(xdmac -> XDMAC_GS & (XDMAC_GS_ST0 << channel ))) {
359
389
return 0 ;
@@ -368,6 +398,8 @@ int sam_xdmac_transfer_stop(const struct device *dev, uint32_t channel)
368
398
/* Clear the pending Interrupt Status bit(s) */
369
399
(void )xdmac -> XDMAC_CHID [channel ].XDMAC_CIS ;
370
400
401
+ dev_data -> dma_channels [channel ].state = DMA_STATE_CONFIGURED ;
402
+
371
403
return 0 ;
372
404
}
373
405
@@ -417,6 +449,16 @@ static int xdmac_suspend(const struct device *dev, uint32_t channel)
417
449
return - EINVAL ;
418
450
}
419
451
452
+ switch (dev_data -> dma_channels [channel ].state ) {
453
+ case DMA_STATE_RUNNING :
454
+ break ;
455
+ case DMA_STATE_SUSPENDED :
456
+ return 0 ;
457
+ default :
458
+ LOG_ERR ("Suspend Channel %d at invalidate state" , channel );
459
+ return - EINVAL ;
460
+ }
461
+
420
462
if (!(xdmac -> XDMAC_GS & BIT (channel ))) {
421
463
LOG_DBG ("Channel %d not enabled" , channel );
422
464
return - EINVAL ;
@@ -435,6 +477,8 @@ static int xdmac_suspend(const struct device *dev, uint32_t channel)
435
477
436
478
xdmac -> XDMAC_GRWS |= BIT (channel );
437
479
480
+ dev_data -> dma_channels [channel ].state = DMA_STATE_SUSPENDED ;
481
+
438
482
return 0 ;
439
483
}
440
484
@@ -451,6 +495,16 @@ static int xdmac_resume(const struct device *dev, uint32_t channel)
451
495
return - EINVAL ;
452
496
}
453
497
498
+ switch (dev_data -> dma_channels [channel ].state ) {
499
+ case DMA_STATE_SUSPENDED :
500
+ break ;
501
+ case DMA_STATE_RUNNING :
502
+ return 0 ;
503
+ default :
504
+ LOG_ERR ("Resume Channel %d at invalidate state" , channel );
505
+ return - EINVAL ;
506
+ }
507
+
454
508
if (!(xdmac -> XDMAC_GS & BIT (channel ))) {
455
509
LOG_DBG ("Channel %d not enabled" , channel );
456
510
return - EINVAL ;
@@ -469,6 +523,8 @@ static int xdmac_resume(const struct device *dev, uint32_t channel)
469
523
470
524
xdmac -> XDMAC_GRWR |= BIT (channel );
471
525
526
+ dev_data -> dma_channels [channel ].state = DMA_STATE_RUNNING ;
527
+
472
528
return 0 ;
473
529
}
474
530
0 commit comments