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