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