uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc17xx_gpdma.c
Go to the documentation of this file.
1 /***********************************************************************/
20 /* Peripheral group ----------------------------------------------------------- */
25 /* Includes ------------------------------------------------------------------- */
26 #include "lpc17xx_gpdma.h"
27 #include "lpc17xx_clkpwr.h"
28 
29 /* If this source file built with example, the LPC17xx FW library configuration
30  * file in each example directory ("lpc17xx_libcfg.h") must be included,
31  * otherwise the default FW library configuration file must be included instead
32  */
33 #ifdef __BUILD_WITH_EXAMPLE__
34 #include "lpc17xx_libcfg.h"
35 #else
36 #include "lpc17xx_libcfg_default.h"
37 #endif /* __BUILD_WITH_EXAMPLE__ */
38 
39 #ifdef _GPDMA
40 
41 
42 /* Private Variables ---------------------------------------------------------- */
51 #ifdef __IAR_SYSTEMS_ICC__
52 volatile const void *GPDMA_LUTPerAddr[] = {
53  (&LPC_SSP0->DR), // SSP0 Tx
54  (&LPC_SSP0->DR), // SSP0 Rx
55  (&LPC_SSP1->DR), // SSP1 Tx
56  (&LPC_SSP1->DR), // SSP1 Rx
57  (&LPC_ADC->ADGDR), // ADC
58  (&LPC_I2S->I2STXFIFO), // I2S Tx
59  (&LPC_I2S->I2SRXFIFO), // I2S Rx
60  (&LPC_DAC->DACR), // DAC
61  (&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx
62  (&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx
63  (&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
64  (&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
65  (&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx
66  (&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx
67  (&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx
68  (&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx
69  (&LPC_TIM0->MR0), // MAT0.0
70  (&LPC_TIM0->MR1), // MAT0.1
71  (&LPC_TIM1->MR0), // MAT1.0
72  (&LPC_TIM1->MR1), // MAT1.1
73  (&LPC_TIM2->MR0), // MAT2.0
74  (&LPC_TIM2->MR1), // MAT2.1
75  (&LPC_TIM3->MR0), // MAT3.0
76  (&LPC_TIM3->MR1), // MAT3.1
77 };
78 #else
79 const uint32_t GPDMA_LUTPerAddr[] = {
80  ((uint32_t)&LPC_SSP0->DR), // SSP0 Tx
81  ((uint32_t)&LPC_SSP0->DR), // SSP0 Rx
82  ((uint32_t)&LPC_SSP1->DR), // SSP1 Tx
83  ((uint32_t)&LPC_SSP1->DR), // SSP1 Rx
84  ((uint32_t)&LPC_ADC->ADGDR), // ADC
85  ((uint32_t)&LPC_I2S->I2STXFIFO), // I2S Tx
86  ((uint32_t)&LPC_I2S->I2SRXFIFO), // I2S Rx
87  ((uint32_t)&LPC_DAC->DACR), // DAC
88  ((uint32_t)&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx
89  ((uint32_t)&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx
90  ((uint32_t)&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
91  ((uint32_t)&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
92  ((uint32_t)&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx
93  ((uint32_t)&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx
94  ((uint32_t)&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx
95  ((uint32_t)&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx
96  ((uint32_t)&LPC_TIM0->MR0), // MAT0.0
97  ((uint32_t)&LPC_TIM0->MR1), // MAT0.1
98  ((uint32_t)&LPC_TIM1->MR0), // MAT1.0
99  ((uint32_t)&LPC_TIM1->MR1), // MAT1.1
100  ((uint32_t)&LPC_TIM2->MR0), // MAT2.0
101  ((uint32_t)&LPC_TIM2->MR1), // MAT2.1
102  ((uint32_t)&LPC_TIM3->MR0), // MAT3.0
103  ((uint32_t)&LPC_TIM3->MR1), // MAT3.1
104 };
105 #endif
106 
110 const LPC_GPDMACH_TypeDef *pGPDMACh[8] = {
111  LPC_GPDMACH0, // GPDMA Channel 0
112  LPC_GPDMACH1, // GPDMA Channel 1
113  LPC_GPDMACH2, // GPDMA Channel 2
114  LPC_GPDMACH3, // GPDMA Channel 3
115  LPC_GPDMACH4, // GPDMA Channel 4
116  LPC_GPDMACH5, // GPDMA Channel 5
117  LPC_GPDMACH6, // GPDMA Channel 6
118  LPC_GPDMACH7, // GPDMA Channel 7
119 };
123 const uint8_t GPDMA_LUTPerBurst[] = {
124  GPDMA_BSIZE_4, // SSP0 Tx
125  GPDMA_BSIZE_4, // SSP0 Rx
126  GPDMA_BSIZE_4, // SSP1 Tx
127  GPDMA_BSIZE_4, // SSP1 Rx
128  GPDMA_BSIZE_4, // ADC
129  GPDMA_BSIZE_32, // I2S channel 0
130  GPDMA_BSIZE_32, // I2S channel 1
131  GPDMA_BSIZE_1, // DAC
132  GPDMA_BSIZE_1, // UART0 Tx
133  GPDMA_BSIZE_1, // UART0 Rx
134  GPDMA_BSIZE_1, // UART1 Tx
135  GPDMA_BSIZE_1, // UART1 Rx
136  GPDMA_BSIZE_1, // UART2 Tx
137  GPDMA_BSIZE_1, // UART2 Rx
138  GPDMA_BSIZE_1, // UART3 Tx
139  GPDMA_BSIZE_1, // UART3 Rx
140  GPDMA_BSIZE_1, // MAT0.0
141  GPDMA_BSIZE_1, // MAT0.1
142  GPDMA_BSIZE_1, // MAT1.0
143  GPDMA_BSIZE_1, // MAT1.1
144  GPDMA_BSIZE_1, // MAT2.0
145  GPDMA_BSIZE_1, // MAT2.1
146  GPDMA_BSIZE_1, // MAT3.0
147  GPDMA_BSIZE_1, // MAT3.1
148 };
152 const uint8_t GPDMA_LUTPerWid[] = {
153  GPDMA_WIDTH_BYTE, // SSP0 Tx
154  GPDMA_WIDTH_BYTE, // SSP0 Rx
155  GPDMA_WIDTH_BYTE, // SSP1 Tx
156  GPDMA_WIDTH_BYTE, // SSP1 Rx
157  GPDMA_WIDTH_WORD, // ADC
158  GPDMA_WIDTH_WORD, // I2S channel 0
159  GPDMA_WIDTH_WORD, // I2S channel 1
160  GPDMA_WIDTH_BYTE, // DAC
161  GPDMA_WIDTH_BYTE, // UART0 Tx
162  GPDMA_WIDTH_BYTE, // UART0 Rx
163  GPDMA_WIDTH_BYTE, // UART1 Tx
164  GPDMA_WIDTH_BYTE, // UART1 Rx
165  GPDMA_WIDTH_BYTE, // UART2 Tx
166  GPDMA_WIDTH_BYTE, // UART2 Rx
167  GPDMA_WIDTH_BYTE, // UART3 Tx
168  GPDMA_WIDTH_BYTE, // UART3 Rx
169  GPDMA_WIDTH_WORD, // MAT0.0
170  GPDMA_WIDTH_WORD, // MAT0.1
171  GPDMA_WIDTH_WORD, // MAT1.0
172  GPDMA_WIDTH_WORD, // MAT1.1
173  GPDMA_WIDTH_WORD, // MAT2.0
174  GPDMA_WIDTH_WORD, // MAT2.1
175  GPDMA_WIDTH_WORD, // MAT3.0
176  GPDMA_WIDTH_WORD, // MAT3.1
177 };
178 
183 /* Public Functions ----------------------------------------------------------- */
188 /********************************************************************/
193 void GPDMA_Init(void)
194 {
195  /* Enable GPDMA clock */
197 
198  // Reset all channel configuration register
199  LPC_GPDMACH0->DMACCConfig = 0;
200  LPC_GPDMACH1->DMACCConfig = 0;
201  LPC_GPDMACH2->DMACCConfig = 0;
202  LPC_GPDMACH3->DMACCConfig = 0;
203  LPC_GPDMACH4->DMACCConfig = 0;
204  LPC_GPDMACH5->DMACCConfig = 0;
205  LPC_GPDMACH6->DMACCConfig = 0;
206  LPC_GPDMACH7->DMACCConfig = 0;
207 
208  /* Clear all DMA interrupt and error flag */
209  LPC_GPDMA->DMACIntTCClear = 0xFF;
210  LPC_GPDMA->DMACIntErrClr = 0xFF;
211 }
212 
213 /********************************************************************/
222 Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig)
223 {
224  LPC_GPDMACH_TypeDef *pDMAch;
225  uint32_t tmp1, tmp2;
226 
227  if (LPC_GPDMA->DMACEnbldChns & (GPDMA_DMACEnbldChns_Ch(GPDMAChannelConfig->ChannelNum))) {
228  // This channel is enabled, return ERROR, need to release this channel first
229  return ERROR;
230  }
231 
232  // Get Channel pointer
233  pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[GPDMAChannelConfig->ChannelNum];
234 
235  // Reset the Interrupt status
236  LPC_GPDMA->DMACIntTCClear = GPDMA_DMACIntTCClear_Ch(GPDMAChannelConfig->ChannelNum);
237  LPC_GPDMA->DMACIntErrClr = GPDMA_DMACIntErrClr_Ch(GPDMAChannelConfig->ChannelNum);
238 
239  // Clear DMA configure
240  pDMAch->DMACCControl = 0x00;
241  pDMAch->DMACCConfig = 0x00;
242 
243  /* Assign Linker List Item value */
244  pDMAch->DMACCLLI = GPDMAChannelConfig->DMALLI;
245 
246  /* Set value to Channel Control Registers */
247  switch (GPDMAChannelConfig->TransferType)
248  {
249  // Memory to memory
251  // Assign physical source and destination address
252  pDMAch->DMACCSrcAddr = GPDMAChannelConfig->SrcMemAddr;
253  pDMAch->DMACCDestAddr = GPDMAChannelConfig->DstMemAddr;
254  pDMAch->DMACCControl
255  = GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize) \
258  | GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth) \
259  | GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth) \
263  break;
264  // Memory to peripheral
266  // Assign physical source
267  pDMAch->DMACCSrcAddr = GPDMAChannelConfig->SrcMemAddr;
268  // Assign peripheral destination address
269  pDMAch->DMACCDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
270  pDMAch->DMACCControl
271  = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
272  | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
273  | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
274  | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
275  | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
278  break;
279  // Peripheral to memory
281  // Assign peripheral source address
282  pDMAch->DMACCSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
283  // Assign memory destination address
284  pDMAch->DMACCDestAddr = GPDMAChannelConfig->DstMemAddr;
285  pDMAch->DMACCControl
286  = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
287  | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
288  | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
289  | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
290  | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
293  break;
294  // Peripheral to peripheral
296  // Assign peripheral source address
297  pDMAch->DMACCSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
298  // Assign peripheral destination address
299  pDMAch->DMACCDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
300  pDMAch->DMACCControl
301  = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
302  | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
303  | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
304  | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
305  | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
307  break;
308  // Do not support any more transfer type, return ERROR
309  default:
310  return ERROR;
311  }
312 
313  /* Re-Configure DMA Request Select for source peripheral */
314  if (GPDMAChannelConfig->SrcConn > 15)
315  {
316  DMAREQSEL |= (1<<(GPDMAChannelConfig->SrcConn - 16));
317  } else {
318  DMAREQSEL &= ~(1<<(GPDMAChannelConfig->SrcConn - 8));
319  }
320 
321  /* Re-Configure DMA Request Select for Destination peripheral */
322  if (GPDMAChannelConfig->DstConn > 15)
323  {
324  DMAREQSEL |= (1<<(GPDMAChannelConfig->DstConn - 16));
325  } else {
326  DMAREQSEL &= ~(1<<(GPDMAChannelConfig->DstConn - 8));
327  }
328 
329  /* Enable DMA channels, little endian */
330  LPC_GPDMA->DMACConfig = GPDMA_DMACConfig_E;
331  while (!(LPC_GPDMA->DMACConfig & GPDMA_DMACConfig_E));
332 
333  // Calculate absolute value for Connection number
334  tmp1 = GPDMAChannelConfig->SrcConn;
335  tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
336  tmp2 = GPDMAChannelConfig->DstConn;
337  tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
338 
339  // Configure DMA Channel, enable Error Counter and Terminate counter
340  pDMAch->DMACCConfig = GPDMA_DMACCxConfig_IE | GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/ \
341  | GPDMA_DMACCxConfig_TransferType((uint32_t)GPDMAChannelConfig->TransferType) \
344 
345  return SUCCESS;
346 }
347 
348 
349 /*********************************************************************/
357 void GPDMA_ChannelCmd(uint8_t channelNum, FunctionalState NewState)
358 {
359  LPC_GPDMACH_TypeDef *pDMAch;
360 
361  // Get Channel pointer
362  pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[channelNum];
363 
364  if (NewState == ENABLE) {
366  } else {
367  pDMAch->DMACCConfig &= ~GPDMA_DMACCxConfig_E;
368  }
369 }
370 /*********************************************************************/
386 IntStatus GPDMA_IntGetStatus(GPDMA_Status_Type type, uint8_t channel)
387 {
390 
391  switch (type)
392  {
393  case GPDMA_STAT_INT: //check status of DMA channel interrupts
394  if (LPC_GPDMA->DMACIntStat & (GPDMA_DMACIntStat_Ch(channel)))
395  return SET;
396  return RESET;
397  case GPDMA_STAT_INTTC: // check terminal count interrupt request status for DMA
398  if (LPC_GPDMA->DMACIntTCStat & GPDMA_DMACIntTCStat_Ch(channel))
399  return SET;
400  return RESET;
401  case GPDMA_STAT_INTERR: //check interrupt status for DMA channels
402  if (LPC_GPDMA->DMACIntErrStat & GPDMA_DMACIntTCClear_Ch(channel))
403  return SET;
404  return RESET;
405  case GPDMA_STAT_RAWINTTC: //check status of the terminal count interrupt for DMA channels
406  if (LPC_GPDMA->DMACRawIntErrStat & GPDMA_DMACRawIntTCStat_Ch(channel))
407  return SET;
408  return RESET;
409  case GPDMA_STAT_RAWINTERR: //check status of the error interrupt for DMA channels
410  if (LPC_GPDMA->DMACRawIntTCStat & GPDMA_DMACRawIntErrStat_Ch(channel))
411  return SET;
412  return RESET;
413  default: //check enable status for DMA channels
414  if (LPC_GPDMA->DMACEnbldChns & GPDMA_DMACEnbldChns_Ch(channel))
415  return SET;
416  return RESET;
417  }
418 }
419 
420 /*********************************************************************/
428 void GPDMA_ClearIntPending(GPDMA_StateClear_Type type, uint8_t channel)
429 {
432 
433  if (type == GPDMA_STATCLR_INTTC) // clears the terminal count interrupt request on DMA channel
434  LPC_GPDMA->DMACIntTCClear = GPDMA_DMACIntTCClear_Ch(channel);
435  else // clear the error interrupt request
436  LPC_GPDMA->DMACIntErrClr = GPDMA_DMACIntErrClr_Ch(channel);
437 }
438 
443 #endif /* _GPDMA */
444 
449 /* --------------------------------- End Of File ------------------------------ */
450