1 /**************************************************************************//**
2 * @file pdma.c
3 * @version V1.00
4 * @brief M2L31 series PDMA driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11
12 static uint8_t u8ChSelect[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 u8ChSelect[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 Transfer Address
91 *
92 * @param[in] pdma The pointer of the specified PDMA module
93 * @param[in] u32Ch The selected channel
94 * @param[in] u32SrcAddr Source address
95 * @param[in] u32SrcCtrl Source control attribute. Valid values are
96 * - \ref PDMA_SAR_INC
97 * - \ref PDMA_SAR_FIX
98 * @param[in] u32DstAddr Destination address
99 * @param[in] u32DstCtrl Destination control attribute. Valid values are
100 * - \ref PDMA_DAR_INC
101 * - \ref PDMA_DAR_FIX
102 *
103 * @return None
104 *
105 * @details This function set the selected channel source/destination address and attribute.
106 */
PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32SrcAddr,uint32_t u32SrcCtrl,uint32_t u32DstAddr,uint32_t u32DstCtrl)107 void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
108 {
109 pdma->DSCT[u32Ch].SA = u32SrcAddr;
110 pdma->DSCT[u32Ch].DA = u32DstAddr;
111 pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
112 pdma->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
113 }
114
115 /**
116 * @brief Set PDMA Transfer Mode
117 *
118 * @param[in] pdma The pointer of the specified PDMA module
119 * @param[in] u32Ch The selected channel
120 * @param[in] u32Peripheral The selected peripheral. Valid values are
121 * - \ref PDMA_MEM
122 * - \ref PDMA_USB_TX
123 * - \ref PDMA_USB_RX
124 * - \ref PDMA_UART0_TX
125 * - \ref PDMA_UART0_RX
126 * - \ref PDMA_UART1_TX
127 * - \ref PDMA_UART1_RX
128 * - \ref PDMA_UART2_TX
129 * - \ref PDMA_UART2_RX
130 * - \ref PDMA_UART3_TX
131 * - \ref PDMA_UART3_RX
132 * - \ref PDMA_UART4_TX
133 * - \ref PDMA_UART4_RX
134 * - \ref PDMA_UART5_TX
135 * - \ref PDMA_UART5_RX
136 * - \ref PDMA_USCI0_TX
137 * - \ref PDMA_USCI0_RX
138 * - \ref PDMA_USCI1_TX
139 * - \ref PDMA_USCI1_RX
140 * - \ref PDMA_QSPI0_TX
141 * - \ref PDMA_QSPI0_RX
142 * - \ref PDMA_SPI0_TX
143 * - \ref PDMA_SPI0_RX
144 * - \ref PDMA_SPI1_TX
145 * - \ref PDMA_SPI1_RX
146 * - \ref PDMA_SPI2_TX
147 * - \ref PDMA_SPI2_RX
148 * - \ref PDMA_SPI3_TX
149 * - \ref PDMA_SPI3_RX
150 * - \ref PDMA_ACMP0
151 * - \ref PDMA_ACMP1
152 * - \ref PDMA_EPWM0_P1_RX
153 * - \ref PDMA_EPWM0_P2_RX
154 * - \ref PDMA_EPWM0_P3_RX
155 * - \ref PDMA_EPWM1_P1_RX
156 * - \ref PDMA_EPWM1_P2_RX
157 * - \ref PDMA_EPWM1_P3_RX
158 * - \ref PDMA_I2C0_TX
159 * - \ref PDMA_I2C0_RX
160 * - \ref PDMA_I2C1_TX
161 * - \ref PDMA_I2C1_RX
162 * - \ref PDMA_I2C2_TX
163 * - \ref PDMA_I2C2_RX
164 * - \ref PDMA_I2C3_TX
165 * - \ref PDMA_I2C3_RX
166 * - \ref PDMA_TMR0
167 * - \ref PDMA_TMR1
168 * - \ref PDMA_TMR2
169 * - \ref PDMA_TMR3
170 * - \ref PDMA_DAC0_TX
171 * - \ref PDMA_DAC1_TX
172 * - \ref PDMA_EPWM0_CH0_TX
173 * - \ref PDMA_EPWM0_CH1_TX
174 * - \ref PDMA_EPWM0_CH2_TX
175 * - \ref PDMA_EPWM0_CH3_TX
176 * - \ref PDMA_EPWM0_CH4_TX
177 * - \ref PDMA_EPWM0_CH5_TX
178 * - \ref PDMA_EPWM1_CH0_TX
179 * - \ref PDMA_EPWM1_CH1_TX
180 * - \ref PDMA_EPWM1_CH2_TX
181 * - \ref PDMA_EPWM1_CH3_TX
182 * - \ref PDMA_EPWM1_CH4_TX
183 * - \ref PDMA_EPWM1_CH5_TX
184 * - \ref PDMA_EADC0_RX
185 * - \ref PDMA_EADC1_RX
186 * - \ref PDMA_UART6_TX
187 * - \ref PDMA_UART6_RX
188 * - \ref PDMA_UART7_TX
189 * - \ref PDMA_UART7_RX
190 * - \ref PDMA_PWM0_P1_RX
191 * - \ref PDMA_PWM0_P2_RX
192 * - \ref PDMA_PWM0_P3_RX
193 * - \ref PDMA_PWM1_P1_RX
194 * - \ref PDMA_PWM1_P2_RX
195 * - \ref PDMA_PWM1_P3_RX
196 * - \ref PDMA_PWM0_CH0_TX
197 * - \ref PDMA_PWM0_CH2_TX
198 * - \ref PDMA_PWM0_CH4_TX
199 * - \ref PDMA_PWM1_CH0_TX
200 * - \ref PDMA_PWM1_CH2_TX
201 * - \ref PDMA_PWM1_CH4_TX
202 * - \ref PDMA_EINT0
203 * - \ref PDMA_EINT1
204 * - \ref PDMA_EINT2
205 * - \ref PDMA_EINT3
206 * - \ref PDMA_EINT4
207 * - \ref PDMA_EINT5
208 * - \ref PDMA_EINT6
209 * - \ref PDMA_EINT7
210 * - \ref PDMA_ACMP2
211 * @param[in] u32ScatterEn Scatter-gather mode enable
212 * @param[in] u32DescAddr Scatter-gather descriptor address
213 *
214 * @return None
215 *
216 * @details This function set the selected channel transfer mode. Include peripheral setting.
217 */
PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Peripheral,uint32_t u32ScatterEn,uint32_t u32DescAddr)218 void PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
219 {
220 u8ChSelect[u32Ch] = u32Peripheral;
221 switch(u32Ch)
222 {
223 case 0ul:
224 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral;
225 break;
226 case 1ul:
227 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
228 break;
229 case 2ul:
230 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
231 break;
232 case 3ul:
233 pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
234 break;
235 case 4ul:
236 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
237 break;
238 case 5ul:
239 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
240 break;
241 case 6ul:
242 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
243 break;
244 case 7ul:
245 pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
246 break;
247 case 8ul:
248 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC8_Msk) | u32Peripheral;
249 break;
250 case 9ul:
251 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC9_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC9_Pos);
252 break;
253 case 10ul:
254 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC10_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC10_Pos);
255 break;
256 case 11ul:
257 pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC11_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC11_Pos);
258 break;
259 case 12ul:
260 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC12_Msk) | u32Peripheral;
261 break;
262 case 13ul:
263 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC13_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC13_Pos);
264 break;
265 case 14ul:
266 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC14_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC14_Pos);
267 break;
268 case 15ul:
269 pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC15_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC15_Pos);
270 break;
271 default:
272 break;
273 }
274
275 if(u32ScatterEn)
276 {
277 pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
278 pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
279 }
280 else
281 {
282 pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
283 }
284 }
285
286 /**
287 * @brief Set PDMA Burst Type and Size
288 *
289 * @param[in] pdma The pointer of the specified PDMA module
290 * @param[in] u32Ch The selected channel
291 * @param[in] u32BurstType Burst mode or single mode. Valid values are
292 * - \ref PDMA_REQ_SINGLE
293 * - \ref PDMA_REQ_BURST
294 * @param[in] u32BurstSize Set the size of burst mode. Valid values are
295 * - \ref PDMA_BURST_128
296 * - \ref PDMA_BURST_64
297 * - \ref PDMA_BURST_32
298 * - \ref PDMA_BURST_16
299 * - \ref PDMA_BURST_8
300 * - \ref PDMA_BURST_4
301 * - \ref PDMA_BURST_2
302 * - \ref PDMA_BURST_1
303 *
304 * @return None
305 *
306 * @details This function set the selected channel burst type and size.
307 */
PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32BurstType,uint32_t u32BurstSize)308 void PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
309 {
310 pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
311 pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
312 }
313
314 /**
315 * @brief Enable timeout function
316 *
317 * @param[in] pdma The pointer of the specified PDMA module
318 *
319 * @param[in] u32Mask Channel enable bits.
320 *
321 * @return None
322 *
323 * @details This function enable timeout function of the selected channel(s).
324 */
PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask)325 void PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask)
326 {
327 pdma->TOUTEN |= u32Mask;
328 }
329
330 /**
331 * @brief Disable timeout function
332 *
333 * @param[in] pdma The pointer of the specified PDMA module
334 *
335 * @param[in] u32Mask Channel enable bits.
336 *
337 * @return None
338 *
339 * @details This function disable timeout function of the selected channel(s).
340 */
PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)341 void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)
342 {
343 pdma->TOUTEN &= ~u32Mask;
344 }
345
346 /**
347 * @brief Set PDMA Timeout Count
348 *
349 * @param[in] pdma The pointer of the specified PDMA module
350 * @param[in] u32Ch The selected channel,
351 * @param[in] u32OnOff Enable/disable time out function
352 * @param[in] u32TimeOutCnt Timeout count
353 *
354 * @return None
355 *
356 * @details This function set the timeout count.
357 * @note M2L31 only supported channel 0/1.
358 */
PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32OnOff,uint32_t u32TimeOutCnt)359 void PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
360 {
361 switch(u32Ch)
362 {
363 case 0ul:
364 pdma->TOC = (pdma->TOC & ~PDMA_TOC_TOC0_Msk) | u32TimeOutCnt;
365 break;
366 case 1ul:
367 pdma->TOC = (pdma->TOC & ~PDMA_TOC_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC_TOC1_Pos);
368 break;
369 default:
370 break;
371 }
372
373 if (u32OnOff)
374 pdma->TOUTEN |= (1ul << u32Ch);
375 else
376 pdma->TOUTEN &= ~(1ul << u32Ch);
377 }
378
379 /**
380 * @brief Trigger PDMA
381 *
382 * @param[in] pdma The pointer of the specified PDMA module
383 * @param[in] u32Ch The selected channel
384 *
385 * @return None
386 *
387 * @details This function trigger the selected channel.
388 */
PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch)389 void PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch)
390 {
391 if(u8ChSelect[u32Ch] == PDMA_MEM)
392 {
393 pdma->SWREQ = (1ul << u32Ch);
394 }
395 else {}
396 }
397
398 /**
399 * @brief Enable Interrupt
400 *
401 * @param[in] pdma The pointer of the specified PDMA module
402 * @param[in] u32Ch The selected channel
403 * @param[in] u32Mask The Interrupt Type. Valid values are
404 * - \ref PDMA_INT_TRANS_DONE
405 * - \ref PDMA_INT_TEMPTY
406 * - \ref PDMA_INT_TIMEOUT
407 *
408 * @return None
409 *
410 * @details This function enable the selected channel interrupt.
411 */
PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Mask)412 void PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask)
413 {
414 switch(u32Mask)
415 {
416 case PDMA_INT_TRANS_DONE:
417 pdma->INTEN |= (1ul << u32Ch);
418 break;
419 case PDMA_INT_TEMPTY:
420 pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
421 break;
422 case PDMA_INT_TIMEOUT:
423 pdma->TOUTIEN |= (1ul << u32Ch);
424 break;
425
426 default:
427 break;
428 }
429 }
430
431 /**
432 * @brief Disable Interrupt
433 *
434 * @param[in] pdma The pointer of the specified PDMA module
435 * @param[in] u32Ch The selected channel
436 * @param[in] u32Mask The Interrupt Type. Valid values are
437 * - \ref PDMA_INT_TRANS_DONE
438 * - \ref PDMA_INT_TEMPTY
439 * - \ref PDMA_INT_TIMEOUT
440 *
441 * @return None
442 *
443 * @details This function disable the selected channel interrupt.
444 */
PDMA_DisableInt(PDMA_T * pdma,uint32_t u32Ch,uint32_t u32Mask)445 void PDMA_DisableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask)
446 {
447 switch(u32Mask)
448 {
449 case PDMA_INT_TRANS_DONE:
450 pdma->INTEN &= ~(1ul << u32Ch);
451 break;
452 case PDMA_INT_TEMPTY:
453 pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
454 break;
455 case PDMA_INT_TIMEOUT:
456 pdma->TOUTIEN &= ~(1ul << u32Ch);
457 break;
458
459 default:
460 break;
461 }
462 }
463
464 /*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
465
466 /*@}*/ /* end of group PDMA_Driver */
467
468 /*@}*/ /* end of group Standard_Driver */
469
470 /*** (C) COPYRIGHT 2023 Nuvoton Technology Corp. ***/
471