| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gpdma_17xx_40xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC17xx/40xx DMA 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 */
39 static DMA_ChannelHandle_t ChannelHandlerArray[GPDMA_NUMBER_CHANNELS];
40 #if defined(CHIP_LPC177X_8X) || defined(CHIP_LPC407X_8X)
41 /* Optimized Peripheral Source and Destination burst size (177x_8x,407x_8x) */
42 static const uint8_t GPDMA_LUTPerBurst[] = {
43 0, /* Reserved */
44 GPDMA_BSIZE_8, /* SD Card */
45 GPDMA_BSIZE_4, /* SSP0 Tx */
46 GPDMA_BSIZE_4, /* SSP0 Rx */
47 GPDMA_BSIZE_4, /* SSP1 Tx */
48 GPDMA_BSIZE_4, /* SSP1 Rx */
49 GPDMA_BSIZE_4, /* SSP2 Tx */
50 GPDMA_BSIZE_4, /* SSP2 Rx */
51 GPDMA_BSIZE_1, /* ADC */
52 GPDMA_BSIZE_1, /* DAC */
53 GPDMA_BSIZE_1, /* UART0 Tx */
54 GPDMA_BSIZE_1, /* UART0 Rx */
55 GPDMA_BSIZE_1, /* UART1 Tx */
56 GPDMA_BSIZE_1, /* UART1 Rx */
57 GPDMA_BSIZE_1, /* UART2 Tx */
58 GPDMA_BSIZE_1, /* UART2 Rx */
59 GPDMA_BSIZE_1, /* MAT0.0 */
60 GPDMA_BSIZE_1, /* MAT0.1 */
61 GPDMA_BSIZE_1, /* MAT1.0 */
62 GPDMA_BSIZE_1, /* MAT1.1 */
63 GPDMA_BSIZE_1, /* MAT2.0 */
64 GPDMA_BSIZE_1, /* MAT2.1 */
65 GPDMA_BSIZE_32, /* I2S channel 0 */
66 GPDMA_BSIZE_32, /* I2S channel 1 */
67 0, /* Reserved */
68 0, /* Reserved */
69 GPDMA_BSIZE_1, /* UART3 Tx */
70 GPDMA_BSIZE_1, /* UART3 Rx */
71 GPDMA_BSIZE_1, /* UART4 Tx */
72 GPDMA_BSIZE_1, /* UART4 Rx */
73 GPDMA_BSIZE_1, /* MAT3.0 */
74 GPDMA_BSIZE_1, /* MAT3.1 */
75 };
76
77 /* Optimized Peripheral Source and Destination transfer width (177x_8x,407x_8x) */
78 static const uint8_t GPDMA_LUTPerWid[] = {
79 0, /* Reserved */
80 GPDMA_WIDTH_WORD, /* SD Card */
81 GPDMA_WIDTH_BYTE, /* SSP0 Tx */
82 GPDMA_WIDTH_BYTE, /* SSP0 Rx */
83 GPDMA_WIDTH_BYTE, /* SSP1 Tx */
84 GPDMA_WIDTH_BYTE, /* SSP1 Rx */
85 GPDMA_WIDTH_BYTE, /* SSP2 Tx */
86 GPDMA_WIDTH_BYTE, /* SSP2 Rx */
87 GPDMA_WIDTH_WORD, /* ADC */
88 GPDMA_WIDTH_HALFWORD, /* DAC */
89 GPDMA_WIDTH_BYTE, /* UART0 Tx */
90 GPDMA_WIDTH_BYTE, /* UART0 Rx */
91 GPDMA_WIDTH_BYTE, /* UART1 Tx */
92 GPDMA_WIDTH_BYTE, /* UART1 Rx */
93 GPDMA_WIDTH_BYTE, /* UART2 Tx */
94 GPDMA_WIDTH_BYTE, /* UART2 Rx */
95 GPDMA_WIDTH_WORD, /* MAT0.0 */
96 GPDMA_WIDTH_WORD, /* MAT0.1 */
97 GPDMA_WIDTH_WORD, /* MAT1.0 */
98 GPDMA_WIDTH_WORD, /* MAT1.1 */
99 GPDMA_WIDTH_WORD, /* MAT2.0 */
100 GPDMA_WIDTH_WORD, /* MAT2.1 */
101 GPDMA_WIDTH_WORD, /* I2S channel 0 */
102 GPDMA_WIDTH_WORD, /* I2S channel 1 */
103 0, /* Reserved */
104 0, /* Reserved */
105 GPDMA_WIDTH_BYTE, /* UART3 Tx */
106 GPDMA_WIDTH_BYTE, /* UART3 Rx */
107 GPDMA_WIDTH_BYTE, /* UART4 Tx */
108 GPDMA_WIDTH_BYTE, /* UART4 Rx */
109 GPDMA_WIDTH_WORD, /* MAT3.0 */
110 GPDMA_WIDTH_WORD, /* MAT3.1 */
111 };
112
113 /* Lookup Table of Connection Type matched with (177x_8x,407x_8x) Peripheral Data (FIFO) register base address */
114 volatile static const void *GPDMA_LUTPerAddr[] = {
115 0, /* Reserved */
116 (&LPC_SDC->FIFO), /* SD Card */
117 (&LPC_SSP0->DR), /* SSP0 Tx */
118 (&LPC_SSP0->DR), /* SSP0 Rx */
119 (&LPC_SSP1->DR), /* SSP1 Tx */
120 (&LPC_SSP1->DR), /* SSP1 Rx */
121 (&LPC_SSP2->DR), /* SSP2 Tx */
122 (&LPC_SSP2->DR), /* SSP2 Rx */
123 (&LPC_ADC->GDR), /* ADC */
124 (&LPC_DAC->CR), /* DAC */
125 (&LPC_UART0-> /*RBTHDLR.*/ THR), /* UART0 Tx */
126 (&LPC_UART0-> /*RBTHDLR.*/ RBR), /* UART0 Rx */
127 (&LPC_UART1-> /*RBTHDLR.*/ THR), /* UART1 Tx */
128 (&LPC_UART1-> /*RBTHDLR.*/ RBR), /* UART1 Rx */
129 (&LPC_UART2-> /*RBTHDLR.*/ THR), /* UART2 Tx */
130 (&LPC_UART2-> /*RBTHDLR.*/ RBR), /* UART2 Rx */
131 (&LPC_TIMER0->MR[0]), /* MAT0.0 */
132 (&LPC_TIMER0->MR[1]), /* MAT0.1 */
133 (&LPC_TIMER1->MR[0]), /* MAT1.0 */
134 (&LPC_TIMER1->MR[1]), /* MAT1.1 */
135 (&LPC_TIMER2->MR[0]), /* MAT2.0 */
136 (&LPC_TIMER2->MR[1]), /* MAT2.1 */
137 (&LPC_I2S->TXFIFO), /* I2S Tx */
138 (&LPC_I2S->RXFIFO), /* I2S Rx */
139 0, /* Reverse */
140 0, /* Reverse */
141 (&LPC_UART3-> /*RBTHDLR.*/ THR), /* UART3 Tx */
142 (&LPC_UART3-> /*RBTHDLR.*/ RBR), /* UART3 Rx */
143 (&LPC_UART4-> /*RBTHDLR.*/ THR), /* UART4 Tx */
144 (&LPC_UART4-> /*RBTHDLR.*/ RBR), /* UART4 Rx */
145 (&LPC_TIMER3->MR[0]), /* MAT3.0 */
146 (&LPC_TIMER3->MR[1]) /* MAT3.1 */
147 };
148 #elif defined(CHIP_LPC175X_6X)
149 const uint8_t GPDMA_LUTPerBurst[] = {
150 GPDMA_BSIZE_4, // SSP0 Tx
151 GPDMA_BSIZE_4, // SSP0 Rx
152 GPDMA_BSIZE_4, // SSP1 Tx
153 GPDMA_BSIZE_4, // SSP1 Rx
154 GPDMA_BSIZE_1, // ADC
155 GPDMA_BSIZE_32, // I2S channel 0
156 GPDMA_BSIZE_32, // I2S channel 1
157 GPDMA_BSIZE_1, // DAC
158 GPDMA_BSIZE_1, // UART0 Tx
159 GPDMA_BSIZE_1, // UART0 Rx
160 GPDMA_BSIZE_1, // UART1 Tx
161 GPDMA_BSIZE_1, // UART1 Rx
162 GPDMA_BSIZE_1, // UART2 Tx
163 GPDMA_BSIZE_1, // UART2 Rx
164 GPDMA_BSIZE_1, // UART3 Tx
165 GPDMA_BSIZE_1, // UART3 Rx
166 GPDMA_BSIZE_1, // MAT0.0
167 GPDMA_BSIZE_1, // MAT0.1
168 GPDMA_BSIZE_1, // MAT1.0
169 GPDMA_BSIZE_1, // MAT1.1
170 GPDMA_BSIZE_1, // MAT2.0
171 GPDMA_BSIZE_1, // MAT2.1
172 GPDMA_BSIZE_1, // MAT3.0
173 GPDMA_BSIZE_1 // MAT3.1
174 };
175
179 const uint8_t GPDMA_LUTPerWid[] = {
180 GPDMA_WIDTH_BYTE, // SSP0 Tx
181 GPDMA_WIDTH_BYTE, // SSP0 Rx
182 GPDMA_WIDTH_BYTE, // SSP1 Tx
183 GPDMA_WIDTH_BYTE, // SSP1 Rx
184 GPDMA_WIDTH_WORD, // ADC
185 GPDMA_WIDTH_WORD, // I2S channel 0
186 GPDMA_WIDTH_WORD, // I2S channel 1
187 GPDMA_WIDTH_HALFWORD, // DAC
188 GPDMA_WIDTH_BYTE, // UART0 Tx
189 GPDMA_WIDTH_BYTE, // UART0 Rx
190 GPDMA_WIDTH_BYTE, // UART1 Tx
191 GPDMA_WIDTH_BYTE, // UART1 Rx
192 GPDMA_WIDTH_BYTE, // UART2 Tx
193 GPDMA_WIDTH_BYTE, // UART2 Rx
194 GPDMA_WIDTH_BYTE, // UART3 Tx
195 GPDMA_WIDTH_BYTE, // UART3 Rx
196 GPDMA_WIDTH_WORD, // MAT0.0
197 GPDMA_WIDTH_WORD, // MAT0.1
198 GPDMA_WIDTH_WORD, // MAT1.0
199 GPDMA_WIDTH_WORD, // MAT1.1
200 GPDMA_WIDTH_WORD, // MAT2.0
201 GPDMA_WIDTH_WORD, // MAT2.1
202 GPDMA_WIDTH_WORD, // MAT3.0
203 GPDMA_WIDTH_WORD // MAT3.1
204 };
205
206
210 volatile const void *GPDMA_LUTPerAddr[] = {
211 (&LPC_SSP0->DR), // SSP0 Tx
212 (&LPC_SSP0->DR), // SSP0 Rx
213 (&LPC_SSP1->DR), // SSP1 Tx
214 (&LPC_SSP1->DR), // SSP1 Rx
215 (&LPC_ADC->GDR), // ADC
216 (&LPC_I2S->TXFIFO), // I2S Tx
217 (&LPC_I2S->RXFIFO), // I2S Rx
218 (&LPC_DAC->CR), // DAC
219 (&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx
220 (&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx
221 (&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
222 (&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
223 (&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx
224 (&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx
225 (&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx
226 (&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx
227 (&LPC_TIMER0->MR[0]), // MAT0.0
228 (&LPC_TIMER0->MR[1]), // MAT0.1
229 (&LPC_TIMER1->MR[0]), // MAT1.0
230 (&LPC_TIMER1->MR[1]), // MAT1.1
231 (&LPC_TIMER2->MR[0]), // MAT2.0
232 (&LPC_TIMER2->MR[1]), // MAT2.1
233 (&LPC_TIMER3->MR[0]), // MAT3.0
234 (&LPC_TIMER3->MR[1]) // MAT3.1
235
236 };
237 #endif
238 /*****************************************************************************
239 * Public types/enumerations/variables
240 ****************************************************************************/
241
242 /*****************************************************************************
243 * Private functions
244 ****************************************************************************/
245
246 /* Control which set of peripherals is connected to the DMA controller */
247 static uint8_t DMAMUX_Config(uint32_t gpdma_peripheral_connection_number)
248 {
249 #if defined(CHIP_LPC175X_6X)
250 if (gpdma_peripheral_connection_number > 15) {
251 LPC_SYSCTL->DMAREQSEL |= (1 << (gpdma_peripheral_connection_number - 16));
252 return gpdma_peripheral_connection_number - 8;
253 }
254 else {
255 if(gpdma_peripheral_connection_number>7)
256 LPC_SYSCTL->DMAREQSEL &= ~(1 << (gpdma_peripheral_connection_number-8));
257 return gpdma_peripheral_connection_number;
258 }
259 #elif defined(CHIP_LPC177X_8X) || defined(CHIP_LPC407X_8X)
260 if (gpdma_peripheral_connection_number > 15) {
261 LPC_SYSCTL->DMAREQSEL |= (1 << (gpdma_peripheral_connection_number - 16));
262 return gpdma_peripheral_connection_number - 16;
263 }
264 else {
265 LPC_SYSCTL->DMAREQSEL &= ~(1 << (gpdma_peripheral_connection_number));
266 return gpdma_peripheral_connection_number;
267 }
268 #endif
269 }
270
271 /*****************************************************************************
272 * Public functions
273 ****************************************************************************/
274
275 /* Initialize the GPDMA */
276 void Chip_GPDMA_Init(LPC_GPDMA_T *pGPDMA)
277 {
278 uint8_t i;
279
280 /* Enable GPDMA master clock */
281 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPDMA);
282
283 IP_GPDMA_Init(pGPDMA);
284
285 /* Reset all channels are free */
286 for (i = 0; i < GPDMA_NUMBER_CHANNELS; i++) {
287 ChannelHandlerArray[i].ChannelStatus = DISABLE;
288 }
289 }
290
291 /* Shutdown the GPDMA */
292 void Chip_GPDMA_DeInit(LPC_GPDMA_T *pGPDMA)
293 {
294 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPDMA);
295 }
296
297 /* Stop a stream DMA transfer */
298 void Chip_DMA_Stop(LPC_GPDMA_T *pGPDMA,
299 uint8_t ChannelNum)
300 {
301 IP_GPDMA_ChannelCmd(pGPDMA, (ChannelNum), DISABLE);
302 if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTTC, ChannelNum)) {
303 /* Clear terminate counter Interrupt pending */
304 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTTC, ChannelNum);
305 }
306 if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTERR, ChannelNum)) {
307 /* Clear terminate counter Interrupt pending */
308 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTERR, ChannelNum);
309 }
310 ChannelHandlerArray[ChannelNum].ChannelStatus = DISABLE;
311 }
312
313 /* The GPDMA stream interrupt status checking */
314 Status Chip_DMA_Interrupt(LPC_GPDMA_T *pGPDMA,
315 uint8_t ChannelNum)
316 {
317
318 if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INT, ChannelNum)) {
319 /* Check counter terminal status */
320 if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTTC, ChannelNum)) {
321 /* Clear terminate counter Interrupt pending */
322 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTTC, ChannelNum);
323 return SUCCESS;
324 }
325 /* Check error terminal status */
326 if (Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_INTERR, ChannelNum)) {
327 /* Clear error counter Interrupt pending */
328
329 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTERR, ChannelNum);
330 return ERROR;
331 }
332 }
333 return ERROR;
334 }
335
336 int Chip_DMA_InitChannelCfg(LPC_GPDMA_T *pGPDMA,
337 GPDMA_Channel_CFG_T *GPDMACfg,
338 uint8_t ChannelNum,
339 uint32_t src,
340 uint32_t dst,
341 uint32_t Size,
342 IP_GPDMA_FLOW_CONTROL_T TransferType)
343 {
344 int rval = -1;
345 GPDMACfg->ChannelNum = ChannelNum;
346 GPDMACfg->TransferType = TransferType;
347 GPDMACfg->TransferSize = Size;
348
349 switch (TransferType) {
350 case GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA:
351 GPDMACfg->SrcAddr = (uint32_t) src;
352 GPDMACfg->DstAddr = (uint32_t) dst;
353 rval = 3;
354 GPDMACfg->TransferWidth = GPDMA_WIDTH_WORD;
355 GPDMACfg->TransferSize = Size / 4;
356 break;
357
358 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA:
359 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL:
360 GPDMACfg->SrcAddr = (uint32_t) src;
361 rval = 1;
362 GPDMACfg->DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
363 break;
364
365 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA:
366 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL:
367 GPDMACfg->SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
368 GPDMACfg->DstAddr = (uint32_t) dst;
369 rval = 2;
370 break;
371
372 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DMA:
373 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DestPERIPHERAL:
374 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_SrcPERIPHERAL:
375 GPDMACfg->SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
376 GPDMACfg->DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
377 rval = 0;
378 break;
379
380 default:
381 break;
382 }
383 return rval;
384 }
385
386 /* Do a DMA transfer M2M, M2P,P2M or P2P */
387 Status Chip_DMA_Transfer(LPC_GPDMA_T *pGPDMA,
388 uint8_t ChannelNum,
389 uint32_t src,
390 uint32_t dst,
391 IP_GPDMA_FLOW_CONTROL_T TransferType,
392 uint32_t Size)
393 {
394 GPDMA_Channel_CFG_T GPDMACfg;
395 uint8_t SrcPeripheral = 0, DstPeripheral = 0;
396 uint32_t cwrd;
397 int ret;
398
399 ret = Chip_DMA_InitChannelCfg(pGPDMA, &GPDMACfg, ChannelNum, src, dst, Size, TransferType);
400 if (ret < 0) {
401 return ERROR;
402 }
403
404 /* Adjust src/dst index if they are memory */
405 if (ret & 1) {
406 src = 0;
407 }
408 else {
409 SrcPeripheral = DMAMUX_Config(src);
410 }
411
412 if (ret & 2) {
413 dst = 0;
414 }
415 else {
416 DstPeripheral = DMAMUX_Config(dst);
417 }
418
419 cwrd = IP_GPDMA_MakeCtrlWord(&GPDMACfg,
420 (uint32_t) GPDMA_LUTPerBurst[src],
421 (uint32_t) GPDMA_LUTPerBurst[dst],
422 (uint32_t) GPDMA_LUTPerWid[src],
423 (uint32_t) GPDMA_LUTPerWid[dst]);
424 if (IP_GPDMA_Setup(pGPDMA, &GPDMACfg, cwrd, 0, SrcPeripheral, DstPeripheral) == ERROR) {
425 return ERROR;
426 }
427
428 /* Start the Channel */
429 IP_GPDMA_ChannelCmd(pGPDMA, ChannelNum, ENABLE);
430 return SUCCESS;
431 }
432
433 Status Chip_DMA_PrepareDescriptor(LPC_GPDMA_T *pGPDMA,
434 DMA_TransferDescriptor_t *DMADescriptor,
435 uint32_t src,
436 uint32_t dst,
437 uint32_t Size,
438 IP_GPDMA_FLOW_CONTROL_T TransferType,
439 const DMA_TransferDescriptor_t *NextDescriptor)
440 {
441 int ret;
442 GPDMA_Channel_CFG_T GPDMACfg;
443
444 ret = Chip_DMA_InitChannelCfg(pGPDMA, &GPDMACfg, 0, src, dst, Size, TransferType);
445 if (ret < 0) {
446 return ERROR;
447 }
448
449 /* Adjust src/dst index if they are memory */
450 if (ret & 1) {
451 src = 0;
452 }
453
454 if (ret & 2) {
455 dst = 0;
456 }
457
458 DMADescriptor->src = GPDMACfg.SrcAddr;
459 DMADescriptor->dst = GPDMACfg.DstAddr;
460 DMADescriptor->lli = (uint32_t) NextDescriptor;
461 DMADescriptor->ctrl = IP_GPDMA_MakeCtrlWord(&GPDMACfg,
462 (uint32_t) GPDMA_LUTPerBurst[src],
463 (uint32_t) GPDMA_LUTPerBurst[dst],
464 (uint32_t) GPDMA_LUTPerWid[src],
465 (uint32_t) GPDMA_LUTPerWid[dst]);
466
467 /* By default set interrupt only for last transfer */
468 if (NextDescriptor) {
469 DMADescriptor->ctrl &= ~GPDMA_DMACCxControl_I;
470 }
471
472 return SUCCESS;
473 }
474
475 /* Do a DMA scatter-gather transfer M2M, M2P,P2M or P2P using DMA descriptors */
476 Status Chip_DMA_SGTransfer(LPC_GPDMA_T *pGPDMA,
477 uint8_t ChannelNum,
478 const DMA_TransferDescriptor_t *DMADescriptor,
479 IP_GPDMA_FLOW_CONTROL_T TransferType)
480 {
481 const DMA_TransferDescriptor_t *dsc = DMADescriptor;
482 GPDMA_Channel_CFG_T GPDMACfg;
483 uint8_t SrcPeripheral = 0, DstPeripheral = 0;
484 uint32_t src = DMADescriptor->src, dst = DMADescriptor->dst;
485 int ret;
486
487 ret = Chip_DMA_InitChannelCfg(pGPDMA, &GPDMACfg, ChannelNum, src, dst, 0, TransferType);
488 if (ret < 0) {
489 return ERROR;
490 }
491
492 /* Adjust src/dst index if they are memory */
493 if (ret & 1) {
494 src = 0;
495 }
496 else {
497 SrcPeripheral = DMAMUX_Config(src);
498 }
499
500 if (ret & 2) {
501 dst = 0;
502 }
503 else {
504 DstPeripheral = DMAMUX_Config(dst);
505 }
506
507 if (IP_GPDMA_Setup(pGPDMA, &GPDMACfg, dsc->ctrl, dsc->lli, SrcPeripheral, DstPeripheral) == ERROR) {
508 return ERROR;
509 }
510
511 /* Start the Channel */
512 IP_GPDMA_ChannelCmd(pGPDMA, ChannelNum, ENABLE);
513 return SUCCESS;
514 }
515
516 /* Get a free GPDMA channel for one DMA connection */
517 uint8_t Chip_DMA_GetFreeChannel(LPC_GPDMA_T *pGPDMA,
518 uint32_t PeripheralConnection_ID)
519 {
520 uint8_t temp = 0;
521 for (temp = 0; temp < GPDMA_NUMBER_CHANNELS; temp++) {
522 if (!Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_ENABLED_CH,
523 temp) && (ChannelHandlerArray[temp].ChannelStatus == DISABLE)) {
524 ChannelHandlerArray[temp].ChannelStatus = ENABLE;
525 return temp;
526 }
527 }
528 return 0;
529 }