edma_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2018 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
49 #include "edma_irq.h"
50 #include "clock_manager.h"
51 #include "interrupt_manager.h"
52 
53 /*******************************************************************************
54  * Variables
55  ******************************************************************************/
56 
57 #ifdef FEATURE_DMA_HWV3
58 
60 
63 
66 
68 #if defined FEATURE_DMA_HAS_ERROR_IRQ
70 #endif
71 
72 #else
73 
74 static DMA_Type * const s_edmaBase[DMA_INSTANCE_COUNT] = DMA_BASE_PTRS;
75 
77 static DMAMUX_Type * const s_dmaMuxBase[DMAMUX_INSTANCE_COUNT] = DMAMUX_BASE_PTRS;
78 
81 
83 #if defined FEATURE_DMA_HAS_ERROR_IRQ
85 #endif
86 #endif
87 
88 #ifdef DEV_ERROR_DETECT
89 
90 static const clock_names_t s_edmaClockNames[DMA_INSTANCE_COUNT] = FEATURE_DMA_CLOCK_NAMES;
91 static const clock_names_t s_dmamuxClockNames[DMAMUX_INSTANCE_COUNT] = FEATURE_DMAMUX_CLOCK_NAMES;
92 #endif
93 
96 
97 /*******************************************************************************
98  * PROTOTYPES
99  ******************************************************************************/
100 static status_t EDMA_DRV_RequestChannel(uint8_t virtualChannel,
101  dma_request_source_t reqSrc,
102  edma_chn_state_t *reqChn);
103 static void EDMA_DRV_ClearIntStatus(uint8_t virtualChannel);
105 #ifdef DEV_ERROR_DETECT
106 static bool EDMA_DRV_ValidTransferSize(edma_transfer_size_t size);
107 #endif
108 
109 /*******************************************************************************
110  * Code
111  ******************************************************************************/
112 /*FUNCTION**********************************************************************
113  *
114  * Function Name : EDMA_DRV_Init
115  * Description : Initializes the eDMA module.
116  *
117  * Implements : EDMA_DRV_Init_Activity
118  *END**************************************************************************/
120  const edma_user_config_t *userConfig,
121  edma_chn_state_t * const chnStateArray[],
122  const edma_channel_config_t * const chnConfigArray[],
123  uint32_t chnCount)
124 {
125  uint32_t index = 0U;
126  DMA_Type *edmaRegBase = NULL;
127  IRQn_Type irqNumber = NotAvail_IRQn;
128  status_t edmaStatus = STATUS_SUCCESS;
129  status_t chnInitStatus = STATUS_SUCCESS;
130 #ifdef DEV_ERROR_DETECT
131  uint32_t freq = 0U;
132  status_t clockManagerStatus = STATUS_SUCCESS;
133 #endif
134 
135  /* Check the state and configuration structure pointers are valid */
136  DEV_ASSERT((edmaState != NULL) && (userConfig != NULL));
137 
138  /* Check the module has not already been initialized */
139  DEV_ASSERT(s_virtEdmaState == NULL);
140 
141 #ifdef DEV_ERROR_DETECT
142  /* Check that eDMA and DMAMUX modules are clock gated on */
143  for (index = 0U; index < (uint32_t)DMA_INSTANCE_COUNT; index++)
144  {
145  clockManagerStatus = CLOCK_SYS_GetFreq(s_edmaClockNames[index], &freq);
146  DEV_ASSERT(clockManagerStatus == STATUS_SUCCESS);
147  }
148 
149  for (index = 0U; index < (uint32_t)DMAMUX_INSTANCE_COUNT; index++)
150  {
151  clockManagerStatus = CLOCK_SYS_GetFreq(s_dmamuxClockNames[index], &freq);
152  DEV_ASSERT(clockManagerStatus == STATUS_SUCCESS);
153  }
154 #endif
155 
156  /* Save the runtime state structure for the driver */
157  s_virtEdmaState = edmaState;
158 
159  /* Clear the state structure. */
160  volatile uint8_t *clearStructPtr = (volatile uint8_t *)s_virtEdmaState;
161  size_t clearSize = sizeof(edma_state_t);
162  while (clearSize > 0U)
163  {
164  *clearStructPtr = 0;
165  clearStructPtr ++;
166  clearSize --;
167  }
168 
169  /* Init all DMA instances */
170  for(index = 0U; index < (uint32_t)DMA_INSTANCE_COUNT; index++)
171  {
172  edmaRegBase = s_edmaBase[index];
173 
174  /* Init eDMA module on hardware level. */
175  EDMA_Init(edmaRegBase);
176 
177 #ifdef FEATURE_DMA_HWV3
178  /* Set arbitration mode */
179  EDMA_SetChannelArbitrationMode(edmaRegBase, userConfig->chnArbitration);
180 #else
181  /* Set arbitration mode */
182  EDMA_SetChannelArbitrationMode(edmaRegBase, userConfig->chnArbitration);
183 #if (FEATURE_DMA_CHANNEL_GROUP_COUNT > 0x1U)
184  EDMA_SetGroupArbitrationMode(edmaRegBase, userConfig->groupArbitration);
185  EDMA_SetGroupPriority(edmaRegBase, userConfig->groupPriority);
186 #endif
187 #endif
188  /* Set 'Halt on error' configuration */
189  EDMA_SetHaltOnErrorCmd(edmaRegBase, userConfig->haltOnError);
190  }
191 
192 #if defined FEATURE_DMA_HAS_ERROR_IRQ
193  /* Enable the error interrupts for eDMA module. */
194  for (index = 0U; index < (uint32_t)FEATURE_DMA_VIRTUAL_ERROR_INTERRUPT_LINES; index++)
195  {
196  /* Enable channel interrupt ID. */
197  irqNumber = s_edmaErrIrqId[index];
198  INT_SYS_EnableIRQ(irqNumber);
199  }
200 #endif
201 
202  /* Register all edma channel interrupt handlers into vector table. */
203  for (index = 0U; index < (uint32_t)FEATURE_DMA_VIRTUAL_CHANNELS_INTERRUPT_LINES; index++)
204  {
205  /* Enable channel interrupt ID. */
206  irqNumber = s_edmaIrqId[index];
207  INT_SYS_EnableIRQ(irqNumber);
208  }
209 
210  /* Initialize all DMAMUX instances */
211  for (index = 0U; index < (uint32_t)DMAMUX_INSTANCE_COUNT; index++)
212  {
213  DMAMUX_Init(s_dmaMuxBase[index]);
214  }
215 
216  /* Initialize the channels based on configuration list */
217  if ((chnStateArray != NULL) && (chnConfigArray != NULL))
218  {
219  for (index = 0U; index < chnCount; index++)
220  {
221  chnInitStatus = EDMA_DRV_ChannelInit(chnStateArray[index], chnConfigArray[index]);
222  if (chnInitStatus != STATUS_SUCCESS)
223  {
224  edmaStatus = chnInitStatus;
225  }
226  }
227  }
228 
229  return edmaStatus;
230 }
231 
232 /*FUNCTION**********************************************************************
233  *
234  * Function Name : EDMA_DRV_Deinit
235  * Description : Deinitialize EDMA.
236  *
237  * Implements : EDMA_DRV_Deinit_Activity
238  *END**************************************************************************/
240 {
241  uint32_t index = 0U;
242  IRQn_Type irqNumber = NotAvail_IRQn;
243  const edma_chn_state_t *chnState = NULL;
244 
245 #if defined FEATURE_DMA_HAS_ERROR_IRQ
246  /* Disable the error interrupts for eDMA module. */
247  for (index = 0U; index < (uint32_t)FEATURE_DMA_VIRTUAL_ERROR_INTERRUPT_LINES; index++)
248  {
249  /* Enable channel interrupt ID. */
250  irqNumber = s_edmaErrIrqId[index];
251  INT_SYS_DisableIRQ(irqNumber);
252  }
253 #endif
254 
255  if (s_virtEdmaState != NULL)
256  {
257  /* Release all edma channel. */
258  for (index = 0U; index < (uint32_t)FEATURE_DMA_VIRTUAL_CHANNELS; index++)
259  {
260  /* Release all channels. */
261  chnState = s_virtEdmaState->virtChnState[index];
262  if (chnState != NULL)
263  {
264  (void) EDMA_DRV_ReleaseChannel(chnState->virtChn);
265  }
266  }
267  for (index = 0U; index < (uint32_t)FEATURE_DMA_VIRTUAL_CHANNELS_INTERRUPT_LINES; index++)
268  {
269  /* Disable channel interrupts. */
270  irqNumber = s_edmaIrqId[index];
271  INT_SYS_DisableIRQ(irqNumber);
272  }
273  }
274 
275  s_virtEdmaState = NULL;
276 
277  return STATUS_SUCCESS;
278 }
279 
280 /*FUNCTION**********************************************************************
281  *
282  * Function Name : EDMA_DRV_ChannelInit
283  * Description : Initialize EDMA channel.
284  *
285  * Implements : EDMA_DRV_ChannelInit_Activity
286  *END**************************************************************************/
288  const edma_channel_config_t *edmaChannelConfig)
289 {
290  /* Check the state and configuration structure pointers are valid */
291  DEV_ASSERT((edmaChannelState != NULL) && (edmaChannelConfig != NULL));
292 
293  /* Check if the module is initialized */
294  DEV_ASSERT(s_virtEdmaState != NULL);
295 
296  /* Check if the channel defined by user in the channel configuration structure is valid */
298 
299  /* Get DMA instance from virtual channel */
300  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(edmaChannelConfig->virtChnConfig);
301 
302  /* Get DMA channel from virtual channel */
303  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(edmaChannelConfig->virtChnConfig);
304 
305  /* Request the channel */
306  status_t retStatus = EDMA_DRV_RequestChannel(edmaChannelConfig->virtChnConfig, edmaChannelConfig->source, edmaChannelState);
307 
308  if (retStatus == STATUS_SUCCESS)
309  {
310  /* Load corresponding DMA instance */
311  DMA_Type * edmaRegBase = s_edmaBase[dmaInstance];
312 #ifdef FEATURE_DMA_HWV3
313  /* Put the channel in a priority group, as defined in configuration */
314  EDMA_SetChannelPriorityGroup(edmaRegBase, dmaChannel, edmaChannelConfig->groupPriority);
315 #endif
316  /* Set the channel priority, as defined in the configuration, only if fixed arbitration mode is selected */
317  if ((EDMA_GetChannelArbitrationMode(edmaRegBase) == EDMA_ARBITRATION_FIXED_PRIORITY) &&
318  (edmaChannelConfig->channelPriority != EDMA_CHN_DEFAULT_PRIORITY))
319  {
320  EDMA_SetChannelPriority(edmaRegBase, dmaChannel, edmaChannelConfig->channelPriority);
321  }
322  /* Install the user callback */
323  retStatus = EDMA_DRV_InstallCallback(edmaChannelConfig->virtChnConfig, edmaChannelConfig->callback, edmaChannelConfig->callbackParam);
324  }
325 
326  return retStatus;
327 }
328 
329 /*FUNCTION**********************************************************************
330  *
331  * Function Name : EDMA_DRV_InstallCallback
332  * Description : Register callback function and parameter.
333  *
334  * Implements : EDMA_DRV_InstallCallback_Activity
335  *END**************************************************************************/
336 status_t EDMA_DRV_InstallCallback(uint8_t virtualChannel,
337  edma_callback_t callback,
338  void *parameter)
339 {
340  /* Check the channel number is valid */
341  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
342 
343  /* Check the channel is allocated */
344  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
345 
346  s_virtEdmaState->virtChnState[virtualChannel]->callback = callback;
347  s_virtEdmaState->virtChnState[virtualChannel]->parameter = parameter;
348 
349  return STATUS_SUCCESS;
350 }
351 
352 /*FUNCTION**********************************************************************
353  *
354  * Function Name : EDMA_DRV_RequestChannel
355  * Description : Request an eDMA channel.
356  *
357  *END**************************************************************************/
358 static status_t EDMA_DRV_RequestChannel(uint8_t virtualChannel,
359  dma_request_source_t reqSrc,
360  edma_chn_state_t *reqChn)
361 {
362  /* Get DMA instance from virtual channel */
363  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
364 
365  /* Get DMA channel from virtual channel */
366  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
367 
368  /* Get DMAMUX instance serving this channel */
369  uint8_t dmaMuxInstance = (uint8_t)FEATURE_DMAMUX_REQ_SRC_TO_INSTANCE(reqSrc);
370 
371  /* Get request source index for the corresponding DMAMUX instance */
372  uint8_t sourceDmamuxChannel = (uint8_t)FEATURE_DMAMUX_REQ_SRC_TO_CH((uint32_t)reqSrc);
373 
374  /* Get DMAMUX channel for the selected request source */
375  uint8_t dmaMuxChannel = (uint8_t)FEATURE_DMAMUX_DMA_CH_TO_CH(dmaChannel);
376 
377  /* Base addresses for eDMA and DMAMUX */
378  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
379  DMAMUX_Type *dmaMuxRegBase = s_dmaMuxBase[dmaMuxInstance];
380 
381  /* Check the channel has not already been allocated */
382  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] == NULL);
383 
384  /* Channel allocation */
385  s_virtEdmaState->virtChnState[virtualChannel] = reqChn;
386 
387  /* Reset the channel state structure to default value. */
388  uint8_t *clearStructPtr = (uint8_t *)reqChn;
389  size_t clearSize = sizeof(edma_chn_state_t);
390  while (clearSize > 0U)
391  {
392  *clearStructPtr = 0;
393  clearStructPtr ++;
394  clearSize --;
395  }
396 
397  /* Init the channel state structure to the allocated channel number. */
398  reqChn->virtChn = virtualChannel;
399 
400  /* Enable error interrupt for this channel */
401  EDMA_SetErrorIntCmd(edmaRegBase, dmaChannel, true);
402 
403  /* Configure the DMAMUX for edma channel */
404  DMAMUX_SetChannelCmd(dmaMuxRegBase, dmaMuxChannel, false);
405  DMAMUX_SetChannelSource(dmaMuxRegBase, dmaMuxChannel, sourceDmamuxChannel);
406  DMAMUX_SetChannelCmd(dmaMuxRegBase, dmaMuxChannel, true);
407 
408  /* Clear the TCD registers for this channel */
409  EDMA_TCDClearReg(edmaRegBase, dmaChannel);
410 
411  return STATUS_SUCCESS;
412 }
413 
414 /*FUNCTION**********************************************************************
415  *
416  * Function Name : EDMA_DRV_ReleaseChannel
417  * Description : Free eDMA channel's hardware and software resource.
418  *
419  * Implements : EDMA_DRV_ReleaseChannel_Activity
420  *END**************************************************************************/
421 status_t EDMA_DRV_ReleaseChannel(uint8_t virtualChannel)
422 {
423  /* Check that virtual channel number is valid */
424  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
425 
426  /* Check the DMA module is initialized */
427  DEV_ASSERT(s_virtEdmaState != NULL);
428 
429  /* Get DMA instance from virtual channel */
430  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
431 
432  /* Get DMA channel from virtual channel*/
433  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
434 
435  /* Get pointer to channel state */
436  edma_chn_state_t *chnState = s_virtEdmaState->virtChnState[virtualChannel];
437 
438  /* Check that virtual channel is initialized */
439  DEV_ASSERT(chnState != NULL);
440 
441  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
442 
443  /* Stop edma channel. */
444  EDMA_SetDmaRequestCmd(edmaRegBase, dmaChannel, false);
445 
446  /* Reset the channel state structure to default value. */
447  uint8_t *clearStructPtr = (uint8_t *)chnState;
448  size_t clearSize = sizeof(edma_chn_state_t);
449  while (clearSize > 0U)
450  {
451  *clearStructPtr = 0;
452  clearStructPtr ++;
453  clearSize --;
454  }
455 
456  s_virtEdmaState->virtChnState[virtualChannel] = NULL;
457 
458  return STATUS_SUCCESS;
459 }
460 
461 /*FUNCTION**********************************************************************
462  *
463  * Function Name : EDMA_DRV_ClearIntStatus
464  * Description : Clear done and interrupt retStatus.
465  *
466  *END**************************************************************************/
467 static void EDMA_DRV_ClearIntStatus(uint8_t virtualChannel)
468 {
469  /* Get DMA instance from virtual channel */
470  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
471 
472  /* Get DMA channel from virtual channel*/
473  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
474 
475  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
476  EDMA_ClearDoneStatusFlag(edmaRegBase, dmaChannel);
477  EDMA_ClearIntStatusFlag(edmaRegBase, dmaChannel);
478 }
479 
480 /*FUNCTION**********************************************************************
481  *
482  * Function Name : EDMA_DRV_ClearSoftwareTCD
483  * Description : Clear the software tcd structure.
484  *
485  *END**************************************************************************/
487 {
488  uint8_t *byteAccess = (uint8_t *)stcd;
489  size_t clearSize = sizeof(edma_software_tcd_t);
490  while (clearSize > 0U)
491  {
492  *byteAccess = 0;
493  byteAccess ++;
494  clearSize --;
495  }
496 }
497 
498 /*FUNCTION**********************************************************************
499  *
500  * Function Name : EDMA_DRV_IRQHandler
501  * Description : EDMA IRQ handler.
502  *END**************************************************************************/
503 void EDMA_DRV_IRQHandler(uint8_t virtualChannel)
504 {
505  const edma_chn_state_t *chnState = s_virtEdmaState->virtChnState[virtualChannel];
506 
507  EDMA_DRV_ClearIntStatus(virtualChannel);
508 
509  if (chnState != NULL)
510  {
511  if (chnState->callback != NULL)
512  {
513  chnState->callback(chnState->parameter, chnState->status);
514  }
515  }
516 }
517 
518 /*FUNCTION**********************************************************************
519  *
520  * Function Name : EDMA_DRV_ErrorIRQHandler
521  * Description : EDMA error IRQ handler
522  *END**************************************************************************/
523 void EDMA_DRV_ErrorIRQHandler(uint8_t virtualChannel)
524 {
525  /* Get DMA instance from virtual channel */
526  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
527 
528  /* Get DMA channel from virtual channel*/
529  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
530 
531  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
532  EDMA_SetDmaRequestCmd(edmaRegBase, dmaChannel, false);
533  edma_chn_state_t *chnState = s_virtEdmaState->virtChnState[virtualChannel];
534  if (chnState != NULL)
535  {
536  EDMA_DRV_ClearIntStatus(virtualChannel);
537  EDMA_ClearErrorIntStatusFlag(edmaRegBase, dmaChannel);
538  chnState->status = EDMA_CHN_ERROR;
539  if (chnState->callback != NULL)
540  {
541  chnState->callback(chnState->parameter, chnState->status);
542  }
543  }
544  EDMA_SetHaltCmd(edmaRegBase, false);
545 }
546 
547 /*FUNCTION**********************************************************************
548  *
549  * Function Name : EDMA_DRV_ConfigSingleBlockTransfer
550  * Description : Configures a DMA single block transfer.
551  *
552  * Implements : EDMA_DRV_ConfigSingleBlockTransfer_Activity
553  *END**************************************************************************/
556  uint32_t srcAddr,
557  uint32_t destAddr,
558  edma_transfer_size_t transferSize,
559  uint32_t dataBufferSize)
560 {
561  /* Check that virtual channel number is valid */
562  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
563 
564  /* Check that eDMA module is initialized */
565  DEV_ASSERT(s_virtEdmaState != NULL);
566 
567  /* Check that virtual channel is initialized */
568  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
569 
570 #ifdef DEV_ERROR_DETECT
571  /* Check if the value passed for 'transferSize' is valid */
572  DEV_ASSERT(EDMA_DRV_ValidTransferSize(transferSize));
573 #endif
574 
575  /* Get DMA instance from virtual channel */
576  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
577 
578  /* Get DMA channel from virtual channel*/
579  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
580 
581  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
582  uint8_t transferOffset;
583  status_t retStatus = STATUS_SUCCESS;
584 
585  /* Compute the transfer offset, based on transfer size.
586  * The number of bytes transferred in each source read/destination write
587  * is obtained with the following formula:
588  * source_read_size = 2^SSIZE
589  * destination_write_size = 2^DSIZE
590  */
591  transferOffset = (uint8_t) (1U << ((uint8_t)transferSize));
592 
593  /* The number of bytes to be transferred (buffer size) must
594  * be a multiple of the source read/destination write size
595  */
596  if ((dataBufferSize % transferOffset) != 0U)
597  {
598  retStatus = STATUS_ERROR;
599  }
600 
601  if (retStatus == STATUS_SUCCESS)
602  {
603  /* Clear transfer control descriptor for the current channel */
604  EDMA_TCDClearReg(edmaRegBase, dmaChannel);
605 
606 #ifdef FEATURE_DMA_ENGINE_STALL
607  /* Configure the DMA Engine to stall for a number of cycles after each R/W */
608  EDMA_TCDSetEngineStall(edmaRegBase, dmaChannel, EDMA_ENGINE_STALL_4_CYCLES);
609 #endif
610 
611  /* Configure source and destination addresses */
612  EDMA_TCDSetSrcAddr(edmaRegBase, dmaChannel, srcAddr);
613  EDMA_TCDSetDestAddr(edmaRegBase, dmaChannel, destAddr);
614 
615  /* Set transfer size (1B/2B/4B/16B/32B) */
616  EDMA_TCDSetAttribute(edmaRegBase, dmaChannel, EDMA_MODULO_OFF, EDMA_MODULO_OFF, transferSize, transferSize);
617 
618  /* Configure source/destination offset. */
619  switch (type)
620  {
622  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, 0);
623  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, (int8_t) transferOffset);
624  break;
626  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, (int8_t) transferOffset);
627  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, 0);
628  break;
630  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, (int8_t) transferOffset);
631  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, (int8_t) transferOffset);
632  break;
634  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, 0);
635  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, 0);
636  break;
637  default:
638  /* This should never be reached - all the possible values have been handled. */
639  break;
640  }
641 
642  /* Set the total number of bytes to be transfered */
643  EDMA_TCDSetNbytes(edmaRegBase, dmaChannel, dataBufferSize);
644 
645  /* Set major iteration count to 1 (single block mode) */
646  EDMA_TCDSetMajorCount(edmaRegBase, dmaChannel, 1U);
647 
648  /* Enable interrupt when the transfer completes */
649  EDMA_TCDSetMajorCompleteIntCmd(edmaRegBase, dmaChannel, true);
650  }
651 
652  return retStatus;
653 }
654 
655 /*FUNCTION**********************************************************************
656  *
657  * Function Name : EDMA_DRV_ConfigMultiBlockTransfer
658  * Description : Configures a DMA single block transfer.
659  *
660  * Implements : EDMA_DRV_ConfigMultiBlockTransfer_Activity
661  *END**************************************************************************/
664  uint32_t srcAddr,
665  uint32_t destAddr,
666  edma_transfer_size_t transferSize,
667  uint32_t blockSize,
668  uint32_t blockCount,
669  bool disableReqOnCompletion)
670 {
671  /* Check that virtual channel number is valid */
672  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
673 
674  /* Check that eDMA module is initialized */
675  DEV_ASSERT(s_virtEdmaState != NULL);
676 
677  /* Get DMA instance from virtual channel */
678  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
679 
680  /* Get DMA channel from virtual channel*/
681  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
682 
683  status_t retStatus = STATUS_SUCCESS;
684 
685  /* Configure the transfer for one data block */
686  retStatus = EDMA_DRV_ConfigSingleBlockTransfer(virtualChannel, type, srcAddr, destAddr, transferSize, blockSize);
687 
688  if (retStatus == STATUS_SUCCESS)
689  {
690  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
691 
692  /* Set the number of data blocks */
693  EDMA_TCDSetMajorCount(edmaRegBase, dmaChannel, blockCount);
694 
695  /* Enable/disable requests upon completion */
696  EDMA_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaRegBase, dmaChannel, disableReqOnCompletion);
697  }
698 
699  return retStatus;
700 }
701 /*FUNCTION**********************************************************************
702  *
703  * Function Name : EDMA_DRV_ConfigLoopTransfer
704  * Description : Configures the DMA transfer in a loop.
705  *
706  * Implements : EDMA_DRV_ConfigLoopTransfer_Activity
707  *END**************************************************************************/
708 status_t EDMA_DRV_ConfigLoopTransfer(uint8_t virtualChannel,
709  const edma_transfer_config_t *transferConfig)
710 {
711  /* Check that virtual channel number is valid */
712  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
713 
714  /* Check that eDMA module is initialized */
715  DEV_ASSERT(s_virtEdmaState != NULL);
716 
717  /* Check that virtual channel is initialized */
718  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
719 
720  /* Check the transfer configuration structure is valid */
721  DEV_ASSERT(transferConfig != NULL);
722 
723  /* Check the minor/major loop properties are defined */
724  DEV_ASSERT(transferConfig->loopTransferConfig != NULL);
725 
726  /* If the modulo feature is enabled, check alignment of addresses */
727  DEV_ASSERT((transferConfig->srcModulo == EDMA_MODULO_OFF) ||
728  ((transferConfig->srcAddr % (((uint32_t)1U) << (uint32_t)transferConfig->srcModulo)) == 0U));
729  DEV_ASSERT((transferConfig->destModulo == EDMA_MODULO_OFF) ||
730  ((transferConfig->destAddr % (((uint32_t)1U) << (uint32_t)transferConfig->destModulo)) == 0U));
731 
732  /* Get DMA instance from virtual channel */
733  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
734 
735 #ifdef FEATURE_DMA_HWV3
736  /* Get DMA channel from virtual channel*/
737  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
738 #endif
739 
740  /* Enable minor loop mapping */
741  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
742 #ifdef FEATURE_DMA_HWV3
743  EDMA_SetMinorLoopMappingCmd(edmaRegBase, dmaChannel, true);
744 #else
745  EDMA_SetMinorLoopMappingCmd(edmaRegBase, true);
746 #endif
747 
748  /* Write the configuration in the transfer control descriptor registers */
749  EDMA_DRV_PushConfigToReg(virtualChannel, transferConfig);
750 
751  return STATUS_SUCCESS;
752 }
753 
754 /*FUNCTION**********************************************************************
755  *
756  * Function Name : EDMA_DRV_ConfigScatterGatherTransfer
757  * Description : Configure eDMA for scatter/gather operation
758  *
759  * Implements : EDMA_DRV_ConfigScatterGatherTransfer_Activity
760  *END**************************************************************************/
762  edma_software_tcd_t *stcd,
763  edma_transfer_size_t transferSize,
764  uint32_t bytesOnEachRequest,
765  const edma_scatter_gather_list_t *srcList,
766  const edma_scatter_gather_list_t *destList,
767  uint8_t tcdCount)
768 {
769  /* Check that virtual channel number is valid */
770  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
771 
772  /* Check that eDMA module is initialized */
773  DEV_ASSERT(s_virtEdmaState != NULL);
774 
775  /* Check that virtual channel is initialized */
776  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
777 
778  /* Check the input arrays for scatter/gather operation are valid */
779  DEV_ASSERT((stcd != NULL) && (srcList != NULL) && (destList != NULL));
780 
781 #ifdef DEV_ERROR_DETECT
782  /* Check if the value passed for 'transferSize' is valid */
783  DEV_ASSERT(EDMA_DRV_ValidTransferSize(transferSize));
784 #endif
785 
786  uint8_t i = 0U;
787  uint16_t transferOffset = 0U;
788  uint32_t stcdAlignedAddr = STCD_ADDR(stcd);
789  edma_software_tcd_t *edmaSwTcdAddr = (edma_software_tcd_t *)stcdAlignedAddr;
790  edma_loop_transfer_config_t edmaLoopConfig;
791  edma_transfer_config_t edmaTransferConfig;
792  status_t retStatus = STATUS_SUCCESS;
793 
794  /* Compute the transfer offset, based on transfer size.
795  * The number of bytes transferred in each source read/destination write
796  * is obtained with the following formula:
797  * source_read_size = 2^SSIZE
798  * destination_write_size = 2^DSIZE
799  */
800  transferOffset = (uint16_t) (1UL << ((uint16_t)transferSize));
801 
802  /* The number of bytes to be transferred on each request must
803  * be a multiple of the source read/destination write size
804  */
805  if ((bytesOnEachRequest % transferOffset) != 0U)
806  {
807  retStatus = STATUS_ERROR;
808  }
809 
810  /* Clear the configuration structures before initializing them. */
811  uint8_t *clearStructPtr = (uint8_t *)(&edmaTransferConfig);
812  size_t clearSize = sizeof(edma_transfer_config_t);
813  while (clearSize > 0U)
814  {
815  *clearStructPtr = 0;
816  clearStructPtr ++;
817  clearSize --;
818  }
819 
820  clearStructPtr = (uint8_t *)(&edmaLoopConfig);
821  clearSize = sizeof(edma_loop_transfer_config_t);
822  while (clearSize > 0U)
823  {
824  *clearStructPtr = 0;
825  clearStructPtr ++;
826  clearSize --;
827  }
828 
829  /* Configure the transfer for scatter/gather mode. */
830  edmaTransferConfig.srcLastAddrAdjust = 0;
831  edmaTransferConfig.destLastAddrAdjust = 0;
832  edmaTransferConfig.srcModulo = EDMA_MODULO_OFF;
833  edmaTransferConfig.destModulo = EDMA_MODULO_OFF;
834  edmaTransferConfig.srcTransferSize = transferSize;
835  edmaTransferConfig.destTransferSize = transferSize;
836  edmaTransferConfig.minorByteTransferCount = bytesOnEachRequest;
837  edmaTransferConfig.interruptEnable = true;
838  edmaTransferConfig.scatterGatherEnable = true;
839  edmaTransferConfig.loopTransferConfig = &edmaLoopConfig;
840  edmaTransferConfig.loopTransferConfig->srcOffsetEnable = false;
841  edmaTransferConfig.loopTransferConfig->dstOffsetEnable = false;
842  edmaTransferConfig.loopTransferConfig->minorLoopChnLinkEnable = false;
843  edmaTransferConfig.loopTransferConfig->majorLoopChnLinkEnable = false;
844 
845  /* Copy scatter/gather lists to transfer configuration*/
846  for (i = 0U; (i < tcdCount) && (retStatus == STATUS_SUCCESS); i++)
847  {
848  edmaTransferConfig.srcAddr = srcList[i].address;
849  edmaTransferConfig.destAddr = destList[i].address;
850  if ((srcList[i].length != destList[i].length) || (srcList[i].type != destList[i].type))
851  {
852  retStatus = STATUS_ERROR;
853  break;
854  }
855  edmaTransferConfig.loopTransferConfig->majorLoopIterationCount = srcList[i].length/bytesOnEachRequest;
856 
857  switch (srcList[i].type)
858  {
860  /* Configure Source Read. */
861  edmaTransferConfig.srcOffset = 0;
862  /* Configure Dest Write. */
863  edmaTransferConfig.destOffset = (int16_t) transferOffset;
864  break;
866  /* Configure Source Read. */
867  edmaTransferConfig.srcOffset = (int16_t) transferOffset;
868  /* Configure Dest Write. */
869  edmaTransferConfig.destOffset = 0;
870  break;
872  /* Configure Source Read. */
873  edmaTransferConfig.srcOffset = (int16_t) transferOffset;
874  /* Configure Dest Write. */
875  edmaTransferConfig.destOffset = (int16_t) transferOffset;
876  break;
878  /* Configure Source Read. */
879  edmaTransferConfig.srcOffset = 0;
880  /* Configure Dest Write. */
881  edmaTransferConfig.destOffset = 0;
882  break;
883  default:
884  /* This should never be reached - all the possible values have been handled. */
885  break;
886  }
887 
888  /* Configure the pointer to next software TCD structure; for the last one, this address should be 0 */
889  if (i == ((uint8_t)(tcdCount - 1U)))
890  {
891  edmaTransferConfig.scatterGatherNextDescAddr = 0U;
892  }
893  else
894  {
895  edma_software_tcd_t * ptNextAddr = &edmaSwTcdAddr[i];
896  edmaTransferConfig.scatterGatherNextDescAddr = ((uint32_t) ptNextAddr);
897  }
898 
899  if (i == 0U)
900  {
901  /* Push the configuration for the first descriptor to registers */
902  EDMA_DRV_PushConfigToReg(virtualChannel, &edmaTransferConfig);
903  }
904  else
905  {
906  /* Copy configuration to software TCD structure */
907  EDMA_DRV_PushConfigToSTCD(&edmaTransferConfig, &edmaSwTcdAddr[i - 1U]);
908  }
909  }
910 
911  return retStatus;
912 }
913 
914 /*FUNCTION**********************************************************************
915  *
916  * Function Name : EDMA_DRV_StartChannel
917  * Description : Starts an eDMA channel.
918  *
919  * Implements : EDMA_DRV_StartChannel_Activity
920  *END**************************************************************************/
921 status_t EDMA_DRV_StartChannel(uint8_t virtualChannel)
922 {
923  /* Check that virtual channel number is valid */
924  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
925 
926  /* Check that eDMA module is initialized */
927  DEV_ASSERT(s_virtEdmaState != NULL);
928 
929  /* Check that virtual channel is initialized */
930  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
931 
932  /* Get DMA instance from virtual channel */
933  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
934 
935  /* Get DMA channel from virtual channel*/
936  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
937 
938  /* Enable requests for current channel */
939  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
940  EDMA_SetDmaRequestCmd(edmaRegBase, dmaChannel, true);
941 
942  return STATUS_SUCCESS;
943 }
944 
945 /*FUNCTION**********************************************************************
946  *
947  * Function Name : EDMA_DRV_StopChannel
948  * Description : Stops an eDMA channel.
949  *
950  * Implements : EDMA_DRV_StopChannel_Activity
951  *END**************************************************************************/
952 status_t EDMA_DRV_StopChannel(uint8_t virtualChannel)
953 {
954  /* Check that virtual channel number is valid */
955  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
956 
957  /* Check that eDMA module is initialized */
958  DEV_ASSERT(s_virtEdmaState != NULL);
959 
960  /* Check that virtual channel is initialized */
961  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
962 
963  /* Get DMA instance from virtual channel */
964  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
965 
966  /* Get DMA channel from virtual channel*/
967  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
968 
969  /* Disable requests for current channel */
970  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
971  EDMA_SetDmaRequestCmd(edmaRegBase, dmaChannel, false);
972 
973  return STATUS_SUCCESS;
974 }
975 
976 /*FUNCTION**********************************************************************
977  *
978  * Function Name : EDMA_DRV_SetChannelRequest
979  * Description : Configures the DMA request for the eDMA channel.
980  *
981  * Implements : EDMA_DRV_SetChannelRequest_Activity
982  *END**************************************************************************/
983 status_t EDMA_DRV_SetChannelRequest(uint8_t virtualChannel,
984  uint8_t req)
985 {
986  /* Check the mux channel number is valid */
987  DEV_ASSERT(virtualChannel < (uint32_t)FEATURE_DMA_VIRTUAL_CHANNELS);
988 
989  /* Check that eDMA module is initialized */
990  DEV_ASSERT(s_virtEdmaState != NULL);
991 
992  /* Retrieve the DMAMUX instance serving this request */
993  uint8_t dmaMuxInstance = (uint8_t)FEATURE_DMAMUX_REQ_SRC_TO_INSTANCE(req);
994 
995  /* Get request source index for the corresponding DMAMUX instance */
996  uint8_t dmaMuxRequest = (uint8_t)FEATURE_DMAMUX_REQ_SRC_TO_CH(req);
997 
998  /* Get DMAMUX channel for the selected request source */
999  uint8_t dmaMuxChannel = (uint8_t)FEATURE_DMAMUX_DMA_CH_TO_CH(virtualChannel);
1000 
1001  /* Retrieve the appropriate DMAMUX instance */
1002  DMAMUX_Type *dmaMuxRegBase = s_dmaMuxBase[dmaMuxInstance];
1003 
1004  /* Set the request */
1005  DMAMUX_SetChannelSource(dmaMuxRegBase, dmaMuxChannel, dmaMuxRequest);
1006 
1007  return STATUS_SUCCESS;
1008 }
1009 
1010 /*FUNCTION**********************************************************************
1011  *
1012  * Function Name : EDMA_DRV_ClearTCD
1013  * Description : Clears all registers to 0 for the hardware TCD.
1014  *
1015  * Implements : EDMA_DRV_ClearTCD_Activity
1016  *END**************************************************************************/
1017 void EDMA_DRV_ClearTCD(uint8_t virtualChannel)
1018 {
1019  /* Check that virtual channel number is valid */
1020  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1021 
1022  /* Check that eDMA module is initialized */
1023  DEV_ASSERT(s_virtEdmaState != NULL);
1024 
1025  /* Check that virtual channel is initialized */
1026  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1027 
1028  /* Get DMA instance from virtual channel */
1029  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1030 
1031  /* Get DMA channel from virtual channel*/
1032  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1033 
1034  /* Clear the TCD memory */
1035  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1036  EDMA_TCDClearReg(edmaRegBase, dmaChannel);
1037 }
1038 
1039 /*FUNCTION**********************************************************************
1040  *
1041  * Function Name : EDMA_DRV_SetSrcAddr
1042  * Description : Configures the source address for the eDMA channel.
1043  *
1044  * Implements : EDMA_DRV_SetSrcAddr_Activity
1045  *END**************************************************************************/
1046 void EDMA_DRV_SetSrcAddr(uint8_t virtualChannel,
1047  uint32_t address)
1048 {
1049  /* Check that virtual channel number is valid */
1050  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1051 
1052  /* Check that eDMA module is initialized */
1053  DEV_ASSERT(s_virtEdmaState != NULL);
1054 
1055  /* Check that virtual channel is initialized */
1056  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1057 
1058  /* Get DMA instance from virtual channel */
1059  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1060 
1061  /* Get DMA channel from virtual channel*/
1062  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1063 
1064  /* Set channel TCD source address */
1065  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1066  EDMA_TCDSetSrcAddr(edmaRegBase, dmaChannel, address);
1067 }
1068 
1069 /*FUNCTION**********************************************************************
1070  *
1071  * Function Name : EDMA_DRV_SetSrcOffset
1072  * Description : Configures the source address signed offset for the eDMA channel.
1073  *
1074  * Implements : EDMA_DRV_SetSrcOffset_Activity
1075  *END**************************************************************************/
1076 void EDMA_DRV_SetSrcOffset(uint8_t virtualChannel,
1077  int16_t offset)
1078 {
1079  /* Check that virtual channel number is valid */
1080  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1081 
1082  /* Check that eDMA module is initialized */
1083  DEV_ASSERT(s_virtEdmaState != NULL);
1084 
1085  /* Check that virtual channel is initialized */
1086  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1087 
1088  /* Get DMA instance from virtual channel */
1089  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1090 
1091  /* Get DMA channel from virtual channel*/
1092  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1093 
1094  /* Set channel TCD source offset */
1095  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1096  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, offset);
1097 }
1098 
1099 /*FUNCTION**********************************************************************
1100  *
1101  * Function Name : EDMA_DRV_SetSrcReadChunkSize
1102  * Description : Configures the source read data chunk size (transferred in a read sequence).
1103  *
1104  * Implements : EDMA_DRV_SetSrcReadChunkSize_Activity
1105  *END**************************************************************************/
1106 void EDMA_DRV_SetSrcReadChunkSize(uint8_t virtualChannel,
1107  edma_transfer_size_t size)
1108 {
1109  /* Check that virtual channel number is valid */
1110  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1111 
1112  /* Check that eDMA module is initialized */
1113  DEV_ASSERT(s_virtEdmaState != NULL);
1114 
1115  /* Check that virtual channel is initialized */
1116  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1117 
1118  /* Get DMA instance from virtual channel */
1119  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1120 
1121  /* Get DMA channel from virtual channel*/
1122  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1123 
1124  /* Set channel TCD source transfer size */
1125  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1126  EDMA_TCDSetSrcTransferSize(edmaRegBase, dmaChannel, size);
1127 }
1128 
1129 /*FUNCTION**********************************************************************
1130  *
1131  * Function Name : EDMA_DRV_SetSrcLastAddrAdjustment
1132  * Description : Configures the source address last adjustment.
1133  *
1134  * Implements : EDMA_DRV_SetSrcLastAddrAdjustment_Activity
1135  *END**************************************************************************/
1136 void EDMA_DRV_SetSrcLastAddrAdjustment(uint8_t virtualChannel,
1137  int32_t adjust)
1138 {
1139  /* Check that virtual channel number is valid */
1140  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1141 
1142  /* Check that eDMA module is initialized */
1143  DEV_ASSERT(s_virtEdmaState != NULL);
1144 
1145  /* Check that virtual channel is initialized */
1146  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1147 
1148  /* Get DMA instance from virtual channel */
1149  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1150 
1151  /* Get DMA channel from virtual channel*/
1152  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1153 
1154  /* Set channel TCD source last adjustment */
1155  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1156  EDMA_TCDSetSrcLastAdjust(edmaRegBase, dmaChannel, adjust);
1157 }
1158 
1159 /*FUNCTION**********************************************************************
1160  *
1161  * Function Name : EDMA_DRV_SetDestLastAddrAdjustment
1162  * Description : Configures the source address last adjustment.
1163  *
1164  * Implements : EDMA_DRV_SetDestLastAddrAdjustment_Activity
1165  *END**************************************************************************/
1166 void EDMA_DRV_SetDestLastAddrAdjustment(uint8_t virtualChannel,
1167  int32_t adjust)
1168 {
1169  /* Check that virtual channel number is valid */
1170  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1171 
1172  /* Check that eDMA module is initialized */
1173  DEV_ASSERT(s_virtEdmaState != NULL);
1174 
1175  /* Check that virtual channel is initialized */
1176  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1177 
1178  /* Get DMA instance from virtual channel */
1179  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1180 
1181  /* Get DMA channel from virtual channel*/
1182  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1183 
1184  /* Set channel TCD source last adjustment */
1185  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1186  EDMA_TCDSetDestLastAdjust(edmaRegBase, dmaChannel, adjust);
1187 }
1188 
1189 /*FUNCTION**********************************************************************
1190  *
1191  * Function Name : EDMA_DRV_SetDestAddr
1192  * Description : Configures the destination address for the eDMA channel.
1193  *
1194  * Implements : EDMA_DRV_SetDestAddr_Activity
1195  *END**************************************************************************/
1196 void EDMA_DRV_SetDestAddr(uint8_t virtualChannel,
1197  uint32_t address)
1198 {
1199  /* Check that virtual channel number is valid */
1200  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1201 
1202  /* Check that eDMA module is initialized */
1203  DEV_ASSERT(s_virtEdmaState != NULL);
1204 
1205  /* Check that virtual channel is initialized */
1206  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1207 
1208  /* Get DMA instance from virtual channel */
1209  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1210 
1211  /* Get DMA channel from virtual channel*/
1212  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1213 
1214  /* Set channel TCD destination address */
1215  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1216  EDMA_TCDSetDestAddr(edmaRegBase, dmaChannel, address);
1217 }
1218 
1219 /*FUNCTION**********************************************************************
1220  *
1221  * Function Name : EDMA_DRV_SetDestOffset
1222  * Description : Configures the destination address signed offset for the eDMA channel.
1223  *
1224  * Implements : EDMA_DRV_SetDestOffset_Activity
1225  *END**************************************************************************/
1226 void EDMA_DRV_SetDestOffset(uint8_t virtualChannel,
1227  int16_t offset)
1228 {
1229  /* Check that virtual channel number is valid */
1230  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1231 
1232  /* Check that eDMA module is initialized */
1233  DEV_ASSERT(s_virtEdmaState != NULL);
1234 
1235  /* Check that virtual channel is initialized */
1236  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1237 
1238  /* Get DMA instance from virtual channel */
1239  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1240 
1241  /* Get DMA channel from virtual channel*/
1242  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1243 
1244  /* Set channel TCD destination offset */
1245  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1246  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, offset);
1247 }
1248 
1249 /*FUNCTION**********************************************************************
1250  *
1251  * Function Name : EDMA_DRV_SetDestWriteChunkSize
1252  * Description : Configures the destination data chunk size (transferred in a write sequence).
1253  *
1254  * Implements : EDMA_DRV_SetDestWriteChunkSize_Activity
1255  *END**************************************************************************/
1256 void EDMA_DRV_SetDestWriteChunkSize(uint8_t virtualChannel,
1257  edma_transfer_size_t size)
1258 {
1259  /* Check that virtual channel number is valid */
1260  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1261 
1262  /* Check that eDMA module is initialized */
1263  DEV_ASSERT(s_virtEdmaState != NULL);
1264 
1265  /* Check that virtual channel is initialized */
1266  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1267 
1268  /* Get DMA instance from virtual channel */
1269  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1270 
1271  /* Get DMA channel from virtual channel*/
1272  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1273 
1274  /* Set channel TCD source transfer size */
1275  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1276  EDMA_TCDSetDestTransferSize(edmaRegBase, dmaChannel, size);
1277 }
1278 
1279 /*FUNCTION**********************************************************************
1280  *
1281  * Function Name : EDMA_DRV_SetMinorLoopBlockSize
1282  * Description : Configures the number of bytes to be transferred in each service request of the channel.
1283  *
1284  * Implements : EDMA_DRV_SetMinorLoopBlockSize_Activity
1285  *END**************************************************************************/
1286 void EDMA_DRV_SetMinorLoopBlockSize(uint8_t virtualChannel,
1287  uint32_t nbytes)
1288 {
1289  /* Check that virtual channel number is valid */
1290  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1291 
1292  /* Check that eDMA module is initialized */
1293  DEV_ASSERT(s_virtEdmaState != NULL);
1294 
1295  /* Check that virtual channel is initialized */
1296  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1297 
1298  /* Get DMA instance from virtual channel */
1299  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1300 
1301  /* Get DMA channel from virtual channel*/
1302  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1303 
1304  /* Set channel TCD minor loop block size */
1305  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1306  EDMA_TCDSetNbytes(edmaRegBase, dmaChannel, nbytes);
1307 }
1308 
1309 /*FUNCTION**********************************************************************
1310  *
1311  * Function Name : EDMA_DRV_SetMajorLoopIterationCount
1312  * Description : Configures the number of major loop iterations.
1313  *
1314  * Implements : EDMA_DRV_SetMajorLoopIterationCount_Activity
1315  *END**************************************************************************/
1316 void EDMA_DRV_SetMajorLoopIterationCount(uint8_t virtualChannel,
1317  uint32_t majorLoopCount)
1318 {
1319  /* Check that virtual channel number is valid */
1320  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1321 
1322  /* Check that eDMA module is initialized */
1323  DEV_ASSERT(s_virtEdmaState != NULL);
1324 
1325  /* Check that virtual channel is initialized */
1326  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1327 
1328  /* Get DMA instance from virtual channel */
1329  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1330 
1331  /* Get DMA channel from virtual channel*/
1332  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1333 
1334  /* Set the major loop iteration count */
1335  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1336  EDMA_TCDSetMajorCount(edmaRegBase, dmaChannel, majorLoopCount);
1337 }
1338 
1339 /*FUNCTION**********************************************************************
1340  *
1341  * Function Name : EDMA_DRV_GetRemainingMajorIterationsCount
1342  * Description : Returns the remaining major loop iteration count.
1343  *
1344  * Implements : EDMA_DRV_GetRemainingMajorIterationsCount_Activity
1345  *END**************************************************************************/
1346 uint32_t EDMA_DRV_GetRemainingMajorIterationsCount(uint8_t virtualChannel)
1347 {
1348  /* Check that virtual channel number is valid */
1349  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1350 
1351  /* Check that eDMA module is initialized */
1352  DEV_ASSERT(s_virtEdmaState != NULL);
1353 
1354  /* Check that virtual channel is initialized */
1355  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1356 
1357  /* Get DMA instance from virtual channel */
1358  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1359 
1360  /* Get DMA channel from virtual channel*/
1361  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1362 
1363  /* Retrieve the number of minor loops yet to be triggered */
1364  const DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1365  uint32_t count = EDMA_TCDGetCurrentMajorCount(edmaRegBase, dmaChannel);
1366 
1367  return count;
1368 }
1369 
1370 /*FUNCTION**********************************************************************
1371  *
1372  * Function Name : EDMA_DRV_SetScatterGatherLink
1373  * Description : Configures the memory address of the next TCD, in scatter/gather mode.
1374  *
1375  * Implements : EDMA_DRV_SetScatterGatherLink_Activity
1376  *END**************************************************************************/
1377 void EDMA_DRV_SetScatterGatherLink(uint8_t virtualChannel,
1378  uint32_t nextTCDAddr)
1379 {
1380  /* Check that virtual channel number is valid */
1381  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1382 
1383  /* Check that eDMA module is initialized */
1384  DEV_ASSERT(s_virtEdmaState != NULL);
1385 
1386  /* Check that virtual channel is initialized */
1387  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1388 
1389  /* Get DMA instance from virtual channel */
1390  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1391 
1392  /* Get DMA channel from virtual channel*/
1393  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1394 
1395  /* Configures the memory address of the next TCD */
1396  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1397  EDMA_TCDSetScatterGatherLink(edmaRegBase, dmaChannel, nextTCDAddr);
1398 }
1399 
1400 /*FUNCTION**********************************************************************
1401  *
1402  * Function Name : EDMA_DRV_DisableRequestsOnTransferComplete
1403  * Description : Disables/Enables the DMA request after the major loop completes for the TCD.
1404  *
1405  * Implements : EDMA_DRV_DisableRequestsOnTransferComplete_Activity
1406  *END**************************************************************************/
1408  bool disable)
1409 {
1410  /* Check that virtual channel number is valid */
1411  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1412 
1413  /* Check that eDMA module is initialized */
1414  DEV_ASSERT(s_virtEdmaState != NULL);
1415 
1416  /* Check that virtual channel is initialized */
1417  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1418 
1419  /* Get DMA instance from virtual channel */
1420  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1421 
1422  /* Get DMA channel from virtual channel*/
1423  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1424 
1425  /* Disables/Enables the DMA request upon TCD completion */
1426  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1427  EDMA_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaRegBase, dmaChannel, disable);
1428 }
1429 
1430 /*FUNCTION**********************************************************************
1431  *
1432  * Function Name : EDMA_DRV_ConfigureInterrupt
1433  * Description : Disables/Enables the channel interrupt requests.
1434  *
1435  * Implements : EDMA_DRV_ConfigureInterrupt_Activity
1436  *END**************************************************************************/
1437 void EDMA_DRV_ConfigureInterrupt(uint8_t virtualChannel,
1438  edma_channel_interrupt_t intSrc,
1439  bool enable)
1440 {
1441  /* Check that virtual channel number is valid */
1442  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1443 
1444  /* Check that eDMA module is initialized */
1445  DEV_ASSERT(s_virtEdmaState != NULL);
1446 
1447  /* Check that virtual channel is initialized */
1448  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1449 
1450  /* Get DMA instance from virtual channel */
1451  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1452 
1453  /* Get DMA channel from virtual channel*/
1454  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1455 
1456  /* Disables/Enables the channel interrupt requests. */
1457  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1458  switch (intSrc)
1459  {
1460  case EDMA_CHN_ERR_INT:
1461  /* Enable channel interrupt request when error conditions occur */
1462  EDMA_SetErrorIntCmd(edmaRegBase, dmaChannel, enable);
1463  break;
1465  /* Enable channel interrupt request when major iteration count reaches halfway point */
1466  EDMA_TCDSetMajorHalfCompleteIntCmd(edmaRegBase, dmaChannel, enable);
1467  break;
1469  /* Enable channel interrupt request when major iteration count reaches zero */
1470  EDMA_TCDSetMajorCompleteIntCmd(edmaRegBase, dmaChannel, enable);
1471  break;
1472  default:
1473  /* This branch should never be reached if driver API is used properly */
1474  break;
1475  }
1476 }
1477 
1478 /*FUNCTION**********************************************************************
1479  *
1480  * Function Name : EDMA_DRV_CancelTransfer
1481  * Description : Cancels the running transfer for this channel.
1482  *
1483  * Implements : EDMA_DRV_CancelTransfer_Activity
1484  *END**************************************************************************/
1485 void EDMA_DRV_CancelTransfer(bool error)
1486 {
1487  /* Check that eDMA module is initialized */
1488  DEV_ASSERT(s_virtEdmaState != NULL);
1489 
1490  uint32_t dmaInstance = 0U;
1491 
1492  for(dmaInstance = 0U; dmaInstance < (uint32_t)DMA_INSTANCE_COUNT; dmaInstance++)
1493  {
1494  /* Cancel the running transfer. */
1495  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1496  if (error)
1497  {
1498  EDMA_CancelTransferWithError(edmaRegBase);
1499  }
1500  else
1501  {
1502  EDMA_CancelTransfer(edmaRegBase);
1503  }
1504  }
1505 }
1506 
1507 /*FUNCTION**********************************************************************
1508  *
1509  * Function Name : EDMA_DRV_TriggerSwRequest
1510  * Description : Triggers a sw request for the current channel.
1511  *
1512  * Implements : EDMA_DRV_TriggerSwRequest_Activity
1513  *END**************************************************************************/
1514 void EDMA_DRV_TriggerSwRequest(uint8_t virtualChannel)
1515 {
1516  /* Check that virtual channel number is valid */
1517  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1518 
1519  /* Check that eDMA module is initialized */
1520  DEV_ASSERT(s_virtEdmaState != NULL);
1521 
1522  /* Check that virtual channel is initialized */
1523  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1524 
1525  /* Get DMA instance from virtual channel */
1526  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1527 
1528  /* Get DMA channel from virtual channel*/
1529  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1530 
1531  /* Trigger the channel transfer. */
1532  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1533  EDMA_TriggerChannelStart(edmaRegBase, dmaChannel);
1534 }
1535 
1536 /*FUNCTION**********************************************************************
1537  *
1538  * Function Name : EDMA_DRV_PushConfigToSTCD
1539  * Description : Copy the configuration to the software TCD structure.
1540  *
1541  * Implements : EDMA_DRV_PushConfigToSTCD_Activity
1542  *END**************************************************************************/
1544  edma_software_tcd_t *stcd)
1545 {
1546  if ((config != NULL) && (stcd != NULL))
1547  {
1548  /* Clear the array of software TCDs passed by the user */
1550 
1551  /* Set the software TCD fields */
1552  stcd->ATTR = (uint16_t)(DMA_TCD_ATTR_SMOD(config->srcModulo) | DMA_TCD_ATTR_SSIZE(config->srcTransferSize) |
1554  stcd->SADDR = config->srcAddr;
1555  stcd->SOFF = config->srcOffset;
1556  stcd->NBYTES = config->minorByteTransferCount;
1557  stcd->SLAST = config->srcLastAddrAdjust;
1558  stcd->DADDR = config->destAddr;
1559  stcd->DOFF = config->destOffset;
1560  stcd->CITER = (uint16_t) config->loopTransferConfig->majorLoopIterationCount;
1561  if (config->scatterGatherEnable)
1562  {
1563  stcd->DLAST_SGA = (int32_t) config->scatterGatherNextDescAddr;
1564  }
1565  else
1566  {
1567  stcd->DLAST_SGA = config->destLastAddrAdjust;
1568  }
1569 #ifdef FEATURE_DMA_HWV3
1570  stcd->CSR = (uint16_t) (((config->interruptEnable ? 1UL : 0UL) << DMA_TCD_CSR_INTMAJOR_SHIFT) |
1571  ((config->scatterGatherEnable ? 1UL : 0UL) << DMA_TCD_CSR_ESG_SHIFT));
1572 #else
1573  stcd->CSR = (uint16_t) (((config->interruptEnable ? 1UL : 0UL) << DMA_TCD_CSR_INTMAJOR_SHIFT) |
1574  ((config->scatterGatherEnable ? 1UL : 0UL) << DMA_TCD_CSR_ESG_SHIFT));
1575 #endif
1576  stcd->BITER = (uint16_t) config->loopTransferConfig->majorLoopIterationCount;
1577  }
1578 }
1579 
1580 /*FUNCTION**********************************************************************
1581  *
1582  * Function Name : EDMA_DRV_PushConfigToReg
1583  * Description : Copy the configuration to the TCD registers.
1584  *
1585  * Implements : EDMA_DRV_PushConfigToReg_Activity
1586  *END**************************************************************************/
1587 void EDMA_DRV_PushConfigToReg(uint8_t virtualChannel,
1588  const edma_transfer_config_t *tcd)
1589 {
1590  /* Check that virtual channel number is valid */
1591  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1592 
1593  /* Check that eDMA module is initialized */
1594  DEV_ASSERT(s_virtEdmaState != NULL);
1595 
1596  /* Check that virtual channel is initialized */
1597  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1598 
1599  /* Check the transfer configuration structure is valid */
1600  DEV_ASSERT(tcd != NULL);
1601 
1602  /* Get DMA instance from virtual channel */
1603  uint8_t dmaInstance = (uint8_t)FEATURE_DMA_VCH_TO_INSTANCE(virtualChannel);
1604 
1605  /* Get DMA channel from virtual channel*/
1606  uint8_t dmaChannel = (uint8_t)FEATURE_DMA_VCH_TO_CH(virtualChannel);
1607 
1608  DMA_Type *edmaRegBase = s_edmaBase[dmaInstance];
1609 
1610  /* Clear TCD registers */
1611  EDMA_TCDClearReg(edmaRegBase, dmaChannel);
1612 
1613 #ifdef FEATURE_DMA_ENGINE_STALL
1614  /* Configure the DMA Engine to stall for a number of cycles after each R/W */
1615  EDMA_TCDSetEngineStall(edmaRegBase, dmaChannel, EDMA_ENGINE_STALL_4_CYCLES);
1616 #endif
1617 
1618  /* Set source and destination addresses */
1619  EDMA_TCDSetSrcAddr(edmaRegBase, dmaChannel, tcd->srcAddr);
1620  EDMA_TCDSetDestAddr(edmaRegBase, dmaChannel, tcd->destAddr);
1621 
1622  /* Set source/destination modulo feature and transfer size */
1623  EDMA_TCDSetAttribute(edmaRegBase, dmaChannel, tcd->srcModulo, tcd->destModulo,
1624  tcd->srcTransferSize, tcd->destTransferSize);
1625 
1626  /* Set source/destination offset and last adjustment; for scatter/gather operation, destination
1627  * last adjustment is the address of the next TCD structure to be loaded by the eDMA engine */
1628  EDMA_TCDSetSrcOffset(edmaRegBase, dmaChannel, tcd->srcOffset);
1629  EDMA_TCDSetDestOffset(edmaRegBase, dmaChannel, tcd->destOffset);
1630  EDMA_TCDSetSrcLastAdjust(edmaRegBase, dmaChannel, tcd->srcLastAddrAdjust);
1631  if (tcd->scatterGatherEnable)
1632  {
1633  EDMA_TCDSetScatterGatherCmd(edmaRegBase, dmaChannel, true);
1634  EDMA_TCDSetScatterGatherLink(edmaRegBase, dmaChannel, tcd->scatterGatherNextDescAddr);
1635  }
1636  else
1637  {
1638  EDMA_TCDSetScatterGatherCmd(edmaRegBase, dmaChannel, false);
1639  EDMA_TCDSetDestLastAdjust(edmaRegBase, dmaChannel, tcd->destLastAddrAdjust);
1640  }
1641 
1642  /* Configure channel interrupt */
1643  EDMA_TCDSetMajorCompleteIntCmd(edmaRegBase, dmaChannel, tcd->interruptEnable);
1644 
1645  /* If loop configuration is available, copy minor/major loop setup to registers */
1646  if (tcd->loopTransferConfig != NULL)
1647  {
1648  EDMA_TCDSetSrcMinorLoopOffsetCmd(edmaRegBase, dmaChannel, tcd->loopTransferConfig->srcOffsetEnable);
1649  EDMA_TCDSetDestMinorLoopOffsetCmd(edmaRegBase, dmaChannel, tcd->loopTransferConfig->dstOffsetEnable);
1650  EDMA_TCDSetMinorLoopOffset(edmaRegBase, dmaChannel, tcd->loopTransferConfig->minorLoopOffset);
1651  EDMA_TCDSetNbytes(edmaRegBase, dmaChannel, tcd->minorByteTransferCount);
1652 
1653  EDMA_TCDSetChannelMinorLink(edmaRegBase, dmaChannel, tcd->loopTransferConfig->minorLoopChnLinkNumber,
1655  EDMA_TCDSetChannelMajorLink(edmaRegBase, dmaChannel, tcd->loopTransferConfig->majorLoopChnLinkNumber,
1657 
1658  EDMA_TCDSetMajorCount(edmaRegBase, dmaChannel, tcd->loopTransferConfig->majorLoopIterationCount);
1659  }
1660  else
1661  {
1662  EDMA_TCDSetNbytes(edmaRegBase, dmaChannel, tcd->minorByteTransferCount);
1663  }
1664 }
1665 
1666 #ifdef DEV_ERROR_DETECT
1667 /*FUNCTION**********************************************************************
1668  *
1669  * Function Name : EDMA_DRV_ValidTransferSize
1670  * Description : Check if the transfer size value is legal (0/1/2/4/5).
1671  *
1672  *END**************************************************************************/
1673 static bool EDMA_DRV_ValidTransferSize(edma_transfer_size_t size)
1674 {
1675  bool isValid;
1676  switch (size)
1677  {
1678  case EDMA_TRANSFER_SIZE_1B:
1679  case EDMA_TRANSFER_SIZE_2B:
1680  case EDMA_TRANSFER_SIZE_4B:
1681 #ifdef FEATURE_DMA_TRANSFER_SIZE_8B
1682  case EDMA_TRANSFER_SIZE_8B:
1683 #endif
1684 #ifdef FEATURE_DMA_TRANSFER_SIZE_16B
1685  case EDMA_TRANSFER_SIZE_16B:
1686 #endif
1687 #ifdef FEATURE_DMA_TRANSFER_SIZE_32B
1688  case EDMA_TRANSFER_SIZE_32B:
1689 #endif
1690 #ifdef FEATURE_DMA_TRANSFER_SIZE_64B
1691  case EDMA_TRANSFER_SIZE_64B:
1692 #endif
1693  isValid = true;
1694  break;
1695  default:
1696  isValid = false;
1697  break;
1698  }
1699  return isValid;
1700 }
1701 #endif
1702 
1703 /*FUNCTION**********************************************************************
1704  *
1705  * Function Name : EDMA_DRV_GetChannelStatus
1706  * Description : Returns the eDMA channel retStatus.
1707  *
1708  * Implements : EDMA_DRV_GetChannelStatus_Activity
1709  *END**************************************************************************/
1711 {
1712  /* Check that virtual channel number is valid */
1713  DEV_ASSERT(virtualChannel < FEATURE_DMA_VIRTUAL_CHANNELS);
1714 
1715  /* Check that eDMA module is initialized */
1716  DEV_ASSERT(s_virtEdmaState != NULL);
1717 
1718  /* Check that virtual channel is initialized */
1719  DEV_ASSERT(s_virtEdmaState->virtChnState[virtualChannel] != NULL);
1720 
1721  return s_virtEdmaState->virtChnState[virtualChannel]->status;
1722 }
1723 
1724 /*FUNCTION**********************************************************************
1725  *
1726  * Function Name : EDMA_DRV_GetDmaRegBaseAddr
1727  * Description : Returns the DMA register base address.
1728  *
1729  * Implements : EDMA_DRV_GetDmaRegBaseAddr
1730  *END**************************************************************************/
1732 {
1733  /* Check that instance is valid */
1734  DEV_ASSERT(instance < DMA_INSTANCE_COUNT);
1735 
1736  return s_edmaBase[instance];
1737 }
1738 
1739 
1740 /*******************************************************************************
1741  * EOF
1742  ******************************************************************************/
1743 
void EDMA_DRV_PushConfigToSTCD(const edma_transfer_config_t *config, edma_software_tcd_t *stcd)
Copies the channel configuration to the software TCD structure.
Definition: edma_driver.c:1543
void EDMA_DRV_SetMajorLoopIterationCount(uint8_t virtualChannel, uint32_t majorLoopCount)
Configures the number of major loop iterations.
Definition: edma_driver.c:1316
eDMA TCD Implements : edma_software_tcd_t_Class
Definition: edma_driver.h:397
#define DMA_TCD_ATTR_SSIZE(x)
Definition: S32K118.h:2906
uint32_t EDMA_DRV_GetRemainingMajorIterationsCount(uint8_t virtualChannel)
Returns the remaining major loop iteration count.
Definition: edma_driver.c:1346
uint32_t minorByteTransferCount
Definition: edma_driver.h:378
#define DMAMUX_INSTANCE_COUNT
Definition: S32K118.h:3081
#define DMA_INSTANCE_COUNT
Definition: S32K118.h:2264
static const IRQn_Type s_edmaIrqId[FEATURE_DMA_VIRTUAL_CHANNELS_INTERRUPT_LINES]
Array of default DMA channel interrupt handlers.
Definition: edma_driver.c:80
status_t EDMA_DRV_InstallCallback(uint8_t virtualChannel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:336
edma_modulo_t destModulo
Definition: edma_driver.h:377
#define FEATURE_DMA_VIRTUAL_CHANNELS_INTERRUPT_LINES
#define FEATURE_DMA_VCH_TO_INSTANCE(x)
status_t EDMA_DRV_ConfigLoopTransfer(uint8_t virtualChannel, const edma_transfer_config_t *transferConfig)
Configures the DMA transfer in loop mode.
Definition: edma_driver.c:708
status_t EDMA_DRV_ConfigMultiBlockTransfer(uint8_t virtualChannel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t blockSize, uint32_t blockCount, bool disableReqOnCompletion)
Configures a multiple block data transfer with DMA.
Definition: edma_driver.c:662
edma_callback_t callback
Definition: edma_driver.h:298
The user configuration structure for the eDMA driver.
Definition: edma_driver.h:235
edma_transfer_type_t
A type for the DMA transfer. Implements : edma_transfer_type_t_Class.
Definition: edma_driver.h:305
void EDMA_DRV_SetDestWriteChunkSize(uint8_t virtualChannel, edma_transfer_size_t size)
Configures the destination data chunk size (transferred in a write sequence).
Definition: edma_driver.c:1256
status_t EDMA_DRV_ConfigSingleBlockTransfer(uint8_t virtualChannel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t dataBufferSize)
Configures a simple single block data transfer with DMA.
Definition: edma_driver.c:554
void EDMA_DRV_PushConfigToReg(uint8_t virtualChannel, const edma_transfer_config_t *tcd)
Copies the channel configuration to the TCD registers.
Definition: edma_driver.c:1587
static status_t EDMA_DRV_RequestChannel(uint8_t virtualChannel, dma_request_source_t reqSrc, edma_chn_state_t *reqChn)
Definition: edma_driver.c:358
#define FEATURE_DMA_VIRTUAL_ERROR_INTERRUPT_LINES
The user configuration structure for the an eDMA driver channel.
Definition: edma_driver.h:287
status_t EDMA_DRV_Deinit(void)
De-initializes the eDMA module.
Definition: edma_driver.c:239
void EDMA_DRV_SetScatterGatherLink(uint8_t virtualChannel, uint32_t nextTCDAddr)
Configures the memory address of the next TCD, in scatter/gather mode.
Definition: edma_driver.c:1377
void EDMA_DRV_SetSrcLastAddrAdjustment(uint8_t virtualChannel, int32_t adjust)
Configures the source address last adjustment.
Definition: edma_driver.c:1136
#define DMA_BASE_PTRS
Definition: S32K118.h:2275
void EDMA_DRV_ConfigureInterrupt(uint8_t virtualChannel, edma_channel_interrupt_t intSrc, bool enable)
Disables/Enables the channel interrupt requests.
Definition: edma_driver.c:1437
void EDMA_DRV_TriggerSwRequest(uint8_t virtualChannel)
Triggers a sw request for the current channel.
Definition: edma_driver.c:1514
void EDMA_DRV_SetDestOffset(uint8_t virtualChannel, int16_t offset)
Configures the destination address signed offset for the eDMA channel.
Definition: edma_driver.c:1226
status_t EDMA_DRV_StopChannel(uint8_t virtualChannel)
Stops the eDMA channel.
Definition: edma_driver.c:952
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
edma_channel_interrupt_t
eDMA channel interrupts. Implements : edma_channel_interrupt_t_Class
Definition: edma_driver.h:73
#define DEV_ASSERT(x)
Definition: devassert.h:77
uint32_t scatterGatherNextDescAddr
Definition: edma_driver.h:381
static DMAMUX_Type *const s_dmaMuxBase[DMAMUX_INSTANCE_COUNT]
Array of base addresses for DMAMUX instances.
Definition: edma_driver.c:77
#define DMA_TCD_ATTR_DSIZE(x)
Definition: S32K118.h:2898
#define STCD_ADDR(address)
Definition: edma_driver.h:60
void EDMA_DRV_DisableRequestsOnTransferComplete(uint8_t virtualChannel, bool disable)
Disables/Enables the DMA request after the major loop completes for the TCD.
Definition: edma_driver.c:1407
status_t EDMA_DRV_ChannelInit(edma_chn_state_t *edmaChannelState, const edma_channel_config_t *edmaChannelConfig)
Initializes an eDMA channel.
Definition: edma_driver.c:287
Runtime state structure for the eDMA driver.
Definition: edma_driver.h:330
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:255
edma_chn_status_t EDMA_DRV_GetChannelStatus(uint8_t virtualChannel)
Gets the eDMA channel status.
Definition: edma_driver.c:1710
edma_transfer_size_t destTransferSize
Definition: edma_driver.h:366
edma_callback_t callback
Definition: edma_driver.h:273
edma_transfer_size_t
eDMA transfer configuration Implements : edma_transfer_size_t_Class
Definition: edma_driver.h:200
#define DMA_TCD_CSR_ESG_SHIFT
Definition: S32K118.h:3006
void EDMA_DRV_SetDestAddr(uint8_t virtualChannel, uint32_t address)
Configures the destination address for the eDMA channel.
Definition: edma_driver.c:1196
status_t CLOCK_SYS_GetFreq(clock_names_t clockName, uint32_t *frequency)
Gets the clock frequency for a specific clock name.
#define DMA_TCD_ATTR_DMOD(x)
Definition: S32K118.h:2902
edma_arbitration_algorithm_t chnArbitration
Definition: edma_driver.h:236
#define FEATURE_DMA_CLOCK_NAMES
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K118.h:188
#define FEATURE_DMAMUX_REQ_SRC_TO_CH(x)
#define FEATURE_DMAMUX_CLOCK_NAMES
edma_modulo_t srcModulo
Definition: edma_driver.h:376
edma_channel_priority_t channelPriority
Definition: edma_driver.h:294
status_t EDMA_DRV_ReleaseChannel(uint8_t virtualChannel)
Releases an eDMA channel.
Definition: edma_driver.c:421
void EDMA_DRV_SetSrcOffset(uint8_t virtualChannel, int16_t offset)
Configures the source address signed offset for the eDMA channel.
Definition: edma_driver.c:1076
edma_transfer_size_t srcTransferSize
Definition: edma_driver.h:365
Data structure for configuring a discrete memory transfer. Implements : edma_scatter_gather_list_t_Cl...
Definition: edma_driver.h:315
volatile edma_chn_status_t status
Definition: edma_driver.h:277
#define DMAMUX_BASE_PTRS
Definition: S32K118.h:3092
DMA_Type * EDMA_DRV_GetDmaRegBaseAddr(uint32_t instance)
Definition: edma_driver.c:1731
void EDMA_DRV_SetSrcReadChunkSize(uint8_t virtualChannel, edma_transfer_size_t size)
Configures the source data chunk size (transferred in a read sequence).
Definition: edma_driver.c:1106
edma_transfer_type_t type
Definition: edma_driver.h:318
void EDMA_DRV_SetSrcAddr(uint8_t virtualChannel, uint32_t address)
Configures the source address for the eDMA channel.
Definition: edma_driver.c:1046
status_t EDMA_DRV_ConfigScatterGatherTransfer(uint8_t virtualChannel, edma_software_tcd_t *stcd, edma_transfer_size_t transferSize, uint32_t bytesOnEachRequest, const edma_scatter_gather_list_t *srcList, const edma_scatter_gather_list_t *destList, uint8_t tcdCount)
Configures the DMA transfer in a scatter-gather mode.
Definition: edma_driver.c:761
void EDMA_DRV_IRQHandler(uint8_t virtualChannel)
DMA channel interrupt handler, implemented in driver c file.
Definition: edma_driver.c:503
#define FEATURE_DMAMUX_REQ_SRC_TO_INSTANCE(x)
void EDMA_DRV_SetMinorLoopBlockSize(uint8_t virtualChannel, uint32_t nbytes)
Configures the number of bytes to be transferred in each service request of the channel.
Definition: edma_driver.c:1286
status_t EDMA_DRV_Init(edma_state_t *edmaState, const edma_user_config_t *userConfig, edma_chn_state_t *const chnStateArray[], const edma_channel_config_t *const chnConfigArray[], uint32_t chnCount)
Initializes the eDMA module.
Definition: edma_driver.c:119
static void EDMA_DRV_ClearIntStatus(uint8_t virtualChannel)
Definition: edma_driver.c:467
void EDMA_DRV_ErrorIRQHandler(uint8_t virtualChannel)
Definition: edma_driver.c:523
status_t EDMA_DRV_StartChannel(uint8_t virtualChannel)
Starts an eDMA channel.
Definition: edma_driver.c:921
static edma_state_t * s_virtEdmaState
Array of default DMA error interrupt handlers.
Definition: edma_driver.c:95
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
#define DMA_TCD_CSR_INTMAJOR_SHIFT
Definition: S32K118.h:2994
status_t EDMA_DRV_SetChannelRequest(uint8_t virtualChannel, uint8_t req)
Configures the DMA request for the eDMA channel.
Definition: edma_driver.c:983
#define FEATURE_DMA_VIRTUAL_CHANNELS
#define FEATURE_DMA_VCH_TO_CH(x)
void EDMA_DRV_CancelTransfer(bool error)
Cancel the running transfer.
Definition: edma_driver.c:1485
edma_chn_state_t *volatile virtChnState[(uint32_t)((uint32_t)(4U)*(uint32_t)(1u))]
Definition: edma_driver.h:331
void(* edma_callback_t)(void *parameter, edma_chn_status_t status)
Definition for the eDMA channel callback function.
Definition: edma_driver.h:266
dma_request_source_t source
Definition: edma_driver.h:297
void EDMA_DRV_SetDestLastAddrAdjustment(uint8_t virtualChannel, int32_t adjust)
Configures the destination address last adjustment.
Definition: edma_driver.c:1166
void EDMA_DRV_ClearTCD(uint8_t virtualChannel)
Clears all registers to 0 for the channel's TCD.
Definition: edma_driver.c:1017
static void EDMA_DRV_ClearSoftwareTCD(edma_software_tcd_t *stcd)
Definition: edma_driver.c:486
eDMA loop transfer configuration.
Definition: edma_driver.h:340
#define FEATURE_DMAMUX_DMA_CH_TO_CH(x)
clock_names_t
Clock names.
eDMA transfer size configuration.
Definition: edma_driver.h:362
edma_loop_transfer_config_t * loopTransferConfig
Definition: edma_driver.h:387
#define DMA_CHN_IRQS
Definition: S32K118.h:2283
#define DMA_TCD_ATTR_SMOD(x)
Definition: S32K118.h:2910
dma_request_source_t
Structure for the DMA hardware request.
static DMA_Type *const s_edmaBase[DMA_INSTANCE_COUNT]
Array of base addresses for DMA instances.
Definition: edma_driver.c:74
#define DMA_ERROR_IRQS
Definition: S32K118.h:2284
Data structure for the eDMA channel state. Implements : edma_chn_state_t_Class.
Definition: edma_driver.h:271