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