1 /**************************************************************************//**
2  * @file     lppdma.c
3  * @version  V1.00
4  * @brief    M2L31 series LPPDMA 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[LPPDMA_CH_MAX];
13 
14 /** @addtogroup Standard_Driver Standard Driver
15   @{
16 */
17 
18 /** @addtogroup LPPDMA_Driver LPPDMA Driver
19   @{
20 */
21 
22 
23 /** @addtogroup LPPDMA_EXPORTED_FUNCTIONS LPPDMA Exported Functions
24   @{
25 */
26 
27 /**
28  * @brief       LPPDMA Open
29  *
30  * @param[in]   lppdma            The pointer of the specified LPPDMA module
31  *
32  * @param[in]   u32Mask     Channel enable bits.
33  *
34  * @return      None
35  *
36  * @details     This function enable the LPPDMA channels.
37  */
LPPDMA_Open(LPPDMA_T * lppdma,uint32_t u32Mask)38 void LPPDMA_Open(LPPDMA_T * lppdma,uint32_t u32Mask)
39 {
40     uint32_t i;
41 
42     for (i=0UL; i < LPPDMA_CH_MAX; i++)
43     {
44         if((1 << i) & u32Mask)
45         {
46             lppdma->LPDSCT[i].CTL = 0UL;
47             u8ChSelect[i] = LPPDMA_MEM;
48         }
49     }
50 
51     lppdma->CHCTL |= u32Mask;
52 }
53 
54 /**
55  * @brief       LPPDMA Close
56  *
57  * @param[in]   lppdma            The pointer of the specified LPPDMA module
58  *
59  * @return      None
60  *
61  * @details     This function disable all LPPDMA channels.
62  */
LPPDMA_Close(LPPDMA_T * lppdma)63 void LPPDMA_Close(LPPDMA_T * lppdma)
64 {
65     lppdma->CHCTL = 0UL;
66 }
67 
68 /**
69  * @brief       Set LPPDMA Transfer Count
70  *
71  * @param[in]   lppdma            The pointer of the specified LPPDMA module
72  * @param[in]   u32Ch           The selected channel
73  * @param[in]   u32Width        Data width. Valid values are
74  *                - \ref LPPDMA_WIDTH_8
75  *                - \ref LPPDMA_WIDTH_16
76  *                - \ref LPPDMA_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  */
LPPDMA_SetTransferCnt(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32Width,uint32_t u32TransCount)83 void LPPDMA_SetTransferCnt(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
84 {
85     lppdma->LPDSCT[u32Ch].CTL &= ~(LPPDMA_DSCT_CTL_TXCNT_Msk | LPPDMA_DSCT_CTL_TXWIDTH_Msk);
86     lppdma->LPDSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << LPPDMA_DSCT_CTL_TXCNT_Pos));
87 }
88 
89 /**
90  * @brief       Set LPPDMA Transfer Address
91   *
92  * @param[in]   lppdma            The pointer of the specified LPPDMA 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 LPPDMA_SAR_INC
97  *                - \ref LPPDMA_SAR_FIX
98  * @param[in]   u32DstAddr      Destination address
99  * @param[in]   u32DstCtrl      Destination control attribute. Valid values are
100  *                - \ref LPPDMA_DAR_INC
101  *                - \ref LPPDMA_DAR_FIX
102  *
103  * @return      None
104  *
105  * @details     This function set the selected channel source/destination address and attribute.
106  */
LPPDMA_SetTransferAddr(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32SrcAddr,uint32_t u32SrcCtrl,uint32_t u32DstAddr,uint32_t u32DstCtrl)107 void LPPDMA_SetTransferAddr(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
108 {
109     lppdma->LPDSCT[u32Ch].SA = u32SrcAddr;
110     lppdma->LPDSCT[u32Ch].DA = u32DstAddr;
111     lppdma->LPDSCT[u32Ch].CTL &= ~(LPPDMA_DSCT_CTL_SAINC_Msk | LPPDMA_DSCT_CTL_DAINC_Msk);
112     lppdma->LPDSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
113 }
114 
115 /**
116  * @brief       Set LPPDMA Transfer Mode
117   *
118  * @param[in]   lppdma            The pointer of the specified LPPDMA module
119  * @param[in]   u32Ch           The selected channel
120  * @param[in]   u32Peripheral   The selected peripheral. Valid values are
121  *                - \ref LPPDMA_MEM
122  *                - \ref LPPDMA_LPUART0_TX
123  *                - \ref LPPDMA_LPUART0_RX
124  *                - \ref LPPDMA_LPSPI0_TX
125  *                - \ref LPPDMA_LPSPI0_RX
126  *                - \ref LPPDMA_LPI2C0_TX
127  *                - \ref LPPDMA_LPI2C0_RX
128  *                - \ref LPPDMA_LPTMR0
129  *                - \ref LPPDMA_LPTMR1
130  *                - \ref LPPDMA_TTMR0
131  *                - \ref LPPDMA_TTMR1
132  *                - \ref LPPDMA_LPADC0_RX
133  *                - \ref LPPDMA_ACMP0
134  *                - \ref LPPDMA_ACMP1
135  *                - \ref LPPDMA_ACMP2
136  * @param[in]   u32ScatterEn    Scatter-gather mode enable
137  * @param[in]   u32DescAddr     Scatter-gather descriptor address
138  *
139  * @return      None
140  *
141  * @details     This function set the selected channel transfer mode. Include peripheral setting.
142  */
LPPDMA_SetTransferMode(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32Peripheral,uint32_t u32ScatterEn,uint32_t u32DescAddr)143 void LPPDMA_SetTransferMode(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
144 {
145     u8ChSelect[u32Ch] = u32Peripheral;
146     switch(u32Ch)
147     {
148     case 0ul:
149         lppdma->REQSEL0_3 = (lppdma->REQSEL0_3 & ~LPPDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral;
150         break;
151     case 1ul:
152         lppdma->REQSEL0_3 = (lppdma->REQSEL0_3 & ~LPPDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << LPPDMA_REQSEL0_3_REQSRC1_Pos);
153         break;
154     case 2ul:
155         lppdma->REQSEL0_3 = (lppdma->REQSEL0_3 & ~LPPDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << LPPDMA_REQSEL0_3_REQSRC2_Pos);
156         break;
157     case 3ul:
158         lppdma->REQSEL0_3 = (lppdma->REQSEL0_3 & ~LPPDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << LPPDMA_REQSEL0_3_REQSRC3_Pos);
159         break;
160     default:
161         break;
162     }
163 
164     if(u32ScatterEn)
165     {
166         lppdma->LPDSCT[u32Ch].CTL = (lppdma->LPDSCT[u32Ch].CTL & ~LPPDMA_DSCT_CTL_OPMODE_Msk) | LPPDMA_OP_SCATTER;
167         lppdma->LPDSCT[u32Ch].NEXT = u32DescAddr - (lppdma->SCATBA);
168     }
169     else
170     {
171         lppdma->LPDSCT[u32Ch].CTL = (lppdma->LPDSCT[u32Ch].CTL & ~LPPDMA_DSCT_CTL_OPMODE_Msk) | LPPDMA_OP_BASIC;
172     }
173 }
174 
175 /**
176  * @brief       Set LPPDMA Burst Type and Size
177  *
178  * @param[in]   lppdma            The pointer of the specified LPPDMA module
179  * @param[in]   u32Ch           The selected channel
180  * @param[in]   u32BurstType    Burst mode or single mode. Valid values are
181  *                - \ref LPPDMA_REQ_SINGLE
182  *                - \ref LPPDMA_REQ_BURST
183  * @param[in]   u32BurstSize    Set the size of burst mode. Valid values are
184  *                - \ref LPPDMA_BURST_128
185  *                - \ref LPPDMA_BURST_64
186  *                - \ref LPPDMA_BURST_32
187  *                - \ref LPPDMA_BURST_16
188  *                - \ref LPPDMA_BURST_8
189  *                - \ref LPPDMA_BURST_4
190  *                - \ref LPPDMA_BURST_2
191  *                - \ref LPPDMA_BURST_1
192  *
193  * @return      None
194  *
195  * @details     This function set the selected channel burst type and size.
196  */
LPPDMA_SetBurstType(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32BurstType,uint32_t u32BurstSize)197 void LPPDMA_SetBurstType(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
198 {
199     lppdma->LPDSCT[u32Ch].CTL &= ~(LPPDMA_DSCT_CTL_TXTYPE_Msk | LPPDMA_DSCT_CTL_BURSIZE_Msk);
200     lppdma->LPDSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
201 }
202 
203 /**
204  * @brief       Trigger LPPDMA
205  *
206  * @param[in]   lppdma            The pointer of the specified LPPDMA module
207  * @param[in]   u32Ch           The selected channel
208  *
209  * @return      None
210  *
211  * @details     This function trigger the selected channel.
212  */
LPPDMA_Trigger(LPPDMA_T * lppdma,uint32_t u32Ch)213 void LPPDMA_Trigger(LPPDMA_T * lppdma,uint32_t u32Ch)
214 {
215     if(u8ChSelect[u32Ch] == LPPDMA_MEM)
216     {
217         lppdma->SWREQ = (1ul << u32Ch);
218     }
219     else {}
220 }
221 
222 /**
223  * @brief       Enable Interrupt
224  *
225  * @param[in]   lppdma            The pointer of the specified LPPDMA module
226  * @param[in]   u32Ch           The selected channel
227  * @param[in]   u32Mask         The Interrupt Type. Valid values are
228  *                - \ref LPPDMA_INT_TRANS_DONE
229  *                - \ref LPPDMA_INT_TEMPTY
230  *
231  * @return      None
232  *
233  * @details     This function enable the selected channel interrupt.
234  */
LPPDMA_EnableInt(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32Mask)235 void LPPDMA_EnableInt(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32Mask)
236 {
237     switch(u32Mask)
238     {
239     case LPPDMA_INT_TRANS_DONE:
240         lppdma->INTEN |= (1ul << u32Ch);
241         break;
242     case LPPDMA_INT_TEMPTY:
243         lppdma->LPDSCT[u32Ch].CTL &= ~LPPDMA_DSCT_CTL_TBINTDIS_Msk;
244         break;
245 
246     default:
247         break;
248     }
249 }
250 
251 /**
252  * @brief       Disable Interrupt
253  *
254  * @param[in]   lppdma            The pointer of the specified LPPDMA module
255  * @param[in]   u32Ch           The selected channel
256  * @param[in]   u32Mask         The Interrupt Type. Valid values are
257  *                - \ref LPPDMA_INT_TRANS_DONE
258  *                - \ref LPPDMA_INT_TEMPTY
259  *
260  * @return      None
261  *
262  * @details     This function disable the selected channel interrupt.
263  */
LPPDMA_DisableInt(LPPDMA_T * lppdma,uint32_t u32Ch,uint32_t u32Mask)264 void LPPDMA_DisableInt(LPPDMA_T * lppdma,uint32_t u32Ch, uint32_t u32Mask)
265 {
266     switch(u32Mask)
267     {
268     case LPPDMA_INT_TRANS_DONE:
269         lppdma->INTEN &= ~(1ul << u32Ch);
270         break;
271     case LPPDMA_INT_TEMPTY:
272         lppdma->LPDSCT[u32Ch].CTL |= LPPDMA_DSCT_CTL_TBINTDIS_Msk;
273         break;
274 
275     default:
276         break;
277     }
278 }
279 
280 /*@}*/ /* end of group LPPDMA_EXPORTED_FUNCTIONS */
281 
282 /*@}*/ /* end of group LPPDMA_Driver */
283 
284 /*@}*/ /* end of group Standard_Driver */
285 
286 /*** (C) COPYRIGHT 2023 Nuvoton Technology Corp. ***/
287