1 /*******************************************************************************
2 * @file rsi_ulpss_clk.c
3 *******************************************************************************
4 * # License
5 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6 *******************************************************************************
7 *
8 * SPDX-License-Identifier: Zlib
9 *
10 * The licensor of this software is Silicon Laboratories Inc.
11 *
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software
22 * in a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 * 2. Altered source versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *
28 ******************************************************************************/
29
30 // Includes
31
32 #include "rsi_ccp_user_config.h"
33 #include "rsi_rom_ulpss_clk.h"
34 #ifndef ULPSS_CLOCK_ROMDRIVER_PRESENT
35 /** @addtogroup SOC3
36 * @{
37 */
38 /*==============================================*/
39 /**
40 * @fn rsi_error_t ulpss_clock_config(M4CLK_Type *pCLK, boolean_t clkEnable, uint16_t divFactor, boolean_t oddDivFactor)
41 * @brief This API is used to select the ULPSS processor clock source when input is soc clk source which is greater than 100MHz
42 * @param[in] pCLK : pointer to the processor clock source
43 * @param[in] clkEnable : clock enable for clock source
44 * @param[in] divFactor : division factor for clock to configure Reg 4
45 * @param[in] oddDivFactor : odd divison factor for clock to configure Reg 5
46 * @return RSI_OK on success
47 */
48
ulpss_clock_config(M4CLK_Type * pCLK,boolean_t clkEnable,uint16_t divFactor,boolean_t oddDivFactor)49 rsi_error_t ulpss_clock_config(M4CLK_Type *pCLK, boolean_t clkEnable, uint16_t divFactor, boolean_t oddDivFactor)
50 {
51 if (pCLK == NULL) {
52 return INVALID_PARAMETERS;
53 }
54 if (clkEnable == Enable) {
55 pCLK->CLK_CONFIG_REG4_b.ULPSS_CLK_DIV_FAC = (unsigned int)(divFactor & 0x3F);
56 pCLK->CLK_CONFIG_REG5_b.ULPSS_ODD_DIV_SEL = (unsigned int)(oddDivFactor & 0x01);
57 pCLK->CLK_ENABLE_SET_REG1 = ULPSS_CLK_ENABLE;
58 } else {
59 pCLK->CLK_ENABLE_CLEAR_REG1 = ULPSS_CLK_ENABLE;
60 }
61 return RSI_OK;
62 }
63
64 /*==============================================*/
65 /**
66 * @fn rsi_error_t ulpss_ulp_peri_clk_enable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
67 * @brief This API is used to enable different peripherial clocks in ULPSS
68 * @param[in] pULPCLK : pointer to the processor ULP clock
69 * @param[in] u32Flags : flags for perpheral clocks
70 * @return RSI_OK on success
71 */
72
ulpss_ulp_peri_clk_enable(ULPCLK_Type * pULPCLK,uint32_t u32Flags)73 rsi_error_t ulpss_ulp_peri_clk_enable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
74 {
75 if (pULPCLK == NULL) {
76 return INVALID_PARAMETERS;
77 }
78 pULPCLK->ULP_MISC_SOFT_SET_REG = (pULPCLK->ULP_MISC_SOFT_SET_REG | u32Flags) & 0xFFFFFFFF;
79 return RSI_OK;
80 }
81
82 /*==============================================*/
83 /**
84 * @fn rsi_error_t ulpss_ulp_peri_clk_disable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
85 * @brief This API is used to disable different peripherial clocks in ULPSS
86 * @param[in] pULPCLK : pointer to the processor ULP clock source
87 * @param[in] u32Flags : flags for peripheral clocks
88 * @return RSI_OK on success
89 */
90
ulpss_ulp_peri_clk_disable(ULPCLK_Type * pULPCLK,uint32_t u32Flags)91 rsi_error_t ulpss_ulp_peri_clk_disable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
92 {
93 if (pULPCLK == NULL) {
94 return INVALID_PARAMETERS;
95 }
96 pULPCLK->ULP_MISC_SOFT_SET_REG = (pULPCLK->ULP_MISC_SOFT_SET_REG & ~u32Flags) & 0xFFFFFFFF;
97 return RSI_OK;
98 }
99
100 /*==============================================*/
101 /**
102 * @fn rsi_error_t ulpss_ulp_dyn_clk_enable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
103 * @brief This API is used to enable different dynamic clocks in ULPSS
104 * @param[in] pULPCLK : pointer to the processor ULP clock source
105 * @param[in] u32Flags : flags for dynamic clocks
106 * @return RSI_OK on success
107 */
108
ulpss_ulp_dyn_clk_enable(ULPCLK_Type * pULPCLK,uint32_t u32Flags)109 rsi_error_t ulpss_ulp_dyn_clk_enable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
110 {
111 if (pULPCLK == NULL) {
112 return INVALID_PARAMETERS;
113 }
114 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE = (pULPCLK->ULP_DYN_CLK_CTRL_DISABLE | u32Flags) & 0xFFFFFFFF;
115 return RSI_OK;
116 }
117
118 /*==============================================*/
119 /**
120 * @fn rsi_error_t ulpss_ulp_dyn_clk_disable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
121 * @brief This API is used to disable different dynamic clocks in ULPSS
122 * @param[in] pULPCLK : pointer to the processor ULP clock source
123 * @param[in] u32Flags : flags for dynamic clocks
124 * @return RSI_OK on success
125 */
126
ulpss_ulp_dyn_clk_disable(ULPCLK_Type * pULPCLK,uint32_t u32Flags)127 rsi_error_t ulpss_ulp_dyn_clk_disable(ULPCLK_Type *pULPCLK, uint32_t u32Flags)
128 {
129 if (pULPCLK == NULL) {
130 return INVALID_PARAMETERS;
131 }
132 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE = (pULPCLK->ULP_DYN_CLK_CTRL_DISABLE & ~u32Flags) & 0xFFFFFFFF;
133 return RSI_OK;
134 }
135
136 /*==============================================*/
137 /**
138 * @fn rsi_error_t ulpss_ulp_ssi_clk_config(ULPCLK_Type *pULPCLK,
139 * CLK_ENABLE_T clkType,
140 * ULP_SSI_CLK_SELECT_T clkSource,
141 * uint16_t divFactor)
142 * @brief This API is used to configure the SSI clock source
143 * @param[in] pULPCLK : pointer to the processor ULP clock source
144 * @param[in] clkType : clock type for SSI clock source
145 * @param[in] clkSource : clock source for ULP SSI
146 * @param[in] divFactor : divison factor for ULP SSI
147 * @return RSI_OK on success
148 */
149
ulpss_ulp_ssi_clk_config(ULPCLK_Type * pULPCLK,CLK_ENABLE_T clkType,ULP_SSI_CLK_SELECT_T clkSource,uint16_t divFactor)150 rsi_error_t ulpss_ulp_ssi_clk_config(ULPCLK_Type *pULPCLK,
151 CLK_ENABLE_T clkType,
152 ULP_SSI_CLK_SELECT_T clkSource,
153 uint16_t divFactor)
154 {
155 /*Parameter validation */
156 if ((pULPCLK == NULL) || (divFactor > ULP_SSI_MAX_DIVISION_FACTOR) || (clkSource > ULP_SSI_MAX_SEL)) {
157 return INVALID_PARAMETERS;
158 }
159
160 ulpss_peripheral_disable(pULPCLK, ULP_SSI_CLK);
161 /*Select */
162 switch (clkSource) {
163 /*0: ref_clk (output of dynamic clock MUX for different possible ref_clk sources)*/
164 case ULP_SSI_REF_CLK:
165 /*Enable clock*/
166 ulpss_enable_ref_clks(MCU_ULP_40MHZ_CLK_EN, ULP_PERIPHERAL_CLK, 0);
167 /*Select clock MUX */
168 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
169 break;
170 /*1: ulp_32khz_ro_clk */
171 case ULP_SSI_ULP_32KHZ_RO_CLK:
172 /*Enable clock*/
173 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
174 /*Select clock MUX */
175 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
176 break;
177 /*2: ulp_32khz_rc_clk*/
178 case ULP_SSI_ULP_32KHZ_RC_CLK:
179 /*Enable clock*/
180 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
181 /*Select clock MUX */
182 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
183 break;
184 /*3: ulp_32khz_xtal_clk*/
185 case ULP_SSI_ULP_32KHZ_XTAL_CLK:
186 /*Enable clock*/
187 /*NOTE: In order to enable the Xtal clk source need to configure the NPSS_GPIO pins
188 which can be done through clk_xtal_clk_config(uint8_t xtalPin) API i.e we need to call that API first*/
189 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
190 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
191 break;
192 /*4: ulp_mhz_rc_clk*/
193 case ULP_SSI_ULP_MHZ_RC_CLK:
194 /*Enable clock*/
195 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
196 /*Select clock MUX */
197 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
198 break;
199 /*5: ulp_20mhz_ro_clk*/
200 case ULP_SSI_ULP_20MHZ_RO_CLK:
201 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
202 /*Select clock MUX */
203 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
204 break;
205 case ULP_SSI_SOC_CLK:
206 /*6: soc_clk*/
207 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_SEL = clkSource;
208 break;
209
210 default:
211 return INVALID_PARAMETERS;
212 }
213
214 /* Wait for clock switched */
215 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_SSI_b != 1)
216 ;
217
218 /*Update the division factor */
219 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_DIV_FACTOR = (unsigned int)(divFactor & 0x7F);
220
221 ulpss_peripheral_enable(pULPCLK, ULP_SSI_CLK, clkType);
222 return RSI_OK;
223 }
224
225 /*==============================================*/
226 /**
227 * @fn rsi_error_t ulpss_ulp_i2s_clk_config(ULPCLK_Type *pULPCLK, ULP_I2S_CLK_SELECT_T clkSource, uint16_t divFactor)
228 * @brief This API is used to configure the I2S clock source
229 * @param[in] pULPCLK : pointer to the processor ULP clock source
230 * @param[in] clkType : clock type for ULP I2S
231 * @param[in] clkSource : clock source for ULP I2S
232 * @param[in] divFactor : divison factor for ULP I2S
233 * @return RSI_OK on success
234 */
235
ulpss_ulp_i2s_clk_config(ULPCLK_Type * pULPCLK,ULP_I2S_CLK_SELECT_T clkSource,uint16_t divFactor)236 rsi_error_t ulpss_ulp_i2s_clk_config(ULPCLK_Type *pULPCLK, ULP_I2S_CLK_SELECT_T clkSource, uint16_t divFactor)
237 {
238 /*Parameter validation */
239 if ((pULPCLK == NULL) || (divFactor > ULP_I2S_MAX_DIVISION_FACTOR) || (clkSource > ULP_I2S_MAX_SEL)) {
240 return INVALID_PARAMETERS;
241 }
242 ulpss_peripheral_disable(pULPCLK, ULP_I2S_CLK);
243 /*Select */
244 switch (clkSource) {
245 /*0: ref_clk (output of dynamic clock MUX for different possible ref_clk sources)*/
246 case ULP_I2S_REF_CLK:
247 /*Select clock MUX */
248 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
249 break;
250 /*1: ulp_32khz_ro_clk */
251 case ULP_I2S_ULP_32KHZ_RO_CLK:
252 /*Enable clock*/
253 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
254 /*Select clock MUX */
255 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
256 break;
257 /*2: ulp_32khz_rc_clk*/
258 case ULP_I2S_ULP_32KHZ_RC_CLK:
259 /*Enable clock*/
260 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
261 /*Select clock MUX */
262 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
263 break;
264 /*3: ulp_32khz_xtal_clk*/
265 case ULP_I2S_ULP_32KHZ_XTAL_CLK:
266 /*Enable clock*/
267 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
268 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
269 break;
270 /*4: ulp_mhz_rc_clk*/
271 case ULP_I2S_ULP_MHZ_RC_CLK:
272 /*Enable clock*/
273 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
274 /*Select clock MUX */
275 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
276 break;
277 /*5: ulp_20mhz_ro_clk*/
278 case ULP_I2S_ULP_20MHZ_RO_CLK:
279 /*Enable clock*/
280 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
281 /*Select clock MUX */
282 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
283 break;
284 case ULP_I2S_SOC_CLK:
285 /*6: soc_clk*/
286 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
287 break;
288 case ULP_I2S_ULP_DOUBLER_CLK:
289 /*7: ulp_doubler_clk*/
290 ulpss_enable_ref_clks(MCU_ULP_DOUBLER_CLK_EN, ULP_PERIPHERAL_CLK, 0);
291 /*Select clock MUX */
292 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
293 break;
294
295 case ULP_I2S_PLL_CLK:
296 /*I2s clock*/
297 if (M4CLK->PLL_STAT_REG_b.I2SPLL_LOCK == 0) {
298 return ERROR_CLOCK_NOT_ENABLED;
299 }
300 /*NOTE: this clock source is not valid in PS2 state. PLL is turned off in PS2*/
301 M4CLK->CLK_CONFIG_REG5_b.I2S_CLK_SEL = 0;
302 /*Select clock MUX */
303 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_SEL_b = clkSource;
304 break;
305 default:
306 return INVALID_PARAMETERS;
307 }
308
309 /* Wait for clock switched */
310 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_I2S_CLK_b != 1U)
311 ;
312
313 /*Set the division factor */
314 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLKDIV_FACTOR = (uint8_t)divFactor;
315
316 ulpss_peripheral_enable(pULPCLK, ULP_I2S_CLK, ENABLE_STATIC_CLK);
317
318 return RSI_OK;
319 }
320
321 /*==============================================*/
322 /**
323 * @fn rsi_error_t ulpss_ulp_uar_clk_config(ULPCLK_Type *pULPCLK,
324 * CLK_ENABLE_T clkType,
325 * boolean_t bFrClkSel,
326 * ULP_UART_CLK_SELECT_T clkSource,
327 * uint16_t divFactor)
328 * @brief This API is used to configure the UART clock source
329 * @param[in] pULPCLK : pointer to the processor ULP clock source
330 * @param[in] clkType : clock type for UART
331 * @param[in] bFrClkSel : fractional clock select for ULP UART
332 * @param[in] clkSource : clock source for ULP UART
333 * @param[in] divFactor : divison factor for ULP UART
334 * @return RSI_OK on success
335 */
336
ulpss_ulp_uar_clk_config(ULPCLK_Type * pULPCLK,CLK_ENABLE_T clkType,boolean_t bFrClkSel,ULP_UART_CLK_SELECT_T clkSource,uint16_t divFactor)337 rsi_error_t ulpss_ulp_uar_clk_config(ULPCLK_Type *pULPCLK,
338 CLK_ENABLE_T clkType,
339 boolean_t bFrClkSel,
340 ULP_UART_CLK_SELECT_T clkSource,
341 uint16_t divFactor)
342 {
343 /*Parameter validation */
344 if ((pULPCLK == NULL) || (divFactor > ULP_UART_MAX_DIVISION_FACTOR) || (clkSource > ULP_UART_MAX_SEL)) {
345 return INVALID_PARAMETERS;
346 }
347 ulpss_peripheral_disable(pULPCLK, ULP_UART_CLK);
348 /*UART Fractional clock select */
349 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_FRAC_CLK_SEL_b = (unsigned int)(bFrClkSel & 0x01);
350
351 /*Select */
352 switch (clkSource) {
353 /*0: ref_clk (output of dynamic clock MUX for different possible ref_clk sources)*/
354 case ULP_UART_REF_CLK:
355 /*Configure the ULPSS reference clock from NPSS clock MUX this is common for all these Sources */
356 /*Select clock MUX */
357 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
358 break;
359 /*1: ulp_32khz_ro_clk */
360 case ULP_UART_ULP_32KHZ_RO_CLK:
361 /*Enable clock*/
362 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
363 /*Select clock MUX */
364 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
365 break;
366 /*2: ulp_32khz_rc_clk*/
367 case ULP_UART_ULP_32KHZ_RC_CLK:
368 /*Enable clock*/
369 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
370 /*Select clock MUX */
371 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
372 break;
373 /*3: ulp_32khz_xtal_clk*/
374 case ULP_UART_ULP_32KHZ_XTAL_CLK:
375 /*Enable clock*/
376 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
377 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
378 break;
379 /*4: ulp_mhz_rc_clk*/
380 case ULP_UART_ULP_MHZ_RC_CLK:
381 /*Enable clock*/
382 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
383 /*Select clock MUX */
384 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
385 break;
386 /*5: ulp_20mhz_ro_clk*/
387 case ULP_UART_ULP_20MHZ_RO_CLK:
388 /*Enable clock*/
389 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
390 /*Select clock MUX */
391 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
392 break;
393 case ULP_UART_SOC_CLK:
394 /*6: soc_clk*/
395 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
396 break;
397 case ULP_UART_ULP_DOUBLER_CLK:
398 /*7: ulp_doubler_clk*/
399 ulpss_enable_ref_clks(MCU_ULP_DOUBLER_CLK_EN, ULP_PERIPHERAL_CLK, 0);
400 /*Select clock MUX */
401 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLK_SEL = clkSource;
402 break;
403 default:
404 return INVALID_PARAMETERS;
405 }
406
407 /* Wait for clock switched */
408 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_UART_CLK_b != 1U)
409 ;
410
411 pULPCLK->ULP_UART_CLK_GEN_REG_b.ULP_UART_CLKDIV_FACTOR = (unsigned int)(divFactor & 0x07);
412
413 ulpss_peripheral_enable(pULPCLK, ULP_UART_CLK, clkType);
414 return RSI_OK;
415 }
416
417 /*==============================================*/
418 /**
419 * @fn rsi_error_t ulpss_time_clk_config(ULPCLK_Type *pULPCLK,
420 * CLK_ENABLE_T clkType,
421 * boolean_t bTmrSync,
422 * ULP_TIMER_CLK_SELECT_T clkSource,
423 * uint8_t skipSwitchTime)
424 * @brief This API is used to configure the timer clock source
425 * @param[in] pULPCLK : pointer to the processor ULP clock source
426 * @param[in] clkType : clock type for timer
427 * @param[in] bTmrSync : Timer Synchronisation for ULP timer
428 * @param[in] clkSource : clock source for ULP timer
429 * @param[in] skipSwitchTime : wait for clock switched for ULP timer
430 * @return RSI_OK on success
431 */
432
ulpss_time_clk_config(ULPCLK_Type * pULPCLK,CLK_ENABLE_T clkType,boolean_t bTmrSync,ULP_TIMER_CLK_SELECT_T clkSource,uint8_t skipSwitchTime)433 rsi_error_t ulpss_time_clk_config(ULPCLK_Type *pULPCLK,
434 CLK_ENABLE_T clkType,
435 boolean_t bTmrSync,
436 ULP_TIMER_CLK_SELECT_T clkSource,
437 uint8_t skipSwitchTime)
438 {
439 /*Parameter validation */
440 if ((pULPCLK == NULL) || (clkSource > ULP_TIMER_MAX_SEL)) {
441 return INVALID_PARAMETERS;
442 }
443 /*Timer PCLK enable */
444 ulpss_peripheral_disable(pULPCLK, ULP_TIMER_CLK);
445
446 if (bTmrSync) {
447 /*Enable m4 core clock*/
448 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_IN_SYNC_b = 1;
449 } else {
450 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_IN_SYNC_b = 0;
451 }
452 /*clock select*/
453 switch (clkSource) {
454 case ULP_TIMER_REF_CLK:
455 /*Select clock MUX */
456 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
457 break;
458 /*1: ulp_32khz_ro_clk */
459 case ULP_TIMER_32KHZ_RO_CLK:
460 /*Enable clock*/
461 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
462 /*Select clock MUX */
463 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
464 break;
465 /*2: ulp_32khz_rc_clk*/
466 case ULP_TIMER_32KHZ_RC_CLK:
467 /*Enable clock*/
468 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
469 /*Select clock MUX */
470 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
471 break;
472 /*3: ulp_32khz_xtal_clk*/
473 case ULP_TIMER_32KHZ_XTAL_CLK:
474 /*Enable clock*/
475 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
476
477 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
478 break;
479 /*4: ulp_mhz_rc_clk*/
480 case ULP_TIMER_MHZ_RC_CLK:
481 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
482
483 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
484 break;
485 /*5: ulp_20mhz_ro_clk*/
486 case ULP_TIMER_20MHZ_RO_CLK:
487 /*Enable clock*/
488 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
489 /*Select clock MUX */
490 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
491 break;
492 case ULP_TIMER_ULP_SOC_CLK:
493 /*6: soc_clk*/
494 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = clkSource;
495 break;
496 default:
497 return INVALID_PARAMETERS;
498 }
499 if (skipSwitchTime == 1) {
500 /* Wait for clock switched */
501 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_TIMER_b != 1U)
502 ;
503 }
504 ulpss_peripheral_enable(pULPCLK, ULP_TIMER_CLK, clkType);
505 return RSI_OK;
506 }
507
508 /*==============================================*/
509 /**
510 * @fn rsi_error_t ulpss_aux_clk_config(ULPCLK_Type *pULPCLK, CLK_ENABLE_T clkType, ULP_AUX_CLK_SELECT_T clkSource)
511 * @brief This API is used to configure the AUX clock source
512 * @param[in] pULPCLK : pointer to the processor ULP clock source
513 * @param[in] clkType : clock type for AUX
514 * @param[in] clkSource : clock source for AUX
515 * @return RSI_OK on success
516 */
517
ulpss_aux_clk_config(ULPCLK_Type * pULPCLK,CLK_ENABLE_T clkType,ULP_AUX_CLK_SELECT_T clkSource)518 rsi_error_t ulpss_aux_clk_config(ULPCLK_Type *pULPCLK, CLK_ENABLE_T clkType, ULP_AUX_CLK_SELECT_T clkSource)
519 {
520 /*Parameter validation */
521 if ((pULPCLK == NULL) || (clkSource > ULP_AUX_MAX_SEL)) {
522 return INVALID_PARAMETERS;
523 }
524 ulpss_peripheral_disable(pULPCLK, ULP_AUX_CLK);
525
526 /*select clock MUX */
527
528 /*Select */
529 switch (clkSource) {
530 /*0: ref_clk (output of dynamic clock MUX for different possible ref_clk sources)*/
531 case ULP_AUX_REF_CLK:
532 /*Select clock MUX */
533 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
534 break;
535 /*1: ulp_32khz_ro_clk */
536 case ULP_AUX_32KHZ_RO_CLK:
537 /*Enable clock*/
538 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
539 /*Select clock MUX */
540 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
541 break;
542 /*2: ulp_32khz_rc_clk*/
543 case ULP_AUX_32KHZ_RC_CLK:
544 /*Enable clock*/
545 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
546 /*Select clock MUX */
547 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
548 break;
549 /*3: ulp_32khz_xtal_clk*/
550 case ULP_AUX_32KHZ_XTAL_CLK:
551 /*Enable clock*/
552 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
553 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
554 break;
555 /*4: ulp_mhz_rc_clk*/
556 case ULP_AUX_MHZ_RC_CLK:
557 /*Enable clock*/
558 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
559 /*Select clock MUX */
560 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
561 break;
562 /*5: ulp_20mhz_ro_clk*/
563 case ULP_AUX_20MHZ_RO_CLK:
564 /*Enable clock*/
565 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
566 /*Select clock MUX */
567 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
568 break;
569 case ULP_AUX_ULP_SOC_CLK:
570 /*6: soc_clk*/
571 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
572 break;
573 case ULP_AUX_ULP_DOUBLER_CLK:
574 /*7: ulp_doubler_clk*/
575 /*Enable clock*/
576 ulpss_enable_ref_clks(MCU_ULP_DOUBLER_CLK_EN, ULP_PERIPHERAL_CLK, 0);
577 /*Select clock MUX */
578 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
579 break;
580 case ULP_AUX_I2S_PLL_CLK:
581 /*8: i2s_pll_clk*/
582 if (M4CLK->PLL_STAT_REG_b.I2SPLL_LOCK == 0) {
583 return ERROR_CLOCK_NOT_ENABLED;
584 }
585 /*Enable clock*/
586 M4CLK->CLK_CONFIG_REG5_b.I2S_CLK_SEL = 0;
587 /*Select clock MUX */
588 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_SEL = clkSource;
589 break;
590 default:
591 return INVALID_PARAMETERS;
592 }
593
594 /* wait for clock switched */
595 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_AUXADC_b != 1U)
596 ;
597
598 ulpss_peripheral_enable(pULPCLK, ULP_AUX_CLK, clkType);
599
600 return RSI_OK;
601 }
602
603 /*==============================================*/
604 /**
605 * @fn rsi_error_t ulpss_vad_clk_config(ULPCLK_Type *pULPCLK,
606 * ULP_VAD_CLK_SELECT_T clkSource,
607 * ULP_VAD_FCLK_SELECT_T FclkSource,
608 * uint16_t divFactor)
609 * @brief This API is used to configure the VAD clock source
610 * @param[in] pULPCLK : pointer to the processor ULP clock source
611 * @param[in] clkSource : clock source for ULP VAD
612 * @param[in] FclkSource : fast clock cource for ULP VAD
613 * @param[in] divFactor : divison factor for ULP VAD
614 * @return RSI_OK on success
615 */
616
ulpss_vad_clk_config(ULPCLK_Type * pULPCLK,ULP_VAD_CLK_SELECT_T clkSource,ULP_VAD_FCLK_SELECT_T FclkSource,uint16_t divFactor)617 rsi_error_t ulpss_vad_clk_config(ULPCLK_Type *pULPCLK,
618 ULP_VAD_CLK_SELECT_T clkSource,
619 ULP_VAD_FCLK_SELECT_T FclkSource,
620 uint16_t divFactor)
621 {
622 /* Parameter validation */
623 if (pULPCLK == NULL || divFactor >= ULP_VAD_MAX_DIVISION_FACTOR || clkSource > ULP_VAD_MAX_SEL
624 || FclkSource > ULP_VAD_FCLK_MAX_SEL) {
625 return INVALID_PARAMETERS;
626 }
627
628 ulpss_peripheral_disable(pULPCLK, ULP_VAD_CLK);
629 /*Select the VAD clock MUX */
630 switch (clkSource) {
631 case ULP_VAD_32KHZ_RO_CLK:
632 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLK_SEL = clkSource;
633 break;
634 case ULP_VAD_32KHZ_RC_CLK:
635 /*1:ulp_32khz_rc_clk */
636 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
637 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLK_SEL = clkSource;
638 break;
639 case ULP_VAD_32KHZ_XTAL_CLK:
640 /*2: ulp_32khz_xtal_clk*/
641 /*Enable clock*/
642 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
643 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLK_SEL = clkSource;
644 break;
645 default:
646 return INVALID_PARAMETERS;
647 }
648 /*Select the VAD Fast clock MUX */
649 switch (FclkSource) {
650 case ULP_VAD_ULP_PROCESSOR_CLK:
651 /* ulpss processor clock */
652 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_SEL = FclkSource;
653 break;
654 case ULP_VAD_REF_CLK:
655 /*1: ref_clk */
656 /*Enable clock*/
657 ulpss_enable_ref_clks(MCU_ULP_40MHZ_CLK_EN, ULP_PERIPHERAL_CLK, 0);
658 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_SEL = FclkSource;
659 break;
660 case ULP_VAD_MHZ_RC_CLK:
661 /*2: ulp_mhz_rc_clk*/
662 /*Enable clock*/
663 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
664 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_SEL = FclkSource;
665 break;
666 case ULP_VAD_20MHZ_RO_CLK:
667 /*3: ulp_20mhz_ro_clk*/
668 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
669 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_SEL = FclkSource;
670 break;
671 case ULP_VAD_ULP_SOC_CLK:
672 /*4: soc_clk*/
673 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_SEL = FclkSource;
674 break;
675 default:
676 return INVALID_PARAMETERS;
677 }
678
679 /*wait for clock switched */
680 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_FCLK_VAD_b != 1U)
681 ;
682 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_SCLK_VAD_b != 1U)
683 ;
684 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_VAD_b != 1U)
685 ;
686 /*Set VAD clock division factor */
687 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLKDIV_FACTOR = (uint8_t)divFactor;
688
689 ulpss_peripheral_enable(pULPCLK, ULP_VAD_CLK, ENABLE_STATIC_CLK);
690
691 return RSI_OK;
692 }
693
694 /*==============================================*/
695 /**
696 * @fn rsi_error_t ulpss_touch_clk_config(ULPCLK_Type *pULPCLK, ULP_TOUCH_CLK_SELECT_T clkSource, uint16_t divFactor)
697 * @brief This API is used to configure the Touch clock source
698 * @param[in] pULPCLK : pointer to the processor ULP clock source
699 * @param[in] clkSource : clock source for ULP Touch
700 * @param[in] divFactor : divison factor for ULP Touch
701 * @return RSI_OK on success
702 */
703
ulpss_touch_clk_config(ULPCLK_Type * pULPCLK,ULP_TOUCH_CLK_SELECT_T clkSource,uint16_t divFactor)704 rsi_error_t ulpss_touch_clk_config(ULPCLK_Type *pULPCLK, ULP_TOUCH_CLK_SELECT_T clkSource, uint16_t divFactor)
705 {
706 /*Parameter validation */
707 if ((pULPCLK == NULL) || (divFactor > ULP_TOUCH_MAX_DIVISION_FACTOR) || (clkSource > ULP_TOUCH_MAX_SEL)) {
708 return INVALID_PARAMETERS;
709 }
710 ulpss_peripheral_disable(pULPCLK, ULP_TOUCH_CLK);
711
712 /*Select */
713 switch (clkSource) {
714 /*0: ref_clk (output of dynamic clock MUX for different possible ref_clk sources)*/
715 case ULP_TOUCH_REF_CLK:
716 /*Select clock MUX */
717 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
718 break;
719 /*1: ulp_32khz_ro_clk */
720 case ULP_TOUCH_32KHZ_RO_CLK:
721 /*Enable clock*/
722 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PERIPHERAL_CLK, 0);
723 /*Select clock MUX */
724 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
725 break;
726 /*2: ulp_32khz_rc_clk*/
727 case ULP_TOUCH_32KHZ_RC_CLK:
728 /*Enable clock*/
729 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
730 /*Select clock MUX */
731 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
732 break;
733 /*3: ulp_32khz_xtal_clk*/
734 case ULP_TOUCH_32KHZ_XTAL_CLK:
735 /*Enable clock*/
736 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PERIPHERAL_CLK, 0);
737 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
738 break;
739 /*4: ulp_mhz_rc_clk*/
740 case ULP_TOUCH_MHZ_RC_CLK:
741 /*Enable clock*/
742 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
743 /*Select clock MUX */
744 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
745 break;
746 /*5: ulp_20mhz_ro_clk*/
747 case ULP_TOUCH_20MHZ_RO_CLK:
748 /*Enable clock*/
749 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
750 /*Select clock MUX */
751 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
752 break;
753 case ULP_TOUCH_ULP_SOC_CLK:
754 /*6: soc_clk*/
755 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_SEL = clkSource;
756 break;
757
758 default:
759 return INVALID_PARAMETERS;
760 }
761
762 /*Wait for clock switched */
763 while ((pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_TOUCH_SENSOR_b) != 1)
764 ;
765
766 /*Program the division factor */
767 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLKDIV_FACTOR = (uint8_t)divFactor;
768
769 ulpss_peripheral_enable(pULPCLK, ULP_TOUCH_CLK, ENABLE_STATIC_CLK);
770
771 return RSI_OK;
772 }
773
774 /*==============================================*/
775 /**
776 * @fn rsi_error_t ulpss_slp_sensor_clk_config(ULPCLK_Type *pULPCLK, boolean_t clkEnable, uint32_t divFactor)
777 * @brief This API is used to configure the sleep sensor clock source
778 * @param[in] pULPCLK : pointer to the processor ULP clock source
779 * @param[in] clkEnable : enable clock for ULP sleep sensor
780 * @param[in] divFactor : divison factor for ULP sleep sensor
781 * @return RSI_OK on success
782 */
783
ulpss_slp_sensor_clk_config(ULPCLK_Type * pULPCLK,boolean_t clkEnable,uint32_t divFactor)784 rsi_error_t ulpss_slp_sensor_clk_config(ULPCLK_Type *pULPCLK, boolean_t clkEnable, uint32_t divFactor)
785 {
786 /*Parameter validation */
787 if ((pULPCLK == NULL) || (divFactor > ULP_SLP_SENSOR_MAX_DIVISION_FACTOR)) {
788 return INVALID_PARAMETERS;
789 }
790 if (clkEnable) {
791 /*Enable sleep sensor clock */
792 pULPCLK->SLP_SENSOR_CLK_REG_b.ENABLE_b = 1;
793 } else {
794 /*Disable sleep sensor clock */
795 pULPCLK->SLP_SENSOR_CLK_REG_b.ENABLE_b = 0;
796 }
797 /*Apply division factor*/
798 pULPCLK->SLP_SENSOR_CLK_REG_b.DIVISON_FACTOR = (uint8_t)divFactor;
799 return RSI_OK;
800 }
801
802 /*==============================================*/
803 /**
804 * @fn rsi_error_t ulpss_peripheral_enable(ULPCLK_Type *pULPCLK, ULPPERIPHERALS_CLK_T module, CLK_ENABLE_T clkType)
805 * @brief This API is used to enable the particular ULP perpheral Clock
806 * @param[in] pULPCLK : pointer to the processor ULP clock source
807 * @param[in] module : module for ULP peripheral Clock
808 * @param[in] clkType : clock type for ULP peripheral Clock
809 * @return RSI_OK on success
810 */
811
ulpss_peripheral_enable(ULPCLK_Type * pULPCLK,ULPPERIPHERALS_CLK_T module,CLK_ENABLE_T clkType)812 rsi_error_t ulpss_peripheral_enable(ULPCLK_Type *pULPCLK, ULPPERIPHERALS_CLK_T module, CLK_ENABLE_T clkType)
813 {
814 if (pULPCLK == NULL) {
815 return INVALID_PARAMETERS;
816 }
817 switch (module) {
818 case ULP_I2C_CLK:
819 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_I2C_CLK_EN_b = 1;
820 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_I2C_b = 1;
821 break;
822 case ULP_EGPIO_CLK:
823 pULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_CLK_EN_b = 1;
824 pULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_PCLK_ENABLE_b = 1;
825 break;
826 case ULP_AUX_CLK:
827 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_CLK_EN_b = 1;
828
829 if (clkType == ENABLE_STATIC_CLK) {
830 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_PCLK_EN_b = 1;
831 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_EN_b = 1;
832 } else {
833 /**Static enable **/
834 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_PCLK_EN_b = 0;
835 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_CLK_DYN_CTRL_DISABLE_b = 0;
836 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_PCLK_DYN_CTRL_DISABLE_b = 0;
837 }
838 break;
839 case ULP_FIM_CLK:
840 pULPCLK->ULP_MISC_SOFT_SET_REG_b.FIM_PCLK_ENABLE_b = 1;
841 if (clkType == ENABLE_STATIC_CLK) {
842 pULPCLK->ULP_MISC_SOFT_SET_REG_b.FIM_CLK_EN_b = 1;
843 } else {
844 pULPCLK->ULP_MISC_SOFT_SET_REG_b.FIM_CLK_EN_b = 0;
845 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.FIM_CLK_DYN_CTRL_DISABLE_b = 0;
846 }
847 break;
848 case ULP_VAD_CLK:
849 pULPCLK->ULP_MISC_SOFT_SET_REG_b.VAD_CLK_EN_b = 1;
850 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLK_EN_b = 1;
851 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_EN = 1;
852 pULPCLK->ULP_MISC_SOFT_SET_REG_b.VAD_PCLK_ENABLE_b = 1;
853 break;
854 case ULP_TIMER_CLK:
855 pULPCLK->ULP_MISC_SOFT_SET_REG_b.CLK_ENABLE_TIMER_b = 1;
856 if (clkType == ENABLE_STATIC_CLK) {
857 pULPCLK->ULP_MISC_SOFT_SET_REG_b.TIMER_PCLK_EN_b = 1;
858 } else {
859 pULPCLK->ULP_MISC_SOFT_SET_REG_b.TIMER_PCLK_EN_b = 0;
860 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.TIMER_PCLK_DYN_CTRL_DISABLE_b = 0;
861 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.TIMER_SCLK_DYN_CTRL_DISABLE_b = 0;
862 }
863 break;
864 case ULP_UDMA_CLK:
865 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UDMA_CLK_ENABLE_b = 1;
866 break;
867 case ULP_TOUCH_CLK:
868 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_EN_b = 1;
869 break;
870 case ULP_UART_CLK:
871 if (clkType == ENABLE_STATIC_CLK) {
872 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_UART_b = 1;
873 pULPCLK->ULP_MISC_SOFT_SET_REG_b.SCLK_ENABLE_UART_b = 1;
874 } else {
875 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UART_CLK_DYN_CTRL_DISABLE_b = 0;
876 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UART_SCLK_DYN_CTRL_DISABLE_b = 0;
877 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_UART_b = 0;
878 pULPCLK->ULP_MISC_SOFT_SET_REG_b.SCLK_ENABLE_UART_b = 0;
879 }
880 break;
881 case ULP_SSI_CLK:
882 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_EN_b = 1;
883 pULPCLK->ULP_MISC_SOFT_SET_REG_b.SCLK_ENABLE_SSI_MASTER_b = 1;
884 if (clkType == ENABLE_STATIC_CLK) {
885 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_SSI_MASTER_b = 1;
886 } else {
887 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.SSI_MST_PCLK_DYN_CTRL_DISABLE_b = 0;
888 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.SSI_MST_SCLK_DYN_CTRL_DISABLE_b = 0;
889 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_SSI_MASTER_b = 0;
890 }
891 break;
892 case ULP_I2S_CLK:
893 /*ULPSS I2S master*/
894 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_EN_b = 1;
895 pULPCLK->ULP_MISC_SOFT_SET_REG_b.CLK_ENABLE_I2S_b = 1;
896 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_PCLK_EN_b = 1;
897 break;
898
899 default:
900 return INVALID_PARAMETERS;
901 }
902 return RSI_OK;
903 }
904 #endif
905
906 /*==============================================*/
907 /**
908 * @fn rsi_error_t ulpss_peripheral_disable(ULPCLK_Type *pULPCLK, ULPPERIPHERALS_CLK_T module)
909 * @brief This API is used to Disable the particulat ULP perpheral Clock
910 * @param[in] pULPCLK : pointer to the processor ULP clock source
911 * @param[in] module : module for ULP peripheral Clock
912 * @return RSI_OK on success
913 */
914
ulpss_peripheral_disable(ULPCLK_Type * pULPCLK,ULPPERIPHERALS_CLK_T module)915 rsi_error_t ulpss_peripheral_disable(ULPCLK_Type *pULPCLK, ULPPERIPHERALS_CLK_T module)
916 {
917 if (pULPCLK == NULL) {
918 return INVALID_PARAMETERS;
919 }
920 switch (module) {
921 case ULP_I2C_CLK:
922 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_I2C_CLK_EN_b = 0;
923 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_I2C_b = 0;
924 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.I2C_PCLK_DYN_CTRL_DISABLE_b = 1;
925 break;
926 case ULP_EGPIO_CLK:
927 pULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_CLK_EN_b = 0;
928 pULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_PCLK_ENABLE_b = 0;
929 pULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_PCLK_DYN_CTRL_DISABLE_b = 1;
930 break;
931 case ULP_AUX_CLK:
932 pULPCLK->ULP_AUXADC_CLK_GEN_REG_b.ULP_AUX_CLK_EN_b = 0;
933 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_CLK_EN_b = 0;
934 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_PCLK_EN_b = 0;
935 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_CLK_DYN_CTRL_DISABLE_b = 1;
936 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.AUX_PCLK_DYN_CTRL_DISABLE_b = 1;
937 break;
938 case ULP_FIM_CLK:
939 pULPCLK->ULP_MISC_SOFT_SET_REG_b.FIM_CLK_EN_b = 0;
940 pULPCLK->ULP_MISC_SOFT_SET_REG_b.FIM_PCLK_ENABLE_b = 0;
941 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.FIM_CLK_DYN_CTRL_DISABLE_b = 1;
942 break;
943 case ULP_VAD_CLK:
944 pULPCLK->ULP_MISC_SOFT_SET_REG_b.VAD_CLK_EN_b = 0;
945 pULPCLK->ULP_MISC_SOFT_SET_REG_b.VAD_PCLK_ENABLE_b = 0;
946 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_CLK_EN_b = 0;
947 pULPCLK->ULP_VAD_CLK_GEN_REG_b.ULP_VAD_FCLK_EN = 0;
948 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.VAD_CLK_DYN_CTRL_DISABLE_b = 1;
949 break;
950 case ULP_TIMER_CLK:
951 pULPCLK->ULP_MISC_SOFT_SET_REG_b.TIMER_PCLK_EN_b = 0;
952 pULPCLK->ULP_MISC_SOFT_SET_REG_b.CLK_ENABLE_TIMER_b = 0;
953 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.TIMER_PCLK_DYN_CTRL_DISABLE_b = 1;
954 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.TIMER_SCLK_DYN_CTRL_DISABLE_b = 1;
955 break;
956 case ULP_UDMA_CLK:
957 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UDMA_CLK_ENABLE_b = 0;
958 break;
959 case ULP_TOUCH_CLK:
960 pULPCLK->ULP_TOUCH_CLK_GEN_REG_b.ULP_TOUCH_CLK_EN_b = 0;
961 break;
962 case ULP_UART_CLK:
963 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_UART_b = 0;
964 pULPCLK->ULP_MISC_SOFT_SET_REG_b.SCLK_ENABLE_UART_b = 0;
965 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UART_SCLK_DYN_CTRL_DISABLE_b = 1;
966 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.UART_CLK_DYN_CTRL_DISABLE_b = 1;
967 break;
968 case ULP_SSI_CLK:
969 pULPCLK->ULP_MISC_SOFT_SET_REG_b.SCLK_ENABLE_SSI_MASTER_b = 0;
970 pULPCLK->ULP_MISC_SOFT_SET_REG_b.PCLK_ENABLE_SSI_MASTER_b = 0;
971 pULPCLK->ULP_I2C_SSI_CLK_GEN_REG_b.ULP_SSI_CLK_EN_b = 0;
972 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.SSI_MST_PCLK_DYN_CTRL_DISABLE_b = 1;
973 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.SSI_MST_SCLK_DYN_CTRL_DISABLE_b = 1;
974 break;
975 case ULP_I2S_CLK:
976 pULPCLK->ULP_MISC_SOFT_SET_REG_b.CLK_ENABLE_I2S_b = 0;
977 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_PCLK_EN_b = 0;
978 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_CLK_EN_b = 0;
979 pULPCLK->ULP_DYN_CLK_CTRL_DISABLE_b.I2S_CLK_DYN_CTRL_DISABLE_b = 1;
980 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_PCLK_DYN_CTRL_DISABLE_b = 1;
981 pULPCLK->ULP_I2S_CLK_GEN_REG_b.ULP_I2S_SCLK_DYN_CTRL_DISABLE_b = 1;
982 break;
983 default:
984 return INVALID_PARAMETERS;
985 }
986 return RSI_OK;
987 }
988
989 /*==============================================*/
990 /**
991 * @fn rsi_error_t ulpss_time_clk_disable(ULPCLK_Type *pULPCLK)
992 * @brief This API is used to disable the timer clock
993 * @param[in] pULPCLK : pointer to the processor ULP clock source
994 * @return ulpss_peripheral_disable on success
995 */
996
ulpss_time_clk_disable(ULPCLK_Type * pULPCLK)997 rsi_error_t ulpss_time_clk_disable(ULPCLK_Type *pULPCLK)
998 {
999 pULPCLK->ULP_TIMER_CLK_GEN_REG_b.ULP_TIMER_CLK_SEL = 0xF;
1000 return ulpss_peripheral_disable(pULPCLK, ULP_TIMER_CLK);
1001 }
1002
1003 /*==============================================*/
1004 /**
1005 * @fn rsi_error_t ulpss_ref_clk_config(ULPSS_REF_CLK_SEL_T clkSource)
1006 * @brief This API is used to select the ULPSS processor ref clk configuration
1007 * @param[in] clkSource : clock source for ULPSS processor reference clock select
1008 * @return RSI_OK on success
1009 */
1010
ulpss_ref_clk_config(ULPSS_REF_CLK_SEL_T clkSource)1011 rsi_error_t ulpss_ref_clk_config(ULPSS_REF_CLK_SEL_T clkSource)
1012 {
1013 switch (clkSource) {
1014 case ULPSS_REF_BYP_CLK:
1015 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1016 system_clocks.ulp_ref_clock_source = clkSource;
1017 system_clocks.ulpss_ref_clk = system_clocks.byp_rc_ref_clock;
1018 break;
1019
1020 case ULPSS_ULP_MHZ_RC_CLK:
1021 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1022 system_clocks.ulp_ref_clock_source = clkSource;
1023 system_clocks.ulpss_ref_clk = system_clocks.rc_mhz_clock;
1024 break;
1025
1026 case ULPSS_40MHZ_CLK:
1027 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1028 system_clocks.ulp_ref_clock_source = clkSource;
1029 system_clocks.ulpss_ref_clk = system_clocks.rf_ref_clock;
1030 break;
1031
1032 case ULPSS_MEMS_REF_CLK:
1033 TASS_PLL_CTRL_SET_REG(AFEPLLCTRLREG1) = MEMS_REF_CLK_ENABLE;
1034 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1035 system_clocks.ulp_ref_clock_source = clkSource;
1036 system_clocks.ulpss_ref_clk = system_clocks.mems_ref_clock;
1037 break;
1038
1039 case ULPSS_ULP_20MHZ_RINGOSC_CLK:
1040 /*Enable clock*/
1041 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PERIPHERAL_CLK, 0);
1042 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1043 system_clocks.ulp_ref_clock_source = clkSource;
1044 system_clocks.ulpss_ref_clk = system_clocks.ro_20mhz_clock;
1045 break;
1046
1047 case ULPSS_ULP_DOUBLER_CLK:
1048 /*6: ulp_doubler_clk*/
1049 /*Enable clock*/
1050 ulpss_enable_ref_clks(MCU_ULP_DOUBLER_CLK_EN, ULP_PERIPHERAL_CLK, 0);
1051 MCU_FSM->MCU_FSM_REF_CLK_REG_b.ULPSS_REF_CLK_SEL_b = clkSource;
1052 system_clocks.ulp_ref_clock_source = clkSource;
1053 system_clocks.ulpss_ref_clk = system_clocks.doubler_clock;
1054 break;
1055
1056 default:
1057 return INVALID_PARAMETERS;
1058 }
1059 return RSI_OK;
1060 }
1061
1062 /*==============================================*/
1063 /**
1064 * @fn rsi_error_t ulpss_ulp_proc_clk_config(ULPCLK_Type *pULPCLK,
1065 * ULP_PROC_CLK_SELECT_T clkSource,
1066 * uint16_t divFactor,
1067 * cdDelay delayFn)
1068 * @brief This API is used to configure the ULPSS processor clock source
1069 * @param[in] pULPCLK : pointer to the processor ULP clock source
1070 * @param[in] clkSource : clock source for ULPSS processor clock select
1071 * @param[in] divFactor : divison factor for processor clock source
1072 * @param[in] delayFn : delay functionfor processor clock source
1073 * @return RSI_OK on success
1074 */
1075
ulpss_ulp_proc_clk_config(ULPCLK_Type * pULPCLK,ULP_PROC_CLK_SELECT_T clkSource,uint16_t divFactor,cdDelay delayFn)1076 rsi_error_t ulpss_ulp_proc_clk_config(ULPCLK_Type *pULPCLK,
1077 ULP_PROC_CLK_SELECT_T clkSource,
1078 uint16_t divFactor,
1079 cdDelay delayFn)
1080 {
1081 /*Parameter validation */
1082 if ((pULPCLK == NULL) || (divFactor > ULP_PROC_MAX_DIVISOIN_FACTOR) || (clkSource > ULP_PROC_MAX_SEL)) {
1083 return INVALID_PARAMETERS;
1084 }
1085
1086 /*Select */
1087 switch (clkSource) {
1088
1089 case ULP_PROC_REF_CLK:
1090 /*Select clock MUX */
1091 RSI_SetRegSpiDivision(0U);
1092 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1093 SystemCoreClock = system_clocks.ulpss_ref_clk;
1094 break;
1095
1096 case ULP_PROC_ULP_32KHZ_RO_CLK:
1097 /*Enable clock*/
1098 RSI_SetRegSpiDivision(0U);
1099 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RO_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1100 /*Select clock MUX */
1101 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1102 SystemCoreClock = system_clocks.ro_32khz_clock;
1103 break;
1104
1105 case ULP_PROC_ULP_32KHZ_RC_CLK:
1106 /*Enable clock*/
1107 RSI_SetRegSpiDivision(0U);
1108 ulpss_enable_ref_clks(MCU_ULP_32KHZ_RC_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1109 SystemCoreClock = system_clocks.rc_32khz_clock;
1110 /*Select clock MUX */
1111 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1112 break;
1113
1114 case ULP_PROC_ULP_32KHZ_XTAL_CLK:
1115 /*Enable clock*/
1116 RSI_SetRegSpiDivision(0U);
1117 ulpss_enable_ref_clks(MCU_ULP_32KHZ_XTAL_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1118 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1119 SystemCoreClock = system_clocks.xtal_32khz_clock;
1120 break;
1121
1122 case ULP_PROC_ULP_MHZ_RC_CLK:
1123 /*Enable clock*/
1124 RSI_SetRegSpiDivision(0U);
1125 ulpss_enable_ref_clks(MCU_ULP_MHZ_RC_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1126 /*Select clock MUX */
1127 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1128 SystemCoreClock = system_clocks.rc_mhz_clock;
1129 break;
1130
1131 case ULP_PROC_ULP_20MHZ_RO_CLK:
1132 /*Enable clock*/
1133 RSI_SetRegSpiDivision(0U);
1134 ulpss_enable_ref_clks(MCU_ULP_20MHZ_RING_OSC_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1135 /*Select clock MUX */
1136 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1137 SystemCoreClock = system_clocks.ro_20mhz_clock;
1138 break;
1139
1140 case ULP_PROC_SOC_CLK:
1141 /*6: soc_clk*/
1142 RSI_SetRegSpiDivision(2U);
1143 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1144 SystemCoreClock = system_clocks.soc_clock;
1145 break;
1146
1147 case ULP_PROC_ULP_DOUBLER_CLK:
1148 /*Enable clock*/
1149 RSI_SetRegSpiDivision(0U);
1150 ulpss_enable_ref_clks(MCU_ULP_DOUBLER_CLK_EN, ULP_PROCESSOR_CLK, delayFn);
1151 /*Select clock MUX */
1152 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_SEL = clkSource;
1153 SystemCoreClock = system_clocks.doubler_clock;
1154 break;
1155 default:
1156 return INVALID_PARAMETERS;
1157 }
1158 while (pULPCLK->CLOCK_STAUS_REG_b.CLOCK_SWITCHED_PROC_CLK_b != 1)
1159 ;
1160 /*update the division factor */
1161 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP_PROC_CLK_DIV_FACTOR = (char)divFactor;
1162 /*clock Enable */
1163 pULPCLK->ULP_TA_CLK_GEN_REG_b.ULP2M4_A2A_BRDG_CLK_EN_b = 1;
1164
1165 if (divFactor) {
1166 SystemCoreClock = (SystemCoreClock / divFactor);
1167 }
1168 system_clocks.soc_clock = SystemCoreClock;
1169 return RSI_OK;
1170 }
1171 /** @} */
1172