LPCOpen Platform for LPC18XX/43XX microcontrollers: C:/w/lpcopen_docs/software/lpc_core/lpc_chip/chip_18xx_43xx/gpdma_18xx_43xx.c Source File

| LPCOpen Platform for LPC18XX/43XX microcontrollers 18XX43XX LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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 */
39 static DMA_ChannelHandle_t ChannelHandlerArray[GPDMA_NUMBER_CHANNELS];
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
186 case GPDMA_CONN_I2S1_Tx_Channel_0:
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
201 case GPDMA_CONN_I2S1_Rx_Channel_1:
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
261 case GPDMA_CONN_I2S_Tx_Channel_0:
262 function = 1;
263 channel = 9;
264 break;
265
266 case GPDMA_CONN_SSP0_Tx:
267 function = 0;
268 channel = 10;
269 break;
270
271 case GPDMA_CONN_I2S_Rx_Channel_1:
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 */
325 case GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA:
326 ctrl_word = GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize)
327 | GPDMA_DMACCxControl_SBSize((4UL))
328 | GPDMA_DMACCxControl_DBSize((4UL))
329 | GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth)
330 | GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth)
331 | GPDMA_DMACCxControl_SI
332 | GPDMA_DMACCxControl_DI
333 | GPDMA_DMACCxControl_I;
334 break;
335
336 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA:
337 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL:
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)
343 | GPDMA_DMACCxControl_DestTransUseAHBMaster1
344 | GPDMA_DMACCxControl_SI
345 | GPDMA_DMACCxControl_I;
346 break;
347
348 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA:
349 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL:
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)
355 | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
356 | GPDMA_DMACCxControl_DI
357 | GPDMA_DMACCxControl_I;
358 break;
359
360 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DMA:
361 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DestPERIPHERAL:
362 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_SrcPERIPHERAL:
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)
368 | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
369 | GPDMA_DMACCxControl_DestTransUseAHBMaster1
370 | GPDMA_DMACCxControl_I;
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 */
382 Status setupChannel(LPC_GPDMA_T *pGPDMA,
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 */
430 void Chip_GPDMA_Init(LPC_GPDMA_T *pGPDMA)
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 */
452 void Chip_GPDMA_DeInit(LPC_GPDMA_T *pGPDMA)
453 {
454 Chip_Clock_Disable(CLK_MX_DMA);
455 }
456
457 /* Stop a stream DMA transfer */
458 void Chip_GPDMA_Stop(LPC_GPDMA_T *pGPDMA,
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 */
468 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTERR, ChannelNum);
469 }
470 ChannelHandlerArray[ChannelNum].ChannelStatus = DISABLE;
471 }
472
473 /* The GPDMA stream interrupt status checking */
474 Status Chip_GPDMA_Interrupt(LPC_GPDMA_T *pGPDMA,
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
489 Chip_GPDMA_ClearIntPending(pGPDMA, GPDMA_STATCLR_INTERR, ChannelNum);
490 return ERROR;
491 }
492 }
493 return ERROR;
494 }
495
496 int Chip_GPDMA_InitChannelCfg(LPC_GPDMA_T *pGPDMA,
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) {
510 case GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA:
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
518 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA:
519 case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL:
520 GPDMACfg->SrcAddr = (uint32_t) src;
521 rval = 1;
522 GPDMACfg->DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
523 break;
524
525 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA:
526 case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL:
527 GPDMACfg->SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
528 GPDMACfg->DstAddr = (uint32_t) dst;
529 rval = 2;
530 break;
531
532 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DMA:
533 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DestPERIPHERAL:
534 case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_SrcPERIPHERAL:
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 */
547 IntStatus Chip_GPDMA_IntGetStatus(LPC_GPDMA_T *pGPDMA, GPDMA_STATUS_T type, uint8_t channel)
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 */
603 Status Chip_GPDMA_Transfer(LPC_GPDMA_T *pGPDMA,
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
649 Status Chip_GPDMA_PrepareDescriptor(LPC_GPDMA_T *pGPDMA,
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 */
692 Status Chip_GPDMA_SGTransfer(LPC_GPDMA_T *pGPDMA,
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 */
733 uint8_t Chip_GPDMA_GetFreeChannel(LPC_GPDMA_T *pGPDMA,
734 uint32_t PeripheralConnection_ID)
735 {
736 uint8_t temp = 0;
737 for (temp = 0; temp < GPDMA_NUMBER_CHANNELS; temp++) {
738 if (!Chip_GPDMA_IntGetStatus(pGPDMA, GPDMA_STAT_ENABLED_CH,
739 temp) && (ChannelHandlerArray[temp].ChannelStatus == DISABLE)) {
740 ChannelHandlerArray[temp].ChannelStatus = ENABLE;
741 return temp;
742 }
743 }
744 return 0;
745 }
746