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