1 /*
2 * edma3_drv_basic.c
3 *
4 * EDMA3 Driver Basic Interface Implementation. This file contains
5 * beginner-level EDMA3 Driver APIs which are required to:
6 * a) Request/free a DMA, QDMA and Link channel.
7 * b) Program various fields in the PaRAM Set like source/destination
8 * parameters, transfer parameters etc.
9 * c) Enable/disable a transfer.
10 * These APIs are provided to program a DMA/QDMA channel for simple use-cases
11 * and don't expose all the features of EDMA3 hardware. Users who want to go
12 * beyond this and have complete control on the EDMA3 hardware are advised
13 * to refer edma3_drv_adv.c source file.
14 *
15 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
16 *
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the
28 * distribution.
29 *
30 * Neither the name of Texas Instruments Incorporated nor the names of
31 * its contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 */
48 /* EDMa3 Driver Internal Header Files */
49 #include <ti/sdo/edma3/drv/src/edma3.h>
50 /* Resource Manager Internal Header Files */
51 #include <ti/sdo/edma3/rm/src/edma3resmgr.h>
53 /* Instrumentation Header File */
54 #ifdef EDMA3_INSTRUMENTATION_ENABLED
55 #include <ti/sdo/edma3/rm/src/edma3_log.h>
56 #endif
58 /* For assert() */
59 /**
60 * Define NDEBUG to ignore assert().
61 * NDEBUG should be defined before including assert.h header file.
62 */
63 #include <assert.h>
66 /* Externel Variables */
67 /*---------------------------------------------------------------------------*/
68 /**
69 * Maximum Resource Manager Instances supported by the EDMA3 Package.
70 */
71 extern const unsigned int EDMA3_MAX_RM_INSTANCES;
74 /**
75 * \brief EDMA3 Resource Manager Objects, tied to each EDMA3 HW Controller.
76 *
77 * Typically one RM object will cater to one EDMA3 HW controller
78 * and will have all the global config information.
79 */
80 extern EDMA3_RM_Obj resMgrObj[EDMA3_MAX_EDMA3_INSTANCES];
83 /**
84 * \brief Region Specific Configuration structure for
85 * EDMA3 controller, to provide region specific Information.
86 *
87 * This configuration info can also be provided by the user at run-time,
88 * while calling EDMA3_RM_open (). If not provided at run-time,
89 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
90 * for the specified platform.
91 */
92 extern EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
95 /**
96 * Handles of EDMA3 Resource Manager Instances.
97 *
98 * Used to maintain information of the EDMA3 RM Instances
99 * for each HW controller.
100 * There could be a maximum of EDMA3_MAX_RM_INSTANCES instances per
101 * EDMA3 HW.
102 */
103 extern EDMA3_RM_Instance *ptrRMIArray;
105 /** Local MemSet function */
106 extern void edma3MemZero(void *dst, unsigned int len);
107 /** Local MemCpy function */
108 extern void edma3MemCpy(void *dst, const void *src, unsigned int len);
110 /**
111 * \brief EDMA3 Driver Objects, tied to each EDMA3 HW Controller.
112 *
113 * Typically one object will cater to one EDMA3 HW controller
114 * and will have all regions' (ARM, DSP etc) specific config information.
115 */
116 extern EDMA3_DRV_Object drvObj [EDMA3_MAX_EDMA3_INSTANCES];
119 /**
120 * Handles of EDMA3 Driver Instances.
121 *
122 * Used to maintain information of the EDMA3 Driver Instances for
123 * each region, for each HW controller.
124 * There could be as many Driver Instances as there are shadow
125 * regions. Multiple EDMA3 Driver instances on the same shadow
126 * region are NOT allowed.
127 */
128 extern EDMA3_DRV_Instance drvInstance [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
131 /**
132 * \brief Resources bound to a Channel
133 *
134 * When a request for a channel is made, the resources PaRAM Set and TCC
135 * get bound to that channel. This information is needed internally by the
136 * driver when a request is made to free the channel (Since it is the
137 * responsibility of the driver to free up the channel-associated resources
138 * from the Resource Manager layer).
139 */
140 extern EDMA3_DRV_ChBoundResources edma3DrvChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
142 /** Max of DMA Channels */
143 extern unsigned int edma3_dma_ch_max_val[];
144 /** Min of Link Channels */
145 extern unsigned int edma3_link_ch_min_val[];
146 /** Max of Link Channels */
147 extern unsigned int edma3_link_ch_max_val[];
148 /** Min of QDMA Channels */
149 extern unsigned int edma3_qdma_ch_min_val[];
150 /** Max of QDMA Channels */
151 extern unsigned int edma3_qdma_ch_max_val[];
152 /** Max of Logical Channels */
153 extern unsigned int edma3_log_ch_max_val[];
155 /* Local functions prototypes */
156 /*---------------------------------------------------------------------------*/
157 /** Remove various mappings and do cleanup for DMA/QDMA channels */
158 static EDMA3_DRV_Result edma3RemoveMapping (EDMA3_DRV_Handle hEdma,
159 unsigned int channelId);
161 /*---------------------------------------------------------------------------*/
164 /**
165 * \brief Request a DMA/QDMA/Link channel.
166 *
167 * Each channel (DMA/QDMA/Link) must be requested before initiating a DMA
168 * transfer on that channel.
169 *
170 * This API is used to allocate a logical channel (DMA/QDMA/Link) along with
171 * the associated resources. For DMA and QDMA channels, TCC and PaRAM Set are
172 * also allocated along with the requested channel. For Link channel, ONLY a
173 * PaRAM Set is allocated.
174 *
175 * User can request a specific logical channel by passing the channel id in
176 * 'pLCh'. Note that the channel id is the same as the actual resource id in
177 * case of DMA channels. To allocate specific QDMA channels, user SHOULD use the
178 * defines EDMA3_DRV_QDMA_CHANNEL_X mentioned above.
179 *
180 * User can also request ANY available logical channel also by specifying the
181 * below mentioned values in '*pLCh':
182 * a) EDMA3_DRV_DMA_CHANNEL_ANY: For DMA channels
183 * b) EDMA3_DRV_QDMA_CHANNEL_ANY: For QDMA channels, and
184 * c) EDMA3_DRV_LINK_CHANNEL: For Link channels. Normally user should use this
185 * value to request link channels (PaRAM Sets used for linking purpose
186 * only), unless he wants to use some specific link channels (PaRAM Sets)
187 * which is also allowed.
188 *
189 * This API internally uses EDMA3_RM_allocResource () to allocate the desired
190 * resources (DMA/QDMA channel, PaRAM Set and TCC).
191 *
192 * This API also registers a specific callback function against the allocated
193 * TCC.
194 *
195 * For DMA/QDMA channels, after allocating all the EDMA3 resources, this API
196 * sets the TCC field of the OPT PaRAM Word with the allocated TCC. It also sets
197 * the event queue for the channel allocated. The event queue needs to be
198 * specified by the user.
199 *
200 * For DMA channel, it also sets the DCHMAP register, if required.
201 *
202 * For QDMA channel, it sets the QCHMAP register and CCNT as trigger word and
203 * enables the QDMA channel by writing to the QEESR register.
204 *
205 * \param hEdma [IN] Handle to the previously opened Driver
206 * Instance.
207 * \param pLCh [IN/OUT] Requested logical channel id.
208 * Examples:
209 * - EDMA3_DRV_HW_CHANNEL_EVENT_0
210 * - To request a DMA Master Channel
211 * mapped to EDMA Event 0.
212 *
213 * - EDMA3_DRV_DMA_CHANNEL_ANY
214 * - For requesting any DMA Master channel
215 * with no event mapping.
216 *
217 * - EDMA3_DRV_QDMA_CHANNEL_ANY
218 * - For requesting any QDMA Master channel
219 *
220 * - EDMA3_DRV_QDMA_CHANNEL_0
221 * - For requesting the QDMA Channel 0.
222 *
223 * - EDMA3_DRV_LINK_CHANNEL
224 * - For requesting a DMA Slave Channel,
225 * - to be linked to some other Master
226 * - channel.
227 *
228 * In case user passes a specific channel
229 * Id, pLCh value is left unchanged. In
230 * case user requests ANY available
231 * resource, the allocated channel id is
232 * returned in pLCh.
233 *
234 * \note To request a PaRAM Set for the purpose of
235 * linking to another channel, call the function with
236 *
237 * *pLCh = EDMA3_DRV_LINK_CHANNEL;
238 *
239 * This function will update *pLCh with the allocated Link channel
240 * handle. This handle could be DIFFERENT from the actual PaRAM Set
241 * allocated by the Resource Manager internally. So user SHOULD NOT
242 * assume the handle as the PaRAM Set Id.
243 *
244 * \param pTcc [IN/OUT] The channel number on which the
245 * completion/error interrupt is generated.
246 * Not used if user requested for a Link
247 * channel.
248 * Examples:
249 * - EDMA3_DRV_HW_CHANNEL_EVENT_0
250 * - To request TCC associated with
251 * - DMA Master Channel mapped to EDMA
252 * - event 0.
253 *
254 * - EDMA3_DRV_TCC_ANY
255 * - For requesting any TCC with no
256 * - channel mapping.
257 * In case user passes a specific TCC
258 * value, pTcc value is left unchanged.
259 * In case user requests ANY available TCC,
260 * the allocated one is returned in pTcc
261 *
262 * \param evtQueue [IN] Event Queue Number to which the channel
263 * will be mapped (valid only for the
264 * Master Channel (DMA/QDMA) request)
265 *
266 * \param tccCb [IN] TCC callback - caters to channel-
267 * specific events like "Event Miss Error"
268 * or "Transfer Complete"
269 *
270 * \param cbData [IN] Data which will be passed directly to
271 * the tccCb callback function
272 *
273 * \return EDMA3_DRV_SOK or EDMA3_DRV Error code
274 *
275 * \note This function internally uses EDMA3 Resource Manager, which
276 * acquires a RM Instance specific semaphore
277 * to prevent simultaneous access to the global pool of resources.
278 * It also disables the global interrupts while modifying
279 * the global CC registers.
280 * It is re-entrant, but SHOULD NOT be called from the user callback
281 * function (ISR context).
282 */
283 EDMA3_DRV_Result EDMA3_DRV_requestChannel (EDMA3_DRV_Handle hEdma,
284 unsigned int *pLCh,
285 unsigned int *pTcc,
286 EDMA3_RM_EventQueue evtQueue,
287 EDMA3_RM_TccCallback tccCb,
288 void *cbData)
289 {
290 EDMA3_RM_ResDesc resObj;
291 EDMA3_RM_ResDesc channelObj;
292 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
293 EDMA3_DRV_Instance *drvInst = NULL;
294 EDMA3_DRV_Object *drvObject = NULL;
295 unsigned int mappedTcc = EDMA3_DRV_CH_NO_TCC_MAP;
296 int paRAMId = (int)EDMA3_RM_RES_ANY;
297 EDMA3_DRV_ChannelType chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
298 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
299 int mappedPaRAMId;
300 unsigned int edma3Id;
301 unsigned int freeDmaQdmaChannel = FALSE;
303 #ifdef EDMA3_INSTRUMENTATION_ENABLED
304 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
305 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
306 EDMA3_DVT_dCOUNTER,
307 EDMA3_DVT_dNONE,
308 EDMA3_DVT_dNONE));
309 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
312 /* If parameter checking is enabled... */
313 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
314 if ((pLCh == NULL) || (hEdma == NULL))
315 {
316 result = EDMA3_DRV_E_INVALID_PARAM;
317 }
318 #endif
320 if (EDMA3_DRV_SOK == result)
321 {
322 drvInst = (EDMA3_DRV_Instance *)hEdma;
323 drvObject = drvInst->pDrvObjectHandle;
325 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
326 {
327 result = EDMA3_DRV_E_INVALID_PARAM;
328 }
329 }
331 if (EDMA3_DRV_SOK == result)
332 {
333 edma3Id = drvObject->phyCtrllerInstId;
334 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
336 /* Identify the request type and validate the appropriate arguments.
337 * Starting in the order of PaRAM Set availability,
338 * check for a specific DMA channel request first.
339 */
340 if ((*pLCh) <= edma3_dma_ch_max_val [edma3Id])
341 {
342 /* A 'Specific' DMA channel is requested */
343 chType = EDMA3_DRV_CHANNEL_TYPE_DMA;
344 /* Fill the resObj structure as well */
345 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
346 resObj.resId = *pLCh;
348 /* Check the TCC and Event Queue number */
349 if ((evtQueue >= drvObject->gblCfgParams.numEvtQueue)
350 || (pTcc == NULL))
351 {
352 result = EDMA3_DRV_E_INVALID_PARAM;
353 }
354 }
356 if ((*pLCh) == EDMA3_DRV_DMA_CHANNEL_ANY)
357 {
358 /* 'Any' DMA channel is requested */
359 chType = EDMA3_DRV_CHANNEL_TYPE_DMA;
360 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
361 resObj.resId = EDMA3_RM_RES_ANY;
363 /* Check the TCC and Event Queue number */
364 if ((evtQueue >= drvObject->gblCfgParams.numEvtQueue)
365 || (pTcc == NULL))
366 {
367 result = EDMA3_DRV_E_INVALID_PARAM;
368 }
369 }
371 if (((*pLCh) >= edma3_link_ch_min_val[edma3Id]) &&
372 ((*pLCh) <= edma3_link_ch_max_val[edma3Id]))
373 {
374 /* A 'Specific' Link channel is requested, TCC may or may not be
375 * required.
376 */
377 /* Save the PaRAM Id for future use */
378 paRAMId = *pLCh;
380 if (pTcc != NULL)
381 {
382 if (*pTcc < drvObject->gblCfgParams.numTccs)
383 {
384 /* Argument passed as *pTcc is a valid TCC number */
385 chType = EDMA3_DRV_CHANNEL_TYPE_LINK_TCC;
386 resObj.type = EDMA3_RM_RES_PARAM_SET;
387 }
388 else
389 {
390 /* Argument passed as *pTcc is Invalid TCC number */
391 result = EDMA3_DRV_E_INVALID_PARAM;
392 }
393 }
394 else
395 {
396 /* pTcc is NULL, only Link Channel required */
397 chType = EDMA3_DRV_CHANNEL_TYPE_LINK;
398 resObj.type = EDMA3_RM_RES_PARAM_SET;
399 }
400 }
402 if ((*pLCh) == EDMA3_DRV_LINK_CHANNEL)
403 {
404 /* 'Any' Link channel is requested, TCC is not required */
405 chType = EDMA3_DRV_CHANNEL_TYPE_LINK;
406 resObj.type = EDMA3_RM_RES_PARAM_SET;
407 }
409 if ((*pLCh) == EDMA3_DRV_LINK_CHANNEL_WITH_TCC)
410 {
411 /* 'Any' Link channel is requested, TCC is required */
412 if (*pTcc < drvObject->gblCfgParams.numTccs)
413 {
414 /* Argument passed as *pTcc is a valid TCC number */
415 chType = EDMA3_DRV_CHANNEL_TYPE_LINK_TCC;
416 resObj.type = EDMA3_RM_RES_PARAM_SET;
417 }
418 else
419 {
420 /* Argument passed as *pTcc is Invalid TCC number */
421 result = EDMA3_DRV_E_INVALID_PARAM;
422 }
423 }
425 if (((*pLCh) >= EDMA3_DRV_QDMA_CHANNEL_0) &&
426 ((*pLCh) <= EDMA3_DRV_QDMA_CHANNEL_7))
427 {
428 /* A 'Specific' QDMA channel is requested */
429 chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
430 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
431 resObj.resId = *pLCh - EDMA3_DRV_QDMA_CHANNEL_0;
433 /* Check the TCC and Event Queue number */
434 if ((evtQueue >= drvObject->gblCfgParams.numEvtQueue)
435 || (pTcc == NULL))
436 {
437 result = EDMA3_DRV_E_INVALID_PARAM;
438 }
439 }
441 if ((*pLCh) == EDMA3_DRV_QDMA_CHANNEL_ANY)
442 {
443 /* 'Any' QDMA channel is requested */
444 chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
445 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
446 resObj.resId = EDMA3_RM_RES_ANY;
448 /* Check the TCC and Event Queue number */
449 if ((evtQueue >= drvObject->gblCfgParams.numEvtQueue)
450 || (pTcc == NULL))
451 {
452 result = EDMA3_DRV_E_INVALID_PARAM;
453 }
454 }
456 if (EDMA3_DRV_CHANNEL_TYPE_NONE == chType)
457 {
458 /* Invalid request */
459 result = EDMA3_DRV_E_INVALID_PARAM;
460 }
461 }
463 /* Step 1: Allocate the DMA/QDMA channel first, if required */
464 if (EDMA3_DRV_SOK == result)
465 {
466 switch (chType)
467 {
468 case EDMA3_DRV_CHANNEL_TYPE_DMA:
469 result = EDMA3_RM_allocResource(drvInst->resMgrInstance,
470 (EDMA3_RM_ResDesc *)&resObj);
471 if (result == EDMA3_RM_SOK)
472 {
473 *pLCh = resObj.resId;
475 mappedPaRAMId = drvObject->gblCfgParams.dmaChannelPaRAMMap[*pLCh];
476 if (mappedPaRAMId != EDMA3_DRV_CH_NO_PARAM_MAP)
477 {
478 paRAMId = mappedPaRAMId;
479 }
481 if (*pTcc == EDMA3_DRV_TCC_ANY)
482 {
483 mappedTcc = drvObject->gblCfgParams.dmaChannelTccMap[*pLCh];
484 if (mappedTcc == EDMA3_DRV_CH_NO_TCC_MAP)
485 {
486 mappedTcc = EDMA3_RM_RES_ANY;
487 }
488 }
489 else
490 {
491 mappedTcc = *pTcc;
492 }
494 /* Save the Resource Type/ID for TCC registeration */
495 channelObj.type = EDMA3_RM_RES_DMA_CHANNEL;
496 channelObj.resId = *pLCh;
498 /* Free DMA channel in case the function fails in future */
499 freeDmaQdmaChannel = TRUE;
500 }
501 else
502 {
503 result = EDMA3_DRV_E_DMA_CHANNEL_UNAVAIL;
504 }
506 break;
508 case EDMA3_DRV_CHANNEL_TYPE_QDMA:
509 result = EDMA3_RM_allocResource(drvInst->resMgrInstance,
510 (EDMA3_RM_ResDesc *)&resObj);
511 if (result == EDMA3_DRV_SOK)
512 {
513 (*pLCh) = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
515 if (*pTcc == EDMA3_DRV_TCC_ANY)
516 {
517 mappedTcc = EDMA3_RM_RES_ANY;
518 }
519 else
520 {
521 mappedTcc = *pTcc;
522 }
524 /* Save the Resource Type/ID for TCC registeration */
525 channelObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
526 channelObj.resId = resObj.resId;
528 /* Free DMA channel in case the function fails in future */
529 freeDmaQdmaChannel = TRUE;
530 }
531 else
532 {
533 result = EDMA3_DRV_E_QDMA_CHANNEL_UNAVAIL;
534 }
535 break;
537 default:
538 break;
539 }
540 }
542 /* Step 2: Allocate the PaRAM Set */
543 if (EDMA3_DRV_SOK == result)
544 {
545 resObj.type = EDMA3_RM_RES_PARAM_SET;
546 resObj.resId = (unsigned int)paRAMId;
547 result = EDMA3_RM_allocResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
548 }
550 if (EDMA3_DRV_SOK == result)
551 {
552 paRAMId = (int)resObj.resId;
554 if (chType == EDMA3_DRV_CHANNEL_TYPE_LINK)
555 {
556 /* Link channel number should be same as the PaRAM Set */
557 *pLCh = resObj.resId;
558 edma3DrvChBoundRes[edma3Id][*pLCh].paRAMId = paRAMId;
559 edma3DrvChBoundRes[edma3Id][*pLCh].trigMode = EDMA3_DRV_TRIG_MODE_NONE;
560 }
562 if (chType == EDMA3_DRV_CHANNEL_TYPE_LINK_TCC)
563 {
564 /* Link channel number should be same as the PaRAM Set */
565 *pLCh = resObj.resId;
566 edma3DrvChBoundRes[edma3Id][*pLCh].paRAMId = paRAMId;
567 edma3DrvChBoundRes[edma3Id][*pLCh].trigMode = EDMA3_DRV_TRIG_MODE_NONE;
569 /* save the tcc now */
570 edma3DrvChBoundRes[edma3Id][*pLCh].tcc = *pTcc;
572 /* Set TCC in ParamSet.OPT field */
573 globalRegs->PARAMENTRY [paRAMId].OPT &= EDMA3_DRV_OPT_TCC_CLR_MASK;
574 globalRegs->PARAMENTRY [paRAMId].OPT |= EDMA3_DRV_OPT_TCC_SET_MASK(*pTcc);
575 }
576 }
577 else
578 {
579 /* PaRAM allocation failed, free the previously allocated DMA/QDMA
580 * channel, if required
581 */
582 if ((chType == EDMA3_DRV_CHANNEL_TYPE_DMA
583 || chType == EDMA3_DRV_CHANNEL_TYPE_QDMA) &&
584 (TRUE == freeDmaQdmaChannel))
585 {
586 EDMA3_RM_freeResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&channelObj);
587 }
588 }
590 /* Step 3: Allocate TCC only for DMA/QDMA channels */
591 if ((EDMA3_DRV_SOK == result) &&
592 (chType == EDMA3_DRV_CHANNEL_TYPE_DMA || chType == EDMA3_DRV_CHANNEL_TYPE_QDMA))
593 {
594 resObj.type = EDMA3_RM_RES_TCC;
595 resObj.resId = mappedTcc;
596 result = EDMA3_RM_allocResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
598 if (EDMA3_DRV_SOK == result)
599 {
600 *pTcc = resObj.resId;
602 /* Save TCC and PaRAM set */
603 edma3DrvChBoundRes[edma3Id][*pLCh].tcc = *pTcc;
604 edma3DrvChBoundRes[edma3Id][*pLCh].paRAMId = paRAMId;
606 switch (chType)
607 {
608 case EDMA3_DRV_CHANNEL_TYPE_DMA:
609 {
610 /* Step 4: Register the callback function, if required */
611 if (NULL != tccCb)
612 {
613 result = EDMA3_RM_registerTccCb (drvInst->resMgrInstance,
614 (EDMA3_RM_ResDesc *)&channelObj,
615 *pTcc, tccCb, cbData);
616 }
617 if (result != EDMA3_DRV_SOK)
618 {
619 EDMA3_DRV_freeChannel (hEdma, *pLCh);
620 result = EDMA3_DRV_E_TCC_REGISTER_FAIL;
621 }
622 else
623 {
624 #ifndef EDMA3_PROGRAM_QUEUE_NUM_REGISTER_INIT_TIME
625 unsigned int intState = 0;
626 edma3OsProtectEntry(edma3Id, EDMA3_OS_PROTECT_INTERRUPT,
627 &intState);
628 /* Step 5: Associate DMA Channel to Event Queue */
629 globalRegs->DMAQNUM[(*pLCh) >> 3u] &= EDMA3_DRV_DMAQNUM_CLR_MASK(*pLCh);
630 globalRegs->DMAQNUM[(*pLCh) >> 3u] |= EDMA3_DRV_DMAQNUM_SET_MASK((*pLCh), evtQueue);
632 edma3OsProtectExit(edma3Id, EDMA3_OS_PROTECT_INTERRUPT,
633 intState);
634 #endif
636 /* Step 6: Map PaRAM Set to DMA Channel */
637 if (TRUE == drvObject->gblCfgParams.dmaChPaRAMMapExists)
638 {
639 globalRegs->DCHMAP[*pLCh] &= EDMA3_DRV_DCH_PARAM_CLR_MASK;
640 globalRegs->DCHMAP[*pLCh] |= EDMA3_DRV_DCH_PARAM_SET_MASK(paRAMId);
641 }
643 /* Step 7: Set TCC in ParamSet.OPT field */
644 globalRegs->PARAMENTRY [paRAMId].OPT &= EDMA3_DRV_OPT_TCC_CLR_MASK;
645 globalRegs->PARAMENTRY [paRAMId].OPT |= EDMA3_DRV_OPT_TCC_SET_MASK(*pTcc);
647 edma3DrvChBoundRes[edma3Id][*pLCh].trigMode = EDMA3_DRV_TRIG_MODE_NONE;
648 }
649 }
650 break;
652 case EDMA3_DRV_CHANNEL_TYPE_QDMA:
653 {
654 unsigned int qdmaChannel = channelObj.resId;
656 /* Step 4: Register the callback function, if required */
657 if (NULL != tccCb)
658 {
659 result = EDMA3_RM_registerTccCb (drvInst->resMgrInstance,
660 (EDMA3_RM_ResDesc *)&channelObj,
661 *pTcc, tccCb, cbData);
662 }
663 if (result != EDMA3_DRV_SOK)
664 {
665 EDMA3_DRV_freeChannel (hEdma, *pLCh);
666 result = EDMA3_DRV_E_TCC_REGISTER_FAIL;
667 }
668 else
669 {
670 #ifndef EDMA3_PROGRAM_QUEUE_NUM_REGISTER_INIT_TIME
671 unsigned int intState = 0;
672 edma3OsProtectEntry(edma3Id, EDMA3_OS_PROTECT_INTERRUPT,
673 &intState);
674 /* Step 5: Associate QDMA Channel to Event Queue */
675 globalRegs->QDMAQNUM &= EDMA3_DRV_QDMAQNUM_CLR_MASK(qdmaChannel);
676 globalRegs->QDMAQNUM |= EDMA3_DRV_QDMAQNUM_SET_MASK(qdmaChannel, evtQueue);
678 edma3OsProtectExit(edma3Id, EDMA3_OS_PROTECT_INTERRUPT,
679 intState);
680 #endif
682 /* Step 6: Map PaRAM Set to DMA Channel and set the Default Trigger Word */
683 globalRegs->QCHMAP[qdmaChannel] &= EDMA3_DRV_QCH_PARAM_TRWORD_CLR_MASK;
684 globalRegs->QCHMAP[qdmaChannel] |= EDMA3_DRV_QCH_PARAM_SET_MASK(paRAMId);
685 globalRegs->QCHMAP[qdmaChannel] |= EDMA3_DRV_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
687 /* Step 7: Set TCC in ParamSet.OPT field */
688 globalRegs->PARAMENTRY [paRAMId].OPT &= EDMA3_DRV_OPT_TCC_CLR_MASK;
689 globalRegs->PARAMENTRY [paRAMId].OPT |= EDMA3_DRV_OPT_TCC_SET_MASK(*pTcc);
691 edma3DrvChBoundRes[edma3Id][*pLCh].trigMode = EDMA3_DRV_TRIG_MODE_QDMA;
693 /* Step 8: Enable the QDMA Channel */
694 drvInst->shadowRegs->QEESR = 1u << qdmaChannel;
695 }
696 }
697 break;
698 }
699 }
700 else
701 {
702 /* TCC allocation failed, free the PaRAM Set, */
703 resObj.type = EDMA3_RM_RES_PARAM_SET;
704 resObj.resId = (unsigned int)paRAMId;
705 EDMA3_RM_freeResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
707 /* And free the DMA/QDMA channel */
708 EDMA3_RM_freeResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&channelObj);
710 result = EDMA3_DRV_E_TCC_UNAVAIL;
711 }
712 }
714 #ifdef EDMA3_INSTRUMENTATION_ENABLED
715 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
716 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
717 EDMA3_DVT_dCOUNTER,
718 EDMA3_DVT_dNONE,
719 EDMA3_DVT_dNONE));
720 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
722 return result;
723 }
726 /**
727 * \brief Free the specified channel (DMA/QDMA/Link) and its associated
728 * resources (PaRAM Set, TCC etc) and removes various mappings.
729 *
730 * This API internally uses EDMA3_RM_freeResource () to free the desired
731 * resources.
732 *
733 * For Link channels, this API only frees the associated PaRAM Set.
734 *
735 * For DMA/QDMA channels, it does the following operations:
736 * a) Disable any ongoing transfer on the channel,
737 * b) Unregister the TCC Callback function and disable the interrupts,
738 * c) Remove the channel to Event Queue mapping,
739 * d) For DMA channels, clear the DCHMAP register, if available
740 * e) For QDMA channels, clear the QCHMAP register,
741 * f) Frees the DMA/QDMA channel in the end.
742 *
743 * \param hEdma [IN] Handle to the EDMA Driver Instance.
744 * \param channelId [IN] Logical Channel number to be freed.
745 *
746 * \return EDMA3_DRV_SOK or EDMA3_DRV Error code
747 *
748 * \note This function disables the global interrupts while modifying
749 * the global CC registers and while modifying global data structures,
750 * to prevent simultaneous access to the global pool of resources.
751 * It internally calls EDMA3_RM_freeResource () for resource
752 * de-allocation. It is re-entrant.
753 */
754 EDMA3_DRV_Result EDMA3_DRV_freeChannel (EDMA3_DRV_Handle hEdma,
755 unsigned int channelId)
756 {
757 EDMA3_RM_ResDesc resObj;
758 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
759 EDMA3_DRV_Instance *drvInst = NULL;
760 EDMA3_DRV_Object *drvObject = NULL;
761 int paRAMId;
762 unsigned int tcc;
763 EDMA3_DRV_ChannelType chType = EDMA3_DRV_CHANNEL_TYPE_NONE;
764 unsigned int edma3Id;
766 #ifdef EDMA3_INSTRUMENTATION_ENABLED
767 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
768 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
769 EDMA3_DVT_dCOUNTER,
770 EDMA3_DVT_dNONE,
771 EDMA3_DVT_dNONE));
772 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
774 /* If parameter checking is enabled... */
775 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
776 if (hEdma == NULL)
777 {
778 result = EDMA3_DRV_E_INVALID_PARAM;
779 }
780 #endif
782 if (EDMA3_DRV_SOK == result)
783 {
784 drvInst = (EDMA3_DRV_Instance *)hEdma;
785 drvObject = drvInst->pDrvObjectHandle;
787 if (drvObject == NULL)
788 {
789 result = EDMA3_DRV_E_INVALID_PARAM;
790 }
791 else
792 {
793 edma3Id = drvObject->phyCtrllerInstId;
794 }
795 }
797 if (EDMA3_DRV_SOK == result)
798 {
799 /* Check the channel type */
800 if (channelId <= edma3_dma_ch_max_val [edma3Id])
801 {
802 /* DMA Channel */
803 chType = EDMA3_DRV_CHANNEL_TYPE_DMA;
804 }
806 if ((channelId >= edma3_link_ch_min_val[edma3Id])
807 && (channelId <= edma3_link_ch_max_val[edma3Id]))
808 {
809 /* LINK Channel */
810 chType = EDMA3_DRV_CHANNEL_TYPE_LINK;
811 }
813 if ((channelId >= edma3_qdma_ch_min_val[edma3Id])
814 && (channelId <= edma3_qdma_ch_max_val[edma3Id]))
815 {
816 /* QDMA Channel */
817 chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
818 }
820 if (chType == EDMA3_DRV_CHANNEL_TYPE_NONE)
821 {
822 result = EDMA3_DRV_E_INVALID_PARAM;
823 }
824 }
827 if (EDMA3_DRV_SOK == result)
828 {
829 if (chType == EDMA3_DRV_CHANNEL_TYPE_LINK)
830 {
831 /* LINK Channel */
832 resObj.type = EDMA3_RM_RES_PARAM_SET;
834 /* Get the PaRAM id from the book-keeping info. */
835 resObj.resId = (unsigned int)(edma3DrvChBoundRes[edma3Id][channelId].paRAMId);
837 result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
838 (EDMA3_RM_ResDesc *)&resObj);
840 if (EDMA3_DRV_SOK == result)
841 {
842 edma3DrvChBoundRes[edma3Id][channelId].paRAMId = -1;
843 }
844 }
845 else
846 {
847 /* DMA/QDMA Channel */
848 paRAMId = edma3DrvChBoundRes[edma3Id][channelId].paRAMId;
849 tcc = edma3DrvChBoundRes[edma3Id][channelId].tcc;
851 /* Check the paRAMId and tcc values first */
852 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
853 {
854 result = EDMA3_DRV_E_INVALID_PARAM;
855 }
857 if (tcc >= drvObject->gblCfgParams.numTccs)
858 {
859 result = EDMA3_DRV_E_INVALID_PARAM;
860 }
862 if (EDMA3_DRV_SOK == result)
863 {
864 /* Disable the transfer and remove various mappings. */
865 result = edma3RemoveMapping(hEdma, channelId);
866 }
868 if (EDMA3_DRV_SOK == result)
869 {
870 /* Now Free the PARAM set and TCC */
871 resObj.type = EDMA3_RM_RES_PARAM_SET;
872 resObj.resId = (unsigned int)paRAMId;
873 result = EDMA3_RM_freeResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
875 if (EDMA3_DRV_SOK == result)
876 {
877 /* PaRAM Set Freed */
878 edma3DrvChBoundRes[edma3Id][channelId].paRAMId = -1;
880 /* Free the TCC */
881 resObj.type = EDMA3_RM_RES_TCC;
882 resObj.resId = tcc;
883 result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
884 (EDMA3_RM_ResDesc *)&resObj);
885 }
887 if (EDMA3_DRV_SOK == result)
888 {
889 /* TCC Freed. */
890 edma3DrvChBoundRes[edma3Id][channelId].tcc = EDMA3_MAX_TCC;
892 /* Now free the DMA/QDMA Channel in the end. */
893 if (chType == EDMA3_DRV_CHANNEL_TYPE_QDMA)
894 {
895 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
896 resObj.resId = (channelId - edma3_qdma_ch_min_val[edma3Id]);
897 result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
898 (EDMA3_RM_ResDesc *)&resObj);
899 }
900 else
901 {
902 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
903 resObj.resId = channelId;
904 result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
905 (EDMA3_RM_ResDesc *)&resObj);
906 }
907 }
908 }
909 }
910 }
913 #ifdef EDMA3_INSTRUMENTATION_ENABLED
914 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
915 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
916 EDMA3_DVT_dCOUNTER,
917 EDMA3_DVT_dNONE,
918 EDMA3_DVT_dNONE));
919 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
921 return result;
922 }
925 /**
926 * \brief Disables the DMA Channel by clearing the Event Enable Register and
927 * clears Error Register & Secondary Event Register for a specific DMA channel.
928 *
929 * This API clears the Event Enable register, Event Miss register and Secondary
930 * Event register for a specific DMA channel. It also clears the CC Error
931 * register.
932 *
933 * \param hEdma [IN] Handle to the EDMA Driver Instance.
934 * \param channelId [IN] DMA Channel needs to be cleaned.
935 *
936 * \return EDMA3_DRV_SOK or EDMA3_DRV Error code
937 *
938 * \note This function is re-entrant for unique channelId values. It is non-
939 * re-entrant for same channelId value.
940 */
941 EDMA3_DRV_Result EDMA3_DRV_clearErrorBits (EDMA3_DRV_Handle hEdma,
942 unsigned int channelId)
943 {
944 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
945 EDMA3_DRV_Instance *drvInst = NULL;
946 EDMA3_DRV_Object *drvObject = NULL;
947 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
948 unsigned int count;
949 unsigned int value = 0;
950 unsigned int edma3Id;
952 #ifdef EDMA3_INSTRUMENTATION_ENABLED
953 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
954 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
955 EDMA3_DVT_dCOUNTER,
956 EDMA3_DVT_dNONE,
957 EDMA3_DVT_dNONE));
958 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
960 /* If parameter checking is enabled... */
961 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
962 if (hEdma == NULL)
963 {
964 result = EDMA3_DRV_E_INVALID_PARAM;
965 }
966 #endif
968 /* Check if the parameters are OK. */
969 if (EDMA3_DRV_SOK == result)
970 {
971 drvInst = (EDMA3_DRV_Instance *)hEdma;
972 drvObject = drvInst->pDrvObjectHandle;
974 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
975 {
976 result = EDMA3_DRV_E_INVALID_PARAM;
977 }
978 else
979 {
980 edma3Id = drvObject->phyCtrllerInstId;
982 /* If parameter checking is enabled... */
983 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
984 if (channelId > edma3_dma_ch_max_val [edma3Id])
985 {
986 result = EDMA3_DRV_E_INVALID_PARAM;
987 }
988 #endif
990 /* Check if the parameters are OK. */
991 if (EDMA3_DRV_SOK == result)
992 {
993 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
995 #ifdef EDMA3_DRV_DEBUG
996 EDMA3_DRV_PRINTF("EMR =%l\r\n", globalRegs->EMR);
997 #endif
998 if(channelId < 32u)
999 {
1000 /* Disables the DMA channels */
1001 drvInst->shadowRegs->EECR = (1u << channelId);
1002 /* Write to EMCR to clear the corresponding EMR bit */
1003 globalRegs->EMCR = (1u << channelId);
1004 /* Clears the SER */
1005 drvInst->shadowRegs->SECR = (1u << channelId);
1006 }
1007 else
1008 {
1009 #ifdef EDMA3_DRV_DEBUG
1010 EDMA3_DRV_PRINTF("EMRH =%l\r\n", globalRegs->EMRH);
1011 #endif
1012 /* Disables the DMA channels */
1013 drvInst->shadowRegs->EECRH = (1u << (channelId - 32u));
1014 /* Write to EMCR to clear the corresponding EMR bit */
1015 globalRegs->EMCRH = (1u << (channelId - 32u));
1016 /* Clears the SER */
1017 drvInst->shadowRegs->SECRH = (1u << (channelId - 32u));
1018 }
1020 /* Clear the global CC Error Register */
1021 for (count = 0; count < drvObject->gblCfgParams.numEvtQueue; count++)
1022 {
1023 value |= (1u << count);
1024 }
1026 globalRegs->CCERRCLR = (EDMA3_CCRL_CCERR_TCCERR_MASK | value);
1027 }
1028 }
1029 }
1031 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1032 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1033 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1034 EDMA3_DVT_dCOUNTER,
1035 EDMA3_DVT_dNONE,
1036 EDMA3_DVT_dNONE));
1037 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1039 return result;
1040 }
1043 /**
1044 * \brief Set a particular OPT field in the PaRAM set associated with the
1045 * logical channel 'lCh'.
1046 *
1047 * This API can be used to set various optional parameters for an EDMA3
1048 * transfer. Like enable/disable completion interrupts, enable/disable chaining,
1049 * setting the transfer mode (A/AB Sync), setting the FIFO width etc.
1050 *
1051 * \param hEdma [IN] Handle to the EDMA Driver Instance.
1052 * \param lCh [IN] Logical Channel, bound to which
1053 * PaRAM set OPT field needs to be set.
1054 * \param optField [IN] The particular field of OPT Word
1055 * that needs setting
1056 * \param newOptFieldVal [IN] The new OPT field value
1057 *
1058 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1059 *
1060 * \note This function is re-entrant for unique lCh values. It is non-
1061 * re-entrant for same lCh value.
1062 */
1063 EDMA3_DRV_Result EDMA3_DRV_setOptField (EDMA3_DRV_Handle hEdma,
1064 unsigned int lCh,
1065 EDMA3_DRV_OptField optField,
1066 unsigned int newOptFieldVal)
1067 {
1068 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1069 EDMA3_DRV_Instance *drvInst = NULL;
1070 EDMA3_DRV_Object *drvObject = NULL;
1071 unsigned int newOptVal = 0;
1072 unsigned int oldOptVal = 0;
1073 int paRAMId = 0;
1074 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1075 unsigned int edma3Id;
1077 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1078 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1079 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1080 EDMA3_DVT_dCOUNTER,
1081 EDMA3_DVT_dNONE,
1082 EDMA3_DVT_dNONE));
1083 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1085 /* If parameter checking is enabled... */
1086 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1087 if ((hEdma == NULL)
1088 || ((optField < EDMA3_DRV_OPT_FIELD_SAM)
1089 || (optField > EDMA3_DRV_OPT_FIELD_ITCCHEN)))
1090 {
1091 result = EDMA3_DRV_E_INVALID_PARAM;
1092 }
1093 #endif
1095 /* Check if the parameters are OK. */
1096 if (EDMA3_DRV_SOK == result)
1097 {
1098 drvInst = (EDMA3_DRV_Instance *)hEdma;
1099 drvObject = drvInst->pDrvObjectHandle;
1101 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1102 {
1103 result = EDMA3_DRV_E_INVALID_PARAM;
1104 }
1105 else
1106 {
1107 edma3Id = drvObject->phyCtrllerInstId;
1108 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1109 }
1110 }
1112 /* If parameter checking is enabled... */
1113 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1114 if (lCh > edma3_log_ch_max_val [edma3Id])
1115 {
1116 result = EDMA3_DRV_E_INVALID_PARAM;
1117 }
1118 #endif
1120 if (EDMA3_DRV_SOK == result)
1121 {
1122 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1123 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1124 {
1125 result = EDMA3_DRV_E_INVALID_PARAM;
1126 }
1127 }
1129 if (EDMA3_DRV_SOK == result)
1130 {
1131 oldOptVal = (unsigned int)(*(&globalRegs->PARAMENTRY [paRAMId].OPT));
1133 switch (optField)
1134 {
1135 case EDMA3_DRV_OPT_FIELD_SAM :
1136 newOptVal = (oldOptVal & EDMA3_DRV_OPT_SAM_CLR_MASK)
1137 |
1138 (EDMA3_DRV_OPT_SAM_SET_MASK(newOptFieldVal));
1139 break;
1140 case EDMA3_DRV_OPT_FIELD_DAM :
1141 newOptVal = (oldOptVal & EDMA3_DRV_OPT_DAM_CLR_MASK)
1142 |
1143 (EDMA3_DRV_OPT_DAM_SET_MASK(newOptFieldVal));
1144 break;
1145 case EDMA3_DRV_OPT_FIELD_SYNCDIM :
1146 newOptVal = (oldOptVal & EDMA3_DRV_OPT_SYNCDIM_CLR_MASK)
1147 |
1148 (EDMA3_DRV_OPT_SYNCDIM_SET_MASK(newOptFieldVal));
1149 break;
1150 case EDMA3_DRV_OPT_FIELD_STATIC :
1151 newOptVal = (oldOptVal & EDMA3_DRV_OPT_STATIC_CLR_MASK)
1152 |
1153 (EDMA3_DRV_OPT_STATIC_SET_MASK(newOptFieldVal));
1154 break;
1155 case EDMA3_DRV_OPT_FIELD_FWID :
1156 newOptVal = (oldOptVal & EDMA3_DRV_OPT_FWID_CLR_MASK)
1157 |
1158 (EDMA3_DRV_OPT_FWID_SET_MASK(newOptFieldVal));
1159 break;
1160 case EDMA3_DRV_OPT_FIELD_TCCMODE :
1161 newOptVal = (oldOptVal & EDMA3_DRV_OPT_TCCMODE_CLR_MASK)
1162 |
1163 (EDMA3_DRV_OPT_TCCMODE_SET_MASK(newOptFieldVal));
1164 break;
1165 case EDMA3_DRV_OPT_FIELD_TCC :
1166 newOptVal = (oldOptVal & EDMA3_DRV_OPT_TCC_CLR_MASK)
1167 |
1168 (EDMA3_DRV_OPT_TCC_SET_MASK(newOptFieldVal));
1169 break;
1170 case EDMA3_DRV_OPT_FIELD_TCINTEN :
1171 newOptVal = (oldOptVal & EDMA3_DRV_OPT_TCINTEN_CLR_MASK)
1172 |
1173 (EDMA3_DRV_OPT_TCINTEN_SET_MASK(newOptFieldVal));
1174 break;
1175 case EDMA3_DRV_OPT_FIELD_ITCINTEN :
1176 newOptVal = (oldOptVal & EDMA3_DRV_OPT_ITCINTEN_CLR_MASK)
1177 |
1178 (EDMA3_DRV_OPT_ITCINTEN_SET_MASK(newOptFieldVal));
1179 break;
1180 case EDMA3_DRV_OPT_FIELD_TCCHEN :
1181 newOptVal = (oldOptVal & EDMA3_DRV_OPT_TCCHEN_CLR_MASK)
1182 |
1183 (EDMA3_DRV_OPT_TCCHEN_SET_MASK(newOptFieldVal));
1184 break;
1185 case EDMA3_DRV_OPT_FIELD_ITCCHEN :
1186 newOptVal = (oldOptVal & EDMA3_DRV_OPT_ITCCHEN_CLR_MASK)
1187 |
1188 (EDMA3_DRV_OPT_ITCCHEN_SET_MASK(newOptFieldVal));
1189 break;
1190 default:
1191 break;
1192 }
1194 *(&globalRegs->PARAMENTRY[paRAMId].OPT) = newOptVal;
1195 }
1197 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1198 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1199 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1200 EDMA3_DVT_dCOUNTER,
1201 EDMA3_DVT_dNONE,
1202 EDMA3_DVT_dNONE));
1203 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1205 return result;
1206 }
1209 /**
1210 * \brief Get a particular OPT field in the PaRAM set associated with the
1211 * logical channel 'lCh'.
1212 *
1213 * This API can be used to read various optional parameters for an EDMA3
1214 * transfer. Like enable/disable completion interrupts, enable/disable chaining,
1215 * setting the transfer mode (A/AB Sync), setting the FIFO width etc.
1216 *
1217 * \param hEdma [IN] Handle to the EDMA Driver Instance.
1218 * \param lCh [IN] Logical Channel, bound to which
1219 * PaRAM set OPT field is required.
1220 * \param optField [IN] The particular field of OPT Word
1221 * that is needed
1222 * \param optFieldVal [IN/OUT] Value of the OPT field
1223 *
1224 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1225 *
1226 * \note This function is re-entrant.
1227 */
1228 EDMA3_DRV_Result EDMA3_DRV_getOptField (EDMA3_DRV_Handle hEdma,
1229 unsigned int lCh,
1230 EDMA3_DRV_OptField optField,
1231 unsigned int *optFieldVal)
1232 {
1233 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1234 EDMA3_DRV_Instance *drvInst = NULL;
1235 EDMA3_DRV_Object *drvObject = NULL;
1236 unsigned int optVal = 0;
1237 int paRAMId = 0;
1238 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1239 unsigned int edma3Id;
1241 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1242 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1243 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1244 EDMA3_DVT_dCOUNTER,
1245 EDMA3_DVT_dNONE,
1246 EDMA3_DVT_dNONE));
1247 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1249 /* If parameter checking is enabled... */
1250 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1251 if (((hEdma == NULL) || (optFieldVal == NULL))
1252 || ((optField < EDMA3_DRV_OPT_FIELD_SAM)
1253 || (optField > EDMA3_DRV_OPT_FIELD_ITCCHEN)))
1254 {
1255 result = EDMA3_DRV_E_INVALID_PARAM;
1256 }
1257 #endif
1259 /* Check if the parameters are OK. */
1260 if (EDMA3_DRV_SOK == result)
1261 {
1262 drvInst = (EDMA3_DRV_Instance *)hEdma;
1263 drvObject = drvInst->pDrvObjectHandle;
1265 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1266 {
1267 result = EDMA3_DRV_E_INVALID_PARAM;
1268 }
1269 else
1270 {
1271 edma3Id = drvObject->phyCtrllerInstId;
1272 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1273 }
1274 }
1276 /* If parameter checking is enabled... */
1277 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1278 if (lCh > edma3_log_ch_max_val [edma3Id])
1279 {
1280 result = EDMA3_DRV_E_INVALID_PARAM;
1281 }
1282 #endif
1284 if (EDMA3_DRV_SOK == result)
1285 {
1286 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1287 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1288 {
1289 result = EDMA3_DRV_E_INVALID_PARAM;
1290 }
1291 }
1293 if (EDMA3_DRV_SOK == result)
1294 {
1295 optVal = (unsigned int)(*(&globalRegs->PARAMENTRY [paRAMId].OPT));
1297 switch (optField)
1298 {
1299 case EDMA3_DRV_OPT_FIELD_SAM :
1300 *optFieldVal = EDMA3_DRV_OPT_SAM_GET_MASK(optVal);
1301 break;
1302 case EDMA3_DRV_OPT_FIELD_DAM :
1303 *optFieldVal = EDMA3_DRV_OPT_DAM_GET_MASK(optVal);
1304 break;
1305 case EDMA3_DRV_OPT_FIELD_SYNCDIM :
1306 *optFieldVal = EDMA3_DRV_OPT_SYNCDIM_GET_MASK(optVal);
1307 break;
1308 case EDMA3_DRV_OPT_FIELD_STATIC :
1309 *optFieldVal = EDMA3_DRV_OPT_STATIC_GET_MASK(optVal);
1310 break;
1311 case EDMA3_DRV_OPT_FIELD_FWID :
1312 *optFieldVal = EDMA3_DRV_OPT_FWID_GET_MASK(optVal);
1313 break;
1314 case EDMA3_DRV_OPT_FIELD_TCCMODE :
1315 *optFieldVal = EDMA3_DRV_OPT_TCCMODE_GET_MASK(optVal);
1316 break;
1317 case EDMA3_DRV_OPT_FIELD_TCC :
1318 *optFieldVal = EDMA3_DRV_OPT_TCC_GET_MASK(optVal);
1319 break;
1320 case EDMA3_DRV_OPT_FIELD_TCINTEN :
1321 *optFieldVal = EDMA3_DRV_OPT_TCINTEN_GET_MASK(optVal);
1322 break;
1323 case EDMA3_DRV_OPT_FIELD_ITCINTEN :
1324 *optFieldVal = EDMA3_DRV_OPT_ITCINTEN_GET_MASK(optVal);
1325 break;
1326 case EDMA3_DRV_OPT_FIELD_TCCHEN :
1327 *optFieldVal = EDMA3_DRV_OPT_TCCHEN_GET_MASK(optVal);
1328 break;
1329 case EDMA3_DRV_OPT_FIELD_ITCCHEN :
1330 *optFieldVal = EDMA3_DRV_OPT_ITCCHEN_GET_MASK(optVal);
1331 break;
1332 default:
1333 break;
1334 }
1335 }
1337 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1338 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1339 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1340 EDMA3_DVT_dCOUNTER,
1341 EDMA3_DVT_dNONE,
1342 EDMA3_DVT_dNONE));
1343 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1345 return result;
1346 }
1350 /**
1351 * \brief DMA source parameters setup
1352 *
1353 * It is used to program the source address, source side addressing mode
1354 * (INCR or FIFO) and the FIFO width in case the addressing mode is FIFO.
1355 *
1356 * In FIFO Addressing mode, memory location must be 32 bytes aligned.
1357 *
1358 * \param hEdma [IN] Handle to the EDMA Driver Instance
1359 * \param lCh [IN] Logical Channel for which the source parameters
1360 * are to be configured
1361 * \param srcAddr [IN] Source address
1362 * \param addrMode [IN] Address mode [FIFO or Increment]
1363 * \param fifoWidth [IN] Width of FIFO (Valid only if addrMode is FIFO)
1364 * -# 0 - 8 bit
1365 * -# 1 - 16 bit
1366 * -# 2 - 32 bit
1367 * -# 3 - 64 bit
1368 * -# 4 - 128 bit
1369 * -# 5 - 256 bit
1370 *
1371 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1372 *
1373 * \note This function is re-entrant for unique lCh values. It is non-
1374 * re-entrant for same lCh value.
1375 */
1376 EDMA3_DRV_Result EDMA3_DRV_setSrcParams (EDMA3_DRV_Handle hEdma,
1377 unsigned int lCh,
1378 unsigned int srcAddr,
1379 EDMA3_DRV_AddrMode addrMode,
1380 EDMA3_DRV_FifoWidth fifoWidth)
1381 {
1382 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1383 unsigned int opt = 0;
1384 EDMA3_DRV_Instance *drvInst = NULL;
1385 EDMA3_DRV_Object *drvObject = NULL;
1386 int paRAMId = 0;
1387 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1388 unsigned int mappedEvtQ = 0;
1389 unsigned int defaultBurstSize = 0;
1390 unsigned int edma3Id;
1392 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1393 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1394 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1395 EDMA3_DVT_dCOUNTER,
1396 EDMA3_DVT_dNONE,
1397 EDMA3_DVT_dNONE));
1398 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1400 /* If parameter checking is enabled... */
1401 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1402 if ((hEdma == NULL)
1403 || (((addrMode < EDMA3_DRV_ADDR_MODE_INCR) || (addrMode > EDMA3_DRV_ADDR_MODE_FIFO))
1404 || ((fifoWidth < EDMA3_DRV_W8BIT) || (fifoWidth > EDMA3_DRV_W256BIT))))
1405 {
1406 result = EDMA3_DRV_E_INVALID_PARAM;
1407 }
1409 /** In FIFO Addressing mode, memory location must be 32 bytes aligned */
1410 if ((addrMode == EDMA3_DRV_ADDR_MODE_FIFO)
1411 && ((srcAddr & 0x1Fu) != NULL))
1412 {
1413 /** Memory is not 32 bytes aligned */
1414 result = EDMA3_DRV_E_ADDRESS_NOT_ALIGNED;
1415 }
1416 #endif
1418 /* Check if the parameters are OK. */
1419 if (EDMA3_DRV_SOK == result)
1420 {
1421 drvInst = (EDMA3_DRV_Instance *)hEdma;
1422 drvObject = drvInst->pDrvObjectHandle;
1424 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1425 {
1426 result = EDMA3_DRV_E_INVALID_PARAM;
1427 }
1428 else
1429 {
1430 edma3Id = drvObject->phyCtrllerInstId;
1431 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1432 }
1433 }
1435 /* If parameter checking is enabled... */
1436 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1437 if (lCh > edma3_log_ch_max_val [edma3Id])
1438 {
1439 result = EDMA3_DRV_E_INVALID_PARAM;
1440 }
1441 #endif
1443 if (EDMA3_DRV_SOK == result)
1444 {
1445 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1446 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1447 {
1448 result = EDMA3_DRV_E_INVALID_PARAM;
1449 }
1450 }
1452 if (EDMA3_DRV_SOK == result)
1453 {
1454 /**
1455 * If request is for FIFO mode, check whether the FIFO size
1456 * is supported by the Transfer Controller which will be used for
1457 * this transfer or not.
1458 */
1459 if (addrMode == EDMA3_DRV_ADDR_MODE_FIFO)
1460 {
1461 if (lCh <= edma3_dma_ch_max_val [edma3Id])
1462 {
1463 mappedEvtQ = ((globalRegs->DMAQNUM[lCh >> 3u])
1464 & (~(EDMA3_DRV_DMAQNUM_CLR_MASK(lCh))))
1465 >> ((lCh%8u)*4u);
1466 }
1467 else
1468 {
1469 if ((lCh >= edma3_qdma_ch_min_val[edma3Id])
1470 &&(lCh <= edma3_qdma_ch_max_val[edma3Id]))
1471 {
1472 mappedEvtQ = ((globalRegs->QDMAQNUM)
1473 & (~(EDMA3_DRV_QDMAQNUM_CLR_MASK(lCh - edma3_qdma_ch_min_val[edma3Id]))))
1474 >> (lCh*4u);
1475 }
1476 }
1478 /**
1479 * mappedEvtQ contains the event queue and hence the TC which will
1480 * process this transfer request. Check whether this TC supports the
1481 * FIFO size or not.
1482 */
1483 defaultBurstSize = 1u << fifoWidth;
1484 if (defaultBurstSize > drvObject->gblCfgParams.tcDefaultBurstSize[mappedEvtQ])
1485 {
1486 result = EDMA3_DRV_E_FIFO_WIDTH_NOT_SUPPORTED;
1487 }
1488 }
1489 }
1491 if (EDMA3_DRV_SOK == result)
1492 {
1493 /* Set Src Address */
1494 *((&globalRegs->PARAMENTRY[paRAMId].OPT) +
1495 (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC) = srcAddr;
1497 opt = (unsigned int)(*(&globalRegs->PARAMENTRY [paRAMId].OPT));
1499 /* Set SAM */
1500 opt &= EDMA3_DRV_OPT_SAM_CLR_MASK;
1501 opt |= EDMA3_DRV_OPT_SAM_SET_MASK(addrMode);
1502 /* Set FIFO Width */
1503 opt &= EDMA3_DRV_OPT_FWID_CLR_MASK;
1504 opt |= EDMA3_DRV_OPT_FWID_SET_MASK(fifoWidth);
1506 /* Set the OPT */
1507 *(&globalRegs->PARAMENTRY[paRAMId].OPT) = opt;
1508 }
1510 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1511 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1512 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1513 EDMA3_DVT_dCOUNTER,
1514 EDMA3_DVT_dNONE,
1515 EDMA3_DVT_dNONE));
1516 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1518 return result;
1519 }
1523 /**
1524 * \brief DMA Destination parameters setup
1525 *
1526 * It is used to program the destination address, destination side addressing
1527 * mode (INCR or FIFO) and the FIFO width in case the addressing mode is FIFO.
1528 *
1529 * In FIFO Addressing mode, memory location must be 32 bytes aligned.
1530 *
1531 * \param hEdma [IN] Handle to the EDMA Driver Instance
1532 * \param lCh [IN] Logical Channel for which the destination
1533 * parameters are to be configured
1534 * \param destAddr [IN] Destination address
1535 * \param addrMode [IN] Address mode [FIFO or Increment]
1536 * \param fifoWidth [IN] Width of FIFO (Valid only if addrMode is FIFO)
1537 * -# 0 - 8 bit
1538 * -# 1 - 16 bit
1539 * -# 2 - 32 bit
1540 * -# 3 - 64 bit
1541 * -# 4 - 128 bit
1542 * -# 5 - 256 bit
1543 *
1544 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1545 *
1546 * \note This function is re-entrant for unique lCh values. It is non-
1547 * re-entrant for same lCh value.
1548 */
1549 EDMA3_DRV_Result EDMA3_DRV_setDestParams (EDMA3_DRV_Handle hEdma,
1550 unsigned int lCh,
1551 unsigned int destAddr,
1552 EDMA3_DRV_AddrMode addrMode,
1553 EDMA3_DRV_FifoWidth fifoWidth)
1554 {
1555 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1556 unsigned int opt = 0;
1557 EDMA3_DRV_Instance *drvInst = NULL;
1558 EDMA3_DRV_Object *drvObject = NULL;
1559 int paRAMId = 0;
1560 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1561 unsigned int mappedEvtQ = 0;
1562 unsigned int defaultBurstSize = 0;
1563 unsigned int edma3Id;
1565 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1566 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1567 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1568 EDMA3_DVT_dCOUNTER,
1569 EDMA3_DVT_dNONE,
1570 EDMA3_DVT_dNONE));
1571 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1573 /* If parameter checking is enabled... */
1574 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1575 if ((hEdma == NULL)
1576 || (((addrMode < EDMA3_DRV_ADDR_MODE_INCR) || (addrMode > EDMA3_DRV_ADDR_MODE_FIFO))
1577 || ((fifoWidth < EDMA3_DRV_W8BIT) || (fifoWidth > EDMA3_DRV_W256BIT))))
1578 {
1579 result = EDMA3_DRV_E_INVALID_PARAM;
1580 }
1582 /** In FIFO Addressing mode, memory location must be 32 bytes aligned */
1583 if ((addrMode == EDMA3_DRV_ADDR_MODE_FIFO)
1584 && ((destAddr & 0x1Fu)!=NULL))
1585 {
1586 /** Memory is not 32 bytes aligned */
1587 result = EDMA3_DRV_E_ADDRESS_NOT_ALIGNED;
1588 }
1589 #endif
1591 /* Check if the parameters are OK. */
1592 if (EDMA3_DRV_SOK == result)
1593 {
1594 drvInst = (EDMA3_DRV_Instance *)hEdma;
1595 drvObject = drvInst->pDrvObjectHandle;
1597 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1598 {
1599 result = EDMA3_DRV_E_INVALID_PARAM;
1600 }
1601 else
1602 {
1603 edma3Id = drvObject->phyCtrllerInstId;
1604 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1605 }
1606 }
1608 /* If parameter checking is enabled... */
1609 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1610 if (lCh > edma3_log_ch_max_val [edma3Id])
1611 {
1612 result = EDMA3_DRV_E_INVALID_PARAM;
1613 }
1614 #endif
1616 if (EDMA3_DRV_SOK == result)
1617 {
1618 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1619 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1620 {
1621 result = EDMA3_DRV_E_INVALID_PARAM;
1622 }
1623 }
1625 if (EDMA3_DRV_SOK == result)
1626 {
1627 /**
1628 * If request is for FIFO mode, check whether the FIFO size
1629 * is supported by the Transfer Controller which will be used for
1630 * this transfer or not.
1631 */
1632 if (addrMode == EDMA3_DRV_ADDR_MODE_FIFO)
1633 {
1634 if (lCh <= edma3_dma_ch_max_val [edma3Id])
1635 {
1636 mappedEvtQ = ((globalRegs->DMAQNUM[lCh >> 3u])
1637 & (~(EDMA3_DRV_DMAQNUM_CLR_MASK(lCh))))
1638 >> ((lCh%8u)*4u);
1639 }
1640 else
1641 {
1642 if ((lCh >= edma3_qdma_ch_min_val[edma3Id])
1643 &&(lCh <= edma3_qdma_ch_max_val[edma3Id]))
1644 {
1645 mappedEvtQ = ((globalRegs->QDMAQNUM)
1646 & (~(EDMA3_DRV_QDMAQNUM_CLR_MASK(lCh - edma3_qdma_ch_min_val[edma3Id]))))
1647 >> (lCh*4u);
1648 }
1649 }
1651 /**
1652 * mappedEvtQ contains the event queue and hence the TC which will
1653 * process this transfer request. Check whether this TC supports the
1654 * FIFO size or not.
1655 */
1656 defaultBurstSize = 1u << fifoWidth;
1657 if (defaultBurstSize > drvObject->gblCfgParams.tcDefaultBurstSize[mappedEvtQ])
1658 {
1659 result = EDMA3_DRV_E_FIFO_WIDTH_NOT_SUPPORTED;
1660 }
1661 }
1662 }
1664 if (EDMA3_DRV_SOK == result)
1665 {
1666 /* Set the Dest address */
1667 *((&globalRegs->PARAMENTRY[paRAMId].OPT) +
1668 (unsigned int)EDMA3_DRV_PARAM_ENTRY_DST) = destAddr;
1670 opt = (unsigned int)(*(&globalRegs->PARAMENTRY [paRAMId].OPT));
1672 /* Set DAM */
1673 opt &= EDMA3_DRV_OPT_DAM_CLR_MASK;
1674 opt |= EDMA3_DRV_OPT_DAM_SET_MASK(addrMode);
1675 /* Set FIFO Width */
1676 opt &= EDMA3_DRV_OPT_FWID_CLR_MASK;
1677 opt |= EDMA3_DRV_OPT_FWID_SET_MASK(fifoWidth);
1679 /* Set the OPT */
1680 *(&globalRegs->PARAMENTRY[paRAMId].OPT) = opt;
1681 }
1683 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1684 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1685 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1686 EDMA3_DVT_dCOUNTER,
1687 EDMA3_DVT_dNONE,
1688 EDMA3_DVT_dNONE));
1689 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1691 return result;
1692 }
1695 /**
1696 * \brief DMA source index setup
1697 *
1698 * It is used to program the source B index and source C index.
1699 *
1700 * SRCBIDX is a 16-bit signed value (2s complement) used for source address
1701 * modification between each array in the 2nd dimension. Valid values for
1702 * SRCBIDX are between -32768 and 32767. It provides a byte address offset
1703 * from the beginning of the source array to the beginning of the next source
1704 * array. It applies to both A-synchronized and AB-synchronized transfers.
1705 *
1706 * SRCCIDX is a 16-bit signed value (2s complement) used for source address
1707 * modification in the 3rd dimension. Valid values for SRCCIDX are between
1708 * -32768 and 32767. It provides a byte address offset from the beginning of
1709 * the current array (pointed to by SRC address) to the beginning of the first
1710 * source array in the next frame. It applies to both A-synchronized and
1711 * AB-synchronized transfers. Note that when SRCCIDX is applied, the current
1712 * array in an A-synchronized transfer is the last array in the frame, while
1713 * the current array in an AB-synchronized transfer is the first array in the
1714 * frame.
1715 *
1716 * \param hEdma [IN] Handle to the EDMA Driver Instance
1717 * \param lCh [IN] Logical Channel for which source
1718 * indices are to be configured
1719 * \param srcBIdx [IN] Source B index
1720 * \param srcCIdx [IN] Source C index
1721 *
1722 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1723 *
1724 * \note This function is re-entrant for unique lCh values. It is non-
1725 * re-entrant for same lCh value.
1726 */
1727 EDMA3_DRV_Result EDMA3_DRV_setSrcIndex (EDMA3_DRV_Handle hEdma,
1728 unsigned int lCh,
1729 int srcBIdx, int srcCIdx)
1730 {
1731 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1732 unsigned int srcDstBidx;
1733 unsigned int srcDstCidx;
1734 EDMA3_DRV_Instance *drvInst = NULL;
1735 EDMA3_DRV_Object *drvObject = NULL;
1736 int paRAMId = 0;
1737 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1738 unsigned int edma3Id;
1740 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1741 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1742 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1743 EDMA3_DVT_dCOUNTER,
1744 EDMA3_DVT_dNONE,
1745 EDMA3_DVT_dNONE));
1746 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1748 /* If parameter checking is enabled... */
1749 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1750 if (hEdma == NULL)
1751 {
1752 result = EDMA3_DRV_E_INVALID_PARAM;
1753 }
1755 if (((srcBIdx > EDMA3_DRV_SRCBIDX_MAX_VAL)
1756 || (srcBIdx < EDMA3_DRV_SRCBIDX_MIN_VAL))
1757 || ((srcCIdx > EDMA3_DRV_SRCCIDX_MAX_VAL)
1758 || (srcCIdx < EDMA3_DRV_SRCCIDX_MIN_VAL)))
1759 {
1760 result = EDMA3_DRV_E_INVALID_PARAM;
1761 }
1762 #endif
1764 /* Check if the parameters are OK. */
1765 if (EDMA3_DRV_SOK == result)
1766 {
1767 drvInst = (EDMA3_DRV_Instance *)hEdma;
1768 drvObject = drvInst->pDrvObjectHandle;
1770 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1771 {
1772 result = EDMA3_DRV_E_INVALID_PARAM;
1773 }
1774 else
1775 {
1776 edma3Id = drvObject->phyCtrllerInstId;
1777 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1778 }
1779 }
1781 /* If parameter checking is enabled... */
1782 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1783 if (lCh > edma3_log_ch_max_val [edma3Id])
1784 {
1785 result = EDMA3_DRV_E_INVALID_PARAM;
1786 }
1787 #endif
1789 if (EDMA3_DRV_SOK == result)
1790 {
1791 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1792 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1793 {
1794 result = EDMA3_DRV_E_INVALID_PARAM;
1795 }
1796 else
1797 {
1798 /* Get SrcDestBidx PaRAM Set entry */
1799 srcDstBidx = (unsigned int)(*((&globalRegs->PARAMENTRY [paRAMId].OPT)
1800 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_BIDX));
1802 srcDstBidx &= 0xFFFF0000u;
1803 /* Update it */
1804 srcDstBidx |= (unsigned int)(srcBIdx & 0xFFFF);
1806 /* Store it back */
1807 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
1808 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_BIDX) = srcDstBidx;
1810 /* Get SrcDestCidx PaRAM Set entry */
1811 srcDstCidx = (unsigned int)(*((&globalRegs->PARAMENTRY [paRAMId].OPT)
1812 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_CIDX));
1814 srcDstCidx &= 0xFFFF0000u;
1815 /* Update it */
1816 srcDstCidx |= (unsigned int)(srcCIdx & 0xFFFF);
1818 /* Store it back */
1819 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
1820 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_CIDX) = srcDstCidx;
1821 }
1822 }
1824 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1825 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1826 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1827 EDMA3_DVT_dCOUNTER,
1828 EDMA3_DVT_dNONE,
1829 EDMA3_DVT_dNONE));
1830 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1832 return result;
1833 }
1837 /**
1838 * \brief DMA destination index setup
1839 *
1840 * It is used to program the destination B index and destination C index.
1841 *
1842 * DSTBIDX is a 16-bit signed value (2s complement) used for destination
1843 * address modification between each array in the 2nd dimension. Valid values
1844 * for DSTBIDX are between -32768 and 32767. It provides a byte address offset
1845 * from the beginning of the destination array to the beginning of the next
1846 * destination array within the current frame. It applies to both
1847 * A-synchronized and AB-synchronized transfers.
1848 *
1849 * DSTCIDX is a 16-bit signed value (2s complement) used for destination address
1850 * modification in the 3rd dimension. Valid values are between -32768 and 32767.
1851 * It provides a byte address offset from the beginning of the current array
1852 * (pointed to by DST address) to the beginning of the first destination array
1853 * TR in the next frame. It applies to both A-synchronized and AB-synchronized
1854 * transfers. Note that when DSTCIDX is applied, the current array in an
1855 * A-synchronized transfer is the last array in the frame, while the current
1856 * array in a AB-synchronized transfer is the first array in the frame
1857 *
1858 * \param hEdma [IN] Handle to the EDMA Driver Instance
1859 * \param lCh [IN] Logical Channel for which dest
1860 * indices are to be configured
1861 * \param destBIdx [IN] Destination B index
1862 * \param destCIdx [IN] Destination C index
1863 *
1864 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
1865 *
1866 * \note This function is re-entrant for unique lCh values. It is non-
1867 * re-entrant for same lCh value.
1868 */
1869 EDMA3_DRV_Result EDMA3_DRV_setDestIndex (EDMA3_DRV_Handle hEdma, unsigned int lCh,
1870 int destBIdx, int destCIdx)
1871 {
1872 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
1873 unsigned int srcDstBidx;
1874 unsigned int srcDstCidx;
1875 EDMA3_DRV_Instance *drvInst = NULL;
1876 EDMA3_DRV_Object *drvObject = NULL;
1877 int paRAMId = 0;
1878 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
1879 unsigned int edma3Id;
1881 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1882 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1883 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1884 EDMA3_DVT_dCOUNTER,
1885 EDMA3_DVT_dNONE,
1886 EDMA3_DVT_dNONE));
1887 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1889 /* If parameter checking is enabled... */
1890 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1891 if (hEdma == NULL)
1892 {
1893 result = EDMA3_DRV_E_INVALID_PARAM;
1894 }
1896 if (((destBIdx > EDMA3_DRV_DSTBIDX_MAX_VAL)
1897 || (destBIdx < EDMA3_DRV_DSTBIDX_MIN_VAL))
1898 || ((destCIdx > EDMA3_DRV_DSTCIDX_MAX_VAL)
1899 || (destCIdx < EDMA3_DRV_DSTCIDX_MIN_VAL)))
1900 {
1901 result = EDMA3_DRV_E_INVALID_PARAM;
1902 }
1903 #endif
1905 /* Check if the parameters are OK. */
1906 if (EDMA3_DRV_SOK == result)
1907 {
1908 drvInst = (EDMA3_DRV_Instance *)hEdma;
1909 drvObject = drvInst->pDrvObjectHandle;
1911 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
1912 {
1913 result = EDMA3_DRV_E_INVALID_PARAM;
1914 }
1915 else
1916 {
1917 edma3Id = drvObject->phyCtrllerInstId;
1918 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
1919 }
1920 }
1922 /* If parameter checking is enabled... */
1923 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
1924 if (lCh > edma3_log_ch_max_val [edma3Id])
1925 {
1926 result = EDMA3_DRV_E_INVALID_PARAM;
1927 }
1928 #endif
1930 if (EDMA3_DRV_SOK == result)
1931 {
1932 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
1933 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
1934 {
1935 result = EDMA3_DRV_E_INVALID_PARAM;
1936 }
1937 else
1938 {
1939 /* Get SrcDestBidx PaRAM Set entry */
1940 srcDstBidx = (unsigned int)(*((&globalRegs->PARAMENTRY [paRAMId].OPT)
1941 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_BIDX));
1943 srcDstBidx &= 0xFFFFu;
1944 /* Update it */
1945 srcDstBidx |= (unsigned int)((destBIdx & 0xFFFF) << 16u);
1947 /* Store it back */
1948 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
1949 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_BIDX) = srcDstBidx;
1951 /* Get SrcDestCidx PaRAM Set entry */
1952 srcDstCidx = (unsigned int)(*((&globalRegs->PARAMENTRY [paRAMId].OPT)
1953 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_CIDX));
1955 srcDstCidx &= 0xFFFFu;
1956 /* Update it */
1957 srcDstCidx |= (unsigned int)((destCIdx & 0xFFFF) << 16u);
1959 /* Store it back */
1960 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
1961 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_SRC_DST_CIDX) = srcDstCidx;
1962 }
1963 }
1965 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1966 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1967 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1968 EDMA3_DVT_dCOUNTER,
1969 EDMA3_DVT_dNONE,
1970 EDMA3_DVT_dNONE));
1971 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1973 return result;
1974 }
1977 /**
1978 * \brief DMA transfer parameters setup
1979 *
1980 * It is used to specify the various counts (ACNT, BCNT and CCNT), B count
1981 * reload and the synchronization type
1982 *
1983 * ACNT represents the number of bytes within the 1st dimension of a transfer.
1984 * ACNT is a 16-bit unsigned value with valid values between 0 and 65535.
1985 * Therefore, the maximum number of bytes in an array is 65535 bytes (64K - 1
1986 * bytes). ACNT must be greater than or equal to 1 for a TR to be submitted to
1987 * EDMA3 Transfer Controller.
1988 * An ACNT equal to 0 is considered either a null or dummy transfer. A dummy or
1989 * null transfer generates a completion code depending on the settings of the
1990 * completion bit fields in OPT.
1992 * BCNT is a 16-bit unsigned value that specifies the number of arrays of length
1993 * ACNT. For normal operation, valid values for BCNT are between 1 and 65535.
1994 * Therefore, the maximum number of arrays in a frame is 65535 (64K - 1 arrays).
1995 * A BCNT equal to 0 is considered either a null or dummy transfer. A dummy or
1996 * null transfer generates a completion code depending on the settings of the
1997 * completion bit fields in OPT.
1998 *
1999 * CCNT is a 16-bit unsigned value that specifies the number of frames in a
2000 * block. Valid values for CCNT are between 1 and 65535. Therefore, the maximum
2001 * number of frames in a block is 65535 (64K - 1 frames). A CCNT equal to 0 is
2002 * considered either a null or dummy transfer. A dummy or null transfer
2003 * generates a completion code depending on the settings of the completion bit
2004 * fields in OPT. A CCNT value of 0 is considered either a null or dummy
2005 * transfer.
2006 *
2007 * BCNTRLD is a 16-bit unsigned value used to reload the BCNT field once the
2008 * last array in the 2nd dimension is transferred. This field is only used for
2009 * A-synchronized transfers. In this case, the EDMA3CC decrements the BCNT
2010 * value by 1 on each TR submission. When BCNT (conceptually) reaches 0, the
2011 * EDMA3CC decrements CCNT and uses the BCNTRLD value to reinitialize the BCNT
2012 * value.
2013 * For AB-synchronized transfers, the EDMA3CC submits the BCNT in the TR and the
2014 * EDMA3TC decrements BCNT appropriately. For AB-synchronized transfers,
2015 * BCNTRLD is not used.
2017 * \param hEdma [IN] Handle to the EDMA Driver Instance
2018 * \param lCh [IN] Logical Channel for which transfer
2019 * parameters are to be configured
2020 * \param aCnt [IN] Count for 1st Dimension.
2021 * \param bCnt [IN] Count for 2nd Dimension.
2022 * \param cCnt [IN] Count for 3rd Dimension.
2023 * \param bCntReload [IN] Reload value for bCnt.
2024 * \param syncType [IN] Transfer synchronization dimension
2025 * 0: A-synchronized. Each event triggers
2026 * the transfer of a single array of
2027 * ACNT bytes.
2028 * 1: AB-synchronized. Each event triggers
2029 * the transfer of BCNT arrays of ACNT
2030 * bytes.
2031 *
2032 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
2033 *
2034 * \note This function is re-entrant for unique lCh values. It is non-
2035 * re-entrant for same lCh value.
2036 */
2037 EDMA3_DRV_Result EDMA3_DRV_setTransferParams (EDMA3_DRV_Handle hEdma,
2038 unsigned int lCh, unsigned int aCnt, unsigned int bCnt, unsigned int cCnt,
2039 unsigned int bCntReload, EDMA3_DRV_SyncType syncType)
2040 {
2041 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
2042 unsigned int abCnt = 0;
2043 unsigned int linkBCntReld = 0;
2044 unsigned int opt = 0;
2045 EDMA3_DRV_Instance *drvInst = NULL;
2046 EDMA3_DRV_Object *drvObject = NULL;
2047 int paRAMId = 0;
2048 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2049 unsigned int edma3Id;
2051 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2052 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2053 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2054 EDMA3_DVT_dCOUNTER,
2055 EDMA3_DVT_dNONE,
2056 EDMA3_DVT_dNONE));
2057 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2059 /* If parameter checking is enabled... */
2060 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2061 if (hEdma == NULL)
2062 {
2063 result = EDMA3_DRV_E_INVALID_PARAM;
2064 }
2066 if ((((aCnt > EDMA3_DRV_ACNT_MAX_VAL)
2067 || (bCnt > EDMA3_DRV_BCNT_MAX_VAL))
2068 || ((cCnt > EDMA3_DRV_CCNT_MAX_VAL)
2069 || (bCntReload > EDMA3_DRV_BCNTRELD_MAX_VAL)))
2070 || ((syncType < EDMA3_DRV_SYNC_A) || (syncType > EDMA3_DRV_SYNC_AB)))
2071 {
2072 result = EDMA3_DRV_E_INVALID_PARAM;
2073 }
2074 #endif
2076 /* Check if the parameters are OK. */
2077 if (EDMA3_DRV_SOK == result)
2078 {
2079 drvInst = (EDMA3_DRV_Instance *)hEdma;
2080 drvObject = drvInst->pDrvObjectHandle;
2082 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
2083 {
2084 result = EDMA3_DRV_E_INVALID_PARAM;
2085 }
2086 else
2087 {
2088 edma3Id = drvObject->phyCtrllerInstId;
2089 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
2090 }
2091 }
2093 /* If parameter checking is enabled... */
2094 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2095 if (lCh > edma3_log_ch_max_val [edma3Id])
2096 {
2097 result = EDMA3_DRV_E_INVALID_PARAM;
2098 }
2099 #endif
2101 if (EDMA3_DRV_SOK == result)
2102 {
2103 paRAMId = edma3DrvChBoundRes[edma3Id][lCh].paRAMId;
2104 if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
2105 {
2106 result = EDMA3_DRV_E_INVALID_PARAM;
2107 }
2108 else
2109 {
2110 abCnt = aCnt | ((bCnt&0xFFFFu) << 16u);
2112 /* Set aCnt and bCnt */
2113 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
2114 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_ACNT_BCNT) = abCnt;
2116 /* Set cCnt */
2117 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
2118 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_CCNT) = cCnt;
2121 linkBCntReld = (unsigned int)(*((&globalRegs->PARAMENTRY [paRAMId].OPT)
2122 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_LINK_BCNTRLD));
2124 linkBCntReld |= ((bCntReload & 0xFFFFu) << 16u);
2126 /* Set bCntReload */
2127 *((&globalRegs->PARAMENTRY[paRAMId].OPT)
2128 + (unsigned int)EDMA3_DRV_PARAM_ENTRY_LINK_BCNTRLD) = linkBCntReld;
2130 opt = (unsigned int)(*(&globalRegs->PARAMENTRY [paRAMId].OPT));
2132 /* Set Sync Type */
2133 opt &= EDMA3_DRV_OPT_SYNCDIM_CLR_MASK;
2134 opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK(syncType);
2136 *(&globalRegs->PARAMENTRY[paRAMId].OPT) = opt;
2137 }
2138 }
2140 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2141 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2142 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2143 EDMA3_DVT_dCOUNTER,
2144 EDMA3_DVT_dNONE,
2145 EDMA3_DVT_dNONE));
2146 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2148 return result;
2149 }
2152 /**
2153 * \brief Start EDMA transfer on the specified channel.
2154 *
2155 * There are multiple ways to trigger an EDMA3 transfer. The triggering mode
2156 * option allows choosing from the available triggering modes: Event,
2157 * Manual or QDMA.
2158 *
2159 * In event triggered, a peripheral or an externally generated event triggers
2160 * the transfer. This API clears the Event and Event Miss Register and then
2161 * enables the DMA channel by writing to the EESR.
2162 *
2163 * In manual triggered mode, CPU manually triggers a transfer by writing a 1
2164 * in the Event Set Register (ESR/ESRH). This API writes to the ESR/ESRH to
2165 * start the transfer.
2166 *
2167 * In QDMA triggered mode, a QDMA transfer is triggered when a CPU (or other
2168 * EDMA3 programmer) writes to the trigger word of the QDMA channel PaRAM set
2169 * (auto-triggered) or when the EDMA3CC performs a link update on a PaRAM set
2170 * that has been mapped to a QDMA channel (link triggered). This API enables
2171 * the QDMA channel by writing to the QEESR register.
2172 *
2173 * \param hEdma [IN] Handle to the EDMA Driver Instance
2174 * \param lCh [IN] Channel on which transfer has to be started
2175 * \param trigMode [IN] Mode of triggering start of transfer (Manual,
2176 * QDMA or Event)
2177 *
2178 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
2179 *
2180 * \note This function is re-entrant for unique lCh values. It is non-
2181 * re-entrant for same lCh value.
2182 */
2183 EDMA3_DRV_Result EDMA3_DRV_enableTransfer (EDMA3_DRV_Handle hEdma,
2184 unsigned int lCh,
2185 EDMA3_DRV_TrigMode trigMode)
2186 {
2187 EDMA3_DRV_Instance *drvInst = NULL;
2188 EDMA3_DRV_Object *drvObject = NULL;
2189 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
2190 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2191 unsigned int edma3Id;
2193 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2194 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2195 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2196 EDMA3_DVT_dCOUNTER,
2197 EDMA3_DVT_dNONE,
2198 EDMA3_DVT_dNONE));
2199 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2201 /* If parameter checking is enabled... */
2202 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2203 if (hEdma == NULL)
2204 {
2205 result = EDMA3_DRV_E_INVALID_PARAM;
2206 }
2207 #endif
2209 if (EDMA3_DRV_SOK == result)
2210 {
2211 drvInst = (EDMA3_DRV_Instance *)hEdma;
2212 drvObject = drvInst->pDrvObjectHandle;
2214 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
2215 {
2216 result = EDMA3_DRV_E_INVALID_PARAM;
2217 }
2218 else
2219 {
2220 edma3Id = drvObject->phyCtrllerInstId;
2221 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
2222 }
2223 }
2225 /* If parameter checking is enabled... */
2226 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2227 if (lCh > edma3_log_ch_max_val [edma3Id])
2228 {
2229 result = EDMA3_DRV_E_INVALID_PARAM;
2230 }
2232 /* Trigger type is Manual */
2233 if ((EDMA3_DRV_TRIG_MODE_MANUAL == trigMode)
2234 && (lCh > edma3_dma_ch_max_val [edma3Id]))
2235 {
2236 /* Channel Id lies outside DMA channel range */
2237 result = EDMA3_DRV_E_INVALID_PARAM;
2238 }
2240 /* Trigger type is QDMA */
2241 if ((EDMA3_DRV_TRIG_MODE_QDMA == trigMode)
2242 && ((lCh < edma3_qdma_ch_min_val[edma3Id])
2243 || (lCh > edma3_qdma_ch_max_val[edma3Id])))
2244 {
2245 /* Channel Id lies outside QDMA channel range */
2246 result = EDMA3_DRV_E_INVALID_PARAM;
2247 }
2249 /* Trigger type is Event */
2250 if ((EDMA3_DRV_TRIG_MODE_EVENT == trigMode)
2251 && ((drvObject->gblCfgParams.dmaChannelHwEvtMap [lCh/32u]
2252 & (1u<<(lCh%32u))) == FALSE))
2253 {
2254 /* Channel was not mapped to any Hw Event. */
2255 result = EDMA3_DRV_E_INVALID_PARAM;
2256 }
2257 #endif
2259 if (EDMA3_DRV_SOK == result)
2260 {
2261 switch (trigMode)
2262 {
2263 case EDMA3_DRV_TRIG_MODE_MANUAL :
2264 {
2265 if (lCh < 32u)
2266 {
2267 drvInst->shadowRegs->ESR = (1UL << lCh);
2268 }
2269 else
2270 {
2271 drvInst->shadowRegs->ESRH = (1UL << (lCh-32u));
2272 }
2273 edma3DrvChBoundRes[edma3Id][lCh].trigMode =
2274 EDMA3_DRV_TRIG_MODE_MANUAL;
2275 }
2276 break;
2278 case EDMA3_DRV_TRIG_MODE_QDMA :
2279 {
2280 drvInst->shadowRegs->QEESR = (1u<<(lCh - edma3_qdma_ch_min_val[edma3Id]));
2281 edma3DrvChBoundRes[edma3Id][lCh].trigMode =
2282 EDMA3_DRV_TRIG_MODE_QDMA;
2283 }
2284 break;
2286 case EDMA3_DRV_TRIG_MODE_EVENT :
2287 {
2288 if (lCh < 32u)
2289 {
2290 /*clear SECR to clean any previous NULL request */
2291 drvInst->shadowRegs->SECR = (1UL << lCh);
2293 /*clear EMCR to clean any previous NULL request */
2294 globalRegs->EMCR = (1UL << lCh);
2296 drvInst->shadowRegs->EESR = (1UL << lCh);
2297 }
2298 else
2299 {
2300 /*clear SECR to clean any previous NULL request */
2301 drvInst->shadowRegs->SECRH = (1UL << (lCh-32u));
2303 /*clear EMCR to clean any previous NULL request */
2304 globalRegs->EMCRH = (1UL << (lCh-32u));
2306 drvInst->shadowRegs->EESRH = (1UL << (lCh-32u));
2307 }
2309 edma3DrvChBoundRes[edma3Id][lCh].trigMode =
2310 EDMA3_DRV_TRIG_MODE_EVENT;
2311 }
2312 break;
2314 default :
2315 result = EDMA3_DRV_E_INVALID_PARAM;
2316 break;
2317 }
2318 }
2320 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2321 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2322 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2323 EDMA3_DVT_dCOUNTER,
2324 EDMA3_DVT_dNONE,
2325 EDMA3_DVT_dNONE));
2326 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2328 return result;
2329 }
2332 /**
2333 * \brief Disable DMA transfer on the specified channel
2334 *
2335 * There are multiple ways by which an EDMA3 transfer could be triggered.
2336 * The triggering mode option allows choosing from the available triggering
2337 * modes: Event, Manual or QDMA.
2338 *
2339 * To disable a channel which was previously triggered in manual mode,
2340 * this API clears the Secondary Event Register and Event Miss Register,
2341 * if set, for the specific DMA channel.
2342 *
2343 * To disable a channel which was previously triggered in QDMA mode, this
2344 * API clears the QDMA Event Enable Register, for the specific QDMA channel.
2345 *
2346 * To disable a channel which was previously triggered in event mode, this API
2347 * clears the Event Enable Register, Event Register, Secondary Event Register
2348 * and Event Miss Register, if set, for the specific DMA channel.
2350 * \param hEdma [IN] Handle to the EDMA Driver Instance
2351 * \param lCh [IN] Channel on which transfer has to be stopped
2352 * \param trigMode [IN] Mode of triggering start of transfer
2353 *
2354 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
2355 *
2356 * \note This function is re-entrant for unique lCh values. It is non-
2357 * re-entrant for same lCh value.
2358 */
2359 EDMA3_DRV_Result EDMA3_DRV_disableTransfer (EDMA3_DRV_Handle hEdma,
2360 unsigned int lCh, EDMA3_DRV_TrigMode trigMode)
2361 {
2362 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
2363 EDMA3_DRV_Instance *drvInst = NULL;
2364 EDMA3_DRV_Object *drvObject = NULL;
2365 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2366 unsigned int edma3Id;
2368 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2369 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2370 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2371 EDMA3_DVT_dCOUNTER,
2372 EDMA3_DVT_dNONE,
2373 EDMA3_DVT_dNONE));
2374 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2376 /* If parameter checking is enabled... */
2377 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2378 if (hEdma == NULL)
2379 {
2380 result = EDMA3_DRV_E_INVALID_PARAM;
2381 }
2382 #endif
2384 /* Check if the parameters are OK. */
2385 if (EDMA3_DRV_SOK == result)
2386 {
2387 drvInst = (EDMA3_DRV_Instance *)hEdma;
2388 drvObject = drvInst->pDrvObjectHandle;
2390 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
2391 {
2392 result = EDMA3_DRV_E_INVALID_PARAM;
2393 }
2394 else
2395 {
2396 edma3Id = drvObject->phyCtrllerInstId;
2397 globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
2398 }
2399 }
2401 /* If parameter checking is enabled... */
2402 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2403 if (lCh > edma3_log_ch_max_val [edma3Id])
2404 {
2405 result = EDMA3_DRV_E_INVALID_PARAM;
2406 }
2408 /* Trigger type is Manual */
2409 if ((EDMA3_DRV_TRIG_MODE_MANUAL == trigMode)
2410 && (lCh > edma3_dma_ch_max_val [edma3Id]))
2411 {
2412 /* Channel Id lies outside DMA channel range */
2413 result = EDMA3_DRV_E_INVALID_PARAM;
2414 }
2416 /* Trigger type is QDMA */
2417 if ((EDMA3_DRV_TRIG_MODE_QDMA == trigMode)
2418 && ((lCh < edma3_qdma_ch_min_val[edma3Id])
2419 || (lCh > edma3_qdma_ch_max_val[edma3Id])))
2420 {
2421 /* Channel Id lies outside QDMA channel range */
2422 result = EDMA3_DRV_E_INVALID_PARAM;
2423 }
2425 /* Trigger type is Event */
2426 if ((EDMA3_DRV_TRIG_MODE_EVENT == trigMode)
2427 && ((drvObject->gblCfgParams.dmaChannelHwEvtMap [lCh/32u]
2428 & (1u<<(lCh%32u))) == FALSE))
2429 {
2430 /* Channel was not mapped to any Hw Event. */
2431 result = EDMA3_DRV_E_INVALID_PARAM;
2432 }
2433 #endif
2435 if (EDMA3_DRV_SOK == result)
2436 {
2437 switch (trigMode)
2438 {
2439 case EDMA3_DRV_TRIG_MODE_MANUAL :
2440 {
2441 if (lCh < 32u)
2442 {
2443 if((drvInst->shadowRegs->SER & (1u<<lCh))!=FALSE)
2444 {
2445 drvInst->shadowRegs->SECR = (1u<<lCh);
2446 }
2447 if((globalRegs->EMR & (1u<<lCh))!=FALSE)
2448 {
2449 globalRegs->EMCR = (1u<<lCh);
2450 }
2451 }
2452 else
2453 {
2454 if((drvInst->shadowRegs->SERH & (1u<<(lCh-32u)))!=FALSE)
2455 {
2456 drvInst->shadowRegs->SECRH = (1u<<(lCh-32u));
2457 }
2459 if((globalRegs->EMRH & (1u<<(lCh-32u)))!=FALSE)
2460 {
2461 globalRegs->EMCRH = (1u<<(lCh-32u));
2462 }
2463 }
2464 }
2465 break;
2467 case EDMA3_DRV_TRIG_MODE_QDMA :
2468 {
2469 drvInst->shadowRegs->QEECR = (1u<<(lCh - edma3_qdma_ch_min_val[edma3Id]));
2470 }
2471 break;
2473 case EDMA3_DRV_TRIG_MODE_EVENT :
2474 {
2475 if (lCh < 32u)
2476 {
2477 drvInst->shadowRegs->EECR = (1u << lCh);
2479 if((drvInst->shadowRegs->ER & (1u<<lCh))!=FALSE)
2480 {
2481 drvInst->shadowRegs->ECR = (1u<<lCh);
2482 }
2483 if((drvInst->shadowRegs->SER & (1u<<lCh))!=FALSE)
2484 {
2485 drvInst->shadowRegs->SECR = (1u<<lCh);
2486 }
2487 if((globalRegs->EMR & (1u<<lCh))!=FALSE)
2488 {
2489 globalRegs->EMCR = (1u<<lCh);
2490 }
2491 }
2492 else
2493 {
2494 drvInst->shadowRegs->EECRH = (1u << (lCh-32u));
2495 if((drvInst->shadowRegs->ERH & (1u<<(lCh-32u)))!=FALSE)
2496 {
2497 drvInst->shadowRegs->ECRH = (1u<<(lCh-32u));
2498 }
2500 if((drvInst->shadowRegs->SERH & (1u<<(lCh-32u)))!=FALSE)
2501 {
2502 drvInst->shadowRegs->SECRH = (1u<<(lCh-32u));
2503 }
2505 if((globalRegs->EMRH & (1u<<(lCh-32u)))!=FALSE)
2506 {
2507 globalRegs->EMCRH = (1u<<(lCh-32u));
2508 }
2509 }
2510 }
2511 break;
2513 default :
2514 result = EDMA3_DRV_E_INVALID_PARAM;
2515 break;
2516 }
2517 }
2519 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2520 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2521 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2522 EDMA3_DVT_dCOUNTER,
2523 EDMA3_DVT_dNONE,
2524 EDMA3_DVT_dNONE));
2525 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2527 return result;
2528 }
2530 /**
2531 * \brief Disable the event driven DMA channel or QDMA channel
2532 *
2533 * This API disables the DMA channel (which was previously triggered in event
2534 * mode) by clearing the Event Enable Register; it disables the QDMA channel by
2535 * clearing the QDMA Event Enable Register.
2536 *
2537 * This API should NOT be used for DMA channels which are not mapped to any
2538 * hardware events and are used for memory-to-memory copy based transfers. In
2539 * case of that, this API returns error.
2540 *
2541 * \param hEdma [IN] Handle to the EDMA Driver Instance
2542 * \param lCh [IN] DMA/QDMA Channel which needs to be disabled
2543 * \param trigMode [IN] Mode of triggering start of transfer
2544 *
2545 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
2546 *
2547 * \note This function is re-entrant for unique lCh values. It is non-
2548 * re-entrant for same lCh value.
2549 */
2550 EDMA3_DRV_Result EDMA3_DRV_disableLogicalChannel (EDMA3_DRV_Handle hEdma,
2551 unsigned int lCh, EDMA3_DRV_TrigMode trigMode)
2552 {
2553 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
2554 EDMA3_DRV_Instance *drvInst = NULL;
2555 EDMA3_DRV_Object *drvObject = NULL;
2556 unsigned int edma3Id;
2558 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2559 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2560 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2561 EDMA3_DVT_dCOUNTER,
2562 EDMA3_DVT_dNONE,
2563 EDMA3_DVT_dNONE));
2564 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2566 /* If parameter checking is enabled... */
2567 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2568 if (hEdma == NULL)
2569 {
2570 result = EDMA3_DRV_E_INVALID_PARAM;
2571 }
2572 #endif
2574 /* Check if the parameters are OK. */
2575 if (EDMA3_DRV_SOK == result)
2576 {
2577 drvInst = (EDMA3_DRV_Instance *)hEdma;
2578 drvObject = drvInst->pDrvObjectHandle;
2580 if (drvObject == NULL)
2581 {
2582 result = EDMA3_DRV_E_INVALID_PARAM;
2583 }
2584 else
2585 {
2586 edma3Id = drvObject->phyCtrllerInstId;
2587 }
2588 }
2590 /* If parameter checking is enabled... */
2591 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
2592 if (lCh > edma3_log_ch_max_val [edma3Id])
2593 {
2594 result = EDMA3_DRV_E_INVALID_PARAM;
2595 }
2597 /* Trigger type is QDMA */
2598 if ((EDMA3_DRV_TRIG_MODE_QDMA == trigMode)
2599 && ((lCh < edma3_qdma_ch_min_val[edma3Id])
2600 || (lCh > edma3_qdma_ch_max_val[edma3Id])))
2601 {
2602 /* Channel Id lies outside QDMA channel range */
2603 result = EDMA3_DRV_E_INVALID_PARAM;
2604 }
2606 /* Trigger type is Event */
2607 if ((EDMA3_DRV_TRIG_MODE_EVENT == trigMode)
2608 && ((drvObject->gblCfgParams.dmaChannelHwEvtMap [lCh/32u]
2609 & (1u<<(lCh%32u))) == FALSE))
2610 {
2611 /* Channel was not mapped to any Hw Event. */
2612 result = EDMA3_DRV_E_INVALID_PARAM;
2613 }
2614 #endif
2616 if (EDMA3_DRV_SOK == result)
2617 {
2618 switch (trigMode)
2619 {
2620 case EDMA3_DRV_TRIG_MODE_QDMA:
2621 {
2622 drvInst->shadowRegs->QEECR = (1u<<(lCh - edma3_qdma_ch_min_val[edma3Id]));
2623 }
2624 break;
2626 case EDMA3_DRV_TRIG_MODE_EVENT:
2627 {
2628 if (lCh < 32u)
2629 drvInst->shadowRegs->EECR = (1u << lCh);
2630 else
2631 drvInst->shadowRegs->EECRH = (1u << (lCh-32u));
2632 }
2633 break;
2635 default :
2636 result = EDMA3_DRV_E_INVALID_PARAM;
2637 break;
2638 }
2639 }
2641 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2642 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2643 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2644 EDMA3_DVT_dCOUNTER,
2645 EDMA3_DVT_dNONE,
2646 EDMA3_DVT_dNONE));
2647 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2649 return result;
2650 }
2652 /* Definitions of Local functions - Start */
2653 /** Remove various mappings and do cleanup for DMA/QDMA channels */
2654 static EDMA3_DRV_Result edma3RemoveMapping (EDMA3_DRV_Handle hEdma,
2655 unsigned int channelId)
2656 {
2657 unsigned int intState=0;
2658 EDMA3_DRV_Instance *drvInst = NULL;
2659 EDMA3_DRV_Object *drvObject = NULL;
2660 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
2661 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2662 EDMA3_RM_ResDesc channelObj;
2663 unsigned int edma3Id;
2665 assert (hEdma != NULL);
2667 drvInst = (EDMA3_DRV_Instance *)hEdma;
2668 drvObject = drvInst->pDrvObjectHandle;
2670 if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
2671 {
2672 result = EDMA3_DRV_E_INVALID_PARAM;
2673 }
2674 else
2675 {
2676 edma3Id = drvObject->phyCtrllerInstId;
2677 globalRegs = (volatile EDMA3_CCRL_Regs *)
2678 (drvObject->gblCfgParams.globalRegs);
2679 }
2681 assert (channelId <= edma3_log_ch_max_val [edma3Id]);
2684 /**
2685 * Disable any ongoing transfer on the channel, if transfer was
2686 * enabled earlier.
2687 */
2688 if (EDMA3_DRV_TRIG_MODE_NONE !=
2689 edma3DrvChBoundRes[edma3Id][channelId].trigMode)
2690 {
2691 result = EDMA3_DRV_disableTransfer(hEdma, channelId,
2692 edma3DrvChBoundRes[edma3Id][channelId].trigMode);
2693 }
2695 if (EDMA3_DRV_SOK == result)
2696 {
2697 /*
2698 * Unregister the TCC Callback function and disable the interrupts.
2699 */
2700 if (channelId < drvObject->gblCfgParams.numDmaChannels)
2701 {
2702 /* DMA channel */
2703 channelObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2704 channelObj.resId = channelId;
2705 }
2706 else
2707 {
2708 /* QDMA channel */
2709 channelObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2710 channelObj.resId = channelId - edma3_qdma_ch_min_val[edma3Id];
2711 }
2713 result = EDMA3_RM_unregisterTccCb(drvInst->resMgrInstance,
2714 (EDMA3_RM_ResDesc *)&channelObj);
2715 }
2717 if (result == EDMA3_RM_SOK)
2718 {
2719 edma3OsProtectEntry(edma3Id, EDMA3_OS_PROTECT_INTERRUPT, &intState);
2721 if (channelId <= edma3_dma_ch_max_val [edma3Id])
2722 {
2723 /* DMA channel */
2724 #ifndef EDMA3_PROGRAM_QUEUE_NUM_REGISTER_INIT_TIME
2725 /* Remove the channel to Event Queue mapping */
2726 globalRegs->DMAQNUM[channelId >> 3u] &=
2727 EDMA3_DRV_DMAQNUM_CLR_MASK(channelId);
2728 #endif
2729 /**
2730 * If DMA channel to PaRAM Set mapping exists,
2731 * remove it too.
2732 */
2733 if (TRUE == drvObject->gblCfgParams.dmaChPaRAMMapExists)
2734 {
2735 globalRegs->DCHMAP[channelId] &=
2736 EDMA3_RM_DCH_PARAM_CLR_MASK;
2737 }
2738 }
2739 else
2740 {
2741 /* QDMA channel */
2742 #ifndef EDMA3_PROGRAM_QUEUE_NUM_REGISTER_INIT_TIME
2743 /* Remove the channel to Event Queue mapping */
2744 globalRegs->QDMAQNUM = (globalRegs->QDMAQNUM) &
2745 (EDMA3_DRV_QDMAQNUM_CLR_MASK(channelId-edma3_qdma_ch_min_val[edma3Id]));
2746 #endif
2747 /* Remove the channel to PARAM set mapping */
2748 /* Unmap PARAM Set Number for specified channelId */
2749 globalRegs->QCHMAP[channelId-edma3_qdma_ch_min_val[edma3Id]] &=
2750 EDMA3_RM_QCH_PARAM_CLR_MASK;
2752 /* Reset the Trigger Word */
2753 globalRegs->QCHMAP[channelId-edma3_qdma_ch_min_val[edma3Id]] &=
2754 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2755 }
2757 edma3OsProtectExit(edma3Id,
2758 EDMA3_OS_PROTECT_INTERRUPT,
2759 intState);
2760 }
2762 return result;
2763 }
2764 /* Definitions of Local functions - End */
2766 /* End of File */