LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gpdma_18xx_43xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC18xx/43xx 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 "gpdma_18xx_43xx.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), /* I2S channel 0 */
132  (&LPC_SSP0->DR), /* SSP0 Tx */
133  (&LPC_I2S0->RXFIFO), /* I2S 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_I2S0->TXFIFO), /* I2S channel 0 */
140  (&LPC_I2S0->RXFIFO) /* I2S channel 0 */
141 };
142 
143 /*****************************************************************************
144  * Public types/enumerations/variables
145  ****************************************************************************/
146 
147 /*****************************************************************************
148  * Private functions
149  ****************************************************************************/
150 
151 /* Control which set of peripherals is connected to the DMA controller */
152 static uint8_t DMAMUX_Config(uint32_t gpdma_peripheral_connection_number)
153 {
154  uint8_t function, channel;
155 
156  switch (gpdma_peripheral_connection_number) {
157  case GPDMA_CONN_MAT0_0:
158  function = 0;
159  channel = 1;
160  break;
161 
162  case GPDMA_CONN_UART0_Tx:
163  function = 1;
164  channel = 1;
165  break;
166 
167  case GPDMA_CONN_MAT0_1:
168  function = 0;
169  channel = 2;
170  break;
171 
172  case GPDMA_CONN_UART0_Rx:
173  function = 1;
174  channel = 2;
175  break;
176 
177  case GPDMA_CONN_MAT1_0:
178  function = 0;
179  channel = 3;
180  break;
181 
182  case GPDMA_CONN_UART1_Tx:
183  function = 1;
184  channel = 3;
185  break;
186 
187  case GPDMA_CONN_MAT1_1:
188  function = 0;
189  channel = 4;
190  break;
191 
192  case GPDMA_CONN_UART1_Rx:
193  function = 1;
194  channel = 4;
195  break;
196 
197  case GPDMA_CONN_MAT2_0:
198  function = 0;
199  channel = 5;
200  break;
201 
202  case GPDMA_CONN_UART2_Tx:
203  function = 1;
204  channel = 5;
205  break;
206 
207  case GPDMA_CONN_MAT2_1:
208  function = 0;
209  channel = 6;
210  break;
211 
212  case GPDMA_CONN_UART2_Rx:
213  function = 1;
214  channel = 6;
215  break;
216 
217  case GPDMA_CONN_MAT3_0:
218  function = 0;
219  channel = 7;
220  break;
221 
222  case GPDMA_CONN_UART3_Tx:
223  function = 1;
224  channel = 7;
225  break;
226 
227  case GPDMA_CONN_SCT_0:
228  function = 2;
229  channel = 7;
230  break;
231 
232  case GPDMA_CONN_MAT3_1:
233  function = 0;
234  channel = 8;
235  break;
236 
237  case GPDMA_CONN_UART3_Rx:
238  function = 1;
239  channel = 8;
240  break;
241 
242  case GPDMA_CONN_SCT_1:
243  function = 2;
244  channel = 8;
245  break;
246 
247  case GPDMA_CONN_SSP0_Rx:
248  function = 0;
249  channel = 9;
250  break;
251 
254  function = 1;
255  channel = 9;
256  break;
257 
258  case GPDMA_CONN_SSP0_Tx:
259  function = 0;
260  channel = 10;
261  break;
262 
265  function = 1;
266  channel = 10;
267  break;
268 
269  case GPDMA_CONN_SSP1_Rx:
270  function = 0;
271  channel = 11;
272  break;
273 
274  case GPDMA_CONN_SSP1_Tx:
275  function = 0;
276  channel = 12;
277  break;
278 
279  case GPDMA_CONN_ADC_0:
280  function = 0;
281  channel = 13;
282  break;
283 
284  case GPDMA_CONN_ADC_1:
285  function = 0;
286  channel = 14;
287  break;
288 
289  case GPDMA_CONN_DAC:
290  function = 0;
291  channel = 15;
292  break;
293 
294  default:
295  function = 3;
296  channel = 15;
297  break;
298  }
299  /* Set select function to dmamux register */
300  if (0 != gpdma_peripheral_connection_number) {
301  LPC_CREG->DMAMUX &= ~(0x03 << (2 * channel));
302  LPC_CREG->DMAMUX |= (function << (2 * channel));
303  }
304  return channel;
305 }
306 
307 /*****************************************************************************
308  * Public functions
309  ****************************************************************************/
310 
311 /* Initialize the GPDMA */
312 void Chip_GPDMA_Init(void)
313 {
314  uint8_t i;
316  /* Reset all channels are free */
317  for (i = 0; i < GPDMA_NUMBER_CHANNELS; i++)
318  ChannelHandlerArray[i].ChannelStatus = DISABLE;
319 }
320 
321 /* Stop a stream DMA transfer */
322 void Chip_DMA_Stop(uint8_t ChannelNum)
323 {
324  IP_GPDMA_ChannelCmd(LPC_GPDMA, (ChannelNum), DISABLE);
325  if (Chip_GPDMA_IntGetStatus(GPDMA_STAT_INTTC, ChannelNum)) {
326  /* Clear terminate counter Interrupt pending */
328  }
329  if (Chip_GPDMA_IntGetStatus(GPDMA_STAT_INTERR, ChannelNum)) {
330  /* Clear terminate counter Interrupt pending */
332  }
333  ChannelHandlerArray[ChannelNum].ChannelStatus = DISABLE;
334 }
335 
336 /* The GPDMA stream interrupt status checking */
337 Status Chip_DMA_Interrupt(uint8_t ChannelNum)
338 {
339 
340  if (Chip_GPDMA_IntGetStatus(GPDMA_STAT_INT, ChannelNum)) {
341  /* Check counter terminal status */
342  if (Chip_GPDMA_IntGetStatus(GPDMA_STAT_INTTC, ChannelNum)) {
343  /* Clear terminate counter Interrupt pending */
345  return SUCCESS;
346  }
347  /* Check error terminal status */
348  if (Chip_GPDMA_IntGetStatus(GPDMA_STAT_INTERR, ChannelNum)) {
349  /* Clear error counter Interrupt pending */
350 
352  return ERROR;
353  }
354  }
355  return ERROR;
356 }
357 
358 /* Do a DMA transfer M2M, M2P,P2M or P2P */
359 void Chip_DMA_Transfer(uint8_t ChannelNum, uint32_t src, uint32_t dst, FlowControlType TransferType, uint32_t Size)
360 {
361  GPDMA_Channel_CFG_Type GPDMACfg;
362  uint8_t SrcPeripheral = 0, DstPeripheral = 0;
363 
364  GPDMACfg.ChannelNum = ChannelNum;
365  GPDMACfg.TransferType = TransferType;
366  GPDMACfg.TransferSize = Size;
367 
368  switch (TransferType) {
370  GPDMACfg.SrcAddr = (uint32_t) src;
371  GPDMACfg.DstAddr = (uint32_t) dst;
372  src = 0; dst = 0;
373  GPDMACfg.TransferWidth = GPDMA_WIDTH_BYTE;
374  break;
375 
378  GPDMACfg.SrcAddr = (uint32_t) src;
379  src = 0;
380  GPDMACfg.DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
381  DstPeripheral = DMAMUX_Config(dst);
382  break;
383 
386  GPDMACfg.SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
387  GPDMACfg.DstAddr = (uint32_t) dst;
388  SrcPeripheral = DMAMUX_Config(src);
389  dst = 0;
390  break;
391 
395  GPDMACfg.SrcAddr = (uint32_t) GPDMA_LUTPerAddr[src];
396  GPDMACfg.DstAddr = (uint32_t) GPDMA_LUTPerAddr[dst];
397  SrcPeripheral = DMAMUX_Config(src);
398  DstPeripheral = DMAMUX_Config(dst);
399  break;
400 
401  default:
402  break;
403  }
404 
407  (uint32_t) GPDMA_LUTPerAddr[dst], SrcPeripheral, DstPeripheral);
408 
409  /* Start the Channel */
410  IP_GPDMA_ChannelCmd(LPC_GPDMA, ChannelNum, ENABLE);
411 }
412 
413 /* Get a free GPDMA channel for one DMA connection */
414 uint8_t Chip_DMA_GetFreeChannel(uint32_t PeripheralConnection_ID)
415 {
416  uint8_t temp = 0;
417  for (temp = 0; temp < GPDMA_NUMBER_CHANNELS; temp++)
419  temp) && (ChannelHandlerArray[temp].ChannelStatus == DISABLE)) {
420  ChannelHandlerArray[temp].ChannelStatus = ENABLE;
421  return temp;
422  }
423  return 0;
424 }