1 /*
2  * Copyright  2016-2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_sdma.h"
10 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
11 #include "fsl_memory.h"
12 #endif
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 
18 /* Component ID definition, used by tools. */
19 #ifndef FSL_COMPONENT_ID
20 #define FSL_COMPONENT_ID "platform.drivers.sdma"
21 #endif
22 
23 /*! @brief SDMA P2P macro definition */
24 #define SDMA_P2P_LOW_WATERMARK_MASK  (0xFFU)
25 #define SDMA_P2P_LOW_WATERMARK_SHIFT (0U)
26 #define SDMA_P2P_LOW_WATERMARK(val)  ((uint32_t)(val)&SDMA_P2P_LOW_WATERMARK_MASK)
27 
28 #define SDMA_P2P_HIGH_WATERMARK_SHIFT (16U)
29 #define SDMA_P2P_HIGH_WATERMARK_MASK  (0xFFUL << SDMA_P2P_HIGH_WATERMARK_SHIFT)
30 #define SDMA_P2P_HIGH_WATERMARK(val)  (((uint32_t)(val) << SDMA_P2P_HIGH_WATERMARK_SHIFT) & SDMA_P2P_HIGH_WATERMARK_MASK)
31 
32 #define SDMA_P2P_SOURCE_SPBA_SHIFT    (11U)
33 #define SDMA_P2P_SOURCE_SPBA_MASK     (1UL << SDMA_P2P_SOURCE_SPBA_SHIFT)
34 #define SDMA_P2P_SOURCE_SPBA_VAL(val) (((uint32_t)(val) << SDMA_P2P_SOURCE_SPBA_SHIFT) & SDMA_P2P_SOURCE_SPBA_MASK)
35 
36 #define SDMA_P2P_DEST_SPBA_SHIFT (12U)
37 #define SDMA_P2P_DEST_SPBA_MASK  (1UL << SDMA_P2P_DEST_SPBA_SHIFT)
38 #define SDMA_P2P_DEST_SPBA(val)  (((uint32_t)(val) << SDMA_P2P_DEST_SPBA_SHIFT) & SDMA_P2P_DEST_SPBA_MASK)
39 
40 #define SDMA_P2P_LOWER_EVENT_REG_SHIFT (28U)
41 #define SDMA_P2P_LOWER_EVENT_REG_MASK  (1UL << SDMA_P2P_LOWER_EVENT_REG_SHIFT)
42 #define SDMA_P2P_LOWER_EVENT_REG(val) \
43     (((uint32_t)(val) << SDMA_P2P_LOWER_EVENT_REG_SHIFT) & SDMA_P2P_LOWER_EVENT_REG_MASK)
44 
45 #define SDMA_P2P_HIGHER_EVENT_REG_SHIFT (29U)
46 #define SDMA_P2P_HIGHER_EVENT_REG_MASK  (1UL << SDMA_P2P_HIGHER_EVENT_REG_SHIFT)
47 #define SDMA_P2P_HIGHER_EVENT_REG(val) \
48     (((uint32_t)(val) << SDMA_P2P_HIGHER_EVENT_REG_SHIFT) & SDMA_P2P_HIGHER_EVENT_REG_MASK)
49 
50 #define SDMA_P2P_CONT_SHIFT (31U)
51 #define SDMA_P2P_CONT_MASK  (1UL << SDMA_P2P_CONT_SHIFT)
52 #define SDMA_P2P_CONT(val)  (((uint32_t)(val) << SDMA_P2P_CONT_SHIFT) & SDMA_P2P_CONT_MASK)
53 
54 /*******************************************************************************
55  * Prototypes
56  ******************************************************************************/
57 
58 /*!
59  * @brief Get instance number for SDMA.
60  *
61  * @param base SDMA peripheral base address.
62  */
63 static uint32_t SDMA_GetInstance(SDMAARM_Type *base);
64 
65 /*!
66  * @brief Run scripts for channel0.
67  *
68  * Channel0 is by default used as the boot channel for SDMA, also the scripts for channel0 will download scripts
69  * for other channels from ARM platform to SDMA RAM context.
70  *
71  * @param base SDMA peripheral base address.
72  */
73 static void SDMA_RunChannel0(SDMAARM_Type *base);
74 
75 /*!
76  * @brief Load the SDMA contex from ARM memory into SDMA RAM region.
77  *
78  * @param base SDMA peripheral base address.
79  * @param channel SDMA channel number.
80  * @param tcd Point to TCD structure.
81  */
82 static void SDMA_LoadContext(sdma_handle_t *handle, const sdma_transfer_config_t *config);
83 
84 /*******************************************************************************
85  * Variables
86  ******************************************************************************/
87 /*! @brief Array to map SDMA instance number to base pointer. */
88 static SDMAARM_Type *const s_sdmaBases[] = SDMAARM_BASE_PTRS;
89 
90 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
91 /*! @brief Array to map SDMA instance number to clock name. */
92 static const clock_ip_name_t s_sdmaClockName[] = SDMA_CLOCKS;
93 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
94 
95 /*! @brief Array to map SDMA instance number to IRQ number. */
96 static const IRQn_Type s_sdmaIRQNumber[FSL_FEATURE_SOC_SDMA_COUNT] = SDMAARM_IRQS;
97 
98 /*! @brief Pointers to transfer handle for each SDMA channel. */
99 static sdma_handle_t *s_SDMAHandle[FSL_FEATURE_SOC_SDMA_COUNT][FSL_FEATURE_SDMA_MODULE_CHANNEL];
100 
101 /*! @brief channel 0 Channel control blcok */
102 AT_NONCACHEABLE_SECTION_ALIGN(
103     static sdma_channel_control_t s_SDMACCB[FSL_FEATURE_SOC_SDMA_COUNT][FSL_FEATURE_SDMA_MODULE_CHANNEL], 4);
104 
105 /*! @brief channel 0 buffer descriptor */
106 AT_NONCACHEABLE_SECTION_ALIGN(
107     static sdma_buffer_descriptor_t s_SDMABD[FSL_FEATURE_SOC_SDMA_COUNT][FSL_FEATURE_SDMA_MODULE_CHANNEL], 4);
108 #if SDMA_DRIVER_LOAD_RAM_SCRIPT
109 /*! @sdma driver ram script*/
110 static short s_sdma_multi_fifo_script[] = FSL_SDMA_MULTI_FIFO_SCRIPT;
111 #endif
112 /*******************************************************************************
113  * Code
114  ******************************************************************************/
SDMA_GetInstance(SDMAARM_Type * base)115 static uint32_t SDMA_GetInstance(SDMAARM_Type *base)
116 {
117     uint32_t instance;
118 
119     /* Find the instance index from base address mappings. */
120     for (instance = 0; instance < ARRAY_SIZE(s_sdmaBases); instance++)
121     {
122         if (s_sdmaBases[instance] == base)
123         {
124             break;
125         }
126     }
127 
128     assert(instance < ARRAY_SIZE(s_sdmaBases));
129 
130     return instance;
131 }
132 
SDMA_RunChannel0(SDMAARM_Type * base)133 static void SDMA_RunChannel0(SDMAARM_Type *base)
134 {
135     /* Start channel 0 */
136     SDMA_StartChannelSoftware(base, 0U);
137 
138     /* Waiting for channel 0 finished */
139     while ((base->STOP_STAT & 0x1U) == 1U)
140     {
141     }
142 
143     /* Clear the channel interrupt status */
144     SDMA_ClearChannelInterruptStatus(base, 0x1U);
145 
146     /* Set SDMA context switch to dynamic switching */
147     SDMA_SetContextSwitchMode(base, kSDMA_ContextSwitchModeDynamic);
148 }
149 
SDMA_GetScriptAddr(sdma_peripheral_t peripheral,sdma_transfer_type_t type)150 static uint32_t SDMA_GetScriptAddr(sdma_peripheral_t peripheral, sdma_transfer_type_t type)
151 {
152     uint32_t val = 0;
153 
154     if (type == kSDMA_MemoryToMemory)
155     {
156         val = FSL_FEATURE_SDMA_M2M_ADDR;
157     }
158     else if (type == kSDMA_MemoryToPeripheral)
159     {
160         switch (peripheral)
161         {
162             case kSDMA_PeripheralTypeUART:
163             case kSDMA_PeripheralNormal:
164                 val = FSL_SDMA_M2P_ADDR;
165                 break;
166             case kSDMA_PeripheralTypeUART_SP:
167             case kSDMA_PeripheralNormal_SP:
168             case kSDMA_PeripheralASRCM2P:
169                 val = FSL_SDMA_M2SHP_ADDR;
170                 break;
171             case kSDMA_PeripheralTypeSPDIF:
172                 val = FSL_SDMA_M2SPDIF_ADDR;
173                 break;
174             case kSDMA_PeripheralMultiFifoSaiTX:
175                 val = FSL_SDMA_MULTI_FIFO_SAI_TX_ADDR;
176                 break;
177             default:
178                 assert(false);
179                 break;
180         }
181     }
182     else if (type == kSDMA_PeripheralToMemory)
183     {
184         switch (peripheral)
185         {
186             case kSDMA_PeripheralTypeUART:
187                 val = FSL_SDMA_UART2M_ADDR;
188                 break;
189             case kSDMA_PeripheralNormal:
190                 val = FSL_SDMA_P2M_ADDR;
191                 break;
192             case kSDMA_PeripheralTypeUART_SP:
193                 val = FSL_SDMA_UARTSH2M_ADDR;
194                 break;
195             case kSDMA_PeripheralNormal_SP:
196             case kSDMA_PeripheralASRCP2M:
197                 val = FSL_SDMA_SHP2M_ADDR;
198                 break;
199             case kSDMA_PeripheralTypeSPDIF:
200                 val = FSL_SDMA_SPDIF2M_ADDR;
201                 break;
202             case kSDMA_PeripheralMultiFifoPDM:
203             case kSDMA_PeripheralMultiFifoSaiRX:
204                 val = FSL_SDMA_MULTI_FIFO_SAI_RX_ADDR;
205                 break;
206             default:
207                 assert(false);
208                 break;
209         }
210     }
211     else
212     {
213         val = FSL_SDMA_PERIPHERAL_TO_PERIPHERAL_ADDR;
214     }
215 
216     return val;
217 }
218 
SDMA_LoadContext(sdma_handle_t * handle,const sdma_transfer_config_t * config)219 static void SDMA_LoadContext(sdma_handle_t *handle, const sdma_transfer_config_t *config)
220 {
221     uint32_t instance            = SDMA_GetInstance(handle->base);
222     sdma_context_data_t *context = handle->context;
223 
224     (void)memset(context, 0, sizeof(sdma_context_data_t));
225 
226     /* Set SDMA core's PC to the channel script address */
227     context->PC = (uint16_t)config->scriptAddr;
228     if (config->type == kSDMA_PeripheralToPeripheral)
229     {
230         context->GeneralReg[0] = config->eventMask1;
231         context->GeneralReg[1] = config->eventMask0;
232         context->GeneralReg[2] = (uint32_t)config->srcAddr;
233         context->GeneralReg[6] = (uint32_t)config->destAddr;
234         context->GeneralReg[7] = config->watermarkLevel;
235     }
236     else
237     {
238         /* Set the request source into context */
239         if (config->eventSource >= 32U)
240         {
241             context->GeneralReg[0] = (1UL << (config->eventSource - 32U));
242         }
243         else
244         {
245             context->GeneralReg[1] = (1UL << config->eventSource);
246         }
247 
248         /* Set source address and dest address for p2p, m2p and p2m */
249         if (config->type == kSDMA_MemoryToPeripheral)
250         {
251             context->GeneralReg[2] = (uint32_t)config->destAddr;
252             context->GeneralReg[6] = (uint32_t)config->destAddr;
253         }
254         else
255         {
256             context->GeneralReg[2] = (uint32_t)config->srcAddr;
257             context->GeneralReg[6] = (uint32_t)config->srcAddr;
258         }
259 
260         /* Set watermark, multi fifo for p2p, m2p and p2m into context */
261         context->GeneralReg[7] =
262             ((config->bytesPerRequest & (uint32_t)kSDMA_MultiFifoWatermarkLevelMask)
263              << kSDMA_MultiFifoWatermarkLevelShift) |
264             ((config->multiFifo.fifoNums & (uint32_t)kSDMA_MultiFifoNumsMask) << kSDMA_MultiFifoNumsShift) |
265             ((config->multiFifo.fifoOffset & (uint32_t)kSDMA_MultiFifoOffsetMask) << kSDMA_MultiFifoOffsetShift) |
266             ((config->swDone.enableSwDone ? (uint32_t)kSDMA_MultiFifoSwDoneMask : 0UL) << kSDMA_MultiFifoSwDoneShift) |
267             ((config->swDone.swDoneSel & (uint32_t)kSDMA_MultiFifoSwDoneSelectorMask)
268              << kSDMA_MultiFifoSwDoneSelectorShift);
269     }
270     s_SDMABD[instance][0].command = (uint8_t)kSDMA_BDCommandSETDM;
271     s_SDMABD[instance][0].status =
272         (uint8_t)kSDMA_BDStatusDone | (uint8_t)kSDMA_BDStatusWrap | (uint8_t)kSDMA_BDStatusInterrupt;
273     s_SDMABD[instance][0].count = sizeof(*context) / 4U;
274 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
275     s_SDMABD[instance][0].bufferAddr = MEMORY_ConvertMemoryMapAddress((uint32_t)context, kMEMORY_Local2DMA);
276 #else
277     s_SDMABD[instance][0].bufferAddr     = (uint32_t)context;
278 #endif
279     s_SDMABD[instance][0].extendBufferAddr = 2048UL + (sizeof(*context) / 4UL) * handle->channel;
280 
281     /* Run channel0 scripts after context prepared */
282     SDMA_RunChannel0(handle->base);
283 }
284 
SDMA_LoadScript(SDMAARM_Type * base,uint32_t destAddr,void * srcAddr,size_t bufferSizeBytes)285 void SDMA_LoadScript(SDMAARM_Type *base, uint32_t destAddr, void *srcAddr, size_t bufferSizeBytes)
286 {
287     /* Set the descriptor to 0 */
288     uint32_t instance   = SDMA_GetInstance(base);
289     uint32_t bufferAddr = 0U;
290 
291 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
292     bufferAddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(uint32_t *)srcAddr, kMEMORY_Local2DMA);
293 #else
294     bufferAddr                           = (uint32_t)srcAddr;
295 #endif
296 
297     s_SDMABD[instance][0].command = (uint8_t)kSDMA_BDCommandSETPM;
298     s_SDMABD[instance][0].status =
299         (uint8_t)kSDMA_BDStatusDone | (uint8_t)kSDMA_BDStatusWrap | (uint8_t)kSDMA_BDStatusExtend;
300     s_SDMABD[instance][0].count            = (uint16_t)bufferSizeBytes;
301     s_SDMABD[instance][0].bufferAddr       = bufferAddr;
302     s_SDMABD[instance][0].extendBufferAddr = destAddr;
303 
304     /* Run channel0 scripts */
305     SDMA_RunChannel0(base);
306 }
307 
SDMA_DumpScript(SDMAARM_Type * base,uint32_t srcAddr,void * destAddr,size_t bufferSizeBytes)308 void SDMA_DumpScript(SDMAARM_Type *base, uint32_t srcAddr, void *destAddr, size_t bufferSizeBytes)
309 {
310     /* Set the descriptor to 0 */
311     uint32_t instance   = SDMA_GetInstance(base);
312     uint32_t bufferAddr = 0U;
313 
314 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
315     bufferAddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(uint32_t *)destAddr, kMEMORY_Local2DMA);
316 #else
317     bufferAddr                           = (uint32_t)destAddr;
318 #endif
319 
320     s_SDMABD[instance][0].command = (uint8_t)kSDMA_BDCommandGETPM;
321     s_SDMABD[instance][0].status =
322         (uint8_t)kSDMA_BDStatusDone | (uint8_t)kSDMA_BDStatusWrap | (uint8_t)kSDMA_BDStatusExtend;
323     s_SDMABD[instance][0].count            = (uint16_t)bufferSizeBytes;
324     s_SDMABD[instance][0].bufferAddr       = bufferAddr;
325     s_SDMABD[instance][0].extendBufferAddr = srcAddr;
326 
327     /* Run channel0 scripts */
328     SDMA_RunChannel0(base);
329 }
330 
331 #if defined FSL_FEATURE_SOC_SPBA_COUNT && (FSL_FEATURE_SOC_SPBA_COUNT > 0)
SDMA_IsPeripheralInSPBA(uint32_t addr)332 bool SDMA_IsPeripheralInSPBA(uint32_t addr)
333 {
334     uint32_t spbaNum = FSL_FEATURE_SOC_SPBA_COUNT;
335     uint32_t i       = 0;
336     SPBA_Type *spbaBase;
337     SPBA_Type *spbaArray[FSL_FEATURE_SOC_SPBA_COUNT] = SPBA_BASE_PTRS;
338 
339     for (i = 0; i < spbaNum; i++)
340     {
341         spbaBase = spbaArray[i];
342 
343         if ((addr >= (uint32_t)FSL_FEATURE_SPBA_STARTn(spbaBase)) &&
344             (addr <= (uint32_t)FSL_FEATURE_SPBA_ENDn(spbaBase)))
345         {
346             return true;
347         }
348     }
349 
350     return false;
351 }
352 #endif /* FSL_FEATURE_SOC_SPBA_COUNT */
353 
SDMA_Init(SDMAARM_Type * base,const sdma_config_t * config)354 void SDMA_Init(SDMAARM_Type *base, const sdma_config_t *config)
355 {
356     assert(config != NULL);
357 
358     uint32_t tmpreg;
359     uint32_t instance = SDMA_GetInstance(base);
360 
361 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
362     /* Ungate SDMA periphral clock */
363     CLOCK_EnableClock(s_sdmaClockName[instance]);
364 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
365 
366     /* Clear the channel CCB */
367     (void)memset(&s_SDMACCB[instance][0], 0,
368                  sizeof(sdma_channel_control_t) * (uint32_t)FSL_FEATURE_SDMA_MODULE_CHANNEL);
369 
370     /* Reset all SDMA registers */
371     SDMA_ResetModule(base);
372 
373     /* Init the CCB for channel 0 */
374     (void)memset(&s_SDMABD[instance][0], 0, sizeof(sdma_buffer_descriptor_t));
375 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
376     s_SDMACCB[instance][0].currentBDAddr =
377         MEMORY_ConvertMemoryMapAddress((uint32_t)(&s_SDMABD[instance][0]), kMEMORY_Local2DMA);
378     s_SDMACCB[instance][0].baseBDAddr =
379         MEMORY_ConvertMemoryMapAddress((uint32_t)(&s_SDMABD[instance][0]), kMEMORY_Local2DMA);
380 #else
381     s_SDMACCB[instance][0].currentBDAddr = (uint32_t)(&s_SDMABD[instance][0]);
382     s_SDMACCB[instance][0].baseBDAddr    = (uint32_t)(&s_SDMABD[instance][0]);
383 #endif
384 
385     /* Set channel 0 priority */
386     SDMA_SetChannelPriority(base, 0, 7U);
387 
388     /* Set channel 0 ownership */
389     base->HOSTOVR = 0U;
390     base->EVTOVR  = 1U;
391 
392     /* Configure SDMA peripheral according to the configuration structure. */
393     tmpreg = base->CONFIG;
394     tmpreg &= ~(SDMAARM_CONFIG_ACR_MASK | SDMAARM_CONFIG_RTDOBS_MASK | SDMAARM_CONFIG_CSM_MASK);
395     /* Channel 0 shall use static context switch method */
396     tmpreg |= (SDMAARM_CONFIG_ACR(config->ratio) | SDMAARM_CONFIG_RTDOBS(config->enableRealTimeDebugPin) |
397                SDMAARM_CONFIG_CSM(0U));
398     base->CONFIG = tmpreg;
399 
400     tmpreg = base->SDMA_LOCK;
401     tmpreg &= ~SDMAARM_SDMA_LOCK_SRESET_LOCK_CLR_MASK;
402     tmpreg |= SDMAARM_SDMA_LOCK_SRESET_LOCK_CLR(config->isSoftwareResetClearLock);
403     base->SDMA_LOCK = tmpreg;
404 
405     /* Set the context size to 32 bytes */
406     base->CHN0ADDR = 0x4050U;
407 
408 /* Set channle 0 CCB address */
409 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
410     base->MC0PTR = MEMORY_ConvertMemoryMapAddress((uint32_t)(&s_SDMACCB[instance][0]), kMEMORY_Local2DMA);
411 #else
412     base->MC0PTR                         = (uint32_t)(&s_SDMACCB[instance][0]);
413 #endif
414 }
415 
SDMA_Deinit(SDMAARM_Type * base)416 void SDMA_Deinit(SDMAARM_Type *base)
417 {
418     /* Clear the MC0PTR register */
419     base->MC0PTR = 0U;
420 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
421     /* Gate SDMA periphral clock */
422     CLOCK_DisableClock(s_sdmaClockName[SDMA_GetInstance(base)]);
423 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
424 }
425 
SDMA_GetDefaultConfig(sdma_config_t * config)426 void SDMA_GetDefaultConfig(sdma_config_t *config)
427 {
428     assert(config != NULL);
429 
430     config->enableRealTimeDebugPin   = false;
431     config->isSoftwareResetClearLock = true;
432     config->ratio                    = kSDMA_HalfARMClockFreq;
433 }
434 
SDMA_ResetModule(SDMAARM_Type * base)435 void SDMA_ResetModule(SDMAARM_Type *base)
436 {
437     uint32_t i = 0, status;
438 
439     base->MC0PTR = 0;
440     status       = base->INTR;
441     SDMA_ClearChannelInterruptStatus(base, status);
442     status = base->STOP_STAT;
443     SDMA_ClearChannelStopStatus(base, status);
444     base->EVTOVR  = 0;
445     base->DSPOVR  = 0xFFFFFFFFU;
446     base->HOSTOVR = 0;
447     status        = base->EVTPEND;
448     SDMA_ClearChannelPendStatus(base, status);
449     base->INTRMASK = 0;
450 
451     /* Disable all events */
452     for (i = 0; i < (uint32_t)FSL_FEATURE_SDMA_EVENT_NUM; i++)
453     {
454         SDMA_SetSourceChannel(base, i, 0);
455     }
456 
457     /* Clear all channel priority */
458     for (i = 0; i < (uint32_t)FSL_FEATURE_SDMA_MODULE_CHANNEL; i++)
459     {
460         SDMA_SetChannelPriority(base, i, 0);
461     }
462 }
463 
SDMA_ConfigBufferDescriptor(sdma_buffer_descriptor_t * bd,uint32_t srcAddr,uint32_t destAddr,sdma_transfer_size_t busWidth,size_t bufferSize,bool isLast,bool enableInterrupt,bool isWrap,sdma_transfer_type_t type)464 void SDMA_ConfigBufferDescriptor(sdma_buffer_descriptor_t *bd,
465                                  uint32_t srcAddr,
466                                  uint32_t destAddr,
467                                  sdma_transfer_size_t busWidth,
468                                  size_t bufferSize,
469                                  bool isLast,
470                                  bool enableInterrupt,
471                                  bool isWrap,
472                                  sdma_transfer_type_t type)
473 {
474     assert(bufferSize <= 0xFFFFU);
475 
476     uint8_t status = 0U;
477     /* Set the descriptor to 0 */
478     (void)memset(bd, 0, sizeof(sdma_buffer_descriptor_t));
479     if (type == kSDMA_PeripheralToMemory)
480     {
481 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
482         bd->bufferAddr = MEMORY_ConvertMemoryMapAddress(destAddr, kMEMORY_Local2DMA);
483 #else
484         bd->bufferAddr = destAddr;
485 #endif
486     }
487     else
488     {
489 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
490         bd->bufferAddr = MEMORY_ConvertMemoryMapAddress(srcAddr, kMEMORY_Local2DMA);
491 #else
492         bd->bufferAddr = srcAddr;
493 #endif
494     }
495 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
496     bd->extendBufferAddr = MEMORY_ConvertMemoryMapAddress(destAddr, kMEMORY_Local2DMA);
497 #else
498     bd->extendBufferAddr                                   = destAddr;
499 #endif
500     if (isLast)
501     {
502         status |= (uint8_t)kSDMA_BDStatusLast;
503     }
504     else
505     {
506         status |= (uint8_t)kSDMA_BDStatusContinuous;
507     }
508 
509     /* Set interrupt and wrap feature */
510     if (enableInterrupt)
511     {
512         status |= (uint8_t)kSDMA_BDStatusInterrupt;
513     }
514     if (isWrap)
515     {
516         status |= (uint8_t)kSDMA_BDStatusWrap;
517     }
518 
519     status |= (uint8_t)kSDMA_BDStatusDone;
520 
521     /* Configure the command according to bus width */
522     bd->status  = status;
523     bd->command = (uint8_t)busWidth;
524     bd->count   = (uint16_t)bufferSize;
525 }
526 
SDMA_SetContextSwitchMode(SDMAARM_Type * base,sdma_context_switch_mode_t mode)527 void SDMA_SetContextSwitchMode(SDMAARM_Type *base, sdma_context_switch_mode_t mode)
528 {
529     uint32_t val = base->CONFIG & (~SDMAARM_CONFIG_CSM_MASK);
530     val |= (uint32_t)mode;
531     base->CONFIG = val;
532 }
533 
SDMA_GetRequestSourceStatus(SDMAARM_Type * base,uint32_t source)534 bool SDMA_GetRequestSourceStatus(SDMAARM_Type *base, uint32_t source)
535 {
536     if (source < 32U)
537     {
538         return ((base->EVT_MIRROR & (1UL << source)) >> source) != 0UL;
539     }
540     else
541     {
542         source -= 32U;
543         return ((base->EVT_MIRROR2 & (1UL << source)) >> source) != 0UL;
544     }
545 }
546 
SDMA_CreateHandle(sdma_handle_t * handle,SDMAARM_Type * base,uint32_t channel,sdma_context_data_t * context)547 void SDMA_CreateHandle(sdma_handle_t *handle, SDMAARM_Type *base, uint32_t channel, sdma_context_data_t *context)
548 {
549     assert(handle != NULL);
550     assert(channel < (uint32_t)FSL_FEATURE_SDMA_MODULE_CHANNEL);
551 
552     uint32_t sdmaInstance;
553 
554     /* Zero the handle */
555     (void)memset(handle, 0, sizeof(*handle));
556 
557     handle->base    = base;
558     handle->channel = (uint8_t)channel;
559     handle->bdCount = 1U;
560     handle->context = context;
561     /* Get the DMA instance number */
562     sdmaInstance                        = SDMA_GetInstance(base);
563     s_SDMAHandle[sdmaInstance][channel] = handle;
564 
565 /* Set channel CCB, default is the static buffer descriptor if not use EDMA_InstallBDMemory */
566 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
567     s_SDMACCB[sdmaInstance][channel].currentBDAddr =
568         MEMORY_ConvertMemoryMapAddress((uint32_t)(&s_SDMABD[sdmaInstance][channel]), kMEMORY_Local2DMA);
569     s_SDMACCB[sdmaInstance][channel].baseBDAddr =
570         MEMORY_ConvertMemoryMapAddress((uint32_t)(&s_SDMABD[sdmaInstance][channel]), kMEMORY_Local2DMA);
571 #else
572     s_SDMACCB[sdmaInstance][channel].baseBDAddr            = (uint32_t)(&s_SDMABD[sdmaInstance][channel]);
573     s_SDMACCB[sdmaInstance][channel].currentBDAddr         = (uint32_t)(&s_SDMABD[sdmaInstance][channel]);
574 #endif
575     /* Enable interrupt */
576     (void)EnableIRQ(s_sdmaIRQNumber[sdmaInstance]);
577 }
578 
SDMA_InstallBDMemory(sdma_handle_t * handle,sdma_buffer_descriptor_t * BDPool,uint32_t BDCount)579 void SDMA_InstallBDMemory(sdma_handle_t *handle, sdma_buffer_descriptor_t *BDPool, uint32_t BDCount)
580 {
581     assert((handle != NULL) && (BDPool != NULL) && (BDCount != 0UL));
582 
583     uint32_t sdmaInstance = SDMA_GetInstance(handle->base);
584 
585     /* Send user defined buffer descrptor pool to handle */
586     handle->BDPool = BDPool;
587 
588     handle->bdCount = BDCount;
589 
590 /* Update the CCB contents */
591 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
592     s_SDMACCB[sdmaInstance][handle->channel].baseBDAddr =
593         MEMORY_ConvertMemoryMapAddress((uint32_t)(handle->BDPool), kMEMORY_Local2DMA);
594     s_SDMACCB[sdmaInstance][handle->channel].currentBDAddr =
595         MEMORY_ConvertMemoryMapAddress((uint32_t)(handle->BDPool), kMEMORY_Local2DMA);
596 #else
597     s_SDMACCB[sdmaInstance][handle->channel].baseBDAddr    = (uint32_t)(handle->BDPool);
598     s_SDMACCB[sdmaInstance][handle->channel].currentBDAddr = (uint32_t)(handle->BDPool);
599 #endif
600 }
601 
SDMA_SetCallback(sdma_handle_t * handle,sdma_callback callback,void * userData)602 void SDMA_SetCallback(sdma_handle_t *handle, sdma_callback callback, void *userData)
603 {
604     assert(handle != NULL);
605 
606     handle->callback = callback;
607     handle->userData = userData;
608 }
609 
SDMA_SetMultiFifoConfig(sdma_transfer_config_t * config,uint32_t fifoNums,uint32_t fifoOffset)610 void SDMA_SetMultiFifoConfig(sdma_transfer_config_t *config, uint32_t fifoNums, uint32_t fifoOffset)
611 {
612     assert(config != NULL);
613     assert(fifoNums <= 15UL);
614     assert(fifoOffset <= 15UL);
615 
616     config->multiFifo.fifoNums   = (uint8_t)fifoNums;
617     config->multiFifo.fifoOffset = (uint8_t)fifoOffset;
618 }
619 
SDMA_EnableSwDone(SDMAARM_Type * base,sdma_transfer_config_t * config,uint8_t sel,sdma_peripheral_t type)620 void SDMA_EnableSwDone(SDMAARM_Type *base, sdma_transfer_config_t *config, uint8_t sel, sdma_peripheral_t type)
621 {
622     assert(config != NULL);
623 
624     config->swDone.swDoneSel    = sel;
625     config->swDone.enableSwDone = true;
626 
627     /* enable sw done function */
628     if (type == kSDMA_PeripheralMultiFifoPDM)
629     {
630         base->DONE0_CONFIG |= 0x80U;
631     }
632 }
633 
SDMA_SetDoneConfig(SDMAARM_Type * base,sdma_transfer_config_t * config,sdma_peripheral_t type,sdma_done_src_t doneSrc)634 void SDMA_SetDoneConfig(SDMAARM_Type *base,
635                         sdma_transfer_config_t *config,
636                         sdma_peripheral_t type,
637                         sdma_done_src_t doneSrc)
638 {
639     assert(config != NULL);
640 
641     uint32_t doneChannel           = 0U;
642     volatile uint32_t *doneAddress = NULL, doneValue = 0U, channelOffset = 0U;
643 
644     /* channel number per peripheral */
645     switch (type)
646     {
647         case kSDMA_PeripheralMultiFifoPDM:
648             doneChannel = (uint32_t)kSDMA_DoneChannel0;
649             doneValue   = base->DONE0_CONFIG;
650             doneAddress = &base->DONE0_CONFIG;
651             break;
652         default:
653             doneAddress = NULL;
654             break;
655     }
656 
657     if (NULL != doneAddress)
658     {
659         if (doneSrc == kSDMA_DoneSrcSW)
660         {
661             config->swDone.swDoneSel    = 0U;
662             config->swDone.enableSwDone = true;
663             doneValue |= (1UL << ((doneChannel - channelOffset) * 8U + 7U));
664             doneValue &= ~(1UL << ((doneChannel - channelOffset) * 8U + 6U));
665         }
666         else
667         {
668             doneValue &= ~(1UL << ((doneChannel - channelOffset) * 8U + 7U));
669             doneValue |= (1UL << ((doneChannel - channelOffset) * 8U + 6U));
670             doneValue &= ~((uint32_t)SDMAARM_DONE0_CONFIG_CH_SEL0_MASK << ((doneChannel - channelOffset) * 8U));
671             doneValue |= SDMAARM_DONE0_CONFIG_CH_SEL0((uint32_t)doneSrc - 1U) << ((doneChannel - channelOffset) * 8U);
672         }
673 
674         *doneAddress = doneValue;
675     }
676 }
677 
SDMA_PrepareTransfer(sdma_transfer_config_t * config,uint32_t srcAddr,uint32_t destAddr,uint32_t srcWidth,uint32_t destWidth,uint32_t bytesEachRequest,uint32_t transferSize,uint32_t eventSource,sdma_peripheral_t peripheral,sdma_transfer_type_t type)678 void SDMA_PrepareTransfer(sdma_transfer_config_t *config,
679                           uint32_t srcAddr,
680                           uint32_t destAddr,
681                           uint32_t srcWidth,
682                           uint32_t destWidth,
683                           uint32_t bytesEachRequest,
684                           uint32_t transferSize,
685                           uint32_t eventSource,
686                           sdma_peripheral_t peripheral,
687                           sdma_transfer_type_t type)
688 {
689     assert(config != NULL);
690     assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 3U) || (srcWidth == 4U));
691     assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 3U) || (destWidth == 4U));
692     assert((bytesEachRequest != 0u) && (bytesEachRequest <= (uint32_t)kSDMA_MultiFifoWatermarkLevelMask));
693     assert(transferSize <= 0xFFFFU);
694 
695 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
696     config->srcAddr  = MEMORY_ConvertMemoryMapAddress(srcAddr, kMEMORY_Local2DMA);
697     config->destAddr = MEMORY_ConvertMemoryMapAddress(destAddr, kMEMORY_Local2DMA);
698 #else
699     config->srcAddr                                        = srcAddr;
700     config->destAddr                                       = destAddr;
701 #endif
702     config->bytesPerRequest = bytesEachRequest;
703     config->transferSzie    = transferSize;
704     config->type            = type;
705 
706     if (srcWidth == 1U)
707     {
708         config->srcTransferSize = kSDMA_TransferSize1Bytes;
709     }
710     else if (srcWidth == 2U)
711     {
712         config->srcTransferSize = kSDMA_TransferSize2Bytes;
713     }
714     else if (srcWidth == 3U)
715     {
716         config->srcTransferSize = kSDMA_TransferSize3Bytes;
717     }
718     else
719     {
720         config->srcTransferSize = kSDMA_TransferSize4Bytes;
721     }
722 
723     if (destWidth == 1U)
724     {
725         config->destTransferSize = kSDMA_TransferSize1Bytes;
726     }
727     else if (destWidth == 2U)
728     {
729         config->destTransferSize = kSDMA_TransferSize2Bytes;
730     }
731     else if (destWidth == 3U)
732     {
733         config->destTransferSize = kSDMA_TransferSize3Bytes;
734     }
735     else
736     {
737         config->destTransferSize = kSDMA_TransferSize4Bytes;
738     }
739 
740     switch (type)
741     {
742         case kSDMA_MemoryToMemory:
743             config->scriptAddr          = FSL_FEATURE_SDMA_M2M_ADDR;
744             config->isEventIgnore       = true;
745             config->isSoftTriggerIgnore = false;
746             config->eventSource         = 0;
747             break;
748         case kSDMA_MemoryToPeripheral:
749             config->scriptAddr          = SDMA_GetScriptAddr(peripheral, kSDMA_MemoryToPeripheral);
750             config->isEventIgnore       = false;
751             config->isSoftTriggerIgnore = true;
752             config->eventSource         = eventSource;
753             break;
754         case kSDMA_PeripheralToMemory:
755             config->scriptAddr          = SDMA_GetScriptAddr(peripheral, kSDMA_PeripheralToMemory);
756             config->isEventIgnore       = false;
757             config->isSoftTriggerIgnore = true;
758             config->eventSource         = eventSource;
759             break;
760         default:
761             assert(false);
762             break;
763     }
764 }
765 
SDMA_PrepareP2PTransfer(sdma_transfer_config_t * config,uint32_t srcAddr,uint32_t destAddr,uint32_t srcWidth,uint32_t destWidth,uint32_t bytesEachRequest,uint32_t transferSize,uint32_t eventSource,uint32_t eventSource1,sdma_peripheral_t peripheral,sdma_p2p_config_t * p2p)766 void SDMA_PrepareP2PTransfer(sdma_transfer_config_t *config,
767                              uint32_t srcAddr,
768                              uint32_t destAddr,
769                              uint32_t srcWidth,
770                              uint32_t destWidth,
771                              uint32_t bytesEachRequest,
772                              uint32_t transferSize,
773                              uint32_t eventSource,
774                              uint32_t eventSource1,
775                              sdma_peripheral_t peripheral,
776                              sdma_p2p_config_t *p2p)
777 {
778     assert((config != NULL) && (p2p != NULL));
779     assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U));
780     assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U));
781     assert((bytesEachRequest != 0U) && (bytesEachRequest <= (uint32_t)kSDMA_MultiFifoWatermarkLevelMask));
782     assert(transferSize <= 0xFFFFU);
783 
784 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
785     config->srcAddr  = MEMORY_ConvertMemoryMapAddress(srcAddr, kMEMORY_Local2DMA);
786     config->destAddr = MEMORY_ConvertMemoryMapAddress(destAddr, kMEMORY_Local2DMA);
787 #else
788     config->srcAddr                                        = srcAddr;
789     config->destAddr                                       = destAddr;
790 #endif
791     config->bytesPerRequest = bytesEachRequest;
792     config->transferSzie    = transferSize;
793     config->type            = kSDMA_PeripheralToPeripheral;
794 
795     if (srcWidth == 1U)
796     {
797         config->srcTransferSize = kSDMA_TransferSize1Bytes;
798     }
799     else if (srcWidth == 2U)
800     {
801         config->srcTransferSize = kSDMA_TransferSize2Bytes;
802     }
803     else
804     {
805         config->srcTransferSize = kSDMA_TransferSize4Bytes;
806     }
807 
808     if (destWidth == 1U)
809     {
810         config->destTransferSize = kSDMA_TransferSize1Bytes;
811     }
812     else if (destWidth == 2U)
813     {
814         config->destTransferSize = kSDMA_TransferSize2Bytes;
815     }
816     else
817     {
818         config->destTransferSize = kSDMA_TransferSize4Bytes;
819     }
820 
821     config->scriptAddr          = SDMA_GetScriptAddr(peripheral, kSDMA_PeripheralToPeripheral);
822     config->isEventIgnore       = false;
823     config->isSoftTriggerIgnore = true;
824     config->eventSource         = eventSource;
825     config->eventSource1        = eventSource1;
826 
827     if (eventSource1 > 31UL)
828     {
829         config->watermarkLevel |= SDMA_P2P_HIGHER_EVENT_REG_MASK;
830     }
831 
832     if (eventSource > 31UL)
833     {
834         config->watermarkLevel |= SDMA_P2P_LOWER_EVENT_REG_MASK;
835     }
836 
837     if (SDMA_IsPeripheralInSPBA(srcAddr))
838     {
839         config->watermarkLevel |= SDMA_P2P_SOURCE_SPBA_MASK;
840     }
841 
842     if (SDMA_IsPeripheralInSPBA(destAddr))
843     {
844         config->watermarkLevel |= SDMA_P2P_DEST_SPBA_MASK;
845     }
846 
847     if (p2p->continuousTransfer)
848     {
849         config->watermarkLevel |= SDMA_P2P_CONT_MASK;
850     }
851 
852     if (p2p->sourceWatermark > p2p->destWatermark)
853     {
854         config->watermarkLevel |=
855             SDMA_P2P_LOW_WATERMARK(p2p->destWatermark) | SDMA_P2P_HIGH_WATERMARK(p2p->sourceWatermark);
856         config->eventMask0 = (1UL << (config->eventSource % 32U));
857         config->eventMask1 = (1UL << (config->eventSource1 % 32U));
858     }
859     else
860     {
861         config->watermarkLevel |=
862             SDMA_P2P_LOW_WATERMARK(p2p->sourceWatermark) | SDMA_P2P_HIGH_WATERMARK(p2p->destWatermark);
863         config->eventMask0 = (1UL << (config->eventSource1 % 32U));
864         config->eventMask1 = (1UL << (config->eventSource % 32U));
865     }
866 }
867 
SDMA_SubmitTransfer(sdma_handle_t * handle,const sdma_transfer_config_t * config)868 void SDMA_SubmitTransfer(sdma_handle_t *handle, const sdma_transfer_config_t *config)
869 {
870     assert(handle != NULL);
871     assert(config != NULL);
872     assert(config->transferSzie <= 0xFFFFU);
873 
874     uint32_t val      = 0U;
875     uint32_t instance = SDMA_GetInstance(handle->base);
876 
877     handle->eventSource  = config->eventSource;
878     handle->eventSource1 = config->eventSource1;
879 
880 #if SDMA_DRIVER_LOAD_RAM_SCRIPT
881     /* make sure ram script is loaded for the multi fifo case */
882     if ((config->scriptAddr == (uint32_t)FSL_SDMA_MULTI_FIFO_SAI_TX_ADDR) ||
883         ((uint32_t)FSL_SDMA_MULTI_FIFO_SAI_RX_ADDR == config->scriptAddr))
884     {
885         if (!handle->isRamscriptLoaded)
886         {
887             SDMA_LoadScript(handle->base, FSL_SDMA_SCRIPT_CODE_START_ADDR, (void *)s_sdma_multi_fifo_script,
888                             (uint32_t)FSL_SDMA_SCRIPT_CODE_SIZE);
889             handle->isRamscriptLoaded = true;
890         }
891     }
892 #endif
893 
894     /* Set event source channel */
895     if (config->type != kSDMA_MemoryToMemory)
896     {
897         val = handle->base->CHNENBL[config->eventSource];
898         val |= (1UL << (handle->channel));
899         SDMA_SetSourceChannel(handle->base, config->eventSource, val);
900         if (config->type == kSDMA_PeripheralToPeripheral)
901         {
902             val = handle->base->CHNENBL[config->eventSource1];
903             val |= (1UL << (handle->channel));
904             SDMA_SetSourceChannel(handle->base, config->eventSource1, val);
905         }
906     }
907 
908     /* DO register shall always set */
909     handle->base->DSPOVR |= (1UL << handle->channel);
910 
911     /* Configure EO bit */
912     if (config->isEventIgnore)
913     {
914         handle->base->EVTOVR |= (1UL << handle->channel);
915     }
916     else
917     {
918         handle->base->EVTOVR &= ~(1UL << handle->channel);
919     }
920 
921     /* Configure HO bits */
922     if (config->isSoftTriggerIgnore)
923     {
924         handle->base->HOSTOVR |= (1UL << handle->channel);
925     }
926     else
927     {
928         handle->base->HOSTOVR &= ~(1UL << handle->channel);
929     }
930 
931     /* If use default buffer descriptor, configure the buffer descriptor */
932     if (handle->BDPool == NULL)
933     {
934         (void)memset(&s_SDMABD[instance][handle->channel], 0, sizeof(sdma_buffer_descriptor_t));
935         if (config->type == kSDMA_MemoryToPeripheral)
936         {
937             SDMA_ConfigBufferDescriptor(&s_SDMABD[instance][handle->channel], config->srcAddr, config->destAddr,
938                                         config->destTransferSize, config->transferSzie, true, true, false,
939                                         config->type);
940         }
941         else
942         {
943             SDMA_ConfigBufferDescriptor(&s_SDMABD[instance][handle->channel], config->srcAddr, config->destAddr,
944                                         config->srcTransferSize, config->transferSzie, true, true, false, config->type);
945         }
946     }
947 
948     /*Load the context */
949     SDMA_LoadContext(handle, config);
950 }
951 
SDMA_StartTransfer(sdma_handle_t * handle)952 void SDMA_StartTransfer(sdma_handle_t *handle)
953 {
954     assert(handle != NULL);
955 
956     /* Set the channel priority */
957     if (handle->priority == 0U)
958     {
959         handle->priority = (uint8_t)handle->base->SDMA_CHNPRI[handle->channel];
960     }
961 
962     /* Set priority if regsiter bit is 0*/
963     if (handle->base->SDMA_CHNPRI[handle->channel] == 0UL)
964     {
965         SDMA_SetChannelPriority(handle->base, handle->channel, handle->priority);
966     }
967 
968     if (!((handle->eventSource != 0UL) || (handle->eventSource1 != 0UL)))
969     {
970         SDMA_StartChannelSoftware(handle->base, handle->channel);
971     }
972 }
973 
SDMA_StopTransfer(sdma_handle_t * handle)974 void SDMA_StopTransfer(sdma_handle_t *handle)
975 {
976     assert(handle != NULL);
977 
978     SDMA_StopChannel(handle->base, handle->channel);
979 }
980 
SDMA_AbortTransfer(sdma_handle_t * handle)981 void SDMA_AbortTransfer(sdma_handle_t *handle)
982 {
983     assert(handle != NULL);
984 
985     uint32_t val = 0;
986 
987     SDMA_StopTransfer(handle);
988 
989     /* Clear the event map. */
990     val = handle->base->CHNENBL[handle->eventSource];
991     val &= ~(1UL << (handle->channel));
992     SDMA_SetSourceChannel(handle->base, handle->eventSource, val);
993 
994     if (handle->eventSource1 != 0UL)
995     {
996         /* Clear the event map. */
997         val = handle->base->CHNENBL[handle->eventSource1];
998         val &= ~(1UL << (handle->channel));
999         SDMA_SetSourceChannel(handle->base, handle->eventSource1, val);
1000     }
1001 
1002     /* Clear the channel priority */
1003     SDMA_SetChannelPriority(handle->base, handle->channel, 0);
1004 }
1005 
SDMA_GetTransferredBytes(sdma_handle_t * handle)1006 uint32_t SDMA_GetTransferredBytes(sdma_handle_t *handle)
1007 {
1008     uint32_t instance = SDMA_GetInstance(handle->base);
1009     uint32_t val      = 0;
1010 
1011     if (handle->BDPool == NULL)
1012     {
1013         val = s_SDMABD[instance][handle->channel].count - 1UL;
1014     }
1015     else
1016     {
1017         val = 0;
1018     }
1019 
1020     return val;
1021 }
1022 
SDMA_HandleIRQ(sdma_handle_t * handle)1023 void SDMA_HandleIRQ(sdma_handle_t *handle)
1024 {
1025     assert(handle != NULL);
1026 
1027     /* Set the current BD address to the CCB */
1028     if (handle->BDPool != NULL)
1029     {
1030         /* Set the DONE bits */
1031         handle->bdIndex                             = (handle->bdIndex + 1U) % handle->bdCount;
1032         s_SDMACCB[0][handle->channel].currentBDAddr = (uint32_t)(&handle->BDPool[handle->bdIndex]);
1033     }
1034     else
1035     {
1036         s_SDMACCB[0][handle->channel].currentBDAddr = s_SDMACCB[0][handle->channel].baseBDAddr;
1037     }
1038 
1039     if (handle->callback != NULL)
1040     {
1041         (handle->callback)(handle, handle->userData, true, handle->bdIndex);
1042     }
1043 }
1044 #if defined(SDMAARM)
1045 void SDMA_DriverIRQHandler(void);
SDMA_DriverIRQHandler(void)1046 void SDMA_DriverIRQHandler(void)
1047 {
1048     uint32_t i = 1U, val;
1049 
1050     /* Clear channel 0 */
1051     SDMA_ClearChannelInterruptStatus(SDMAARM, 1U);
1052     /* Ignore channel0, as channel0 is only used for download */
1053     val = (SDMAARM->INTR) >> 1U;
1054     while (val)
1055     {
1056         if ((val & 0x1UL) != 0UL)
1057         {
1058             SDMA_ClearChannelInterruptStatus(s_SDMAHandle[0][i]->base, 1UL << i);
1059             SDMA_HandleIRQ(s_SDMAHandle[0][i]);
1060         }
1061         i++;
1062         val >>= 1U;
1063     }
1064 }
1065 #endif
1066 #if defined(SDMAARM1)
1067 void SDMA1_DriverIRQHandler(void);
SDMA1_DriverIRQHandler(void)1068 void SDMA1_DriverIRQHandler(void)
1069 {
1070     uint32_t i = 1U, val;
1071 
1072     /* Clear channel 0 */
1073     SDMA_ClearChannelInterruptStatus(SDMAARM1, 1U);
1074     /* Ignore channel0, as channel0 is only used for download */
1075     val = (SDMAARM1->INTR) >> 1U;
1076     while (val != 0UL)
1077     {
1078         if ((val & 0x1UL) != 0UL)
1079         {
1080             SDMA_ClearChannelInterruptStatus(s_SDMAHandle[0][i]->base, 1UL << i);
1081             SDMA_HandleIRQ(s_SDMAHandle[0][i]);
1082         }
1083         i++;
1084         val >>= 1U;
1085     }
1086 }
1087 #endif
1088 #if defined(SDMAARM2)
1089 void SDMA2_DriverIRQHandler(void);
SDMA2_DriverIRQHandler(void)1090 void SDMA2_DriverIRQHandler(void)
1091 {
1092     uint32_t i = 1U, val;
1093 
1094     /* Clear channel 0 */
1095     SDMA_ClearChannelInterruptStatus(SDMAARM2, 1U);
1096     /* Ignore channel0, as channel0 is only used for download */
1097     val = (SDMAARM2->INTR) >> 1U;
1098     while (val != 0UL)
1099     {
1100         if ((val & 0x1UL) != 0UL)
1101         {
1102             SDMA_ClearChannelInterruptStatus(s_SDMAHandle[1][i]->base, 1UL << i);
1103             SDMA_HandleIRQ(s_SDMAHandle[1][i]);
1104         }
1105         i++;
1106         val >>= 1U;
1107     }
1108 }
1109 #endif
1110 
1111 #if defined(SDMAARM3)
1112 void SDMA3_DriverIRQHandler(void);
SDMA3_DriverIRQHandler(void)1113 void SDMA3_DriverIRQHandler(void)
1114 {
1115     uint32_t i = 1U, val;
1116 
1117     /* Clear channel 0 */
1118     SDMA_ClearChannelInterruptStatus(SDMAARM3, 1U);
1119     /* Ignore channel0, as channel0 is only used for download */
1120     val = (SDMAARM3->INTR) >> 1U;
1121     while (val != 0UL)
1122     {
1123         if ((val & 0x1UL) != 0UL)
1124         {
1125             SDMA_ClearChannelInterruptStatus(s_SDMAHandle[2][i]->base, 1UL << i);
1126             SDMA_HandleIRQ(s_SDMAHandle[2][i]);
1127         }
1128         i++;
1129         val >>= 1U;
1130     }
1131 }
1132 #endif
1133