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