LPCOpen Platform for LPC18XX/43XX microcontrollers  18XX43XX
LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers
gpdma_18xx_43xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC18xx/43xx GPDMA driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "chip.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /* Channel array to monitor free channel */
40 
41 /* Optimized Peripheral Source and Destination burst size (18xx,43xx) */
42 static const uint8_t GPDMA_LUTPerBurst[] = {
43  GPDMA_BSIZE_4, /* MEMORY */
44  GPDMA_BSIZE_1, /* MAT0.0 */
45  GPDMA_BSIZE_1, /* UART0 Tx */
46  GPDMA_BSIZE_1, /* MAT0.1 */
47  GPDMA_BSIZE_1, /* UART0 Rx */
48  GPDMA_BSIZE_1, /* MAT1.0 */
49  GPDMA_BSIZE_1, /* UART1 Tx */
50  GPDMA_BSIZE_1, /* MAT1.1 */
51  GPDMA_BSIZE_1, /* UART1 Rx */
52  GPDMA_BSIZE_1, /* MAT2.0 */
53  GPDMA_BSIZE_1, /* UART2 Tx */
54  GPDMA_BSIZE_1, /* MAT2.1 */
55  GPDMA_BSIZE_1, /* UART2 Rx */
56  GPDMA_BSIZE_1, /* MAT3.0 */
57  GPDMA_BSIZE_1, /* UART3 Tx */
58  0, /* SCT timer channel 0*/
59  GPDMA_BSIZE_1, /* MAT3.1 */
60  GPDMA_BSIZE_1, /* UART3 Rx */
61  0, /* SCT timer channel 1*/
62  GPDMA_BSIZE_4, /* SSP0 Rx */
63  GPDMA_BSIZE_32, /* I2S channel 0 */
64  GPDMA_BSIZE_4, /* SSP0 Tx */
65  GPDMA_BSIZE_32, /* I2S channel 1 */
66  GPDMA_BSIZE_4, /* SSP1 Rx */
67  GPDMA_BSIZE_4, /* SSP1 Tx */
68  GPDMA_BSIZE_4, /* ADC 0 */
69  GPDMA_BSIZE_4, /* ADC 1 */
70  GPDMA_BSIZE_1, /* DAC */
71  GPDMA_BSIZE_32, /* I2S channel 0 */
72  GPDMA_BSIZE_32 /* I2S channel 0 */
73 };
74 
75 /* Optimized Peripheral Source and Destination transfer width (18xx,43xx) */
76 static const uint8_t GPDMA_LUTPerWid[] = {
77  GPDMA_WIDTH_WORD, /* MEMORY */
78  GPDMA_WIDTH_WORD, /* MAT0.0 */
79  GPDMA_WIDTH_BYTE, /* UART0 Tx */
80  GPDMA_WIDTH_WORD, /* MAT0.1 */
81  GPDMA_WIDTH_BYTE, /* UART0 Rx */
82  GPDMA_WIDTH_WORD, /* MAT1.0 */
83  GPDMA_WIDTH_BYTE, /* UART1 Tx */
84  GPDMA_WIDTH_WORD, /* MAT1.1 */
85  GPDMA_WIDTH_BYTE, /* UART1 Rx */
86  GPDMA_WIDTH_WORD, /* MAT2.0 */
87  GPDMA_WIDTH_BYTE, /* UART2 Tx */
88  GPDMA_WIDTH_WORD, /* MAT2.1 */
89  GPDMA_WIDTH_BYTE, /* UART2 Rx */
90  GPDMA_WIDTH_WORD, /* MAT3.0 */
91  GPDMA_WIDTH_BYTE, /* UART3 Tx */
92  0, /* SCT timer channel 0*/
93  GPDMA_WIDTH_WORD, /* MAT3.1 */
94  GPDMA_WIDTH_BYTE, /* UART3 Rx */
95  0, /* SCT timer channel 1*/
96  GPDMA_WIDTH_BYTE, /* SSP0 Rx */
97  GPDMA_WIDTH_WORD, /* I2S channel 0 */
98  GPDMA_WIDTH_BYTE, /* SSP0 Tx */
99  GPDMA_WIDTH_WORD, /* I2S channel 1 */
100  GPDMA_WIDTH_BYTE, /* SSP1 Rx */
101  GPDMA_WIDTH_BYTE, /* SSP1 Tx */
102  GPDMA_WIDTH_WORD, /* ADC 0 */
103  GPDMA_WIDTH_WORD, /* ADC 1 */
104  GPDMA_WIDTH_WORD, /* DAC */
105  GPDMA_WIDTH_WORD, /* I2S channel 0 */
106  GPDMA_WIDTH_WORD/* I2S channel 0 */
107 };
108 
109 /* Lookup Table of Connection Type matched with (18xx,43xx) Peripheral Data (FIFO) register base address */
110 volatile static const void *GPDMA_LUTPerAddr[] = {
111  NULL, /* MEMORY */
112  (&LPC_TIMER0->MR), /* MAT0.0 */
113  (&LPC_USART0-> /*RBTHDLR.*/ THR), /* UART0 Tx */
114  ((uint32_t *) &LPC_TIMER0->MR + 1), /* MAT0.1 */
115  (&LPC_USART0-> /*RBTHDLR.*/ RBR), /* UART0 Rx */
116  (&LPC_TIMER1->MR), /* MAT1.0 */
117  (&LPC_UART1-> /*RBTHDLR.*/ THR),/* UART1 Tx */
118  ((uint32_t *) &LPC_TIMER1->MR + 1), /* MAT1.1 */
119  (&LPC_UART1-> /*RBTHDLR.*/ RBR),/* UART1 Rx */
120  (&LPC_TIMER2->MR), /* MAT2.0 */
121  (&LPC_USART2-> /*RBTHDLR.*/ THR), /* UART2 Tx */
122  ((uint32_t *) &LPC_TIMER2->MR + 1), /* MAT2.1 */
123  (&LPC_USART2-> /*RBTHDLR.*/ RBR), /* UART2 Rx */
124  (&LPC_TIMER3->MR), /* MAT3.0 */
125  (&LPC_USART3-> /*RBTHDLR.*/ THR), /* UART3 Tx */
126  0, /* SCT timer channel 0*/
127  ((uint32_t *) &LPC_TIMER3->MR + 1), /* MAT3.1 */
128  (&LPC_USART3-> /*RBTHDLR.*/ RBR), /* UART3 Rx */
129  0, /* SCT timer channel 1*/
130  (&LPC_SSP0->DR), /* SSP0 Rx */
131  (&LPC_I2S0->TXFIFO), /* I2S0 Tx on channel 0 */
132  (&LPC_SSP0->DR), /* SSP0 Tx */
133  (&LPC_I2S0->RXFIFO), /* I2S0 Rx on channel 1 */
134  (&LPC_SSP1->DR), /* SSP1 Rx */
135  (&LPC_SSP1->DR), /* SSP1 Tx */
136  (&LPC_ADC0->GDR), /* ADC 0 */
137  (&LPC_ADC1->GDR), /* ADC 1 */
138  (&LPC_DAC->CR), /* DAC */
139  (&LPC_I2S1->TXFIFO), /* I2S1 Tx on channel 0 */
140  (&LPC_I2S1->RXFIFO) /* I2S1 Rx on channel 1 */
141 };
142 
143 /*****************************************************************************
144  * Public types/enumerations/variables
145  ****************************************************************************/
146 
147 /*****************************************************************************
148  * Private functions
149  ****************************************************************************/
150 /* Control which set of peripherals is connected to the DMA controller */
151 STATIC uint8_t configDMAMux(uint32_t gpdma_peripheral_connection_number)
152 {
153  uint8_t function, channel;
154 
155  switch (gpdma_peripheral_connection_number) {
156  case GPDMA_CONN_MAT0_0:
157  function = 0;
158  channel = 1;
159  break;
160 
161  case GPDMA_CONN_UART0_Tx:
162  function = 1;
163  channel = 1;
164  break;
165 
166  case GPDMA_CONN_MAT0_1:
167  function = 0;
168  channel = 2;
169  break;
170 
171  case GPDMA_CONN_UART0_Rx:
172  function = 1;
173  channel = 2;
174  break;
175 
176  case GPDMA_CONN_MAT1_0:
177  function = 0;
178  channel = 3;
179  break;
180 
181  case GPDMA_CONN_UART1_Tx:
182  function = 1;
183  channel = 3;
184  break;
185 
187  function = 2;
188  channel = 3;
189  break;
190 
191  case GPDMA_CONN_MAT1_1:
192  function = 0;
193  channel = 4;
194  break;
195 
196  case GPDMA_CONN_UART1_Rx:
197  function = 1;
198  channel = 4;
199  break;
200 
202  function = 2;
203  channel = 4;
204  break;
205 
206  case GPDMA_CONN_MAT2_0:
207  function = 0;
208  channel = 5;
209  break;
210 
211  case GPDMA_CONN_UART2_Tx:
212  function = 1;
213  channel = 5;
214  break;
215 
216  case GPDMA_CONN_MAT2_1:
217  function = 0;
218  channel = 6;
219  break;
220 
221  case GPDMA_CONN_UART2_Rx:
222  function = 1;
223  channel = 6;
224  break;
225 
226  case GPDMA_CONN_MAT3_0:
227  function = 0;
228  channel = 7;
229  break;
230 
231  case GPDMA_CONN_UART3_Tx:
232  function = 1;
233  channel = 7;
234  break;
235 
236  case GPDMA_CONN_SCT_0:
237  function = 2;
238  channel = 7;
239  break;
240 
241  case GPDMA_CONN_MAT3_1:
242  function = 0;
243  channel = 8;
244  break;
245 
246  case GPDMA_CONN_UART3_Rx:
247  function = 1;
248  channel = 8;
249  break;
250 
251  case GPDMA_CONN_SCT_1:
252  function = 2;
253  channel = 8;
254  break;
255 
256  case GPDMA_CONN_SSP0_Rx:
257  function = 0;
258  channel = 9;
259  break;
260 
262  function = 1;
263  channel = 9;
264  break;
265 
266  case GPDMA_CONN_SSP0_Tx:
267  function = 0;
268  channel = 10;
269  break;
270 
272  function = 1;
273  channel = 10;
274  break;
275 
276  case GPDMA_CONN_SSP1_Rx:
277  function = 0;
278  channel = 11;
279  break;
280 
281  case GPDMA_CONN_SSP1_Tx:
282  function = 0;
283  channel = 12;
284  break;
285 
286  case GPDMA_CONN_ADC_0:
287  function = 0;
288  channel = 13;
289  break;
290 
291  case GPDMA_CONN_ADC_1:
292  function = 0;
293  channel = 14;
294  break;
295 
296  case GPDMA_CONN_DAC:
297  function = 0;
298  channel = 15;
299  break;
300 
301  default:
302  function = 3;
303  channel = 15;
304  break;
305  }
306  /* Set select function to dmamux register */
307  if (0 != gpdma_peripheral_connection_number) {
308  uint32_t temp;
309  temp = LPC_CREG->DMAMUX & (~(0x03 << (2 * channel)));
310  LPC_CREG->DMAMUX = temp | (function << (2 * channel));
311  }
312  return channel;
313 }
314 
315 uint32_t makeCtrlWord(const GPDMA_CH_CFG_T *GPDMAChannelConfig,
316  uint32_t GPDMA_LUTPerBurstSrcConn,
317  uint32_t GPDMA_LUTPerBurstDstConn,
318  uint32_t GPDMA_LUTPerWidSrcConn,
319  uint32_t GPDMA_LUTPerWidDstConn)
320 {
321  uint32_t ctrl_word = 0;
322 
323  switch (GPDMAChannelConfig->TransferType) {
324  /* Memory to memory */
326  ctrl_word = GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize)
329  | GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth)
330  | GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth)
334  break;
335 
338  ctrl_word = GPDMA_DMACCxControl_TransferSize((uint32_t) GPDMAChannelConfig->TransferSize)
339  | GPDMA_DMACCxControl_SBSize(GPDMA_LUTPerBurstDstConn)
340  | GPDMA_DMACCxControl_DBSize(GPDMA_LUTPerBurstDstConn)
341  | GPDMA_DMACCxControl_SWidth(GPDMA_LUTPerWidDstConn)
342  | GPDMA_DMACCxControl_DWidth(GPDMA_LUTPerWidDstConn)
346  break;
347 
350  ctrl_word = GPDMA_DMACCxControl_TransferSize((uint32_t) GPDMAChannelConfig->TransferSize)
351  | GPDMA_DMACCxControl_SBSize(GPDMA_LUTPerBurstSrcConn)
352  | GPDMA_DMACCxControl_DBSize(GPDMA_LUTPerBurstSrcConn)
353  | GPDMA_DMACCxControl_SWidth(GPDMA_LUTPerWidSrcConn)
354  | GPDMA_DMACCxControl_DWidth(GPDMA_LUTPerWidSrcConn)
358  break;
359 
363  ctrl_word = GPDMA_DMACCxControl_TransferSize((uint32_t) GPDMAChannelConfig->TransferSize)
364  | GPDMA_DMACCxControl_SBSize(GPDMA_LUTPerBurstSrcConn)
365  | GPDMA_DMACCxControl_DBSize(GPDMA_LUTPerBurstDstConn)
366  | GPDMA_DMACCxControl_SWidth(GPDMA_LUTPerWidSrcConn)
367  | GPDMA_DMACCxControl_DWidth(GPDMA_LUTPerWidDstConn)
371 
372  break;
373 
374  /* Do not support any more transfer type, return ERROR */
375  default:
376  return ERROR;
377  }
378  return ctrl_word;
379 }
380 
381 /* Set up the DPDMA according to the specification configuration details */
383  GPDMA_CH_CFG_T *GPDMAChannelConfig,
384  uint32_t CtrlWord,
385  uint32_t LinkListItem,
386  uint8_t SrcPeripheral,
387  uint8_t DstPeripheral)
388 {
389  GPDMA_CH_T *pDMAch;
390 
391  if (pGPDMA->ENBLDCHNS & ((((1UL << (GPDMAChannelConfig->ChannelNum)) & 0xFF)))) {
392  /* This channel is enabled, return ERROR, need to release this channel first */
393  return ERROR;
394  }
395 
396  /* Get Channel pointer */
397  pDMAch = (GPDMA_CH_T *) &(pGPDMA->CH[GPDMAChannelConfig->ChannelNum]);
398 
399  /* Reset the Interrupt status */
400  pGPDMA->INTTCCLEAR = (((1UL << (GPDMAChannelConfig->ChannelNum)) & 0xFF));
401  pGPDMA->INTERRCLR = (((1UL << (GPDMAChannelConfig->ChannelNum)) & 0xFF));
402 
403  /* Assign Linker List Item value */
404  pDMAch->LLI = LinkListItem;
405 
406  /* Enable DMA channels, little endian */
407  pGPDMA->CONFIG = GPDMA_DMACConfig_E;
408  while (!(pGPDMA->CONFIG & GPDMA_DMACConfig_E)) {}
409 
410  pDMAch->SRCADDR = GPDMAChannelConfig->SrcAddr;
411  pDMAch->DESTADDR = GPDMAChannelConfig->DstAddr;
412 
413  /* Configure DMA Channel, enable Error Counter and Terminate counter */
414  pDMAch->CONFIG = GPDMA_DMACCxConfig_IE
415  | GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/
416  | GPDMA_DMACCxConfig_TransferType((uint32_t) GPDMAChannelConfig->TransferType)
417  | GPDMA_DMACCxConfig_SrcPeripheral(SrcPeripheral)
418  | GPDMA_DMACCxConfig_DestPeripheral(DstPeripheral);
419 
420  pDMAch->CONTROL = CtrlWord;
421 
422  return SUCCESS;
423 }
424 
425 /*****************************************************************************
426  * Public functions
427  ****************************************************************************/
428 
429 /* Initialize the GPDMA */
431 {
432  uint8_t i;
433 
434  Chip_Clock_EnableOpts(CLK_MX_DMA, true, true, 1);
435 
436  /* Reset all channel configuration register */
437  for (i = 8; i > 0; i--) {
438  pGPDMA->CH[i - 1].CONFIG = 0;
439  }
440 
441  /* Clear all DMA interrupt and error flag */
442  pGPDMA->INTTCCLEAR = 0xFF;
443  pGPDMA->INTERRCLR = 0xFF;
444 
445  /* Reset all channels are free */
446  for (i = 0; i < GPDMA_NUMBER_CHANNELS; i++) {
447  ChannelHandlerArray[i].ChannelStatus = DISABLE;
448  }
449 }
450 
451 /* Shutdown the GPDMA */
453 {
455 }
456 
457 /* Stop a stream DMA transfer */
459  uint8_t ChannelNum)
460 {
461  Chip_GPDMA_ChannelCmd(pGPDMA, (ChannelNum), DISABLE);
462  if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTTC, ChannelNum)) {
463  /* Clear terminate counter Interrupt pending */
464  Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTTC, ChannelNum);
465  }
466  if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTERR, ChannelNum)) {
467  /* Clear terminate counter Interrupt pending */
469  }
470  ChannelHandlerArray[ChannelNum].ChannelStatus = DISABLE;
471 }
472 
473 /* The GPDMA stream interrupt status checking */
475  uint8_t ChannelNum)
476 {
477 
478  if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INT, ChannelNum)) {
479  /* Check counter terminal status */
480  if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTTC, ChannelNum)) {
481  /* Clear terminate counter Interrupt pending */
482  Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTTC, ChannelNum);
483  return SUCCESS;
484  }
485  /* Check error terminal status */
486  if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTERR, ChannelNum)) {
487  /* Clear error counter Interrupt pending */
488 
490  return ERROR;
491  }
492  }
493  return ERROR;
494 }
495 
497  GPDMA_CH_CFG_T *GPDMACfg,
498  uint8_t ChannelNum,
499  uint32_t src,
500  uint32_t dst,
501  uint32_t Size,
502  GPDMA_FLOW_CONTROL_T TransferType)
503 {
504  int rval = -1;
505  GPDMACfg->ChannelNum = ChannelNum;
506  GPDMACfg->TransferType = TransferType;
507  GPDMACfg->TransferSize = Size;
508 
509  switch (TransferType) {
511  GPDMACfg->SrcAddr = (uint32_t) src;
512  GPDMACfg->DstAddr = (uint32_t) dst;
513  rval = 3;
514  GPDMACfg->TransferWidth = GPDMA_WIDTH_WORD;
515  GPDMACfg->TransferSize = Size / 4;
516  break;
517 
520  GPDMACfg->SrcAddr = (uint32_t) src;
521  rval = 1;
522  GPDMACfg->DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
523  break;
524 
527  GPDMACfg->SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
528  GPDMACfg->DstAddr = (uint32_t) dst;
529  rval = 2;
530  break;
531 
535  GPDMACfg->SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
536  GPDMACfg->DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
537  rval = 0;
538  break;
539 
540  default:
541  break;
542  }
543  return rval;
544 }
545 
546 /* Read the status from different registers according to the type */
548 {
552  switch (type) {
553  case GPDMA_STAT_INT:/* check status of DMA channel interrupts */
554  return (IntStatus) (pGPDMA->INTSTAT & (((1UL << channel) & 0xFF)));
555 
556  case GPDMA_STAT_INTTC: /* check terminal count interrupt request status for DMA */
557  return (IntStatus) (pGPDMA->INTTCSTAT & (((1UL << channel) & 0xFF)));
558 
559  case GPDMA_STAT_INTERR: /* check interrupt status for DMA channels */
560  return (IntStatus) (pGPDMA->INTERRSTAT & (((1UL << channel) & 0xFF)));
561 
562  case GPDMA_STAT_RAWINTTC: /* check status of the terminal count interrupt for DMA channels */
563  return (IntStatus) (pGPDMA->RAWINTTCSTAT & (((1UL << channel) & 0xFF)));
564 
565  case GPDMA_STAT_RAWINTERR: /* check status of the error interrupt for DMA channels */
566  return (IntStatus) (pGPDMA->RAWINTERRSTAT & (((1UL << channel) & 0xFF)));
567 
568  default:/* check enable status for DMA channels */
569  return (IntStatus) (pGPDMA->ENBLDCHNS & (((1UL << channel) & 0xFF)));
570  }
571 }
572 
573 /* Clear the Interrupt Flag from different registers according to the type */
574 void Chip_GPDMA_ClearIntPending(LPC_GPDMA_T *pGPDMA, GPDMA_STATECLEAR_T type, uint8_t channel)
575 {
576  if (type == GPDMA_STATCLR_INTTC) {
577  /* clears the terminal count interrupt request on DMA channel */
578  pGPDMA->INTTCCLEAR = (((1UL << (channel)) & 0xFF));
579  }
580  else {
581  /* clear the error interrupt request */
582  pGPDMA->INTERRCLR = (((1UL << (channel)) & 0xFF));
583  }
584 }
585 
586 /* Enable or Disable the GPDMA Channel */
587 void Chip_GPDMA_ChannelCmd(LPC_GPDMA_T *pGPDMA, uint8_t channelNum, FunctionalState NewState)
588 {
589  GPDMA_CH_T *pDMAch;
590 
591  /* Get Channel pointer */
592  pDMAch = (GPDMA_CH_T *) &(pGPDMA->CH[channelNum]);
593 
594  if (NewState == ENABLE) {
595  pDMAch->CONFIG |= GPDMA_DMACCxConfig_E;
596  }
597  else {
598  pDMAch->CONFIG &= ~GPDMA_DMACCxConfig_E;
599  }
600 }
601 
602 /* Do a DMA transfer M2M, M2P,P2M or P2P */
604  uint8_t ChannelNum,
605  uint32_t src,
606  uint32_t dst,
607  GPDMA_FLOW_CONTROL_T TransferType,
608  uint32_t Size)
609 {
610  GPDMA_CH_CFG_T GPDMACfg;
611  uint8_t SrcPeripheral = 0, DstPeripheral = 0;
612  uint32_t cwrd;
613  int ret;
614 
615  ret = Chip_GPDMA_InitChannelCfg(pGPDMA, &GPDMACfg, ChannelNum, src, dst, Size, TransferType);
616  if (ret < 0) {
617  return ERROR;
618  }
619 
620  /* Adjust src/dst index if they are memory */
621  if (ret & 1) {
622  src = 0;
623  }
624  else {
625  SrcPeripheral = configDMAMux(src);
626  }
627 
628  if (ret & 2) {
629  dst = 0;
630  }
631  else {
632  DstPeripheral = configDMAMux(dst);
633  }
634 
635  cwrd = makeCtrlWord(&GPDMACfg,
636  (uint32_t) GPDMA_LUTPerBurst[src],
637  (uint32_t) GPDMA_LUTPerBurst[dst],
638  (uint32_t) GPDMA_LUTPerWid[src],
639  (uint32_t) GPDMA_LUTPerWid[dst]);
640  if (setupChannel(pGPDMA, &GPDMACfg, cwrd, 0, SrcPeripheral, DstPeripheral) == ERROR) {
641  return ERROR;
642  }
643 
644  /* Start the Channel */
645  Chip_GPDMA_ChannelCmd(pGPDMA, ChannelNum, ENABLE);
646  return SUCCESS;
647 }
648 
650  DMA_TransferDescriptor_t *DMADescriptor,
651  uint32_t src,
652  uint32_t dst,
653  uint32_t Size,
654  GPDMA_FLOW_CONTROL_T TransferType,
655  const DMA_TransferDescriptor_t *NextDescriptor)
656 {
657  int ret;
658  GPDMA_CH_CFG_T GPDMACfg;
659 
660  ret = Chip_GPDMA_InitChannelCfg(pGPDMA, &GPDMACfg, 0, src, dst, Size, TransferType);
661  if (ret < 0) {
662  return ERROR;
663  }
664 
665  /* Adjust src/dst index if they are memory */
666  if (ret & 1) {
667  src = 0;
668  }
669 
670  if (ret & 2) {
671  dst = 0;
672  }
673 
674  DMADescriptor->src = GPDMACfg.SrcAddr;
675  DMADescriptor->dst = GPDMACfg.DstAddr;
676  DMADescriptor->lli = (uint32_t) NextDescriptor;
677  DMADescriptor->ctrl = makeCtrlWord(&GPDMACfg,
678  (uint32_t) GPDMA_LUTPerBurst[src],
679  (uint32_t) GPDMA_LUTPerBurst[dst],
680  (uint32_t) GPDMA_LUTPerWid[src],
681  (uint32_t) GPDMA_LUTPerWid[dst]);
682 
683  /* By default set interrupt only for last transfer */
684  if (NextDescriptor) {
685  DMADescriptor->ctrl &= ~GPDMA_DMACCxControl_I;
686  }
687 
688  return SUCCESS;
689 }
690 
691 /* Do a DMA scatter-gather transfer M2M, M2P,P2M or P2P using DMA descriptors */
693  uint8_t ChannelNum,
694  const DMA_TransferDescriptor_t *DMADescriptor,
695  GPDMA_FLOW_CONTROL_T TransferType)
696 {
697  const DMA_TransferDescriptor_t *dsc = DMADescriptor;
698  GPDMA_CH_CFG_T GPDMACfg;
699  uint8_t SrcPeripheral = 0, DstPeripheral = 0;
700  uint32_t src = DMADescriptor->src, dst = DMADescriptor->dst;
701  int ret;
702 
703  ret = Chip_GPDMA_InitChannelCfg(pGPDMA, &GPDMACfg, ChannelNum, src, dst, 0, TransferType);
704  if (ret < 0) {
705  return ERROR;
706  }
707 
708  /* Adjust src/dst index if they are memory */
709  if (ret & 1) {
710  src = 0;
711  }
712  else {
713  SrcPeripheral = configDMAMux(src);
714  }
715 
716  if (ret & 2) {
717  dst = 0;
718  }
719  else {
720  DstPeripheral = configDMAMux(dst);
721  }
722 
723  if (setupChannel(pGPDMA, &GPDMACfg, dsc->ctrl, dsc->lli, SrcPeripheral, DstPeripheral) == ERROR) {
724  return ERROR;
725  }
726 
727  /* Start the Channel */
728  Chip_GPDMA_ChannelCmd(pGPDMA, ChannelNum, ENABLE);
729  return SUCCESS;
730 }
731 
732 /* Get a free GPDMA channel for one DMA connection */
734  uint32_t PeripheralConnection_ID)
735 {
736  uint8_t temp = 0;
737  for (temp = 0; temp < GPDMA_NUMBER_CHANNELS; temp++) {
739  temp) && (ChannelHandlerArray[temp].ChannelStatus == DISABLE)) {
740  ChannelHandlerArray[temp].ChannelStatus = ENABLE;
741  return temp;
742  }
743  }
744  return 0;
745 }
746