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