1 /**************************************************************************//**
2 * @file pdma.c
3 * @version V1.00
4 * @brief M480 series PDMA driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11
12 static uint8_t u32ChSelect[PDMA_CH_MAX];
13
14 /** @addtogroup Standard_Driver Standard Driver
15 @{
16 */
17
18 /** @addtogroup PDMA_Driver PDMA Driver
19 @{
20 */
21
22
23 /** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
24 @{
25 */
26
27 /**
28 * @brief PDMA Open
29 *
30 * @param[in] pdma The pointer of the specified PDMA module
31 *
32 * @param[in] u32Mask Channel enable bits.
33 *
34 * @return None
35 *
36 * @details This function enable the PDMA channels.
37 */
PDMA_Open(PDMA_T * pdma,uint32_t u32Mask)38 void PDMA_Open(PDMA_T * pdma,uint32_t u32Mask)
39 {
40 uint32_t i;
41
42 for (i=0UL; i<PDMA_CH_MAX; i++)
43 {
44 if((1 << i) & u32Mask)
45 {
46 pdma->DSCT[i].CTL = 0UL;
47 u32ChSelect[i] = PDMA_MEM;
48 }
49 }
50
51 pdma->CHCTL |= u32Mask;
52 }
53
54 /**
55 * @brief PDMA Close
56 *
57 * @param[in] pdma The pointer of the specified PDMA module
58 *
59 * @return None
60 *
61 * @details This function disable all PDMA channels.
62 */
PDMA_Close(PDMA_T * pdma)63 void PDMA_Close(PDMA_T * pdma)
64 {
65 pdma->CHCTL = 0UL;
66 }
67
68 /**
69 * @brief Set PDMA Transfer Count
70 *
71 * @param[in] pdma The pointer of the specified PDMA module
72 * @param[in] u32Ch The selected channel
73 * @param[in] u32Width Data width. Valid values are
74 * - \ref PDMA_WIDTH_8
75 * - \ref PDMA_WIDTH_16
76 * - \ref PDMA_WIDTH_32
77 * @param[in] u32TransCount Transfer count
78 *
79 * @return None
80 *
81 * @details This function set the selected channel data width and transfer count.
82 */
PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Width,uint32_t u32TransCount)83 void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
84 {
85 pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);
86 pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos));
87 }
88
89 /**
90 * @brief Set PDMA Stride Mode
91 *
92 * @param[in] pdma The pointer of the specified PDMA module
93 * @param[in] u32Ch The selected channel
94 * @param[in] u32DestLen Destination stride count
95 * @param[in] u32SrcLen Source stride count
96 * @param[in] u32TransCount Transfer count
97 *
98 * @return None
99 *
100 * @details This function set the selected stride mode.
101 */
PDMA_SetStride(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32DestLen,uint32_t u32SrcLen,uint32_t u32TransCount)102 void PDMA_SetStride(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount)
103 {
104 pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
105 pdma->STRIDE[u32Ch].ASOCR =((u32DestLen-1)<<16) | (u32SrcLen-1);
106 pdma->STRIDE[u32Ch].STCR = u32TransCount-1;
107 }
108
109 /**
110 * @brief Set PDMA Repeat
111 *
112 * @param[in] pdma The pointer of the specified PDMA module
113 * @param[in] u32Ch The selected channel
114 * @param[in] u32DestInterval Destination address interval count
115 * @param[in] u32SrcInterval Source address interval count
116 * @param[in] u32RepeatCount Repeat count
117 *
118 * @return None
119 *
120 * @details This function set the selected repeat.
121 */
PDMA_SetRepeat(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32DestInterval,uint32_t u32SrcInterval,uint32_t u32RepeatCount)122 void PDMA_SetRepeat(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestInterval, uint32_t u32SrcInterval, uint32_t u32RepeatCount)
123 {
124 pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
125 pdma->REPEAT[u32Ch].AICTL =((u32DestInterval)<<16) | (u32SrcInterval);
126 pdma->REPEAT[u32Ch].RCNT = u32RepeatCount;
127 }
128
129 /**
130 * @brief Set PDMA Transfer Address
131 *
132 * @param[in] pdma The pointer of the specified PDMA module
133 * @param[in] u32Ch The selected channel
134 * @param[in] u32SrcAddr Source address
135 * @param[in] u32SrcCtrl Source control attribute. Valid values are
136 * - \ref PDMA_SAR_INC
137 * - \ref PDMA_SAR_FIX
138 * @param[in] u32DstAddr destination address
139 * @param[in] u32DstCtrl destination control attribute. Valid values are
140 * - \ref PDMA_DAR_INC
141 * - \ref PDMA_DAR_FIX
142 *
143 * @return None
144 *
145 * @details This function set the selected channel source/destination address and attribute.
146 */
PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32SrcAddr,uint32_t u32SrcCtrl,uint32_t u32DstAddr,uint32_t u32DstCtrl)147 void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
148 {
149 pdma->DSCT[u32Ch].SA = u32SrcAddr;
150 pdma->DSCT[u32Ch].DA = u32DstAddr;
151 pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
152 pdma->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
153 }
154
155 /**
156 * @brief Set PDMA Transfer Mode
157 *
158 * @param[in] pdma The pointer of the specified PDMA module
159 * @param[in] u32Ch The selected channel
160 * @param[in] u32Peripheral The selected peripheral. Valid values are
161 * - \ref PDMA_MEM
162 * - \ref PDMA_USB_TX
163 * - \ref PDMA_USB_RX
164 * - \ref PDMA_UART0_TX
165 * - \ref PDMA_UART0_RX
166 * - \ref PDMA_UART1_TX
167 * - \ref PDMA_UART1_RX
168 * - \ref PDMA_UART2_TX
169 * - \ref PDMA_UART2_RX
170 * - \ref PDMA_UART3_TX
171 * - \ref PDMA_UART3_RX
172 * - \ref PDMA_UART4_TX
173 * - \ref PDMA_UART4_RX
174 * - \ref PDMA_UART5_TX
175 * - \ref PDMA_UART5_RX
176 * - \ref PDMA_USCI0_TX
177 * - \ref PDMA_USCI0_RX
178 * - \ref PDMA_USCI1_TX
179 * - \ref PDMA_USCI1_RX
180 * - \ref PDMA_QSPI0_TX
181 * - \ref PDMA_QSPI0_RX
182 * - \ref PDMA_SPI0_TX
183 * - \ref PDMA_SPI0_RX
184 * - \ref PDMA_SPI1_TX
185 * - \ref PDMA_SPI1_RX
186 * - \ref PDMA_SPI2_TX
187 * - \ref PDMA_SPI2_RX
188 * - \ref PDMA_SPI3_TX
189 * - \ref PDMA_SPI3_RX
190 * - \ref PDMA_EPWM0_P1_RX
191 * - \ref PDMA_EPWM0_P2_RX
192 * - \ref PDMA_EPWM0_P3_RX
193 * - \ref PDMA_EPWM1_P1_RX
194 * - \ref PDMA_EPWM1_P2_RX
195 * - \ref PDMA_EPWM1_P3_RX
196 * - \ref PDMA_I2C0_TX
197 * - \ref PDMA_I2C0_RX
198 * - \ref PDMA_I2C1_TX
199 * - \ref PDMA_I2C1_RX
200 * - \ref PDMA_I2C2_TX
201 * - \ref PDMA_I2C2_RX
202 * - \ref PDMA_I2S0_TX
203 * - \ref PDMA_I2S0_RX
204 * - \ref PDMA_TMR0
205 * - \ref PDMA_TMR1
206 * - \ref PDMA_TMR2
207 * - \ref PDMA_TMR3
208 * - \ref PDMA_EADC0_RX
209 * - \ref PDMA_DAC0_TX
210 * - \ref PDMA_DAC1_TX
211 * - \ref PDMA_EPWM0_CH0_TX
212 * - \ref PDMA_EPWM0_CH1_TX
213 * - \ref PDMA_EPWM0_CH2_TX
214 * - \ref PDMA_EPWM0_CH3_TX
215 * - \ref PDMA_EPWM0_CH4_TX
216 * - \ref PDMA_EPWM0_CH5_TX
217 * - \ref PDMA_EPWM1_CH0_TX
218 * - \ref PDMA_EPWM1_CH1_TX
219 * - \ref PDMA_EPWM1_CH2_TX
220 * - \ref PDMA_EPWM1_CH3_TX
221 * - \ref PDMA_EPWM1_CH4_TX
222 * - \ref PDMA_EPWM1_CH5_TX
223 * - \ref PDMA_UART6_TX
224 * - \ref PDMA_UART6_RX
225 * - \ref PDMA_UART7_TX
226 * - \ref PDMA_UART7_RX
227 * - \ref PDMA_EADC1_RX
228 * @param[in] u32ScatterEn Scatter-gather mode enable
229 * @param[in] u32DescAddr Scatter-gather descriptor address
230 *
231 * @return None
232 *
233 * @details This function set the selected channel transfer mode. Include peripheral setting.
234 */
PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Peripheral,uint32_t u32ScatterEn,uint32_t u32DescAddr)235 void PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
236 {
237 u32ChSelect[u32Ch] = u32Peripheral;
238 switch(u32Ch)
239 {
240 case 0ul:
241 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral;
242 break;
243 case 1ul:
244 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
245 break;
246 case 2ul:
247 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
248 break;
249 case 3ul:
250 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
251 break;
252 case 4ul:
253 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
254 break;
255 case 5ul:
256 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
257 break;
258 case 6ul:
259 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
260 break;
261 case 7ul:
262 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
263 break;
264 case 8ul:
265 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC8_Msk) | u32Peripheral;
266 break;
267 case 9ul:
268 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC9_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC9_Pos);
269 break;
270 case 10ul:
271 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC10_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC10_Pos);
272 break;
273 case 11ul:
274 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC11_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC11_Pos);
275 break;
276 case 12ul:
277 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC12_Msk) | u32Peripheral;
278 break;
279 case 13ul:
280 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC13_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC13_Pos);
281 break;
282 case 14ul:
283 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC14_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC14_Pos);
284 break;
285 case 15ul:
286 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC15_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC15_Pos);
287 break;
288 default:
289 break;
290 }
291
292 if(u32ScatterEn)
293 {
294 pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
295 pdma->DSCT[u32Ch].NEXT = u32DescAddr - (PDMA->SCATBA);
296 }
297 else
298 {
299 pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
300 }
301 }
302
303 /**
304 * @brief Set PDMA Burst Type and Size
305 *
306 * @param[in] pdma The pointer of the specified PDMA module
307 * @param[in] u32Ch The selected channel
308 * @param[in] u32BurstType Burst mode or single mode. Valid values are
309 * - \ref PDMA_REQ_SINGLE
310 * - \ref PDMA_REQ_BURST
311 * @param[in] u32BurstSize Set the size of burst mode. Valid values are
312 * - \ref PDMA_BURST_128
313 * - \ref PDMA_BURST_64
314 * - \ref PDMA_BURST_32
315 * - \ref PDMA_BURST_16
316 * - \ref PDMA_BURST_8
317 * - \ref PDMA_BURST_4
318 * - \ref PDMA_BURST_2
319 * - \ref PDMA_BURST_1
320 *
321 * @return None
322 *
323 * @details This function set the selected channel burst type and size.
324 */
PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32BurstType,uint32_t u32BurstSize)325 void PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
326 {
327 pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
328 pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
329 }
330
331 /**
332 * @brief Enable timeout function
333 *
334 * @param[in] pdma The pointer of the specified PDMA module
335 *
336 * @param[in] u32Mask Channel enable bits.
337 *
338 * @return None
339 *
340 * @details This function enable timeout function of the selected channel(s).
341 */
PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask)342 void PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask)
343 {
344 pdma->TOUTEN |= u32Mask;
345 }
346
347 /**
348 * @brief Disable timeout function
349 *
350 * @param[in] pdma The pointer of the specified PDMA module
351 *
352 * @param[in] u32Mask Channel enable bits.
353 *
354 * @return None
355 *
356 * @details This function disable timeout function of the selected channel(s).
357 */
PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)358 void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)
359 {
360 pdma->TOUTEN &= ~u32Mask;
361 }
362
363 /**
364 * @brief Set PDMA Timeout Count
365 *
366 * @param[in] pdma The pointer of the specified PDMA module
367 * @param[in] u32Ch The selected channel,
368 * @param[in] u32OnOff Enable/disable time out function
369 * @param[in] u32TimeOutCnt Timeout count
370 *
371 * @return None
372 *
373 * @details This function set the timeout count.
374 * @note M480 only supported channel 0/1.
375 */
PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32OnOff,uint32_t u32TimeOutCnt)376 void PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
377 {
378 switch(u32Ch)
379 {
380 case 0ul:
381 pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt;
382 break;
383 case 1ul:
384 pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
385 break;
386 default:
387 break;
388 }
389
390 if (u32OnOff)
391 pdma->TOUTEN |= (1 << u32Ch);
392 else
393 pdma->TOUTEN &= ~(1 << u32Ch);
394 }
395
396 /**
397 * @brief Trigger PDMA
398 *
399 * @param[in] pdma The pointer of the specified PDMA module
400 * @param[in] u32Ch The selected channel
401 *
402 * @return None
403 *
404 * @details This function trigger the selected channel.
405 */
PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch)406 void PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch)
407 {
408 if(u32ChSelect[u32Ch] == PDMA_MEM)
409 {
410 pdma->SWREQ = (1ul << u32Ch);
411 }
412 else {}
413 }
414
415 /**
416 * @brief Enable Interrupt
417 *
418 * @param[in] pdma The pointer of the specified PDMA module
419 * @param[in] u32Ch The selected channel
420 * @param[in] u32Mask The Interrupt Type. Valid values are
421 * - \ref PDMA_INT_TRANS_DONE
422 * - \ref PDMA_INT_TEMPTY
423 * - \ref PDMA_INT_TIMEOUT
424 *
425 * @return None
426 *
427 * @details This function enable the selected channel interrupt.
428 */
PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Mask)429 void PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask)
430 {
431 switch(u32Mask)
432 {
433 case PDMA_INT_TRANS_DONE:
434 pdma->INTEN |= (1ul << u32Ch);
435 break;
436 case PDMA_INT_TEMPTY:
437 pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
438 break;
439 case PDMA_INT_TIMEOUT:
440 pdma->TOUTIEN |= (1ul << u32Ch);
441 break;
442
443 default:
444 break;
445 }
446 }
447
448 /**
449 * @brief Disable Interrupt
450 *
451 * @param[in] pdma The pointer of the specified PDMA module
452 * @param[in] u32Ch The selected channel
453 * @param[in] u32Mask The Interrupt Type. Valid values are
454 * - \ref PDMA_INT_TRANS_DONE
455 * - \ref PDMA_INT_TEMPTY
456 * - \ref PDMA_INT_TIMEOUT
457 *
458 * @return None
459 *
460 * @details This function disable the selected channel interrupt.
461 */
PDMA_DisableInt(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Mask)462 void PDMA_DisableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask)
463 {
464 switch(u32Mask)
465 {
466 case PDMA_INT_TRANS_DONE:
467 pdma->INTEN &= ~(1ul << u32Ch);
468 break;
469 case PDMA_INT_TEMPTY:
470 pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
471 break;
472 case PDMA_INT_TIMEOUT:
473 pdma->TOUTIEN &= ~(1ul << u32Ch);
474 break;
475
476 default:
477 break;
478 }
479 }
480
481 /*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
482
483 /*@}*/ /* end of group PDMA_Driver */
484
485 /*@}*/ /* end of group Standard_Driver */
486
487 /*** (C) COPYRIGHT 2014~2016 Nuvoton Technology Corp. ***/
488