1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes   <System Includes> , "Project Includes"
9  **********************************************************************************************************************/
10 #include "bsp_clocks.h"
11 
12 #if BSP_TZ_NONSECURE_BUILD
13  #include "bsp_guard.h"
14 #endif
15 
16 /***********************************************************************************************************************
17  * Macro definitions
18  **********************************************************************************************************************/
19 
20 /* Key code for writing PRCR register. */
21 #define BSP_PRV_PRCR_KEY                        (0xA500U)
22 #define BSP_PRV_PRCR_UNLOCK                     ((BSP_PRV_PRCR_KEY) | 0x3U)
23 #define BSP_PRV_PRCR_LOCK                       ((BSP_PRV_PRCR_KEY) | 0x0U)
24 
25 /* Wait state definitions for MEMWAIT. */
26 #define BSP_PRV_MEMWAIT_ZERO_WAIT_CYCLES        (0U)
27 #define BSP_PRV_MEMWAIT_ONE_WAIT_CYCLES         (1U)
28 #define BSP_PRV_MEMWAIT_TWO_WAIT_CYCLES         (2U)
29 #define BSP_PRV_MEMWAIT_MAX_ZERO_WAIT_FREQ      (32000000U)
30 #define BSP_PRV_MEMWAIT_MAX_ONE_WAIT_FREQ       (48000000U)
31 
32 /* Wait state definitions for FLDWAITR. */
33 #define BSP_PRV_FLDWAITR_ONE_WAIT_CYCLES        (0U)
34 #define BSP_PRV_FLDWAITR_TWO_WAIT_CYCLES        (1U)
35 #define BSP_PRV_FLDWAITR_MAX_ONE_WAIT_FREQ      (32000000U)
36 
37 /* Temporary solution until R_FACI is added to renesas.h. */
38 #define BSP_PRV_FLDWAITR_REG_ACCESS             (*((volatile uint8_t *) (0x407EFFC4U)))
39 
40 /* Wait state definitions for MCUS with SRAMWTSC and FLWT. */
41 #define BSP_PRV_SRAMWTSC_WAIT_CYCLES_DISABLE    (0U)
42 #define BSP_PRV_ROM_ZERO_WAIT_CYCLES            (0U)
43 #define BSP_PRV_ROM_ONE_WAIT_CYCLES             (1U)
44 #define BSP_PRV_ROM_TWO_WAIT_CYCLES             (2U)
45 #define BSP_PRV_ROM_THREE_WAIT_CYCLES           (3U)
46 #define BSP_PRV_ROM_FOUR_WAIT_CYCLES            (4U)
47 #define BSP_PRV_ROM_FIVE_WAIT_CYCLES            (5U)
48 #define BSP_PRV_SRAM_UNLOCK                     (((BSP_FEATURE_CGC_SRAMPRCR_KW_VALUE) << \
49                                                   BSP_FEATURE_CGC_SRAMPRCR_KW_OFFSET) | 0x1U)
50 #define BSP_PRV_SRAM_LOCK                       (((BSP_FEATURE_CGC_SRAMPRCR_KW_VALUE) << \
51                                                   BSP_FEATURE_CGC_SRAMPRCR_KW_OFFSET) | 0x0U)
52 
53 /* Calculate value to write to MOMCR/CMC (MODRV controls main clock drive strength and MOSEL determines the source of the
54  * main oscillator). */
55 #if BSP_FEATURE_CGC_MODRV_MASK
56  #define BSP_PRV_MODRV                          ((CGC_MAINCLOCK_DRIVE << BSP_FEATURE_CGC_MODRV_SHIFT) & \
57                                                  BSP_FEATURE_CGC_MODRV_MASK)
58 #else
59  #define BSP_PRV_MODRV                          (0x1AU)
60 #endif
61 
62 #if !BSP_FEATURE_CGC_REGISTER_SET_B
63  #define BSP_PRV_MOSEL                          (BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE << R_SYSTEM_MOMCR_MOSEL_Pos)
64  #define BSP_PRV_MOMCR                          (BSP_PRV_MODRV | BSP_PRV_MOSEL)
65 #else
66  #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
67   #if BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE
68    #define BSP_PRV_MOSEL                        (3U << R_SYSTEM_CMC_MOSEL_Pos) // External clock input mode
69   #else
70    #define BSP_PRV_MOSEL                        (1U << R_SYSTEM_CMC_MOSEL_Pos) // Oscillation mode
71   #endif
72   #define BSP_PRV_CMC_MOSC                      (BSP_PRV_MODRV | BSP_PRV_MOSEL)
73  #endif
74 
75 /* Calculate value to write to CMC (SODRV controls sub-clock oscillator drive capability and SOSEL determines the source of the
76  * sub-clock oscillator). */
77  #if (0 == BSP_CLOCK_CFG_SUBCLOCK_DRIVE)
78   #define BSP_PRV_SODRV                         (1U << R_SYSTEM_CMC_SODRV_Pos) // Sub-Clock Oscillator Drive Capability Normal mode
79  #elif (1 == BSP_CLOCK_CFG_SUBCLOCK_DRIVE)
80   #define BSP_PRV_SODRV                         (0U << R_SYSTEM_CMC_SODRV_Pos) // Sub-Clock Oscillator Drive Capability Low Power Mode 1
81  #else
82   #define BSP_PRV_SODRV                         (BSP_CLOCK_CFG_SUBCLOCK_DRIVE << R_SYSTEM_CMC_SODRV_Pos)
83  #endif
84  #define BSP_PRV_CMC_SOSC                       (BSP_PRV_SODRV |                                                \
85                                                  (BSP_CLOCK_CFG_SUBCLOCK_POPULATED << R_SYSTEM_CMC_SOSEL_Pos) | \
86                                                  (BSP_CLOCK_CFG_SUBCLOCK_POPULATED << R_SYSTEM_CMC_XTSEL_Pos))
87 
88  #if (BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_FSXP_SOURCE)
89   #define BSP_PRV_OSMC                          (0U << R_SYSTEM_OSMC_WUTMMCK0_Pos) // Use Sub-clock oscillator (SOSC) as Subsystem Clock (FSXP) source.
90  #elif (BSP_CLOCKS_SOURCE_CLOCK_LOCO == BSP_CFG_FSXP_SOURCE)
91   #define BSP_PRV_OSMC                          (1U << R_SYSTEM_OSMC_WUTMMCK0_Pos) // Use Low-speed on-chip oscillator clock (LOCO) as Subsystem Clock (FSXP) source.
92  #endif
93 #endif
94 
95 /* Locations of bitfields used to configure CLKOUT. */
96 #define BSP_PRV_CKOCR_CKODIV_BIT                (4U)
97 #define BSP_PRV_CKOCR_CKOEN_BIT                 (7U)
98 
99 /* Stop interval of at least 5 SOSC clock cycles between stop and restart of SOSC.
100  * Calculated based on 8Mhz of MOCO clock. */
101 #define BSP_PRV_SUBCLOCK_STOP_INTERVAL_US       (200U)
102 
103 /* Locations of bitfields used to configure Peripheral Clocks. */
104 #define BSP_PRV_PERIPHERAL_CLK_REQ_BIT_POS      (6U)
105 #define BSP_PRV_PERIPHERAL_CLK_REQ_BIT_MASK     (1U << BSP_PRV_PERIPHERAL_CLK_REQ_BIT_POS)
106 #define BSP_PRV_PERIPHERAL_CLK_RDY_BIT_POS      (7U)
107 #define BSP_PRV_PERIPHERAL_CLK_RDY_BIT_MASK     (1U << BSP_PRV_PERIPHERAL_CLK_RDY_BIT_POS)
108 
109 #ifdef BSP_CFG_UCK_DIV
110 
111 /* If the MCU has SCKDIVCR2 for USBCK configuration. */
112  #if !BSP_FEATURE_BSP_HAS_USBCKDIVCR
113 
114 /* Location of bitfield used to configure USB clock divider. */
115   #define BSP_PRV_SCKDIVCR2_UCK_BIT    (4U)
116   #define BSP_PRV_UCK_DIV              (BSP_CFG_UCK_DIV)
117 
118 /* If the MCU has USBCKDIVCR. */
119  #elif BSP_FEATURE_BSP_HAS_USBCKDIVCR
120   #if BSP_CLOCKS_USB_CLOCK_DIV_1 == BSP_CFG_UCK_DIV
121    #define BSP_PRV_UCK_DIV             (0U)
122   #elif BSP_CLOCKS_USB_CLOCK_DIV_2 == BSP_CFG_UCK_DIV
123    #define BSP_PRV_UCK_DIV             (1U)
124   #elif BSP_CLOCKS_USB_CLOCK_DIV_3 == BSP_CFG_UCK_DIV
125    #define BSP_PRV_UCK_DIV             (5U)
126   #elif BSP_CLOCKS_USB_CLOCK_DIV_4 == BSP_CFG_UCK_DIV
127    #define BSP_PRV_UCK_DIV             (2U)
128   #elif BSP_CLOCKS_USB_CLOCK_DIV_5 == BSP_CFG_UCK_DIV
129    #define BSP_PRV_UCK_DIV             (6U)
130   #elif BSP_CLOCKS_USB_CLOCK_DIV_6 == BSP_CFG_UCK_DIV
131    #define BSP_PRV_UCK_DIV             (3U)
132   #elif BSP_CLOCKS_USB_CLOCK_DIV_8 == BSP_CFG_UCK_DIV
133    #define BSP_PRV_UCK_DIV             (4U)
134   #else
135 
136    #error "BSP_CFG_UCK_DIV not supported."
137 
138   #endif
139  #endif
140 #endif
141 #if BSP_FEATURE_BSP_HAS_USB60_CLOCK_REQ
142  #define BSP_CLOCKS_USB60_CLOCK_DIV_1            (0) // Divide USB source clock by 1
143  #define BSP_CLOCKS_USB60_CLOCK_DIV_2            (1) // Divide USB source clock by 2
144  #define BSP_CLOCKS_USB60_CLOCK_DIV_3            (5) // Divide USB source clock by 3
145  #define BSP_CLOCKS_USB60_CLOCK_DIV_4            (2) // Divide USB source clock by 4
146  #define BSP_CLOCKS_USB60_CLOCK_DIV_5            (6) // Divide USB source clock by 5
147  #define BSP_CLOCKS_USB60_CLOCK_DIV_6            (3) // Divide USB source clock by 6
148  #define BSP_CLOCKS_USB60_CLOCK_DIV_8            (4) // Divide USB source clock by 8
149 #endif /* BSP_FEATURE_BSP_HAS_USB60_CLOCK_REQ*/
150 /* Choose the value to write to FLLCR2 (if applicable). */
151 #if BSP_PRV_HOCO_USE_FLL
152  #if 1U == BSP_CFG_HOCO_FREQUENCY
153   #define BSP_PRV_FLL_FLLCR2                     (0x226U)
154  #elif 2U == BSP_CFG_HOCO_FREQUENCY
155   #define BSP_PRV_FLL_FLLCR2                     (0x263U)
156  #elif 4U == BSP_CFG_HOCO_FREQUENCY
157   #define BSP_PRV_FLL_FLLCR2                     (0x263U)
158  #else
159 
160 /* When BSP_CFG_HOCO_FREQUENCY is 0, 4, 7 */
161   #define BSP_PRV_FLL_FLLCR2                     (0x1E9U)
162  #endif
163 #endif
164 
165 /* Calculate the value to write to SCKDIVCR. */
166 #define BSP_PRV_STARTUP_SCKDIVCR_ICLK_BITS       ((BSP_CFG_ICLK_DIV & 0xFU) << 24U)
167 #if BSP_FEATURE_CGC_HAS_PCLKE
168  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKE_BITS     ((BSP_CFG_PCLKE_DIV & 0xFU) << 20U)
169 #else
170  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKE_BITS     (0U)
171 #endif
172 #if BSP_FEATURE_CGC_HAS_PCLKD
173  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKD_BITS     (BSP_CFG_PCLKD_DIV & 0xFU)
174 #else
175  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKD_BITS     (0U)
176 #endif
177 #if BSP_FEATURE_CGC_HAS_PCLKC
178  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKC_BITS     ((BSP_CFG_PCLKC_DIV & 0xFU) << 4U)
179 #else
180  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKC_BITS     (0U)
181 #endif
182 #if BSP_FEATURE_CGC_HAS_PCLKB
183  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKB_BITS     ((BSP_CFG_PCLKB_DIV & 0xFU) << 8U)
184 #else
185  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKB_BITS     (0U)
186 #endif
187 #if BSP_FEATURE_CGC_HAS_PCLKA
188  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKA_BITS     ((BSP_CFG_PCLKA_DIV & 0xFU) << 12U)
189 #else
190  #define BSP_PRV_STARTUP_SCKDIVCR_PCLKA_BITS     (0U)
191 #endif
192 #if BSP_FEATURE_CGC_HAS_BCLK
193  #define BSP_PRV_STARTUP_SCKDIVCR_BCLK_BITS      ((BSP_CFG_BCLK_DIV & 0xFU) << 16U)
194 #elif BSP_FEATURE_CGC_SCKDIVCR_BCLK_MATCHES_PCLKB
195 
196 /* Some MCUs have a requirement that bits 18-16 be set to the same value as the bits for configuring the PCLKB divisor. */
197  #define BSP_PRV_STARTUP_SCKDIVCR_BCLK_BITS      ((BSP_CFG_PCLKB_DIV & 0xFU) << 16U)
198 #else
199  #define BSP_PRV_STARTUP_SCKDIVCR_BCLK_BITS      (0U)
200 #endif
201 #if BSP_FEATURE_CGC_HAS_FCLK
202  #define BSP_PRV_STARTUP_SCKDIVCR_FCLK_BITS      ((BSP_CFG_FCLK_DIV & 0xFU) << 28U)
203 #else
204  #define BSP_PRV_STARTUP_SCKDIVCR_FCLK_BITS      (0U)
205 #endif
206 #define BSP_PRV_STARTUP_SCKDIVCR                 (BSP_PRV_STARTUP_SCKDIVCR_ICLK_BITS |  \
207                                                   BSP_PRV_STARTUP_SCKDIVCR_PCLKE_BITS | \
208                                                   BSP_PRV_STARTUP_SCKDIVCR_PCLKD_BITS | \
209                                                   BSP_PRV_STARTUP_SCKDIVCR_PCLKC_BITS | \
210                                                   BSP_PRV_STARTUP_SCKDIVCR_PCLKB_BITS | \
211                                                   BSP_PRV_STARTUP_SCKDIVCR_PCLKA_BITS | \
212                                                   BSP_PRV_STARTUP_SCKDIVCR_BCLK_BITS |  \
213                                                   BSP_PRV_STARTUP_SCKDIVCR_FCLK_BITS)
214 #if BSP_FEATURE_CGC_HAS_CPUCLK
215  #define BSP_PRV_STARTUP_SCKDIVCR2_CPUCK_BITS    (BSP_CFG_CPUCLK_DIV & 0xFU)
216  #define BSP_PRV_STARTUP_SCKDIVCR2               (BSP_PRV_STARTUP_SCKDIVCR2_CPUCK_BITS)
217 #endif
218 
219 /* The number of clocks is used to size the g_clock_freq array. */
220 #if BSP_PRV_PLL2_SUPPORTED
221  #define BSP_PRV_NUM_CLOCKS                      ((uint8_t) BSP_CLOCKS_SOURCE_CLOCK_PLL2 +       \
222                                                   (BSP_FEATURE_CGC_PLL1_NUM_OUTPUT_CLOCKS - 1) + \
223                                                   BSP_FEATURE_CGC_PLL2_NUM_OUTPUT_CLOCKS)
224 #elif BSP_PRV_PLL_SUPPORTED
225  #define BSP_PRV_NUM_CLOCKS                      ((uint8_t) BSP_CLOCKS_SOURCE_CLOCK_PLL + \
226                                                   BSP_FEATURE_CGC_PLL1_NUM_OUTPUT_CLOCKS)
227 #else
228  #define BSP_PRV_NUM_CLOCKS                      ((uint8_t) BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK + 1U)
229 #endif
230 
231 /* Calculate PLLCCR value. */
232 #if BSP_PRV_PLL_SUPPORTED
233  #if (1U == BSP_FEATURE_CGC_PLLCCR_TYPE)
234   #if BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == BSP_CFG_PLL_SOURCE
235    #define BSP_PRV_PLSRCSEL                        (0)
236    #define BSP_PRV_PLL_USED                        (1)
237   #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_PLL_SOURCE
238    #define BSP_PRV_PLSRCSEL                        (1)
239    #define BSP_PRV_PLL_USED                        (1)
240   #else
241    #define BSP_PRV_PLL_USED                        (0)
242   #endif
243   #define BSP_PRV_PLLCCR_PLLMUL_MASK               (0x3F) // PLLMUL in PLLCCR is 6 bits wide
244   #define BSP_PRV_PLLCCR_PLLMUL_BIT                (8)    // PLLMUL in PLLCCR starts at bit 8
245   #define BSP_PRV_PLLCCR_PLSRCSEL_BIT              (4)    // PLSRCSEL in PLLCCR starts at bit 4
246   #define BSP_PRV_PLLCCR                           ((((BSP_CFG_PLL_MUL & BSP_PRV_PLLCCR_PLLMUL_MASK) <<   \
247                                                       BSP_PRV_PLLCCR_PLLMUL_BIT) |                        \
248                                                      (BSP_PRV_PLSRCSEL << BSP_PRV_PLLCCR_PLSRCSEL_BIT)) | \
249                                                     BSP_CFG_PLL_DIV)
250  #endif
251  #if (2U == BSP_FEATURE_CGC_PLLCCR_TYPE)
252   #if BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == BSP_CFG_PLL_SOURCE
253    #define BSP_PRV_PLSRCSEL                        (0)
254    #define BSP_PRV_PLL_USED                        (1)
255   #else
256    #define BSP_PRV_PLL_USED                        (0)
257   #endif
258   #define BSP_PRV_PLLCCR2_PLLMUL_MASK              (0x1F) // PLLMUL in PLLCCR2 is 5 bits wide
259   #define BSP_PRV_PLLCCR2_PLODIV_BIT               (6)    // PLODIV in PLLCCR2 starts at bit 6
260 
261   #define BSP_PRV_PLLCCR2_PLLMUL                   (BSP_CFG_PLL_MUL >> 1)
262   #define BSP_PRV_PLLCCR                           ((BSP_PRV_PLLCCR2_PLLMUL & BSP_PRV_PLLCCR2_PLLMUL_MASK) | \
263                                                     (BSP_CFG_PLL_DIV << BSP_PRV_PLLCCR2_PLODIV_BIT))
264  #endif
265  #if (3U == BSP_FEATURE_CGC_PLLCCR_TYPE)
266   #if BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == BSP_CFG_PLL_SOURCE
267    #define BSP_PRV_PLSRCSEL                        (0)
268    #define BSP_PRV_PLL_USED                        (1)
269   #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_PLL_SOURCE
270    #define BSP_PRV_PLSRCSEL                        (1)
271    #define BSP_PRV_PLL_USED                        (1)
272   #else
273    #define BSP_PRV_PLL_USED                        (0)
274   #endif
275 
276   #define BSP_PRV_PLL_MUL_CFG_MACRO_PLLMUL_MASK    (0x3FFU)
277   #define BSP_PRV_PLLCCR_PLLMULNF_BIT              (6) // PLLMULNF in PLLCCR starts at bit 6
278   #define BSP_PRV_PLLCCR_PLSRCSEL_BIT              (4) // PLSRCSEL in PLLCCR starts at bit 4
279   #define BSP_PRV_PLLCCR                           ((((BSP_CFG_PLL_MUL & BSP_PRV_PLL_MUL_CFG_MACRO_PLLMUL_MASK) << \
280                                                       BSP_PRV_PLLCCR_PLLMULNF_BIT) |                               \
281                                                      (BSP_PRV_PLSRCSEL << BSP_PRV_PLLCCR_PLSRCSEL_BIT)) |          \
282                                                     BSP_CFG_PLL_DIV)
283   #define BSP_PRV_PLLCCR2_PLL_DIV_MASK             (0x0F) // PLL DIV in PLLCCR2/PLL2CCR2 is 4 bits wide
284   #define BSP_PRV_PLLCCR2_PLL_DIV_Q_BIT            (4)    // PLL DIV Q in PLLCCR2/PLL2CCR2 starts at bit 4
285   #define BSP_PRV_PLLCCR2_PLL_DIV_R_BIT            (8)    // PLL DIV R in PLLCCR2/PLL2CCR2 starts at bit 8
286   #define BSP_PRV_PLLCCR2                          (((BSP_CFG_PLODIVR & BSP_PRV_PLLCCR2_PLL_DIV_MASK) << \
287                                                      BSP_PRV_PLLCCR2_PLL_DIV_R_BIT) |                    \
288                                                     ((BSP_CFG_PLODIVQ & BSP_PRV_PLLCCR2_PLL_DIV_MASK) << \
289                                                      BSP_PRV_PLLCCR2_PLL_DIV_Q_BIT) |                    \
290                                                     (BSP_CFG_PLODIVP & BSP_PRV_PLLCCR2_PLL_DIV_MASK))
291  #endif
292  #if (4U == BSP_FEATURE_CGC_PLLCCR_TYPE)
293   #if BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_PLL_SOURCE
294    #define BSP_PRV_PLL_USED                        (1)
295   #else
296    #define BSP_PRV_PLL_USED                        (0)
297   #endif
298 
299   #define BSP_PRV_PLLCCR_PLLMUL_MASK               (0xFFU)   // PLLMUL is 8 bits wide
300   #define BSP_PRV_PLLCCR_PLLMUL_BIT                (8)       // PLLMUL starts at bit 8
301   #define BSP_PRV_PLLCCR_RESET                     (0x0004U) // Bit 2 must be written as 1
302   #define BSP_PRV_PLLCCR                           (((BSP_CFG_PLL_MUL & BSP_PRV_PLLCCR_PLLMUL_MASK) << \
303                                                      BSP_PRV_PLLCCR_PLLMUL_BIT) |                      \
304                                                     BSP_PRV_PLLCCR_RESET)
305  #endif
306 
307  #if (5U == BSP_FEATURE_CGC_PLLCCR_TYPE)
308   #if BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == BSP_CFG_PLL_SOURCE
309    #define BSP_PRV_PLSRCSEL                        (0)
310    #define BSP_PRV_PLL_USED                        (1)
311   #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_PLL_SOURCE
312    #define BSP_PRV_PLSRCSEL                        (1)
313    #define BSP_PRV_PLL_USED                        (1)
314   #else
315    #define BSP_PRV_PLL_USED                        (0)
316   #endif
317   #define BSP_PRV_PLLCCR_PLLMUL_MASK               (0x1F) // PLLMUL in PLLCCR is 5 bits wide
318   #define BSP_PRV_PLLCCR_PLLMUL_BIT                (8)    // PLLMUL in PLLCCR starts at bit 8
319   #define BSP_PRV_PLLCCR_PLSRCSEL_BIT              (4)    // PLSRCSEL in PLLCCR starts at bit 4
320   #if (BSP_CFG_PLL_DIV == BSP_CLOCKS_PLL_DIV_1)
321    #define BSP_PRV_PLLCCR                          ((((BSP_CFG_PLL_MUL & BSP_PRV_PLLCCR_PLLMUL_MASK) <<   \
322                                                       BSP_PRV_PLLCCR_PLLMUL_BIT) |                        \
323                                                      (BSP_PRV_PLSRCSEL << BSP_PRV_PLLCCR_PLSRCSEL_BIT)) | \
324                                                     (0U))
325   #elif (BSP_CFG_PLL_DIV == BSP_CLOCKS_PLL_DIV_4)
326    #define BSP_PRV_PLLCCR                          ((((BSP_CFG_PLL_MUL & BSP_PRV_PLLCCR_PLLMUL_MASK) <<   \
327                                                       BSP_PRV_PLLCCR_PLLMUL_BIT) |                        \
328                                                      (BSP_PRV_PLSRCSEL << BSP_PRV_PLLCCR_PLSRCSEL_BIT)) | \
329                                                     (1U))
330   #elif (BSP_CFG_PLL_DIV == BSP_CLOCKS_PLL_DIV_6)
331    #define BSP_PRV_PLLCCR                          ((((BSP_CFG_PLL_MUL & BSP_PRV_PLLCCR_PLLMUL_MASK) <<   \
332                                                       BSP_PRV_PLLCCR_PLLMUL_BIT) |                        \
333                                                      (BSP_PRV_PLSRCSEL << BSP_PRV_PLLCCR_PLSRCSEL_BIT)) | \
334                                                     (2U))
335   #endif
336  #endif
337 #endif
338 
339 #if BSP_FEATURE_CGC_HAS_PLL2
340  #if BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == BSP_CFG_PLL2_SOURCE
341   #define BSP_PRV_PL2SRCSEL                           (0)
342   #define BSP_PRV_PLL2_USED                           (1)
343  #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_PLL2_SOURCE
344   #define BSP_PRV_PL2SRCSEL                           (1)
345   #define BSP_PRV_PLL2_USED                           (1)
346  #else
347   #define BSP_PRV_PLL2_USED                           (0)
348  #endif
349 
350  #if (3U == BSP_FEATURE_CGC_PLLCCR_TYPE)
351   #define BSP_PRV_PLL2_MUL_CFG_MACRO_PLLMUL_MASK      (0x3FF)
352   #define BSP_PRV_PLL2_MUL_CFG_MACRO_PLLMULNF_MASK    (0x003U)
353   #define BSP_PRV_PLL2CCR_PLLMULNF_BIT                (6) // PLLMULNF in PLLCCR starts at bit 6
354   #define BSP_PRV_PLL2CCR_PLSRCSEL_BIT                (4) // PLSRCSEL in PLLCCR starts at bit 4
355   #define BSP_PRV_PLL2CCR                             ((((BSP_CFG_PLL2_MUL & BSP_PRV_PLL2_MUL_CFG_MACRO_PLLMUL_MASK) << \
356                                                          BSP_PRV_PLL2CCR_PLLMULNF_BIT) |                                \
357                                                         (BSP_PRV_PL2SRCSEL << BSP_PRV_PLL2CCR_PLSRCSEL_BIT)) |          \
358                                                        BSP_CFG_PLL2_DIV)
359   #define BSP_PRV_PLL2CCR2_PLL_DIV_MASK               (0x0F) // PLL DIV in PLL2CCR2 is 4 bits wide
360   #define BSP_PRV_PLL2CCR2_PLL_DIV_Q_BIT              (4)    // PLL DIV Q in PLL2CCR2 starts at bit 4
361   #define BSP_PRV_PLL2CCR2_PLL_DIV_R_BIT              (8)    // PLL DIV R in PLL2CCR2 starts at bit 8
362   #define BSP_PRV_PLL2CCR2                            (((BSP_CFG_PL2ODIVR & BSP_PRV_PLL2CCR2_PLL_DIV_MASK) << \
363                                                         BSP_PRV_PLL2CCR2_PLL_DIV_R_BIT) |                     \
364                                                        ((BSP_CFG_PL2ODIVQ & BSP_PRV_PLL2CCR2_PLL_DIV_MASK) << \
365                                                         BSP_PRV_PLL2CCR2_PLL_DIV_Q_BIT) |                     \
366                                                        (BSP_CFG_PL2ODIVP & BSP_PRV_PLL2CCR2_PLL_DIV_MASK))
367  #else
368   #define BSP_PRV_PLL2CCR                             ((BSP_CFG_PLL2_MUL << R_SYSTEM_PLL2CCR_PLL2MUL_Pos) | \
369                                                        (BSP_CFG_PLL2_DIV << R_SYSTEM_PLL2CCR_PL2IDIV_Pos) | \
370                                                        (BSP_PRV_PL2SRCSEL << R_SYSTEM_PLL2CCR_PL2SRCSEL_Pos))
371  #endif
372 #endif
373 
374 /* All clocks with configurable source except PLL and CLKOUT can use PLL. */
375 #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_PLL)
376  #define BSP_PRV_STABILIZE_PLL                    (1)
377 #endif
378 
379 /* All clocks with configurable source can use the main oscillator. */
380 #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
381  #define BSP_PRV_MAIN_OSC_USED                    (1)
382  #define BSP_PRV_STABILIZE_MAIN_OSC               (1)
383 #elif defined(BSP_CFG_UCK_SOURCE) && BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ && \
384     (BSP_CFG_UCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
385  #define BSP_PRV_MAIN_OSC_USED                    (1)
386 #elif defined(BSP_CFG_CANFDCLK_SOURCE) && (BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
387  #define BSP_PRV_MAIN_OSC_USED                    (1)
388 #elif defined(BSP_CFG_PLL_SOURCE) && (BSP_CFG_PLL_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) && BSP_PRV_PLL_USED
389  #define BSP_PRV_MAIN_OSC_USED                    (1)
390  #define BSP_PRV_STABILIZE_MAIN_OSC               (1)
391 #elif defined(BSP_CFG_PLL2_SOURCE) && (BSP_CFG_PLL2_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) && BSP_PRV_PLL2_USED
392  #define BSP_PRV_MAIN_OSC_USED                    (1)
393  #define BSP_PRV_STABILIZE_MAIN_OSC               (1)
394 #elif defined(BSP_CFG_CLKOUT_SOURCE) && (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
395  #define BSP_PRV_MAIN_OSC_USED                    (1)
396 #elif defined(BSP_CFG_SCISPICLK_SOURCE) && (BSP_CFG_SCISPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
397  #define BSP_PRV_MAIN_OSC_USED                    (1)
398 #elif defined(BSP_CFG_SPICLK_SOURCE) && (BSP_CFG_SPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
399  #define BSP_PRV_MAIN_OSC_USED                    (1)
400 #elif defined(BSP_CFG_SCICLK_SOURCE) && (BSP_CFG_SCICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
401  #define BSP_PRV_MAIN_OSC_USED                    (1)
402 #elif defined(BSP_CFG_CANFDCLK_SOURCE) && (BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
403  #define BSP_PRV_MAIN_OSC_USED                    (1)
404 #elif defined(BSP_CFG_GPTCLK_SOURCE) && (BSP_CFG_GPTCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
405  #define BSP_PRV_MAIN_OSC_USED                    (1)
406 #elif defined(BSP_CFG_IICCLK_SOURCE) && (BSP_CFG_IICCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
407  #define BSP_PRV_MAIN_OSC_USED                    (1)
408 #elif defined(BSP_CFG_CECCLK_SOURCE) && (BSP_CFG_CECCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
409  #define BSP_PRV_MAIN_OSC_USED                    (1)
410 #elif defined(BSP_CFG_I3CCLK_SOURCE) && (BSP_CFG_I3CCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
411  #define BSP_PRV_MAIN_OSC_USED                    (1)
412 #elif defined(BSP_CFG_LCDCLK_SOURCE) && (BSP_CFG_LCDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
413  #define BSP_PRV_MAIN_OSC_USED                    (1)
414 #elif defined(BSP_CFG_U60CLK_SOURCE) && (BSP_CFG_U60CLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
415  #define BSP_PRV_MAIN_OSC_USED                    (1)
416 #elif defined(BSP_CFG_OCTA_SOURCE) && (BSP_CFG_OCTA_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
417  #define BSP_PRV_MAIN_OSC_USED                    (1)
418 #elif defined(BSP_CFG_SDADC_CLOCK_SOURCE) && (BSP_CFG_SDADC_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
419  #define BSP_PRV_MAIN_OSC_USED                    (1)
420 #elif defined(BSP_CFG_UARTA_CLOCK_SOURCE) && (BSP_CFG_UARTA_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
421  #define BSP_PRV_MAIN_OSC_USED                    (1)
422 #elif defined(BSP_CFG_TML_FITL0_SOURCE) && (BSP_CFG_TML_FITL0_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
423  #define BSP_PRV_MAIN_OSC_USED                    (1)
424 #elif defined(BSP_CFG_TML_FITL1_SOURCE) && (BSP_CFG_TML_FITL1_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
425  #define BSP_PRV_MAIN_OSC_USED                    (1)
426 #else
427  #define BSP_PRV_MAIN_OSC_USED                    (0)
428 #endif
429 
430 /* All clocks with configurable source can use HOCO except the CECCLK and I3CCLK. */
431 #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
432  #define BSP_PRV_HOCO_USED                        (1)
433  #define BSP_PRV_STABILIZE_HOCO                   (1)
434 #elif defined(BSP_CFG_PLL_SOURCE) && (BSP_CFG_PLL_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO) && BSP_PRV_PLL_USED
435  #define BSP_PRV_HOCO_USED                        (1)
436  #define BSP_PRV_STABILIZE_HOCO                   (1)
437 #elif defined(BSP_CFG_PLL2_SOURCE) && (BSP_CFG_PLL2_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO) && BSP_PRV_PLL2_USED
438  #define BSP_PRV_HOCO_USED                        (1)
439  #define BSP_PRV_STABILIZE_HOCO                   (1)
440 #elif defined(BSP_CFG_UCK_SOURCE) && BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ && \
441     (BSP_CFG_UCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
442  #define BSP_PRV_HOCO_USED                        (1)
443 #elif defined(BSP_CFG_CLKOUT_SOURCE) && (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
444  #define BSP_PRV_HOCO_USED                        (1)
445 #elif defined(BSP_CFG_SCISPICLK_SOURCE) && (BSP_CFG_SCISPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
446  #define BSP_PRV_HOCO_USED                        (1)
447 #elif defined(BSP_CFG_SPICLK_SOURCE) && (BSP_CFG_SPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
448  #define BSP_PRV_HOCO_USED                        (1)
449 #elif defined(BSP_CFG_SCICLK_SOURCE) && (BSP_CFG_SCICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
450  #define BSP_PRV_HOCO_USED                        (1)
451 #elif defined(BSP_CFG_CANFDCLK_SOURCE) && (BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
452  #define BSP_PRV_HOCO_USED                        (1)
453 #elif defined(BSP_CFG_GPTCLK_SOURCE) && (BSP_CFG_GPTCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
454  #define BSP_PRV_HOCO_USED                        (1)
455 #elif defined(BSP_CFG_IICCLK_SOURCE) && (BSP_CFG_IICCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
456  #define BSP_PRV_HOCO_USED                        (1)
457 #elif defined(BSP_CFG_LCDCLK_SOURCE) && (BSP_CFG_LCDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
458  #define BSP_PRV_HOCO_USED                        (1)
459 #elif defined(BSP_CFG_U60CLK_SOURCE) && (BSP_CFG_U60CLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
460  #define BSP_PRV_HOCO_USED                        (1)
461 #elif defined(BSP_CFG_OCTA_SOURCE) && (BSP_CFG_OCTA_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
462  #define BSP_PRV_HOCO_USED                        (1)
463 #elif defined(BSP_CFG_SDADC_CLOCK_SOURCE) && (BSP_CFG_SDADC_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_HOCO)
464  #define BSP_PRV_HOCO_USED                        (1)
465 #elif defined(BSP_CFG_UARTA_CLOCK_SOURCE) && (BSP_CFG_UARTA_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_HOCO)
466  #define BSP_PRV_HOCO_USED                        (1)
467 #elif defined(BSP_CFG_TML_FITL0_SOURCE) && (BSP_CFG_TML_FITL0_SOURCE == BSP_CLOCKS_SOURCE_HOCO)
468  #define BSP_PRV_HOCO_USED                        (1)
469 #elif defined(BSP_CFG_TML_FITL1_SOURCE) && (BSP_CFG_TML_FITL1_SOURCE == BSP_CLOCKS_SOURCE_HOCO)
470  #define BSP_PRV_HOCO_USED                        (1)
471 #else
472  #define BSP_PRV_HOCO_USED                        (0)
473 #endif
474 
475 /* All clocks with configurable source except PLL can use MOCO. */
476 #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
477  #define BSP_PRV_MOCO_USED                        (1)
478  #define BSP_PRV_STABILIZE_MOCO                   (1)
479 #elif defined(BSP_CFG_CLKOUT_SOURCE) && (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
480  #define BSP_PRV_MOCO_USED                        (1)
481 #elif defined(BSP_CFG_UCK_SOURCE) && BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ && \
482     (BSP_CFG_UCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
483  #define BSP_PRV_MOCO_USED                        (1)
484 #elif defined(BSP_CFG_SCISPICLK_SOURCE) && (BSP_CFG_SCISPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
485  #define BSP_PRV_MOCO_USED                        (1)
486 #elif defined(BSP_CFG_SPICLK_SOURCE) && (BSP_CFG_SPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
487  #define BSP_PRV_MOCO_USED                        (1)
488 #elif defined(BSP_CFG_SCICLK_SOURCE) && (BSP_CFG_SCICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
489  #define BSP_PRV_MOCO_USED                        (1)
490 #elif defined(BSP_CFG_CANFDCLK_SOURCE) && (BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
491  #define BSP_PRV_MOCO_USED                        (1)
492 #elif defined(BSP_CFG_GPTCLK_SOURCE) && (BSP_CFG_GPTCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
493  #define BSP_PRV_MOCO_USED                        (1)
494 #elif defined(BSP_CFG_IICCLK_SOURCE) && (BSP_CFG_IICCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
495  #define BSP_PRV_MOCO_USED                        (1)
496 #elif defined(BSP_CFG_I3CCLK_SOURCE) && (BSP_CFG_I3CCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
497  #define BSP_PRV_MOCO_USED                        (1)
498 #elif defined(BSP_CFG_LCDCLK_SOURCE) && (BSP_CFG_LCDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
499  #define BSP_PRV_MOCO_USED                        (1)
500 #elif defined(BSP_CFG_U60CLK_SOURCE) && (BSP_CFG_U60CLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
501  #define BSP_PRV_MOCO_USED                        (1)
502 #elif defined(BSP_CFG_OCTA_SOURCE) && (BSP_CFG_OCTA_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
503  #define BSP_PRV_MOCO_USED                        (1)
504 #elif defined(BSP_CFG_UARTA_CLOCK_SOURCE) && (BSP_CFG_UARTA_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
505  #define BSP_PRV_MOCO_USED                        (1)
506 #elif defined(BSP_CFG_TML_FITL0_SOURCE) && (BSP_CFG_TML_FITL0_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
507  #define BSP_PRV_MOCO_USED                        (1)
508 #elif defined(BSP_CFG_TML_FITL1_SOURCE) && (BSP_CFG_TML_FITL1_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
509  #define BSP_PRV_MOCO_USED                        (1)
510 #else
511  #define BSP_PRV_MOCO_USED                        (0)
512 #endif
513 
514 /* All clocks with configurable source except UCK, CANFD, LCDCLK, USBHSCLK, I3CCLK and PLL can use LOCO. */
515 #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
516  #define BSP_PRV_LOCO_USED                        (1)
517  #define BSP_PRV_STABILIZE_LOCO                   (1)
518 #elif defined(BSP_CFG_CLKOUT_SOURCE) && (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
519  #define BSP_PRV_LOCO_USED                        (1)
520 #elif defined(BSP_CFG_SCISPICLK_SOURCE) && (BSP_CFG_SCISPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
521  #define BSP_PRV_LOCO_USED                        (1)
522 #elif defined(BSP_CFG_SPICLK_SOURCE) && (BSP_CFG_SPICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
523  #define BSP_PRV_LOCO_USED                        (1)
524 #elif defined(BSP_CFG_SCICLK_SOURCE) && (BSP_CFG_SCICLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
525  #define BSP_PRV_LOCO_USED                        (1)
526 #elif defined(BSP_CFG_CANFDCLK_SOURCE) && (BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
527  #define BSP_PRV_LOCO_USED                        (1)
528 #elif defined(BSP_CFG_GPTCLK_SOURCE) && (BSP_CFG_GPTCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
529  #define BSP_PRV_LOCO_USED                        (1)
530 #elif defined(BSP_CFG_IICCLK_SOURCE) && (BSP_CFG_IICCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
531  #define BSP_PRV_LOCO_USED                        (1)
532 #elif defined(BSP_CFG_OCTA_SOURCE) && (BSP_CFG_OCTA_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
533  #define BSP_PRV_LOCO_USED                        (1)
534 #elif (defined(BSP_CFG_UARTA_CLOCK_SOURCE) && (BSP_CFG_UARTA_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_FSXP)) && \
535     (defined(BSP_CFG_FSXP_SOURCE) && (BSP_CFG_FSXP_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO))
536  #define BSP_PRV_LOCO_USED                        (1)
537 #elif (defined(BSP_CFG_FSXP_SOURCE) && (BSP_CFG_FSXP_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO))
538  #define BSP_PRV_LOCO_USED                        (1)
539 #else
540  #define BSP_PRV_LOCO_USED                        (0)
541 #endif
542 
543 /* Determine the optimal operating speed mode to apply after clock configuration based on the startup clock
544  * frequency. */
545 #if BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_CGC_LOW_SPEED_MAX_FREQ_HZ && \
546     !BSP_PRV_PLL_USED && !BSP_PRV_PLL2_USED
547  #define BSP_PRV_STARTUP_OPERATING_MODE           (BSP_PRV_OPERATING_MODE_LOW_SPEED)
548 #elif BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_CGC_MIDDLE_SPEED_MAX_FREQ_HZ
549  #define BSP_PRV_STARTUP_OPERATING_MODE           (BSP_PRV_OPERATING_MODE_MIDDLE_SPEED)
550 #else
551  #define BSP_PRV_STARTUP_OPERATING_MODE           (BSP_PRV_OPERATING_MODE_HIGH_SPEED)
552 #endif
553 
554 #if BSP_FEATURE_BSP_HAS_CLOCK_SUPPLY_TYPEB
555  #define BSP_PRV_CLOCK_SUPPLY_TYPE_B              (0 == BSP_CFG_ROM_REG_OFS1_ICSATS)
556 #else
557  #define BSP_PRV_CLOCK_SUPPLY_TYPE_B              (0)
558 #endif
559 
560 #if (BSP_FEATURE_BSP_HAS_CANFD_CLOCK && (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) &&    \
561     (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)) ||                                \
562     (BSP_FEATURE_BSP_HAS_SCISPI_CLOCK && (BSP_CFG_SCISPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) || \
563     (BSP_FEATURE_BSP_HAS_SCI_CLOCK && (BSP_CFG_SCICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
564     (BSP_FEATURE_BSP_HAS_SPI_CLOCK && (BSP_CFG_SPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
565     (BSP_FEATURE_BSP_HAS_GPT_CLOCK && (BSP_CFG_GPTCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
566     (BSP_FEATURE_BSP_HAS_IIC_CLOCK && (BSP_CFG_IICCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
567     (BSP_FEATURE_BSP_HAS_CEC_CLOCK && (BSP_CFG_CECCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
568     (BSP_FEATURE_BSP_HAS_I3C_CLOCK && (BSP_CFG_I3CCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||       \
569     (BSP_FEATURE_BSP_HAS_USB60_CLOCK_REQ && (BSP_CFG_U60CK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)) ||  \
570     (BSP_FEATURE_BSP_HAS_LCD_CLOCK && (BSP_CFG_LCDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED))
571 
572  #define BSP_PRV_HAS_ENABLED_PERIPHERAL_CLOCKS    (1U)
573 #else
574  #define BSP_PRV_HAS_ENABLED_PERIPHERAL_CLOCKS    (0U)
575 #endif
576 
577 /***********************************************************************************************************************
578  * Typedef definitions
579  **********************************************************************************************************************/
580 
581 /***********************************************************************************************************************
582  * Exported global variables (to be accessed by other files)
583  **********************************************************************************************************************/
584 
585 /***********************************************************************************************************************
586  * Private global variables and functions
587  **********************************************************************************************************************/
588 #if !BSP_FEATURE_CGC_REGISTER_SET_B
589 static uint8_t bsp_clock_set_prechange(uint32_t requested_freq_hz);
590 static void    bsp_clock_set_postchange(uint32_t updated_freq_hz, uint8_t new_rom_wait_state);
591 
592  #if BSP_FEATURE_CGC_HAS_MEMWAIT && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
593 static void bsp_clock_set_memwait(uint32_t updated_freq_hz);
594 
595  #endif
596 
597  #if !BSP_CFG_USE_LOW_VOLTAGE_MODE
598 static void bsp_prv_operating_mode_opccr_set(uint8_t operating_mode);
599 
600  #endif
601 void prv_clock_dividers_set(uint32_t sckdivcr, uint8_t sckdivcr2);
602 
603 #else
604 static void bsp_prv_cmc_init(void);
605 static void bsp_prv_operating_mode_flmode_set(uint8_t operating_mode);
606 
607  #if (BSP_CFG_CLKOUT_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) && (BSP_CFG_CLKOUT_SOURCE != BSP_CFG_CLOCK_SOURCE)
608 void bsp_prv_clkout_clock_set(void);
609 
610  #endif
611 
612 #endif
613 
614 static void bsp_prv_sosc_init(void);
615 
616 #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
617  #if defined(__ICCARM__)
618 
619 void R_BSP_SubClockStabilizeWait(uint32_t delay_ms);
620 void R_BSP_SubClockStabilizeWaitAfterReset(uint32_t delay_ms);
621 
622   #pragma weak R_BSP_SubClockStabilizeWait
623   #pragma weak R_BSP_SubClockStabilizeWaitAfterReset
624 
625  #elif defined(__GNUC__) || defined(__ARMCC_VERSION)
626 
627 void R_BSP_SubClockStabilizeWait(uint32_t delay_ms) __attribute__((weak));
628 void R_BSP_SubClockStabilizeWaitAfterReset(uint32_t delay_ms) __attribute__((weak));
629 
630  #endif
631 #endif
632 
633 #if (BSP_PRV_HAS_ENABLED_PERIPHERAL_CLOCKS == 1U)
634 static void bsp_peripheral_clock_set(volatile uint8_t * p_clk_ctrl_reg,
635                                      volatile uint8_t * p_clk_div_reg,
636                                      uint8_t            peripheral_clk_div,
637                                      uint8_t            peripheral_clk_source);
638 
639 #endif
640 
641 #if !BSP_FEATURE_CGC_REGISTER_SET_B
642  #if !BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
643 static void bsp_prv_clock_set_hard_reset(void);
644 
645  #else
646 void bsp_soft_reset_prepare(void);
647 
648  #endif
649 #endif
650 
651 /* This array stores the clock frequency of each system clock. This section of RAM should not be initialized by the C
652  * runtime environment. This is initialized and used in bsp_clock_init, which is called before the C runtime
653  * environment is initialized. */
654 static uint32_t g_clock_freq[BSP_PRV_NUM_CLOCKS]  BSP_PLACE_IN_SECTION(BSP_SECTION_NOINIT);
655 
656 #if BSP_TZ_SECURE_BUILD
657 
658 /* Callback used to notify the nonsecure project that the clock settings have changed. */
659 static bsp_clock_update_callback_t g_bsp_clock_update_callback = NULL;
660 
661 /* Pointer to nonsecure memory to store the callback args. */
662 static bsp_clock_update_callback_args_t * gp_callback_memory = NULL;
663 
664 /* Reentrant method of calling the clock_update_callback. */
r_bsp_clock_update_callback_call(bsp_clock_update_callback_t p_callback,bsp_clock_update_callback_args_t * p_callback_args)665 static void r_bsp_clock_update_callback_call (bsp_clock_update_callback_t        p_callback,
666                                               bsp_clock_update_callback_args_t * p_callback_args)
667 {
668     /* Allocate memory for saving global callback args on the secure stack. */
669     bsp_clock_update_callback_args_t callback_args;
670 
671     /* Save current info stored in callback memory. */
672     callback_args = *gp_callback_memory;
673 
674     /* Write the callback args to the nonsecure callback memory. */
675     *gp_callback_memory = *p_callback_args;
676 
677     /* Call the callback to notifiy ns project about clock changes. */
678     p_callback(gp_callback_memory);
679 
680     /* Restore the info in callback memory. */
681     *gp_callback_memory = callback_args;
682 }
683 
684 /* Initialize the callback, callback memory and invoke the callback to ensure the nonsecure project has the correct clock settings. */
r_bsp_clock_update_callback_set(bsp_clock_update_callback_t p_callback,bsp_clock_update_callback_args_t * p_callback_memory)685 void r_bsp_clock_update_callback_set (bsp_clock_update_callback_t        p_callback,
686                                       bsp_clock_update_callback_args_t * p_callback_memory)
687 {
688     /* Store pointer to nonsecure callback memory. */
689     gp_callback_memory = p_callback_memory;
690 
691     /* Store callback. */
692     g_bsp_clock_update_callback = p_callback;
693 
694     /* Set callback args. */
695     bsp_clock_update_callback_args_t callback_args =
696     {
697         .pll_freq = g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL]
698     };
699 
700     /* Call the callback. */
701     r_bsp_clock_update_callback_call(g_bsp_clock_update_callback, &callback_args);
702 }
703 
704 #elif BSP_TZ_NONSECURE_BUILD && BSP_CFG_CLOCKS_SECURE == 1
705 
706 bsp_clock_update_callback_args_t g_callback_memory;
707  #if BSP_TZ_SECURE_BUILD || BSP_TZ_NONSECURE_BUILD
708   #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
g_bsp_clock_update_callback(bsp_clock_update_callback_args_t * p_callback_args)709 static void BSP_CMSE_NONSECURE_CALL g_bsp_clock_update_callback (bsp_clock_update_callback_args_t * p_callback_args)
710   #elif defined(__GNUC__)
711 
712 static BSP_CMSE_NONSECURE_CALL void g_bsp_clock_update_callback (bsp_clock_update_callback_args_t * p_callback_args)
713   #endif
714 
715 {
716     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = p_callback_args->pll_freq;
717 
718     /* Update the SystemCoreClock value based on the new g_clock_freq settings. */
719     SystemCoreClockUpdate();
720 }
721 
722  #endif
723 #endif
724 
725 #if BSP_FEATURE_LPM_CHANGE_MSTP_REQUIRED
726 
727 /* List of MSTP bits that must be set before entering low power modes or changing SCKDIVCR. */
728 static const uint8_t g_bsp_prv_power_change_mstp_data[][2] = BSP_FEATURE_LPM_CHANGE_MSTP_ARRAY;
729 
730 static const uint8_t g_bsp_prv_power_change_mstp_length = sizeof(g_bsp_prv_power_change_mstp_data) /
731                                                           sizeof(g_bsp_prv_power_change_mstp_data[0]);
732 
733 static volatile uint32_t * const gp_bsp_prv_mstp = &R_MSTP->MSTPCRB;
734 #endif
735 
736 /*******************************************************************************************************************//**
737  * @internal
738  * @addtogroup BSP_MCU_PRV Internal BSP Documentation
739  * @ingroup RENESAS_INTERNAL
740  * @{
741  **********************************************************************************************************************/
742 
743 #if !BSP_FEATURE_CGC_REGISTER_SET_B
744  #if !BSP_CFG_USE_LOW_VOLTAGE_MODE
745 
746 /***********************************************************************************************************************
747  * Changes the operating speed in OPCCR.  Assumes the LPM registers are unlocked in PRCR and cache is off.
748  *
749  * @param[in]  operating_mode  Desired operating mode, must be one of the BSP_PRV_OPERATING_MODE_* macros, cannot be
750  *                             BSP_PRV_OPERATING_MODE_SUBOSC_SPEED
751  **********************************************************************************************************************/
bsp_prv_operating_mode_opccr_set(uint8_t operating_mode)752 static void bsp_prv_operating_mode_opccr_set (uint8_t operating_mode)
753 {
754   #if BSP_FEATURE_CGC_HOCOSF_BEFORE_OPCCR
755 
756     /* If the desired operating mode is already set, return. */
757     if (operating_mode == R_SYSTEM->OPCCR)
758     {
759         return;
760     }
761 
762     /* On some MCUs, the HOCO must be stable before updating OPCCR.OPCM. */
763     if (0U == R_SYSTEM->HOCOCR)
764     {
765         /* Wait for HOCO to stabilize. */
766         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 1U);
767     }
768   #endif
769 
770     /* Wait for transition to complete. */
771     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OPCCR_b.OPCMTSF, 0U);
772 
773     /* Apply requested operating speed mode. */
774     R_SYSTEM->OPCCR = operating_mode;
775 
776     /* Wait for transition to complete. */
777     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OPCCR_b.OPCMTSF, 0U);
778 }
779 
780  #endif
781 #endif
782 
783 #if !BSP_CFG_USE_LOW_VOLTAGE_MODE
784 
785 /***********************************************************************************************************************
786  * Changes the operating speed mode.  Assumes the LPM registers are unlocked in PRCR and cache is off.
787  *
788  * @param[in]  operating_mode  Desired operating mode, must be one of the BSP_PRV_OPERATING_MODE_* macros
789  **********************************************************************************************************************/
bsp_prv_operating_mode_set(uint8_t operating_mode)790 void bsp_prv_operating_mode_set (uint8_t operating_mode)
791 {
792  #if BSP_PRV_POWER_USE_DCDC
793     static bsp_power_mode_t power_mode = BSP_POWER_MODE_LDO;
794 
795     /* Disable DCDC if transitioning to an incompatible mode. */
796     if ((operating_mode > BSP_PRV_OPERATING_MODE_MIDDLE_SPEED) && (R_SYSTEM->DCDCCTL & R_SYSTEM_DCDCCTL_DCDCON_Msk))
797     {
798         /* LDO boost must be used if entering subclock speed mode (see RA2L1 User's Manual (R01UH0853EJ0100) Section
799          * 10.5.1 (5) Switching from High-speed/Middle-speed mode in DCDC power mode to Subosc-speed mode or Software
800          * Standby mode). */
801         power_mode = R_BSP_PowerModeSet((BSP_PRV_OPERATING_MODE_SUBOSC_SPEED == operating_mode) ?
802                                         BSP_POWER_MODE_LDO_BOOST : BSP_POWER_MODE_LDO);
803     }
804  #endif
805 
806  #if BSP_FEATURE_CGC_HAS_SOPCCR
807     if (BSP_PRV_OPERATING_MODE_SUBOSC_SPEED == operating_mode)
808     {
809         /* Wait for transition to complete. */
810         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOPCCR_b.SOPCMTSF, 0U);
811 
812         /* Set subosc speed mode. */
813         R_SYSTEM->SOPCCR = 0x1U;
814 
815         /* Wait for transition to complete. */
816         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOPCCR_b.SOPCMTSF, 0U);
817     }
818     else
819  #endif
820     {
821  #if BSP_FEATURE_CGC_HAS_SOPCCR
822 
823         /* Wait for transition to complete. */
824         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOPCCR_b.SOPCMTSF, 0U);
825 
826         /* Exit subosc speed mode first. */
827         R_SYSTEM->SOPCCR = 0U;
828 
829         /* Wait for transition to complete. Check the entire register here since it should be set to 0 at this point.
830          * Checking the entire register is slightly more efficient. This will also hang the program if the LPM
831          * registers are not unlocked, which can help catch programming errors. */
832         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOPCCR, 0U);
833  #endif
834 
835  #if BSP_FEATURE_CGC_REGISTER_SET_B
836         bsp_prv_operating_mode_flmode_set(operating_mode);
837  #else
838         bsp_prv_operating_mode_opccr_set(operating_mode);
839  #endif
840     }
841 
842  #if BSP_PRV_POWER_USE_DCDC
843 
844     /* Enable DCDC if it was previously enabled. */
845     if ((operating_mode <= BSP_PRV_OPERATING_MODE_MIDDLE_SPEED) && (power_mode < BSP_POWER_MODE_LDO))
846     {
847         R_BSP_PowerModeSet(power_mode);
848         power_mode = BSP_POWER_MODE_LDO;
849     }
850  #endif
851 }
852 
853 #endif
854 
855 #if BSP_PRV_PLL_SUPPORTED
856 
857 /***********************************************************************************************************************
858  * Updates the operating frequency of the specified PLL and all its output channels.
859  *
860  * @param[in] clock                    PLL being configured
861  * @param[in] p_pll_hz                 Array of values of the new PLL output clock frequencies
862  **********************************************************************************************************************/
bsp_prv_prepare_pll(uint32_t clock,uint32_t const * const p_pll_hz)863 void bsp_prv_prepare_pll (uint32_t clock, uint32_t const * const p_pll_hz)
864 {
865     if (BSP_CLOCKS_SOURCE_CLOCK_PLL == clock)
866     {
867         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = p_pll_hz[0];
868  #if 3 == BSP_FEATURE_CGC_PLL1_NUM_OUTPUT_CLOCKS
869         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1Q] = p_pll_hz[1];
870         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1R] = p_pll_hz[2];
871  #endif
872     }
873 
874  #if BSP_PRV_PLL2_SUPPORTED
875     else
876     {
877         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2] = p_pll_hz[0];
878   #if 3 == BSP_FEATURE_CGC_PLL2_NUM_OUTPUT_CLOCKS
879         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2Q] = p_pll_hz[1];
880         g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2R] = p_pll_hz[2];
881   #endif
882     }
883  #endif
884 }
885 
886 #endif
887 
888 /*******************************************************************************************************************//**
889  * Update SystemCoreClock variable based on current clock settings.
890  **********************************************************************************************************************/
SystemCoreClockUpdate(void)891 void SystemCoreClockUpdate (void)
892 {
893 #if !BSP_FEATURE_CGC_REGISTER_SET_B
894  #if BSP_FEATURE_TZ_HAS_TRUSTZONE && (BSP_TZ_SECURE_BUILD || BSP_TZ_NONSECURE_BUILD) && BSP_FEATURE_TZ_VERSION == 2
895     bool secure = !R_SYSTEM->CGFSAR_b.NONSEC00;
896  #endif
897 
898     uint32_t clock_index = FSP_STYPE3_REG8_READ(R_SYSTEM->SCKSCR, secure);
899 
900  #if !BSP_FEATURE_CGC_HAS_CPUCLK
901     uint32_t ick =
902         (FSP_STYPE3_REG32_READ(R_SYSTEM->SCKDIVCR, secure) & R_SYSTEM_SCKDIVCR_ICK_Msk) >> R_SYSTEM_SCKDIVCR_ICK_Pos;
903     SystemCoreClock = g_clock_freq[clock_index] >> ick;
904  #else
905     uint8_t cpuck = (FSP_STYPE3_REG8_READ(R_SYSTEM->SCKDIVCR2, secure) & R_SYSTEM_SCKDIVCR2_CPUCK_Msk) >>
906                     R_SYSTEM_SCKDIVCR2_CPUCK_Pos;
907     uint8_t cpuclk_div = cpuck;
908 
909     if (8U == cpuclk_div)
910     {
911         SystemCoreClock = g_clock_freq[clock_index] / 3U;
912     }
913     else if (9U == cpuclk_div)
914     {
915         SystemCoreClock = g_clock_freq[clock_index] / 6U;
916     }
917     else if (10U == cpuclk_div)
918     {
919         SystemCoreClock = g_clock_freq[clock_index] / 12U;
920     }
921     else
922     {
923         SystemCoreClock = g_clock_freq[clock_index] >> cpuclk_div;
924     }
925  #endif
926 #else
927  #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
928     SystemCoreClock = g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC] >> R_SYSTEM->MOSCDIV;
929  #endif
930     if (BSP_CLOCKS_SOURCE_CLOCK_FSUB == R_SYSTEM->ICLKSCR_b.CKST)
931     {
932  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
933         SystemCoreClock = R_SYSTEM->FSUBSCR ? g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_LOCO] : \
934                           g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK];
935  #else
936         SystemCoreClock = g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_LOCO];
937  #endif
938     }
939     else
940     {
941  #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
942         if (BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO == R_SYSTEM->FMAINSCR_b.CKST)
943  #endif
944         {
945             SystemCoreClock = R_SYSTEM->FOCOSCR_b.CKST ?                                        \
946                               g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_MOCO] >> R_SYSTEM->MOCODIV : \
947                               g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_HOCO] >> R_SYSTEM->HOCODIV;
948         }
949     }
950 #endif
951 }
952 
953 #if BSP_FEATURE_LPM_CHANGE_MSTP_REQUIRED
954 
955 /*******************************************************************************************************************//**
956  * Sets MSTP bits as required by the hardware manual for the MCU (reference Figure 9.2 "Example flow for changing the
957  * value of SCKDIVCR" in the RA6M3 manual R01UH0886EJ0100).
958  *
959  * This function must be called before entering standby or changing SCKDIVCR.
960  *
961  * @return bitmask of bits set, where each bit corresponds to an index in g_bsp_prv_power_change_mstp_data
962  **********************************************************************************************************************/
bsp_prv_power_change_mstp_set(void)963 uint32_t bsp_prv_power_change_mstp_set (void)
964 {
965     uint32_t mstp_set_bitmask = 0U;
966     for (uint32_t i = 0U; i < g_bsp_prv_power_change_mstp_length; i++)
967     {
968         /* Get the MSTP register index and the bit to test from the MCU specific array. */
969         uint32_t mstp_index = g_bsp_prv_power_change_mstp_data[i][0];
970         uint32_t mstp_bit   = 1U << g_bsp_prv_power_change_mstp_data[i][1];
971 
972         /* Only set the bit if it's currently cleared. */
973         if (!(gp_bsp_prv_mstp[mstp_index] & mstp_bit))
974         {
975             gp_bsp_prv_mstp[mstp_index] |= mstp_bit;
976             mstp_set_bitmask            |= 1U << i;
977         }
978 
979         /* This loop takes over 250 ns (30 cycles at 120 MHz) between 2 consecutive bits being set. It was measured
980          * at 58 cycles for default IAR build configurations and 59 cycles for default GCC build configurations. */
981     }
982 
983     /* The time between setting last MSTP bit and setting SCKDIVCR takes over 750 ns (90 cycles at 120 MHz). It was
984      * measured at 96 cycles for default IAR build configurations and 102 cycles for default GCC build
985      * configurations. */
986 
987     return mstp_set_bitmask;
988 }
989 
990 #endif
991 
992 #if BSP_FEATURE_LPM_CHANGE_MSTP_REQUIRED
993 
994 /*******************************************************************************************************************//**
995  * Clears MSTP bits set by bsp_prv_power_change_mstp_set as required by the hardware manual for the MCU (reference
996  * Figure 9.2 "Example flow for changing the value of SCKDIVCR" in the RA6M3 manual R01UH0886EJ0100).
997  *
998  * This function must be called after exiting standby or changing SCKDIVCR.
999  *
1000  * @param[in] mstp_clear_bitmask       bitmask of bits to clear, where each bit corresponds to an index in
1001  *                                     g_bsp_prv_power_change_mstp_data
1002  **********************************************************************************************************************/
bsp_prv_power_change_mstp_clear(uint32_t mstp_clear_bitmask)1003 void bsp_prv_power_change_mstp_clear (uint32_t mstp_clear_bitmask)
1004 {
1005     /* The time between setting SCKDIVCR and clearing the first MSTP bit takes over 250 ns (30 cycles at 120 MHz). It
1006      * was measured at 38 cycles for default IAR build configurations and 68 cycles for default GCC build
1007      * configurations. */
1008 
1009     for (uint32_t i = 0U; i < g_bsp_prv_power_change_mstp_length; i++)
1010     {
1011         /* Only clear the bit if it was set in bsp_prv_power_change_mstp_set. */
1012         if ((1U << i) & mstp_clear_bitmask)
1013         {
1014             /* Get the MSTP register index and the bit to test from the MCU specific array. */
1015             uint32_t mstp_index = g_bsp_prv_power_change_mstp_data[i][0];
1016             uint32_t mstp_bit   = 1U << g_bsp_prv_power_change_mstp_data[i][1];
1017 
1018             gp_bsp_prv_mstp[mstp_index] &= ~mstp_bit;
1019         }
1020 
1021         /* This loop takes over 250 ns (30 cycles at 120 MHz) between 2 consecutive bits being cleared. It was measured
1022          * at 44 cycles for default IAR build configurations and 53 cycles for default GCC build configurations. */
1023     }
1024 }
1025 
1026 #endif
1027 
1028 #if !BSP_FEATURE_CGC_REGISTER_SET_B
1029 
1030 /*******************************************************************************************************************//**
1031  * Write SCKDIVCR and SCKDIVCR2 in the correct order to ensure that CPUCLK frequency is greater than ICLK frequency.
1032  *
1033  * @param[in] sckdivcr                 The new SCKDIVCR setting.
1034  * @param[in] sckdivcr2                The new SCKDIVCR2 setting.
1035  **********************************************************************************************************************/
prv_clock_dividers_set(uint32_t sckdivcr,uint8_t sckdivcr2)1036 void prv_clock_dividers_set (uint32_t sckdivcr, uint8_t sckdivcr2)
1037 {
1038  #if BSP_FEATURE_CGC_HAS_CPUCLK
1039     uint32_t requested_iclk_div = BSP_PRV_SCKDIVCR_DIV_VALUE(
1040         (sckdivcr >> FSP_PRIV_CLOCK_ICLK) & FSP_PRV_SCKDIVCR_DIV_MASK);
1041     uint32_t current_iclk_div = BSP_PRV_SCKDIVCR_DIV_VALUE(R_SYSTEM->SCKDIVCR_b.ICK);
1042 
1043     if (requested_iclk_div >= current_iclk_div)
1044     {
1045         /* If the requested ICLK divider is greater than or equal to the current ICLK divider, then writing to
1046          * SCKDIVCR first will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1047         R_SYSTEM->SCKDIVCR  = sckdivcr;
1048         R_SYSTEM->SCKDIVCR2 = sckdivcr2;
1049     }
1050     else
1051     {
1052         /* If the requested ICLK divider is less than the current ICLK divider, then writing to SCKDIVCR2 first
1053          * will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1054         R_SYSTEM->SCKDIVCR2 = sckdivcr2;
1055         R_SYSTEM->SCKDIVCR  = sckdivcr;
1056     }
1057 
1058  #else
1059     FSP_PARAMETER_NOT_USED(sckdivcr2);
1060 
1061     R_SYSTEM->SCKDIVCR = sckdivcr;
1062  #endif
1063 }
1064 
1065 /*******************************************************************************************************************//**
1066  * Applies system core clock source and divider changes.  The MCU is expected to be in high speed mode during this
1067  * configuration and the CGC registers are expected to be unlocked in PRCR.
1068  *
1069  * @param[in] clock                    Desired system clock
1070  * @param[in] sckdivcr                 Value to set in SCKDIVCR register
1071  * @param[in] sckdivcr2                Value to set in SCKDIVCR2 register
1072  **********************************************************************************************************************/
bsp_prv_clock_set(uint32_t clock,uint32_t sckdivcr,uint8_t sckdivcr2)1073 void bsp_prv_clock_set (uint32_t clock, uint32_t sckdivcr, uint8_t sckdivcr2)
1074 {
1075  #if BSP_FEATURE_LPM_CHANGE_MSTP_REQUIRED
1076 
1077     /* Set MSTP bits as required by the hardware manual. This is done first to ensure the 750 ns delay required after
1078      * increasing any division ratio in SCKDIVCR is met. */
1079     uint32_t mstp_set_bitmask = bsp_prv_power_change_mstp_set();
1080  #endif
1081 
1082     uint32_t iclk_div                 = (sckdivcr >> FSP_PRIV_CLOCK_ICLK) & FSP_PRV_SCKDIVCR_DIV_MASK;
1083     uint32_t iclk_freq_hz_post_change = g_clock_freq[clock] / BSP_PRV_SCKDIVCR_DIV_VALUE(iclk_div);
1084  #if BSP_FEATURE_CGC_HAS_CPUCLK
1085     uint32_t cpuclk_div                = sckdivcr2 & R_SYSTEM_SCKDIVCR2_CPUCK_Msk;
1086     uint32_t clock_freq_hz_post_change = g_clock_freq[clock] / BSP_PRV_SCKDIVCR_DIV_VALUE(cpuclk_div);
1087  #else
1088     uint32_t clock_freq_hz_post_change = iclk_freq_hz_post_change;
1089  #endif
1090 
1091     /* Adjust the MCU specific wait state right before the system clock is set, if the system clock frequency to be
1092      * set is higher than before. */
1093     uint8_t new_rom_wait_state = bsp_clock_set_prechange(iclk_freq_hz_post_change);
1094 
1095     /* Switching to a faster source clock. */
1096     if (g_clock_freq[clock] >= g_clock_freq[R_SYSTEM->SCKSCR])
1097     {
1098  #if BSP_CFG_CLOCK_SETTLING_DELAY_ENABLE
1099         bool post_div_set_delay = false;
1100 
1101         if ((clock_freq_hz_post_change > SystemCoreClock) &&
1102             ((clock_freq_hz_post_change - SystemCoreClock) > BSP_MAX_CLOCK_CHANGE_THRESHOLD))
1103         {
1104             /* If the requested ICLK divider is greater than or equal to the current ICLK divider, then writing to
1105              * SCKDIVCR first will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1106             if (iclk_div == sckdivcr2)
1107             {
1108                 /* If dividers are equal, bump both down 1 notch.
1109                  * /1 and /2 are the only possible options. */
1110                 uint32_t new_div = BSP_CLOCKS_SYS_CLOCK_DIV_2;
1111                 if (cpuclk_div == BSP_CLOCKS_SYS_CLOCK_DIV_1)
1112                 {
1113                     new_div = BSP_CLOCKS_SYS_CLOCK_DIV_4;
1114                 }
1115 
1116                 R_SYSTEM->SCKDIVCR = (sckdivcr & ~(R_SYSTEM_SCKDIVCR_ICK_Msk)) |
1117                                      (new_div << R_SYSTEM_SCKDIVCR_ICK_Pos);
1118                 R_SYSTEM->SCKDIVCR2 = (uint8_t) new_div;
1119             }
1120             else
1121             {
1122                 R_SYSTEM->SCKDIVCR = sckdivcr;
1123                 if (cpuclk_div == BSP_CLOCKS_SYS_CLOCK_DIV_1)
1124                 {
1125                     /* Determine what the other dividers are using and stay aligned with that. */
1126                     R_SYSTEM->SCKDIVCR2 =
1127                         (iclk_div & 0x8) ? BSP_CLOCKS_SYS_CLOCK_DIV_3 : BSP_CLOCKS_SYS_CLOCK_DIV_2;
1128                 }
1129                 else
1130                 {
1131                     /* If not /1, can just add 1 to it. */
1132                     R_SYSTEM->SCKDIVCR2 = sckdivcr2 + 1;
1133                 }
1134             }
1135 
1136             /* Set the system source clock */
1137             R_SYSTEM->SCKSCR = (uint8_t) clock;
1138 
1139             /* Wait for settling delay. */
1140             SystemCoreClockUpdate();
1141             R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1142 
1143             /* Trigger delay after setting dividers */
1144             post_div_set_delay = true;
1145         }
1146         /* Continue and set clock to actual target speed. */
1147  #endif
1148 
1149         /* Set the clock dividers before switching to the new clock source. */
1150         prv_clock_dividers_set(sckdivcr, sckdivcr2);
1151 
1152  #if BSP_CFG_CLOCK_SETTLING_DELAY_ENABLE
1153         if (post_div_set_delay)
1154         {
1155             /* Update the CMSIS core clock variable so that it reflects the new ICLK frequency. */
1156             SystemCoreClock = clock_freq_hz_post_change;
1157 
1158             /* Wait for settling delay. */
1159             R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1160         }
1161         else
1162  #endif
1163         {
1164             /* Switch to the new clock source. */
1165             R_SYSTEM->SCKSCR = (uint8_t) clock;
1166         }
1167     }
1168     /* Switching to a slower source clock. */
1169     else
1170     {
1171  #if BSP_CFG_CLOCK_SETTLING_DELAY_ENABLE
1172         if ((SystemCoreClock > clock_freq_hz_post_change) &&
1173             ((SystemCoreClock - clock_freq_hz_post_change) > BSP_MAX_CLOCK_CHANGE_THRESHOLD))
1174         {
1175             uint32_t current_sckdivcr = R_SYSTEM->SCKDIVCR;
1176 
1177             /* Must first step CPUCLK down by factor of 2 or 3 if it is currently above threshold. */
1178             if (R_SYSTEM->SCKDIVCR2 == ((current_sckdivcr >> R_SYSTEM_SCKDIVCR_ICK_Pos) & 0xF))
1179             {
1180                 /* If ICLK and CPUCLK have same divider currently, move ICLK down 1 notch first. */
1181                 uint32_t current_iclk_div = (current_sckdivcr >> R_SYSTEM_SCKDIVCR_ICK_Pos) & 0xF;
1182                 uint32_t new_div          = current_iclk_div + 1;
1183                 if (current_iclk_div == 0)
1184                 {
1185                     /* Align with already selected divider for PCLKA because it must have one > 1 already. */
1186                     new_div =
1187                         (current_sckdivcr &
1188                          (0x8 << R_SYSTEM_SCKDIVCR_PCKA_Pos)) ? BSP_CLOCKS_SYS_CLOCK_DIV_3 : BSP_CLOCKS_SYS_CLOCK_DIV_2;
1189                 }
1190 
1191                 R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1192                 R_SYSTEM->SCKDIVCR = (current_sckdivcr & ~(R_SYSTEM_SCKDIVCR_ICK_Msk)) |
1193                                      (new_div << R_SYSTEM_SCKDIVCR_ICK_Pos);
1194                 R_SYSTEM->SCKDIVCR2 = (uint8_t) new_div;
1195 
1196                 SystemCoreClockUpdate();
1197             }
1198         }
1199         R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1200  #endif
1201         R_SYSTEM->SCKSCR = (uint8_t) clock;
1202 
1203         /* Set the clock dividers after switching to the new clock source. */
1204         prv_clock_dividers_set(sckdivcr, sckdivcr2);
1205     }
1206 
1207     /* Clock is now at requested frequency. */
1208 
1209     /* Update the CMSIS core clock variable so that it reflects the new ICLK frequency. */
1210     SystemCoreClock = clock_freq_hz_post_change;
1211 
1212  #if BSP_TZ_SECURE_BUILD
1213     if (NULL != g_bsp_clock_update_callback)
1214     {
1215         /* Set callback args. */
1216         bsp_clock_update_callback_args_t callback_args =
1217         {
1218             .pll_freq = g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL]
1219         };
1220 
1221         /* Call the callback. */
1222         r_bsp_clock_update_callback_call(g_bsp_clock_update_callback, &callback_args);
1223     }
1224  #endif
1225 
1226     /* Adjust the MCU specific wait state soon after the system clock is set, if the system clock frequency to be
1227      * set is lower than previous. */
1228     bsp_clock_set_postchange(SystemCoreClock, new_rom_wait_state);
1229 
1230  #if BSP_FEATURE_LPM_CHANGE_MSTP_REQUIRED
1231 
1232     /* Clear MSTP bits as required by the hardware manual. This is done last to ensure the 250 ns delay required after
1233      * decreasing any division ratio in SCKDIVCR is met. */
1234     bsp_prv_power_change_mstp_clear(mstp_set_bitmask);
1235  #endif
1236 }
1237 
1238  #if BSP_CFG_SLEEP_MODE_DELAY_ENABLE || BSP_CFG_RTOS_SLEEP_MODE_DELAY_ENABLE
1239 
bsp_prv_clock_prepare_pre_sleep(void)1240 bool bsp_prv_clock_prepare_pre_sleep (void)
1241 {
1242     /* Must wait before entering or exiting sleep modes.
1243      * See Section 10.7.10 in RA8M1 manual R01UH0994EJ0100 */
1244     R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1245 
1246     /* Need to slow CPUCLK down before sleeping if it is above 240MHz. */
1247     bool cpuclk_slowed = false;
1248     if (SystemCoreClock > BSP_MAX_CLOCK_CHANGE_THRESHOLD)
1249     {
1250         /* Reduce speed of CPUCLK to /2 or /3 of current, select which ones based on what ICLK divider is. */
1251         R_SYSTEM->SCKDIVCR2 =
1252             (R_SYSTEM->SCKDIVCR &
1253              (0x8 << R_SYSTEM_SCKDIVCR_ICK_Pos)) ? BSP_CLOCKS_SYS_CLOCK_DIV_3 : BSP_CLOCKS_SYS_CLOCK_DIV_2;
1254         cpuclk_slowed = true;
1255         SystemCoreClockUpdate();
1256         R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1257     }
1258 
1259     return cpuclk_slowed;
1260 }
1261 
bsp_prv_clock_prepare_post_sleep(bool cpuclk_slowed)1262 void bsp_prv_clock_prepare_post_sleep (bool cpuclk_slowed)
1263 {
1264     /* Set CPUCLK back to original speed here if it was slowed down before sleeping (dropped to below 240MHz)
1265      * Add delays as described in Section 10.7.10 of RA8M1 manual R01UH0994EJ0100 */
1266     R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1267     if (cpuclk_slowed)
1268     {
1269         /* Set divider of CPUCLK back to /1. This is the only possible value for it to have been over 240MHz before sleeping. */
1270         R_SYSTEM->SCKDIVCR2 = BSP_CLOCKS_SYS_CLOCK_DIV_1;
1271         SystemCoreClockUpdate();
1272         R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1273     }
1274 }
1275 
1276  #endif
1277 
1278 #else
1279 
1280 /*******************************************************************************************************************//**
1281  * Get system core clock source.
1282  *
1283  **********************************************************************************************************************/
bsp_prv_clock_source_get(void)1284 uint32_t bsp_prv_clock_source_get (void)
1285 {
1286     /*
1287      * | System clock source | FOCOSCR.CKSEL | FMAINSCR.CKSEL | FSUBSCR.CKSEL | ICLKSCR.CKSEL |
1288      * | ------------------- | ------------- | -------------- | ------------- | ------------- |
1289      * | HOCO                | 0U            | 0U             | x             | 0U            |
1290      * | MOCO                | 1U            | 0U             | x             | 0U            |
1291      * | MOSC                | x             | 1U             | x             | 0U            |
1292      * | LOCO                | x             | x              | 1U            | 1U            |
1293      * | SOSC                | x             | x              | 0U            | 1U            |
1294      *
1295      * */
1296     uint32_t clock = BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC;
1297 
1298     if (BSP_CLOCKS_SOURCE_CLOCK_FSUB == R_SYSTEM->ICLKSCR_b.CKST)
1299     {
1300         clock = R_SYSTEM->FSUBSCR ? BSP_CLOCKS_SOURCE_CLOCK_LOCO : BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK;
1301     }
1302     else if (BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO == R_SYSTEM->FMAINSCR_b.CKST)
1303     {
1304         clock = R_SYSTEM->FOCOSCR_b.CKST ? BSP_CLOCKS_SOURCE_CLOCK_MOCO : BSP_CLOCKS_SOURCE_CLOCK_HOCO;
1305     }
1306     else
1307     {
1308         /* Do nothing. */
1309     }
1310 
1311     return clock;
1312 }
1313 
1314 /*******************************************************************************************************************//**
1315  * Applies system core clock source and divider changes.  The MCU is expected to be in high speed mode during this
1316  * configuration and the CGC registers are expected to be unlocked in PRCR.
1317  *
1318  * @param[in] clock                  Desired system clock
1319  * @param[in] hocodiv                The new HOCODIV setting.
1320  * @param[in] mocodiv                The new MOCODIV setting.
1321  * @param[in] moscdiv                The new MOSCDIV setting.
1322  **********************************************************************************************************************/
bsp_prv_clock_set(uint32_t clock,uint8_t hocodiv,uint8_t mocodiv,uint8_t moscdiv)1323 void bsp_prv_clock_set (uint32_t clock, uint8_t hocodiv, uint8_t mocodiv, uint8_t moscdiv)
1324 {
1325     /*
1326      * | System clock source | FOCOSCR.CKSEL | FMAINSCR.CKSEL | FSUBSCR.CKSEL | ICLKSCR.CKSEL |
1327      * | ------------------- | ------------- | -------------- | ------------- | ------------- |
1328      * | HOCO                | 0U            | 0U             | x             | 0U            |
1329      * | MOCO                | 1U            | 0U             | x             | 0U            |
1330      * | MOSC                | x             | 1U             | x             | 0U            |
1331      * | LOCO                | x             | x              | 1U            | 1U            |
1332      * | SOSC                | x             | x              | 0U            | 1U            |
1333      *
1334      * */
1335     R_SYSTEM->ICLKSCR_b.CKSEL = BSP_CLOCKS_SOURCE_CLOCK_FMAIN;
1336     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->ICLKSCR_b.CKST, BSP_CLOCKS_SOURCE_CLOCK_FMAIN);
1337 
1338     if ((BSP_CLOCKS_SOURCE_CLOCK_HOCO == clock) || (BSP_CLOCKS_SOURCE_CLOCK_MOCO == clock))
1339     {
1340         R_SYSTEM->FMAINSCR_b.CKSEL = BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO;
1341         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FMAINSCR_b.CKST, BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO);
1342 
1343         if (BSP_CLOCKS_SOURCE_CLOCK_HOCO == clock)
1344         {
1345             R_SYSTEM->FOCOSCR_b.CKSEL = BSP_CLOCKS_FOCO_SOURCE_CLOCK_HOCO;
1346             FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FOCOSCR_b.CKST, BSP_CLOCKS_FOCO_SOURCE_CLOCK_HOCO);
1347 
1348             /* Due to register access restrictions (see 8.6.1 Register Access), only set the HOCODIV when system clock source is HOCO */
1349             R_SYSTEM->HOCODIV = hocodiv;
1350         }
1351         else
1352         {
1353             R_SYSTEM->FOCOSCR_b.CKSEL = BSP_CLOCKS_FOCO_SOURCE_CLOCK_MOCO;
1354             FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FOCOSCR_b.CKST, BSP_CLOCKS_FOCO_SOURCE_CLOCK_MOCO);
1355         }
1356     }
1357 
1358  #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
1359     else if (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC == clock)
1360     {
1361         R_SYSTEM->FMAINSCR_b.CKSEL = BSP_CLOCKS_FMAIN_SOURCE_CLOCK_MAIN_OSC;
1362         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FMAINSCR_b.CKST, BSP_CLOCKS_FMAIN_SOURCE_CLOCK_MAIN_OSC);
1363     }
1364  #endif
1365     else
1366     {
1367         if (BSP_CLOCKS_SOURCE_CLOCK_LOCO == clock)
1368         {
1369             R_SYSTEM->FSUBSCR = BSP_CLOCKS_FSUB_SOURCE_CLOCK_LOCO;
1370         }
1371 
1372  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
1373         else
1374         {
1375             R_SYSTEM->FSUBSCR = BSP_CLOCKS_FSUB_SOURCE_CLOCK_SUBCLOCK;
1376         }
1377  #endif
1378 
1379         R_SYSTEM->ICLKSCR_b.CKSEL = BSP_CLOCKS_SOURCE_CLOCK_FSUB;
1380         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->ICLKSCR_b.CKST, BSP_CLOCKS_SOURCE_CLOCK_FSUB);
1381     }
1382 
1383     R_SYSTEM->MOCODIV = mocodiv;
1384     R_SYSTEM->MOSCDIV = moscdiv;
1385 
1386     /* Clock is now at requested frequency. Update the CMSIS core clock variable so that it reflects the new ICLK frequency.*/
1387     SystemCoreClockUpdate();
1388 }
1389 
1390  #if (BSP_CFG_CLKOUT_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) && (BSP_CFG_CLKOUT_SOURCE != BSP_CFG_CLOCK_SOURCE)
1391 
1392 /*******************************************************************************************************************//**
1393  * Applies CLKOUT clock source
1394  **********************************************************************************************************************/
bsp_prv_clkout_clock_set(void)1395 void bsp_prv_clkout_clock_set (void)
1396 {
1397   #if (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK) || \
1398     (BSP_CFG_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO)
1399 
1400     /* Due to register access restrictions (see 8.6.1 Register Access), change the ICLKSCR.CKSEL = 1 (ICLK = FMAIN) before configuration */
1401     R_SYSTEM->ICLKSCR_b.CKSEL = BSP_CLOCKS_SOURCE_CLOCK_FMAIN;
1402     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->ICLKSCR_b.CKST, BSP_CLOCKS_SOURCE_CLOCK_FMAIN);
1403 
1404    #if (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO)
1405     R_SYSTEM->FMAINSCR_b.CKSEL = BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO;
1406     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FMAINSCR_b.CKST, BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO);
1407     R_SYSTEM->FOCOSCR_b.CKSEL = BSP_CLOCKS_FOCO_SOURCE_CLOCK_HOCO;
1408     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FOCOSCR_b.CKST, BSP_CLOCKS_FOCO_SOURCE_CLOCK_HOCO);
1409     R_SYSTEM->HOCODIV = BSP_CFG_HOCO_DIV;
1410    #elif (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MOCO)
1411     R_SYSTEM->FMAINSCR_b.CKSEL = BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO;
1412     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FMAINSCR_b.CKST, BSP_CLOCKS_FMAIN_SOURCE_CLOCK_FOCO);
1413     R_SYSTEM->FOCOSCR_b.CKSEL = BSP_CLOCKS_FOCO_SOURCE_CLOCK_MOCO;
1414     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FOCOSCR_b.CKST, BSP_CLOCKS_FOCO_SOURCE_CLOCK_MOCO);
1415    #else
1416     R_SYSTEM->FMAINSCR_b.CKSEL = BSP_CLOCKS_FMAIN_SOURCE_CLOCK_MAIN_OSC;
1417     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->FMAINSCR_b.CKST, BSP_CLOCKS_FMAIN_SOURCE_CLOCK_MAIN_OSC);
1418    #endif
1419 
1420     /* Change back ICLK to FSUB */
1421     R_SYSTEM->ICLKSCR_b.CKSEL = BSP_CLOCKS_SOURCE_CLOCK_FSUB;
1422     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->ICLKSCR_b.CKST, BSP_CLOCKS_SOURCE_CLOCK_FSUB);
1423   #else
1424    #if (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK)
1425     R_SYSTEM->FSUBSCR = BSP_CLOCKS_FSUB_SOURCE_CLOCK_SUBCLOCK;
1426    #else
1427     R_SYSTEM->FSUBSCR = BSP_CLOCKS_FSUB_SOURCE_CLOCK_LOCO;
1428    #endif
1429   #endif
1430 }
1431 
1432  #endif
1433 #endif
1434 
1435 #if !BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET && !BSP_FEATURE_CGC_REGISTER_SET_B
1436 
bsp_prv_clock_set_hard_reset(void)1437 static void bsp_prv_clock_set_hard_reset (void)
1438 {
1439     /* Wait states in SRAMWTSC are set after hard reset. No change required here. */
1440 
1441     /* Calculate the wait states for ROM */
1442  #if BSP_FEATURE_CGC_HAS_FLWT
1443   #if BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS
1444 
1445     /* Do nothing. Default setting in FLWT is correct. */
1446   #elif BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS || \
1447     BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS == 0
1448     R_FCACHE->FLWT = BSP_PRV_ROM_ONE_WAIT_CYCLES;
1449   #elif 0 == BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS || \
1450     (BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS)
1451     R_FCACHE->FLWT = BSP_PRV_ROM_TWO_WAIT_CYCLES;
1452   #elif 0 == BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FOUR_ROM_WAITS || \
1453     (BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FOUR_ROM_WAITS)
1454     R_FCACHE->FLWT = BSP_PRV_ROM_THREE_WAIT_CYCLES;
1455   #elif 0 == BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FIVE_ROM_WAITS || \
1456     (BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FIVE_ROM_WAITS)
1457     R_FCACHE->FLWT = BSP_PRV_ROM_FOUR_WAIT_CYCLES;
1458   #else
1459     R_FCACHE->FLWT = BSP_PRV_ROM_FIVE_WAIT_CYCLES;
1460   #endif
1461  #endif
1462 
1463  #if BSP_FEATURE_CGC_HAS_MEMWAIT && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
1464   #if BSP_STARTUP_ICLK_HZ > BSP_PRV_MEMWAIT_MAX_ZERO_WAIT_FREQ
1465    #if BSP_STARTUP_ICLK_HZ > BSP_PRV_MEMWAIT_MAX_ONE_WAIT_FREQ
1466 
1467     /* The MCU must be in high speed mode to set wait states to 2. High speed mode is the default out of reset. */
1468     R_SYSTEM->MEMWAIT = BSP_PRV_MEMWAIT_TWO_WAIT_CYCLES;
1469    #else
1470     R_SYSTEM->MEMWAIT = BSP_PRV_MEMWAIT_ONE_WAIT_CYCLES;
1471    #endif
1472   #endif
1473  #endif
1474 
1475  #if BSP_FEATURE_CGC_HAS_FLDWAITR && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
1476   #if BSP_STARTUP_ICLK_HZ > BSP_PRV_FLDWAITR_MAX_ONE_WAIT_FREQ
1477 
1478     /* The MCU must be in high speed mode to set wait states to 2. High speed mode is the default out of reset. */
1479     BSP_PRV_FLDWAITR_REG_ACCESS = BSP_PRV_FLDWAITR_TWO_WAIT_CYCLES;
1480   #endif
1481  #endif
1482 
1483     /* In order to avoid a system clock (momentarily) higher than expected, the order of switching the clock and
1484      * dividers must be so that the frequency of the clock goes lower, instead of higher, before being correct. */
1485 
1486     /* MOCO is the source clock after reset. If the new source clock is faster than the current source clock,
1487      * then set the clock dividers before switching to the new source clock. */
1488  #if BSP_MOCO_FREQ_HZ <= BSP_STARTUP_SOURCE_CLOCK_HZ
1489   #if BSP_FEATURE_CGC_HAS_CPUCLK
1490    #if BSP_CFG_CLOCK_SETTLING_DELAY_ENABLE && (BSP_STARTUP_CPUCLK_HZ >= BSP_MAX_CLOCK_CHANGE_THRESHOLD)
1491 
1492     /* If the requested ICLK divider is greater than or equal to the current ICLK divider, then writing to
1493      * SCKDIVCR first will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1494     #if BSP_CFG_ICLK_DIV == BSP_CFG_CPUCLK_DIV
1495 
1496     /* If dividers are equal, bump both down 1 notch.
1497      * /1 and /2 are the only possible options. */
1498      #if BSP_CFG_CPUCLK_DIV == BSP_CLOCKS_SYS_CLOCK_DIV_1
1499     R_SYSTEM->SCKDIVCR = (BSP_PRV_STARTUP_SCKDIVCR & ~(R_SYSTEM_SCKDIVCR_ICK_Msk)) |
1500                          (BSP_CLOCKS_SYS_CLOCK_DIV_2 << R_SYSTEM_SCKDIVCR_ICK_Pos);
1501     R_SYSTEM->SCKDIVCR2 = BSP_CLOCKS_SYS_CLOCK_DIV_2;
1502      #else
1503     R_SYSTEM->SCKDIVCR = (BSP_PRV_STARTUP_SCKDIVCR & ~(R_SYSTEM_SCKDIVCR_ICK_Msk)) |
1504                          (BSP_CLOCKS_SYS_CLOCK_DIV_4 << R_SYSTEM_SCKDIVCR_ICK_Pos);
1505     R_SYSTEM->SCKDIVCR2 = BSP_CLOCKS_SYS_CLOCK_DIV_4;
1506      #endif
1507     #else
1508     R_SYSTEM->SCKDIVCR = BSP_PRV_STARTUP_SCKDIVCR;
1509      #if BSP_CFG_CPUCLK_DIV == BSP_CLOCKS_SYS_CLOCK_DIV_1
1510 
1511     /* Determine what the other dividers are using and stay aligned with that. */
1512     R_SYSTEM->SCKDIVCR2 = (BSP_CFG_ICLK_DIV & 0x8) ? BSP_CLOCKS_SYS_CLOCK_DIV_3 : BSP_CLOCKS_SYS_CLOCK_DIV_2;
1513      #else
1514 
1515     /* If not /1, can just add 1 to it. */
1516     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2 + 1;
1517      #endif
1518     #endif
1519 
1520     /* Set the system source clock */
1521     R_SYSTEM->SCKSCR = BSP_CFG_CLOCK_SOURCE;
1522 
1523     /* Wait for settling delay. */
1524     SystemCoreClockUpdate();
1525     R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1526 
1527     /* Continue and set clock to actual target speed. */
1528     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2;
1529     R_SYSTEM->SCKDIVCR  = BSP_PRV_STARTUP_SCKDIVCR;
1530 
1531     /* Wait for settling delay. */
1532     SystemCoreClockUpdate();
1533     R_BSP_SoftwareDelay(BSP_CFG_CLOCK_SETTLING_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1534    #else
1535     #if BSP_PRV_ICLK_DIV_VALUE >= BSP_PRV_SCKDIVCR_DIV_VALUE(BSP_FEATURE_CGC_ICLK_DIV_RESET)
1536 
1537     /* If the requested ICLK divider is greater than or equal to the current ICLK divider, then writing to
1538      * SCKDIVCR first will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1539     R_SYSTEM->SCKDIVCR  = BSP_PRV_STARTUP_SCKDIVCR;
1540     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2;
1541     #else
1542 
1543     /* If the requested ICLK divider is less than the current ICLK divider, then writing to SCKDIVCR2 first
1544      * will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1545     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2;
1546     R_SYSTEM->SCKDIVCR  = BSP_PRV_STARTUP_SCKDIVCR;
1547     #endif
1548    #endif
1549   #else
1550     R_SYSTEM->SCKDIVCR = BSP_PRV_STARTUP_SCKDIVCR;
1551   #endif
1552  #endif
1553 
1554     /* Set the system source clock */
1555     R_SYSTEM->SCKSCR = BSP_CFG_CLOCK_SOURCE;
1556 
1557     /* MOCO is the source clock after reset. If the new source clock is slower than the current source clock,
1558      * then set the clock dividers after switching to the new source clock. */
1559  #if BSP_MOCO_FREQ_HZ > BSP_STARTUP_SOURCE_CLOCK_HZ
1560   #if BSP_FEATURE_CGC_HAS_CPUCLK
1561    #if BSP_PRV_ICLK_DIV_VALUE >= BSP_PRV_SCKDIVCR_DIV_VALUE(BSP_FEATURE_CGC_ICLK_DIV_RESET)
1562 
1563     /* If the requested ICLK divider is greater than or equal to the current ICLK divider, then writing to
1564      * SCKDIVCR first will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1565     R_SYSTEM->SCKDIVCR  = BSP_PRV_STARTUP_SCKDIVCR;
1566     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2;
1567    #else
1568 
1569     /* If the requested ICLK divider is less than the current ICLK divider, then writing to SCKDIVCR2 first
1570      * will always satisfy the constraint: CPUCLK frequency >= ICLK frequency. */
1571     R_SYSTEM->SCKDIVCR2 = BSP_PRV_STARTUP_SCKDIVCR2;
1572     R_SYSTEM->SCKDIVCR  = BSP_PRV_STARTUP_SCKDIVCR;
1573    #endif
1574   #else
1575     R_SYSTEM->SCKDIVCR = BSP_PRV_STARTUP_SCKDIVCR;
1576   #endif
1577  #endif
1578 
1579     /* Update the CMSIS core clock variable so that it reflects the new ICLK frequency. */
1580     SystemCoreClockUpdate();
1581 
1582     /* Clocks are now at requested frequencies. */
1583 
1584     /* Adjust the MCU specific wait state soon after the system clock is set, if the system clock frequency to be
1585      * set is lower than previous. */
1586  #if BSP_FEATURE_CGC_HAS_SRAMWTSC
1587   #if BSP_STARTUP_ICLK_HZ <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_NO_RAM_WAITS
1588    #if BSP_FEATURE_CGC_HAS_SRAMPRCR2 == 1
1589     R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_UNLOCK;
1590     R_SRAM->SRAMWTSC  = BSP_PRV_SRAMWTSC_WAIT_CYCLES_DISABLE;
1591     R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_LOCK;
1592    #else
1593     R_SRAM->SRAMPRCR = BSP_PRV_SRAM_UNLOCK;
1594 
1595     /* Execute data memory barrier before and after setting the wait states, See Section 50.4.2 in the RA8M1
1596      * manual R01UH0994EJ0100 */
1597     __DMB();
1598     R_SRAM->SRAMWTSC = BSP_PRV_SRAMWTSC_WAIT_CYCLES_DISABLE;
1599     __DMB();
1600 
1601     R_SRAM->SRAMPRCR = BSP_PRV_SRAM_LOCK;
1602    #endif
1603   #endif
1604  #endif
1605 
1606     /* ROM wait states are 0 by default.  No change required here. */
1607 }
1608 
1609 #endif
1610 
1611 /*******************************************************************************************************************//**
1612  * Initializes variable to store system clock frequencies.
1613  **********************************************************************************************************************/
1614 #if BSP_TZ_NONSECURE_BUILD
bsp_clock_freq_var_init(void)1615 void bsp_clock_freq_var_init (void)
1616 #else
1617 static void bsp_clock_freq_var_init (void)
1618 #endif
1619 {
1620     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_HOCO] = BSP_HOCO_HZ;
1621     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_MOCO] = BSP_MOCO_FREQ_HZ;
1622     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_LOCO] = BSP_LOCO_FREQ_HZ;
1623 #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
1624     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC] = BSP_CFG_XTAL_HZ;
1625 #else
1626     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC] = 0U;
1627 #endif
1628 #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
1629     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK] = BSP_SUBCLOCK_FREQ_HZ;
1630 #else
1631     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK] = 0U;
1632 #endif
1633 #if BSP_PRV_PLL_SUPPORTED
1634  #if BSP_CLOCKS_SOURCE_CLOCK_PLL == BSP_CFG_CLOCK_SOURCE
1635   #if (3U != BSP_FEATURE_CGC_PLLCCR_TYPE)
1636 
1637     /* The PLL Is the startup clock. */
1638     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = BSP_STARTUP_SOURCE_CLOCK_HZ;
1639   #else
1640     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL]   = BSP_CFG_PLL1P_FREQUENCY_HZ;
1641     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1Q] = BSP_CFG_PLL1Q_FREQUENCY_HZ;
1642     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1R] = BSP_CFG_PLL1R_FREQUENCY_HZ;
1643   #endif
1644  #else
1645 
1646     /* The PLL value will be calculated at initialization. */
1647     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = BSP_CFG_XTAL_HZ;
1648  #endif
1649 #endif
1650 
1651 #if BSP_TZ_NONSECURE_BUILD && BSP_CFG_CLOCKS_SECURE == 1
1652 
1653     /* If the CGC is secure and this is a non secure project, register a callback for getting clock settings. */
1654     R_BSP_ClockUpdateCallbackSet(g_bsp_clock_update_callback, &g_callback_memory);
1655 #endif
1656 
1657     /* Update PLL Clock Frequency based on BSP Configuration. */
1658 #if BSP_PRV_PLL_SUPPORTED && BSP_CLOCKS_SOURCE_CLOCK_PLL != BSP_CFG_CLOCK_SOURCE && BSP_PRV_PLL_USED
1659  #if (1U == BSP_FEATURE_CGC_PLLCCR_TYPE) || (5U == BSP_FEATURE_CGC_PLLCCR_TYPE)
1660     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = ((g_clock_freq[BSP_CFG_PLL_SOURCE] * (BSP_CFG_PLL_MUL + 1U)) >> 1U) /
1661                                                 (BSP_CFG_PLL_DIV + 1U);
1662  #elif (3U == BSP_FEATURE_CGC_PLLCCR_TYPE)
1663     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL]   = BSP_CFG_PLL1P_FREQUENCY_HZ;
1664     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1Q] = BSP_CFG_PLL1Q_FREQUENCY_HZ;
1665     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL1R] = BSP_CFG_PLL1R_FREQUENCY_HZ;
1666  #elif (4U == BSP_FEATURE_CGC_PLLCCR_TYPE)
1667     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = (g_clock_freq[BSP_CFG_PLL_SOURCE] * (BSP_CFG_PLL_MUL + 1U)) >> 1U;
1668  #else
1669     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL] = ((g_clock_freq[BSP_CFG_PLL_SOURCE] * (BSP_CFG_PLL_MUL + 1U)) >> 1U) >>
1670                                                 BSP_CFG_PLL_DIV;
1671  #endif
1672 #endif
1673 
1674     /* Update PLL2 Clock Frequency based on BSP Configuration. */
1675 #if BSP_PRV_PLL2_SUPPORTED && BSP_PRV_PLL2_USED
1676  #if (1U == BSP_FEATURE_CGC_PLLCCR_TYPE)
1677     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2] = ((g_clock_freq[BSP_CFG_PLL2_SOURCE] * (BSP_CFG_PLL2_MUL + 1U)) >> 1U) /
1678                                                  (BSP_CFG_PLL2_DIV + 1U);
1679  #elif (3U == BSP_FEATURE_CGC_PLLCCR_TYPE)
1680     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2]  = BSP_CFG_PLL2P_FREQUENCY_HZ;
1681     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2Q] = BSP_CFG_PLL2Q_FREQUENCY_HZ;
1682     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2R] = BSP_CFG_PLL2R_FREQUENCY_HZ;
1683  #else
1684     g_clock_freq[BSP_CLOCKS_SOURCE_CLOCK_PLL2] =
1685         ((g_clock_freq[BSP_CFG_PLL2_SOURCE] * (BSP_CFG_PLL2_MUL + 1U)) >> 1U) >> BSP_CFG_PLL2_DIV;
1686  #endif
1687 #endif
1688 
1689     /* The SystemCoreClock needs to be updated before calling R_BSP_SoftwareDelay. */
1690     SystemCoreClockUpdate();
1691 }
1692 
1693 #if !BSP_FEATURE_CGC_REGISTER_SET_B
1694  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
1695 
1696 /*
1697  * If the clock registers are not guaranteed to be set to their value after reset (Ie. the application is executing after a bootloader),
1698  * then the current state of the registers must be taken into consideration before writing the clock configuration.
1699  *
1700  * The HOCO must be stopped in the following situations:
1701  *  - The application configures the HOCO to be stopped.
1702  *  - The application enables the FLL, but the HOCO is already running. In order to enable the FLL, the HOCO must be stopped.
1703  * The PLL must be stopped in the following situations:
1704  *  - The application configures the PLL to be stopped.
1705  *  - The application configures settings that are different than the current settings, but the PLL is already running. In order to
1706  *    write new PLL settings, the PLL must be stopped.
1707  *  - The HOCO is the PLL source clock and the HOCO is being stopped.
1708  * The PLL2 must be stopped in the following situations:
1709  *  - The application configures the PLL2 to be stopped.
1710  *  - The application configures settings that are different than the current settings, but the PLL2 is already running. In order to
1711  *    write new PLL2 settings, the PLL2 must be stopped.
1712  *  - The HOCO is the PLL2 source clock and the HOCO is being stopped.
1713  *
1714  * If the HOCO or PLL are being used as the system clock source and they need to be stopped, then the system clock source needs to be switched
1715  * to the default system clock source before the current system clock source is disabled.
1716  */
bsp_soft_reset_prepare(void)1717 void bsp_soft_reset_prepare (void)
1718 {
1719     bool stop_hoco = false;
1720   #if BSP_PRV_PLL_SUPPORTED
1721     bool stop_pll = false;
1722   #endif
1723   #if BSP_PRV_PLL2_SUPPORTED
1724     bool stop_pll2 = false;
1725   #endif
1726 
1727   #if BSP_PRV_HOCO_USE_FLL || !BSP_PRV_HOCO_USED
1728    #if BSP_PRV_HOCO_USE_FLL
1729 
1730     /* Determine if the FLL needs to be enabled. */
1731     bool enable_fll = (0 == R_SYSTEM->FLLCR1 && BSP_PRV_HOCO_USE_FLL);
1732    #else
1733     bool enable_fll = false;
1734    #endif
1735 
1736     /* If the HOCO is already enabled and either the FLL needs to be enabled or the HOCO is not used, then stop the HOCO. */
1737     if ((0 == R_SYSTEM->HOCOCR) && (enable_fll || !BSP_PRV_HOCO_USED))
1738     {
1739         stop_hoco = true;
1740     }
1741   #endif
1742 
1743   #if BSP_PRV_PLL_SUPPORTED
1744     if (0 == R_SYSTEM->PLLCR)
1745     {
1746         /*
1747          * If any of the following conditions are true, then the PLL needs to be stopped:
1748          * - The PLL is not used
1749          * - The PLL settings need to be changed
1750          * - The HOCO is selected as the PLL clock source and the HOCO needs to be stopped
1751          *   - Note that PLL type 2 does not support running off of the HOCO
1752          */
1753    #if BSP_PRV_PLL_USED
1754     #if 3 == BSP_FEATURE_CGC_PLLCCR_TYPE
1755         if ((BSP_PRV_PLLCCR != R_SYSTEM->PLLCCR) || (BSP_PRV_PLLCCR2 != R_SYSTEM->PLLCCR2) ||
1756             (stop_hoco && (1 == R_SYSTEM->PLLCCR_b.PLSRCSEL)))
1757     #elif 2 == BSP_FEATURE_CGC_PLLCCR_TYPE
1758         if (BSP_PRV_PLLCCR != R_SYSTEM->PLLCCR2)
1759     #else
1760         if ((BSP_PRV_PLLCCR != R_SYSTEM->PLLCCR) || (stop_hoco && (1 == R_SYSTEM->PLLCCR_b.PLSRCSEL)))
1761     #endif
1762    #endif
1763         {
1764             stop_pll = true;
1765         }
1766     }
1767   #endif
1768 
1769   #if BSP_PRV_PLL2_SUPPORTED
1770     if (0 == R_SYSTEM->PLL2CR)
1771     {
1772         /*
1773          * If any of the following conditions are true, then the PLL2 needs to be stopped:
1774          * - The PLL2 is not used
1775          * - The PLL2 settings need to be changed
1776          * - The HOCO is selected as the PLL2 clock source and the HOCO needs to be stopped
1777          *   - Note that PLL type 2 does not support running off of the HOCO
1778          */
1779    #if BSP_PRV_PLL2_USED
1780     #if 3 == BSP_FEATURE_CGC_PLLCCR_TYPE
1781         if ((BSP_PRV_PLL2CCR != R_SYSTEM->PLL2CCR) || (BSP_PRV_PLL2CCR2 != R_SYSTEM->PLL2CCR2) ||
1782             (stop_hoco && (1 == R_SYSTEM->PLL2CCR_b.PL2SRCSEL)))
1783     #else
1784         if ((BSP_PRV_PLL2CCR != R_SYSTEM->PLL2CCR) || (stop_hoco && (1 == R_SYSTEM->PLL2CCR_b.PL2SRCSEL)))
1785     #endif
1786    #endif
1787         {
1788             stop_pll2 = true;
1789         }
1790     }
1791   #endif
1792 
1793     uint8_t sckscr = R_SYSTEM->SCKSCR;
1794 
1795     /* If the System Clock source needs to be stopped, then switch to the MOCO. */
1796   #if BSP_PRV_PLL_SUPPORTED
1797     if ((stop_hoco && (BSP_CLOCKS_SOURCE_CLOCK_HOCO == sckscr)) ||
1798         (stop_pll && (BSP_CLOCKS_SOURCE_CLOCK_PLL == sckscr)))
1799   #else
1800     if (stop_hoco && (BSP_CLOCKS_SOURCE_CLOCK_HOCO == sckscr))
1801   #endif
1802     {
1803         bsp_prv_clock_set(BSP_FEATURE_CGC_STARTUP_SCKSCR,
1804                           BSP_FEATURE_CGC_STARTUP_SCKDIVCR,
1805                           BSP_FEATURE_CGC_STARTUP_SCKDIVCR2);
1806     }
1807 
1808     /* Disable the oscillators so that the application can write the new clock configuration. */
1809 
1810   #if BSP_PRV_PLL_SUPPORTED
1811     if (stop_pll)
1812     {
1813         R_SYSTEM->PLLCR = 1;
1814         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLLSF, 0);
1815     }
1816   #endif
1817 
1818   #if BSP_PRV_PLL2_SUPPORTED
1819     if (stop_pll2)
1820     {
1821         R_SYSTEM->PLL2CR = 1;
1822         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLL2SF, 0);
1823     }
1824   #endif
1825 
1826     if (stop_hoco)
1827     {
1828         R_SYSTEM->HOCOCR = 1;
1829         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 0);
1830     }
1831 }
1832 
1833  #endif
1834 #else
1835 
1836 /*******************************************************************************************************************//**
1837  * Initializes CMC and OSMC registers according to the BSP configuration.
1838  **********************************************************************************************************************/
bsp_prv_cmc_init(void)1839 void bsp_prv_cmc_init (void)
1840 {
1841     /* The CMC register can be written only once after release from the reset state. If clock registers not reset
1842      * values during startup, assume CMC register has already been set appropriately. */
1843     uint8_t cmc_reg = 0x00U;
1844 
1845     /* Set main clock oscillator drive capability */
1846  #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
1847     cmc_reg |= BSP_PRV_CMC_MOSC;
1848  #endif
1849 
1850     /* Set sub-clock oscillator drive capability and pin switching */
1851  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
1852     cmc_reg |= BSP_PRV_CMC_SOSC;
1853  #endif
1854 
1855     R_SYSTEM->CMC = cmc_reg;
1856 
1857  #if (BSP_CFG_FSXP_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
1858     uint8_t osmc = R_SYSTEM->OSMC;
1859 
1860     if (BSP_PRV_OSMC != osmc)
1861     {
1862         /* Stop RTC counter operation to update the OSMC register. */
1863         BSP_MSTP_REG_FSP_IP_RTC(0) &= ~BSP_MSTP_BIT_FSP_IP_RTC(0);
1864         FSP_REGISTER_READ(BSP_MSTP_REG_FSP_IP_RTC(0));
1865         R_RTC_C->RTCC0_b.RTCE       = 0U;
1866         BSP_MSTP_REG_FSP_IP_RTC(0) |= BSP_MSTP_BIT_FSP_IP_RTC(0);
1867         FSP_REGISTER_READ(BSP_MSTP_REG_FSP_IP_RTC(0));
1868 
1869   #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
1870         if (0U == osmc)
1871         {
1872             /* Current Subsystem Clock (FSXP) source is SOSC. */
1873             if (0U == R_SYSTEM->SOSCCR)
1874             {
1875                 /* Stop the Sub-Clock Oscillator to update the OSMC register. */
1876                 R_SYSTEM->SOSCCR = 1U;
1877 
1878                 /* Allow a stop interval of at least 5 SOSC clock cycles before restarting Sub-Clock Oscillator. */
1879                 R_BSP_SoftwareDelay(BSP_PRV_SUBCLOCK_STOP_INTERVAL_US, BSP_DELAY_UNITS_MICROSECONDS);
1880 
1881                 /* When changing the value of the SOSTP bit, only execute subsequent
1882                  * instructions after reading the bit to check that the value is updated. */
1883                 FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOSCCR, 1U);
1884             }
1885         }
1886   #endif
1887 
1888         R_SYSTEM->OSMC = BSP_PRV_OSMC;
1889     }
1890  #endif
1891 }
1892 
1893 /***********************************************************************************************************************
1894  * Changes the operating speed in FLMODE.  Assumes the LPM registers are unlocked in PRCR.
1895  *
1896  * @param[in]  operating_mode  Desired operating mode, must be one of the BSP_PRV_OPERATING_MODE_* macros, cannot be
1897  *                             BSP_PRV_OPERATING_MODE_SUBOSC_SPEED
1898  **********************************************************************************************************************/
bsp_prv_operating_mode_flmode_set(uint8_t operating_mode)1899 static void bsp_prv_operating_mode_flmode_set (uint8_t operating_mode)
1900 {
1901     if (operating_mode != R_FACI_LP->FLMODE_b.MODE)
1902     {
1903         /* Enable FLMWRP.FLMWEN bit to before rewrite to FLMODE register */
1904         R_FACI_LP->FLMWRP_b.FLMWEN = 0x1U;
1905 
1906         if ((BSP_PRV_OPERATING_MODE_MIDDLE_SPEED != operating_mode) &&
1907             (BSP_PRV_OPERATING_MODE_MIDDLE_SPEED != R_FACI_LP->FLMODE_b.MODE))
1908         {
1909             /* Set flash operating mode to middle-speed mode first */
1910             R_FACI_LP->FLMODE = (uint8_t) (BSP_PRV_OPERATING_MODE_MIDDLE_SPEED << R_FACI_LP_FLMODE_MODE_Pos);
1911         }
1912 
1913         /* Set flash operating mode */
1914         R_FACI_LP->FLMODE = (uint8_t) (operating_mode << R_FACI_LP_FLMODE_MODE_Pos);
1915 
1916         /* Disable FLMWRP.FLMWEN bit to after rewrite to FLMODE register */
1917         R_FACI_LP->FLMWRP_b.FLMWEN = 0x0U;
1918     }
1919 }
1920 
1921 #endif
1922 
1923 /*******************************************************************************************************************//**
1924  * Initializes system clocks.  Makes no assumptions about current register settings.
1925  **********************************************************************************************************************/
bsp_clock_init(void)1926 void bsp_clock_init (void)
1927 {
1928     /* Unlock CGC and LPM protection registers. */
1929 #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_NONSECURE_BUILD == 1
1930     R_SYSTEM->PRCR_NS = (uint16_t) BSP_PRV_PRCR_UNLOCK;
1931 #else
1932     R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_UNLOCK;
1933 #endif
1934 
1935 #if BSP_FEATURE_BSP_FLASH_CACHE
1936  #if !BSP_CFG_USE_LOW_VOLTAGE_MODE && BSP_FEATURE_BSP_FLASH_CACHE_DISABLE_OPM
1937 
1938     /* Disable flash cache before modifying MEMWAIT, SOPCCR, or OPCCR. */
1939     R_BSP_FlashCacheDisable();
1940  #else
1941 
1942     /* Enable the flash cache and don't disable it while running from flash. On these MCUs, the flash cache does not
1943      * need to be disabled when adjusting the operating power mode. */
1944     R_BSP_FlashCacheEnable();
1945  #endif
1946 #endif
1947 
1948 #if BSP_FEATURE_BSP_FLASH_PREFETCH_BUFFER
1949 
1950     /* Disable the flash prefetch buffer. */
1951     R_FACI_LP->PFBER = 0;
1952 #endif
1953 
1954     bsp_clock_freq_var_init();
1955 
1956 #if BSP_FEATURE_CGC_REGISTER_SET_B
1957     bsp_prv_cmc_init();
1958 #else
1959  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
1960 
1961     /* Transition to an intermediate clock configuration in order to prepare for writing the new clock configuraiton. */
1962     bsp_soft_reset_prepare();
1963  #endif
1964 #endif
1965 
1966 #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED
1967  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
1968 
1969     /* Update the main oscillator drive, source, and wait states if the main oscillator is stopped.  If the main
1970      * oscillator is running, the drive, source, and wait states are assumed to be already set appropriately. */
1971     if (R_SYSTEM->MOSCCR)
1972     {
1973   #if BSP_FEATURE_CGC_REGISTER_SET_B
1974 
1975         /* Set the main oscillator wait time. */
1976         R_SYSTEM->OSTS = BSP_CLOCK_CFG_MAIN_OSC_WAIT;
1977   #else
1978 
1979         /* Don't write to MOSCWTCR unless MOSTP is 1 and MOSCSF = 0. */
1980         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.MOSCSF, 0U);
1981 
1982         /* Configure main oscillator drive. */
1983         R_SYSTEM->MOMCR = BSP_PRV_MOMCR;
1984 
1985         /* Set the main oscillator wait time. */
1986         R_SYSTEM->MOSCWTCR = (uint8_t) BSP_CLOCK_CFG_MAIN_OSC_WAIT;
1987   #endif
1988     }
1989 
1990  #else
1991   #if BSP_FEATURE_CGC_REGISTER_SET_B
1992 
1993     /* Set the main oscillator wait time. */
1994     R_SYSTEM->OSTS = BSP_CLOCK_CFG_MAIN_OSC_WAIT;
1995   #else
1996 
1997     /* Configure main oscillator drive. */
1998     R_SYSTEM->MOMCR = BSP_PRV_MOMCR;
1999 
2000     /* Set the stabilization time for XTAL. */
2001     R_SYSTEM->MOSCWTCR = (uint8_t) BSP_CLOCK_CFG_MAIN_OSC_WAIT;
2002   #endif
2003  #endif
2004 #endif
2005 
2006     /* Initialize the sub-clock according to the BSP configuration. */
2007     bsp_prv_sosc_init();
2008 
2009 #if BSP_FEATURE_CGC_HAS_HOCOWTCR
2010  #if BSP_FEATURE_CGC_HOCOWTCR_64MHZ_ONLY
2011 
2012     /* These MCUs only require writes to HOCOWTCR if HOCO is set to 64 MHz. */
2013   #if 64000000 == BSP_HOCO_HZ
2014    #if BSP_CFG_USE_LOW_VOLTAGE_MODE
2015 
2016     /* Wait for HOCO to stabilize before writing to HOCOWTCR. */
2017     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 1U);
2018    #else
2019 
2020     /* HOCO is assumed to be stable because these MCUs also require the HOCO to be stable before changing the operating
2021      * power control mode. */
2022    #endif
2023     R_SYSTEM->HOCOWTCR = BSP_FEATURE_CGC_HOCOWTCR_VALUE;
2024   #endif
2025  #else
2026 
2027     /* These MCUs require HOCOWTCR to be set to the maximum value except in snooze mode.  There is no restriction to
2028      * writing this register. */
2029     R_SYSTEM->HOCOWTCR = BSP_FEATURE_CGC_HOCOWTCR_VALUE;
2030  #endif
2031 #endif
2032 
2033 #if !BSP_CFG_USE_LOW_VOLTAGE_MODE
2034  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2035 
2036     /* Switch to high-speed to prevent any issues with the subsequent clock configurations. */
2037     bsp_prv_operating_mode_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED);
2038  #elif BSP_FEATURE_CGC_LOW_VOLTAGE_MAX_FREQ_HZ > 0U
2039 
2040     /* MCUs that support low voltage mode start up in low voltage mode. */
2041     bsp_prv_operating_mode_opccr_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED);
2042 
2043   #if !BSP_PRV_HOCO_USED
2044 
2045     /* HOCO must be running during startup in low voltage mode. If HOCO is not used, turn it off after exiting low
2046      * voltage mode. */
2047     R_SYSTEM->HOCOCR = 1U;
2048   #endif
2049  #elif BSP_FEATURE_CGC_STARTUP_OPCCR_MODE != BSP_PRV_OPERATING_MODE_HIGH_SPEED
2050 
2051     /* Some MCUs do not start in high speed mode. */
2052   #if !BSP_FEATURE_CGC_REGISTER_SET_B
2053     bsp_prv_operating_mode_opccr_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED);
2054   #else
2055     bsp_prv_operating_mode_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED);
2056   #endif
2057  #endif
2058 #endif
2059 
2060     /* The FLL function can only be used when the subclock is running. */
2061 #if BSP_PRV_HOCO_USE_FLL
2062 
2063     /* If FLL is to be used configure FLLCR1 and FLLCR2 before starting HOCO. */
2064     R_SYSTEM->FLLCR2 = BSP_PRV_FLL_FLLCR2;
2065     R_SYSTEM->FLLCR1 = 1U;
2066 #endif
2067 
2068     /* Start all clocks used by other clocks first. */
2069 #if BSP_PRV_HOCO_USED
2070     R_SYSTEM->HOCOCR = 0U;
2071 
2072  #if BSP_PRV_HOCO_USE_FLL && (BSP_CLOCKS_SOURCE_CLOCK_HOCO != BSP_CFG_PLL_SOURCE)
2073 
2074     /* If FLL is enabled, wait for the FLL stabilization delay (1.8 ms) */
2075     R_BSP_SoftwareDelay(BSP_PRV_FLL_STABILIZATION_TIME_US, BSP_DELAY_UNITS_MICROSECONDS);
2076  #endif
2077 
2078  #if BSP_PRV_STABILIZE_HOCO
2079 
2080     /* Wait for HOCO to stabilize. */
2081     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 1U);
2082  #endif
2083 #endif
2084 #if BSP_PRV_MOCO_USED
2085  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2086 
2087     /* If the MOCO is not running, start it and wait for it to stabilize using a software delay. */
2088     if (0U != R_SYSTEM->MOCOCR)
2089     {
2090         R_SYSTEM->MOCOCR = 0U;
2091   #if BSP_PRV_STABILIZE_MOCO
2092         R_BSP_SoftwareDelay(BSP_FEATURE_CGC_MOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS);
2093   #endif
2094     }
2095 
2096  #else
2097   #if BSP_FEATURE_CGC_REGISTER_SET_B
2098     R_SYSTEM->MOCOCR = 0U;
2099    #if BSP_PRV_STABILIZE_MOCO
2100     R_BSP_SoftwareDelay(BSP_FEATURE_CGC_MOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS);
2101    #endif
2102   #endif
2103  #endif
2104 #endif
2105 #if BSP_PRV_LOCO_USED
2106  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2107 
2108     /* If the LOCO is not running, start it and wait for it to stabilize using a software delay. */
2109     if (0U != R_SYSTEM->LOCOCR)
2110     {
2111         R_SYSTEM->LOCOCR = 0U;
2112   #if BSP_PRV_STABILIZE_LOCO
2113         R_BSP_SoftwareDelay(BSP_FEATURE_CGC_LOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS);
2114   #endif
2115     }
2116 
2117  #else
2118     R_SYSTEM->LOCOCR = 0U;
2119   #if BSP_PRV_STABILIZE_LOCO
2120     R_BSP_SoftwareDelay(BSP_FEATURE_CGC_LOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS);
2121   #endif
2122  #endif
2123 #endif
2124 #if BSP_PRV_MAIN_OSC_USED
2125  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2126     if (R_SYSTEM->MOSCCR)
2127  #endif
2128     {
2129         R_SYSTEM->MOSCCR = 0U;
2130 
2131  #if BSP_PRV_STABILIZE_MAIN_OSC
2132 
2133         /* Wait for main oscillator to stabilize. */
2134   #if BSP_FEATURE_CGC_REGISTER_SET_B
2135 
2136         /*
2137          * The main oscillation stabilization time countered by OSTC
2138          *  0x80:  2^8/fx min
2139          *  0xC0:  2^9/fx min
2140          *  0xE0:  2^10/fx min
2141          *  0xF0:  2^11/fx min
2142          *  0xF8:  2^13/fx min
2143          *  0xFC:  2^15/fx min
2144          *  0xFE:  2^17/fx min
2145          *  0xFF:  2^18/fx min
2146          */
2147         uint8_t mainosc_stable_value = (uint8_t) ~(BSP_PRV_OSTC_OFFSET >> BSP_CLOCK_CFG_MAIN_OSC_WAIT);
2148         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSTC, mainosc_stable_value);
2149   #else
2150         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.MOSCSF, 1U);
2151   #endif
2152  #endif
2153     }
2154 #endif
2155 
2156     /* Start clocks that require other clocks. At this point, all dependent clocks are running and stable if needed. */
2157 
2158 #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED
2159  #if BSP_FEATURE_CGC_HAS_PLL2 && BSP_CFG_PLL2_SOURCE != BSP_CLOCKS_CLOCK_DISABLED
2160   #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2161     if (R_SYSTEM->PLL2CR)
2162   #endif
2163     {
2164         R_SYSTEM->PLL2CCR = BSP_PRV_PLL2CCR;
2165   #if (3U == BSP_FEATURE_CGC_PLLCCR_TYPE)
2166         R_SYSTEM->PLL2CCR2 = BSP_PRV_PLL2CCR2;
2167   #endif
2168 
2169         /* Start PLL2. */
2170         R_SYSTEM->PLL2CR = 0U;
2171     }
2172  #endif                                /* BSP_FEATURE_CGC_HAS_PLL2 && BSP_CFG_PLL2_ENABLE */
2173 #endif
2174 
2175 #if BSP_PRV_PLL_SUPPORTED && BSP_PRV_PLL_USED
2176  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2177     if (R_SYSTEM->PLLCR)
2178  #endif
2179     {
2180  #if (1U == BSP_FEATURE_CGC_PLLCCR_TYPE) || (4U == BSP_FEATURE_CGC_PLLCCR_TYPE) || (5U == BSP_FEATURE_CGC_PLLCCR_TYPE)
2181         R_SYSTEM->PLLCCR = (uint16_t) BSP_PRV_PLLCCR;
2182  #elif 2U == BSP_FEATURE_CGC_PLLCCR_TYPE
2183         R_SYSTEM->PLLCCR2 = (uint8_t) BSP_PRV_PLLCCR;
2184  #elif 3U == BSP_FEATURE_CGC_PLLCCR_TYPE
2185         R_SYSTEM->PLLCCR  = (uint16_t) BSP_PRV_PLLCCR;
2186         R_SYSTEM->PLLCCR2 = (uint16_t) BSP_PRV_PLLCCR2;
2187  #endif
2188 
2189  #if BSP_FEATURE_CGC_PLLCCR_WAIT_US > 0
2190 
2191         /* This loop is provided to ensure at least 1 us passes between setting PLLMUL and clearing PLLSTP on some
2192          * MCUs (see PLLSTP notes in Section 8.2.4 "PLL Control Register (PLLCR)" of the RA4M1 manual R01UH0887EJ0100).
2193          * Five loops are needed here to ensure the most efficient path takes at least 1 us from the setting of
2194          * PLLMUL to the clearing of PLLSTP. HOCO is the fastest clock we can be using here since PLL cannot be running
2195          * while setting PLLCCR. */
2196         bsp_prv_software_delay_loop(BSP_DELAY_LOOPS_CALCULATE(BSP_PRV_MAX_HOCO_CYCLES_PER_US));
2197  #endif
2198 
2199         R_SYSTEM->PLLCR = 0U;
2200 
2201  #if BSP_PRV_STABILIZE_PLL
2202 
2203         /* Wait for PLL to stabilize. */
2204         FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLLSF, 1U);
2205  #endif
2206     }
2207 #endif
2208 
2209     /* Set source clock and dividers. */
2210 #if !BSP_FEATURE_CGC_REGISTER_SET_B
2211  #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2212   #if BSP_TZ_SECURE_BUILD
2213 
2214     /* In case of soft reset, make sure callback pointer is NULL initially. */
2215     g_bsp_clock_update_callback = NULL;
2216   #endif
2217 
2218   #if BSP_FEATURE_CGC_HAS_CPUCLK
2219     bsp_prv_clock_set(BSP_CFG_CLOCK_SOURCE, BSP_PRV_STARTUP_SCKDIVCR, BSP_PRV_STARTUP_SCKDIVCR2);
2220   #else
2221     bsp_prv_clock_set(BSP_CFG_CLOCK_SOURCE, BSP_PRV_STARTUP_SCKDIVCR, 0);
2222   #endif
2223  #else
2224     bsp_prv_clock_set_hard_reset();
2225  #endif
2226 #else
2227     bsp_prv_clock_set(BSP_CFG_CLOCK_SOURCE, BSP_CFG_HOCO_DIV, BSP_CFG_MOCO_DIV, BSP_CFG_XTAL_DIV);
2228 #endif
2229 
2230     /* If the MCU can run in a lower power mode, apply the optimal operating speed mode. */
2231 #if !BSP_CFG_USE_LOW_VOLTAGE_MODE
2232  #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_HIGH_SPEED
2233     bsp_prv_operating_mode_set(BSP_PRV_STARTUP_OPERATING_MODE);
2234  #endif
2235 #endif
2236 
2237 #if defined(BSP_PRV_POWER_USE_DCDC) && (BSP_PRV_POWER_USE_DCDC == BSP_PRV_POWER_DCDC_STARTUP) && \
2238     (BSP_PRV_STARTUP_OPERATING_MODE <= BSP_PRV_OPERATING_MODE_MIDDLE_SPEED)
2239 
2240     /* Start DCDC as part of BSP startup when configured (BSP_CFG_DCDC_ENABLE == 2). */
2241     R_BSP_PowerModeSet(BSP_CFG_DCDC_VOLTAGE_RANGE);
2242 #endif
2243 
2244     /* Configure BCLK if it exists on the MCU. */
2245 #ifdef BSP_CFG_BCLK_OUTPUT
2246  #if BSP_CFG_BCLK_OUTPUT > 0U
2247     R_SYSTEM->BCKCR   = BSP_CFG_BCLK_OUTPUT - 1U;
2248     R_SYSTEM->EBCKOCR = 1U;
2249  #else
2250   #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2251     R_SYSTEM->EBCKOCR = 0U;
2252   #endif
2253  #endif
2254 #endif
2255 
2256     /* Configure SDRAM clock if it exists on the MCU. */
2257 #ifdef BSP_CFG_SDCLK_OUTPUT
2258     R_SYSTEM->SDCKOCR = BSP_CFG_SDCLK_OUTPUT;
2259 #endif
2260 
2261     /* Configure CLKOUT. */
2262 #if !BSP_FEATURE_CGC_REGISTER_SET_B
2263  #if BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_CLOCK_DISABLED
2264   #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2265     R_SYSTEM->CKOCR = 0U;
2266   #endif
2267  #else
2268     uint8_t ckocr = BSP_CFG_CLKOUT_SOURCE | (BSP_CFG_CLKOUT_DIV << BSP_PRV_CKOCR_CKODIV_BIT);
2269     R_SYSTEM->CKOCR = ckocr;
2270     ckocr          |= (1U << BSP_PRV_CKOCR_CKOEN_BIT);
2271     R_SYSTEM->CKOCR = ckocr;
2272  #endif
2273 #else
2274  #if BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_CLOCK_DISABLED
2275   #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET
2276     R_PCLBUZ->CKS0 = 0U;
2277   #endif
2278  #else
2279   #if (BSP_CFG_CLKOUT_SOURCE != BSP_CFG_CLOCK_SOURCE)
2280     bsp_prv_clkout_clock_set();
2281   #endif
2282 
2283     uint8_t cks0 = (BSP_CFG_CLKOUT_DIV << R_PCLBUZ_CKS0_CCS_Pos);
2284   #if (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_LOCO) || \
2285     (BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK)
2286     cks0 |= (BSP_CLOCKS_CLKOUT_SOURCE_CLOCK_FSUB << R_PCLBUZ_CKS0_CSEL_Pos);
2287   #else
2288     cks0 |= (BSP_CLOCKS_CLKOUT_SOURCE_CLOCK_FMAIN << R_PCLBUZ_CKS0_CSEL_Pos);
2289   #endif
2290     R_PCLBUZ->CKS0  = cks0;
2291     R_PCLBUZ->CKS0 |= (1U << R_PCLBUZ_CKS0_PCLOE_Pos);
2292  #endif
2293 #endif
2294 
2295 #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED
2296  #if BSP_CFG_UCK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED
2297 
2298     /* If the USB clock has a divider setting in SCKDIVCR2. */
2299   #if BSP_FEATURE_BSP_HAS_USB_CLOCK_DIV && !BSP_FEATURE_BSP_HAS_USBCKDIVCR
2300     R_SYSTEM->SCKDIVCR2 = BSP_PRV_UCK_DIV << BSP_PRV_SCKDIVCR2_UCK_BIT;
2301   #endif                               /* BSP_FEATURE_BSP_HAS_USB_CLOCK_DIV && !BSP_FEATURE_BSP_HAS_USBCKDIVCR */
2302 
2303     /* If there is a REQ bit in USBCKCR, then follow sequence from section 8.2.29 in RA6M4 hardware manual R01UH0890EJ0050. */
2304   #if BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ
2305 
2306     /* Request to change the USB Clock. */
2307     R_SYSTEM->USBCKCR_b.USBCKSREQ = 1;
2308 
2309     /* Wait for the clock to be stopped. */
2310     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->USBCKCR_b.USBCKSRDY, 1U);
2311 
2312     /* Write the settings. */
2313     R_SYSTEM->USBCKDIVCR = BSP_PRV_UCK_DIV;
2314 
2315     /* Select the USB Clock without enabling it. */
2316     R_SYSTEM->USBCKCR = BSP_CFG_UCK_SOURCE | R_SYSTEM_USBCKCR_USBCKSREQ_Msk;
2317   #endif                               /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */
2318 
2319   #if BSP_FEATURE_BSP_HAS_USB_CLOCK_SEL
2320 
2321     /* Some MCUs use an alternate register for selecting the USB clock source. */
2322    #if BSP_FEATURE_BSP_HAS_USB_CLOCK_SEL_ALT
2323     #if BSP_CLOCKS_SOURCE_CLOCK_PLL == BSP_CFG_UCK_SOURCE
2324 
2325     /* Write to USBCKCR to select the PLL. */
2326     R_SYSTEM->USBCKCR_ALT = 0;
2327     #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_UCK_SOURCE
2328 
2329     /* Write to USBCKCR to select the HOCO. */
2330     R_SYSTEM->USBCKCR_ALT = 1;
2331     #endif
2332    #else
2333 
2334     /* Select the USB Clock. */
2335     R_SYSTEM->USBCKCR = BSP_CFG_UCK_SOURCE;
2336    #endif
2337   #endif                               /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */
2338 
2339   #if BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ
2340 
2341     /* Wait for the USB Clock to be started. */
2342     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->USBCKCR_b.USBCKSRDY, 0U);
2343   #endif                               /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */
2344  #endif                                /* BSP_CFG_USB_ENABLE */
2345 #endif                                 /* BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED */
2346 
2347     /* Set the OCTASPI clock if it exists on the MCU (See section 8.2.30 of the RA6M4 hardware manual R01UH0890EJ0050). */
2348 #if BSP_FEATURE_BSP_HAS_OCTASPI_CLOCK && BSP_CFG_OCTA_SOURCE != BSP_CLOCKS_CLOCK_DISABLED
2349     bsp_octaclk_settings_t octaclk_settings =
2350     {
2351         .source_clock = (bsp_clocks_source_t) BSP_CFG_OCTA_SOURCE,
2352         .divider      = (bsp_clocks_octaclk_div_t) BSP_CFG_OCTA_DIV
2353     };
2354     R_BSP_OctaclkUpdate(&octaclk_settings);
2355 #endif                                 /* BSP_FEATURE_BSP_HAS_OCTASPI_CLOCK && BSP_CFG_OCTASPI_CLOCK_ENABLE */
2356 
2357     /* Set the CANFD clock if it exists on the MCU */
2358 #if BSP_FEATURE_BSP_HAS_CANFD_CLOCK && (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) && \
2359     (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC)
2360 
2361     bsp_peripheral_clock_set(&R_SYSTEM->CANFDCKCR,
2362                              &R_SYSTEM->CANFDCKDIVCR,
2363                              BSP_CFG_CANFDCLK_DIV,
2364                              BSP_CFG_CANFDCLK_SOURCE);
2365 #endif
2366 
2367     /* Set the SCISPI clock if it exists on the MCU */
2368 #if BSP_FEATURE_BSP_HAS_SCISPI_CLOCK && (BSP_CFG_SCISPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2369     bsp_peripheral_clock_set(&R_SYSTEM->SCISPICKCR,
2370                              &R_SYSTEM->SCISPICKDIVCR,
2371                              BSP_CFG_SCISPICLK_DIV,
2372                              BSP_CFG_SCISPICLK_SOURCE);
2373 #endif
2374 
2375     /* Set the SCI clock if it exists on the MCU */
2376 #if BSP_FEATURE_BSP_HAS_SCI_CLOCK && (BSP_CFG_SCICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2377     bsp_peripheral_clock_set(&R_SYSTEM->SCICKCR, &R_SYSTEM->SCICKDIVCR, BSP_CFG_SCICLK_DIV, BSP_CFG_SCICLK_SOURCE);
2378 #endif
2379 
2380     /* Set the SPI clock if it exists on the MCU */
2381 #if BSP_FEATURE_BSP_HAS_SPI_CLOCK && (BSP_CFG_SPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2382     bsp_peripheral_clock_set(&R_SYSTEM->SPICKCR, &R_SYSTEM->SPICKDIVCR, BSP_CFG_SPICLK_DIV, BSP_CFG_SPICLK_SOURCE);
2383 #endif
2384 
2385     /* Set the GPT clock if it exists on the MCU */
2386 #if BSP_FEATURE_BSP_HAS_GPT_CLOCK && (BSP_CFG_GPTCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2387     bsp_peripheral_clock_set(&R_SYSTEM->GPTCKCR, &R_SYSTEM->GPTCKDIVCR, BSP_CFG_GPTCLK_DIV, BSP_CFG_GPTCLK_SOURCE);
2388 #endif
2389 
2390     /* Set the IIC clock if it exists on the MCU */
2391 #if BSP_FEATURE_BSP_HAS_IIC_CLOCK && (BSP_CFG_IICCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2392     bsp_peripheral_clock_set(&R_SYSTEM->IICCKCR, &R_SYSTEM->IICCKDIVCR, BSP_CFG_IICCLK_DIV, BSP_CFG_IICCLK_SOURCE);
2393 #endif
2394 
2395     /* Set the CEC clock if it exists on the MCU */
2396 #if BSP_FEATURE_BSP_HAS_CEC_CLOCK && (BSP_CFG_CECCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2397     bsp_peripheral_clock_set(&R_SYSTEM->CECCKCR, &R_SYSTEM->CECCKDIVCR, BSP_CFG_CECCLK_DIV, BSP_CFG_CECCLK_SOURCE);
2398 #endif
2399 
2400     /* Set the I3C clock if it exists on the MCU */
2401 #if BSP_FEATURE_BSP_HAS_I3C_CLOCK && (BSP_CFG_I3CCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2402     bsp_peripheral_clock_set(&R_SYSTEM->I3CCKCR, &R_SYSTEM->I3CCKDIVCR, BSP_CFG_I3CCLK_DIV, BSP_CFG_I3CCLK_SOURCE);
2403 #endif
2404 
2405     /* Set the LCD clock if it exists on the MCU */
2406 #if BSP_FEATURE_BSP_HAS_LCD_CLOCK && (BSP_CFG_LCDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2407     bsp_peripheral_clock_set(&R_SYSTEM->LCDCKCR, &R_SYSTEM->LCDCKDIVCR, BSP_CFG_LCDCLK_DIV, BSP_CFG_LCDCLK_SOURCE);
2408 #endif
2409 
2410     /* Set the USB-HS clock if it exists on the MCU */
2411 #if BSP_FEATURE_BSP_HAS_USB60_CLOCK_REQ && (BSP_CFG_U60CK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2412     bsp_peripheral_clock_set(&R_SYSTEM->USB60CKCR, &R_SYSTEM->USB60CKDIVCR, BSP_CFG_U60CK_DIV, BSP_CFG_U60CK_SOURCE);
2413 #endif
2414 
2415     /* Set the SDADC clock if it exists on the MCU. */
2416 #if BSP_FEATURE_BSP_HAS_SDADC_CLOCK && (BSP_CFG_SDADC_CLOCK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED)
2417  #if BSP_CFG_SDADC_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_HOCO
2418     uint8_t sdadcckcr = 1U;
2419  #elif BSP_CFG_SDADC_CLOCK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_PLL
2420     uint8_t sdadcckcr = 2U;
2421  #else                                 /* BSP_CLOCK_SOURCE_CLOCK_MOSC */
2422     uint8_t sdadcckcr = 0U;
2423  #endif
2424 
2425     /* SDADC isn't controlled like the other peripheral clocks so we cannot use the generic setter. */
2426     R_SYSTEM->SDADCCKCR = sdadcckcr & R_SYSTEM_SDADCCKCR_SDADCCKSEL_Msk;
2427 #endif
2428 
2429     /* Lock CGC and LPM protection registers. */
2430 #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_NONSECURE_BUILD == 1
2431     R_SYSTEM->PRCR_NS = (uint16_t) BSP_PRV_PRCR_LOCK;
2432 #else
2433     R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_LOCK;
2434 #endif
2435 
2436 #if BSP_FEATURE_BSP_FLASH_CACHE && BSP_FEATURE_BSP_FLASH_CACHE_DISABLE_OPM
2437     R_BSP_FlashCacheEnable();
2438 #endif
2439 
2440 #if BSP_FEATURE_BSP_FLASH_PREFETCH_BUFFER
2441     R_FACI_LP->PFBER = 1;
2442 #endif
2443 }
2444 
2445 #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
2446 
2447 /*******************************************************************************************************************//**
2448  * This function is called during SOSC stabilization when Sub-Clock oscillator is populated.
2449  * This function is declared as a weak symbol higher up in this file because it is meant to be overridden by a user
2450  * implemented version. One of the main uses for this function is to update the IWDT/WDT Refresh Register if an
2451  * application starts IWDT/WDT automatically after reset. To use this function just copy this function into your own
2452  * code and modify it to meet your needs.
2453  *
2454  * @param[in]  delay_ms    Stabilization Time for the clock.
2455  **********************************************************************************************************************/
R_BSP_SubClockStabilizeWait(uint32_t delay_ms)2456 void R_BSP_SubClockStabilizeWait (uint32_t delay_ms)
2457 {
2458     /* Wait for clock to stabilize. */
2459     R_BSP_SoftwareDelay(delay_ms, BSP_DELAY_UNITS_MILLISECONDS);
2460 }
2461 
2462 /*******************************************************************************************************************//**
2463  * This function is called during SOSC registers initialization when Sub-Clock oscillator is populated.
2464  * This function is declared as a weak symbol higher up in this file because it is meant to be overridden by a user
2465  * implemented version. One of the main uses for this function is to skip waiting for stabilization time after reset.
2466  * To use this function just copy this function into your own code and modify it to meet your needs.
2467  *
2468  * @param[in]  delay_ms    Stabilization Time for the clock.
2469  **********************************************************************************************************************/
R_BSP_SubClockStabilizeWaitAfterReset(uint32_t delay_ms)2470 void R_BSP_SubClockStabilizeWaitAfterReset (uint32_t delay_ms)
2471 {
2472  #if (BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_CLOCK_SOURCE) || (BSP_PRV_HOCO_USE_FLL)
2473 
2474     /* Wait for clock to stabilize after reset. */
2475     R_BSP_SoftwareDelay(delay_ms, BSP_DELAY_UNITS_MILLISECONDS);
2476  #else
2477     FSP_PARAMETER_NOT_USED(delay_ms);
2478  #endif
2479 }
2480 
2481 #endif
2482 
2483 #if (BSP_PRV_HAS_ENABLED_PERIPHERAL_CLOCKS == 1U)
2484 
2485 /*******************************************************************************************************************//**
2486  * Set the peripheral clock on the MCU
2487  *
2488  * @param[in] p_clk_ctrl_reg            Pointer to peripheral clock control register
2489  * @param[in] p_clk_div_reg             Pointer to peripheral clock division control register
2490  * @param[in] peripheral_clk_div        Peripheral clock division
2491  * @param[in] peripheral_clk_source     Peripheral clock source
2492  *
2493  * @return The wait states for FLWT required after the clock change (or 0 if FLWT does not exist).
2494  **********************************************************************************************************************/
bsp_peripheral_clock_set(volatile uint8_t * p_clk_ctrl_reg,volatile uint8_t * p_clk_div_reg,uint8_t peripheral_clk_div,uint8_t peripheral_clk_source)2495 static void bsp_peripheral_clock_set (volatile uint8_t * p_clk_ctrl_reg,
2496                                       volatile uint8_t * p_clk_div_reg,
2497                                       uint8_t            peripheral_clk_div,
2498                                       uint8_t            peripheral_clk_source)
2499 {
2500     /* Request to stop the peripheral clock. */
2501     *p_clk_ctrl_reg |= (uint8_t) BSP_PRV_PERIPHERAL_CLK_REQ_BIT_MASK;
2502 
2503     /* Wait for the peripheral clock to stop. */
2504     FSP_HARDWARE_REGISTER_WAIT((uint8_t) ((*p_clk_ctrl_reg & BSP_PRV_PERIPHERAL_CLK_RDY_BIT_MASK) >>
2505                                           BSP_PRV_PERIPHERAL_CLK_RDY_BIT_POS),
2506                                1U);
2507 
2508     /* Select the peripheral clock divisor and source. */
2509     *p_clk_div_reg  = peripheral_clk_div;
2510     *p_clk_ctrl_reg = peripheral_clk_source | BSP_PRV_PERIPHERAL_CLK_REQ_BIT_MASK |
2511                       BSP_PRV_PERIPHERAL_CLK_RDY_BIT_MASK;
2512 
2513     /* Request to start the peripheral clock. */
2514     *p_clk_ctrl_reg &= (uint8_t) ~BSP_PRV_PERIPHERAL_CLK_REQ_BIT_MASK;
2515 
2516     /* Wait for the peripheral clock to start. */
2517     FSP_HARDWARE_REGISTER_WAIT((uint8_t) ((*p_clk_ctrl_reg & BSP_PRV_PERIPHERAL_CLK_RDY_BIT_MASK) >>
2518                                           BSP_PRV_PERIPHERAL_CLK_RDY_BIT_POS),
2519                                0U);
2520 }
2521 
2522 #endif
2523 
2524 #if !BSP_FEATURE_CGC_REGISTER_SET_B
2525 
2526 /*******************************************************************************************************************//**
2527  * Increases the ROM and RAM wait state settings to the minimum required based on the requested clock change.
2528  *
2529  * @param[in] requested_freq_hz        New core clock frequency after the clock change.
2530  *
2531  * @return The wait states for FLWT required after the clock change (or 0 if FLWT does not exist).
2532  **********************************************************************************************************************/
bsp_clock_set_prechange(uint32_t requested_freq_hz)2533 static uint8_t bsp_clock_set_prechange (uint32_t requested_freq_hz)
2534 {
2535     uint8_t new_rom_wait_state = 0U;
2536 
2537     FSP_PARAMETER_NOT_USED(requested_freq_hz);
2538 
2539  #if BSP_FEATURE_CGC_HAS_SRAMWTSC
2540 
2541     /* Wait states for SRAM (SRAM0, SRAM1 and SRAM0 (DED)). */
2542     if (requested_freq_hz > BSP_FEATURE_BSP_SYS_CLOCK_FREQ_NO_RAM_WAITS)
2543     {
2544   #if BSP_FEATURE_CGC_HAS_SRAMPRCR2 == 1
2545         R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_UNLOCK;
2546         R_SRAM->SRAMWTSC  = BSP_FEATURE_SRAM_SRAMWTSC_WAIT_CYCLE_ENABLE;
2547         R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_LOCK;
2548   #else
2549         R_SRAM->SRAMPRCR = BSP_PRV_SRAM_UNLOCK;
2550 
2551         /* Execute data memory barrier before and after setting the wait states, See Section 50.4.2 in the RA8M1
2552          * manual R01UH0994EJ0100 */
2553         __DMB();
2554         R_SRAM->SRAMWTSC = BSP_FEATURE_SRAM_SRAMWTSC_WAIT_CYCLE_ENABLE;
2555         __DMB();
2556 
2557         R_SRAM->SRAMPRCR = BSP_PRV_SRAM_LOCK;
2558   #endif
2559     }
2560  #endif
2561 
2562  #if BSP_FEATURE_CGC_HAS_FLWT
2563 
2564     /* Calculate the wait states for ROM */
2565   #if BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS == 0
2566     if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS)
2567     {
2568         new_rom_wait_state = BSP_PRV_ROM_ZERO_WAIT_CYCLES;
2569     }
2570     else
2571     {
2572         new_rom_wait_state = BSP_PRV_ROM_ONE_WAIT_CYCLES;
2573     }
2574 
2575   #elif BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS == 0
2576     if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS)
2577     {
2578         new_rom_wait_state = BSP_PRV_ROM_ZERO_WAIT_CYCLES;
2579     }
2580     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS)
2581     {
2582         new_rom_wait_state = BSP_PRV_ROM_ONE_WAIT_CYCLES;
2583     }
2584     else
2585     {
2586         new_rom_wait_state = BSP_PRV_ROM_TWO_WAIT_CYCLES;
2587     }
2588 
2589   #elif BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FOUR_ROM_WAITS == 0
2590     if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS)
2591     {
2592         new_rom_wait_state = BSP_PRV_ROM_ZERO_WAIT_CYCLES;
2593     }
2594     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS)
2595     {
2596         new_rom_wait_state = BSP_PRV_ROM_ONE_WAIT_CYCLES;
2597     }
2598     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS)
2599     {
2600         new_rom_wait_state = BSP_PRV_ROM_TWO_WAIT_CYCLES;
2601     }
2602     else
2603     {
2604         new_rom_wait_state = BSP_PRV_ROM_THREE_WAIT_CYCLES;
2605     }
2606 
2607   #elif BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FIVE_ROM_WAITS == 0
2608     if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS)
2609     {
2610         new_rom_wait_state = BSP_PRV_ROM_ZERO_WAIT_CYCLES;
2611     }
2612     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS)
2613     {
2614         new_rom_wait_state = BSP_PRV_ROM_ONE_WAIT_CYCLES;
2615     }
2616     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS)
2617     {
2618         new_rom_wait_state = BSP_PRV_ROM_TWO_WAIT_CYCLES;
2619     }
2620     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FOUR_ROM_WAITS)
2621     {
2622         new_rom_wait_state = BSP_PRV_ROM_THREE_WAIT_CYCLES;
2623     }
2624     else
2625     {
2626         new_rom_wait_state = BSP_PRV_ROM_FOUR_WAIT_CYCLES;
2627     }
2628 
2629   #else
2630     if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_ONE_ROM_WAITS)
2631     {
2632         new_rom_wait_state = BSP_PRV_ROM_ZERO_WAIT_CYCLES;
2633     }
2634     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_TWO_ROM_WAITS)
2635     {
2636         new_rom_wait_state = BSP_PRV_ROM_ONE_WAIT_CYCLES;
2637     }
2638     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_THREE_ROM_WAITS)
2639     {
2640         new_rom_wait_state = BSP_PRV_ROM_TWO_WAIT_CYCLES;
2641     }
2642     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FOUR_ROM_WAITS)
2643     {
2644         new_rom_wait_state = BSP_PRV_ROM_THREE_WAIT_CYCLES;
2645     }
2646     else if (requested_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_FIVE_ROM_WAITS)
2647     {
2648         new_rom_wait_state = BSP_PRV_ROM_FOUR_WAIT_CYCLES;
2649     }
2650     else
2651     {
2652         new_rom_wait_state = BSP_PRV_ROM_FIVE_WAIT_CYCLES;
2653     }
2654   #endif
2655 
2656     /* If more wait states are required after the change, then set the wait states before changing the clock. */
2657     if (new_rom_wait_state > R_FCACHE->FLWT)
2658     {
2659         R_FCACHE->FLWT = new_rom_wait_state;
2660     }
2661  #endif
2662 
2663  #if BSP_FEATURE_CGC_HAS_MEMWAIT && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
2664 
2665     /* Set the wait state to MEMWAIT */
2666     bsp_clock_set_memwait(requested_freq_hz);
2667  #endif
2668 
2669  #if BSP_FEATURE_CGC_HAS_FLDWAITR && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
2670     if (requested_freq_hz > BSP_PRV_FLDWAITR_MAX_ONE_WAIT_FREQ)
2671     {
2672         /* The MCU must be in high speed mode to set wait states to 2. The MCU should already be in high speed mode as
2673          * a precondition to bsp_prv_clock_set. */
2674         BSP_PRV_FLDWAITR_REG_ACCESS = BSP_PRV_FLDWAITR_TWO_WAIT_CYCLES;
2675     }
2676  #endif
2677 
2678     return new_rom_wait_state;
2679 }
2680 
2681 /*******************************************************************************************************************//**
2682  * Decreases the ROM and RAM wait state settings to the minimum supported based on the applied clock change.
2683  *
2684  * @param[in] updated_freq_hz          New clock frequency after clock change
2685  * @param[in] new_rom_wait_state       Optimal value for FLWT if it exists, 0 if FLWT does not exist on the MCU
2686  **********************************************************************************************************************/
bsp_clock_set_postchange(uint32_t updated_freq_hz,uint8_t new_rom_wait_state)2687 static void bsp_clock_set_postchange (uint32_t updated_freq_hz, uint8_t new_rom_wait_state)
2688 {
2689     /* These variables are unused for some MCUs. */
2690     FSP_PARAMETER_NOT_USED(new_rom_wait_state);
2691     FSP_PARAMETER_NOT_USED(updated_freq_hz);
2692 
2693  #if BSP_FEATURE_CGC_HAS_SRAMWTSC
2694 
2695     /* Wait states for SRAM (SRAM0, SRAM1 and SRAM0 (DED)). */
2696     if (updated_freq_hz <= BSP_FEATURE_BSP_SYS_CLOCK_FREQ_NO_RAM_WAITS)
2697     {
2698   #if BSP_FEATURE_CGC_HAS_SRAMPRCR2 == 1
2699         R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_UNLOCK;
2700         R_SRAM->SRAMWTSC  = BSP_PRV_SRAMWTSC_WAIT_CYCLES_DISABLE;
2701         R_SRAM->SRAMPRCR2 = BSP_PRV_SRAM_LOCK;
2702   #else
2703         R_SRAM->SRAMPRCR = BSP_PRV_SRAM_UNLOCK;
2704 
2705         /* Execute data memory barrier before and after setting the wait states,See Section 50.4.2 in the RA8M1
2706          * manual R01UH0994EJ0100*/
2707         __DMB();
2708         R_SRAM->SRAMWTSC = BSP_PRV_SRAMWTSC_WAIT_CYCLES_DISABLE;
2709         __DMB();
2710 
2711         R_SRAM->SRAMPRCR = BSP_PRV_SRAM_LOCK;
2712   #endif
2713     }
2714  #endif
2715 
2716  #if BSP_FEATURE_CGC_HAS_FLWT
2717     if (new_rom_wait_state != R_FCACHE->FLWT)
2718     {
2719         R_FCACHE->FLWT = new_rom_wait_state;
2720     }
2721  #endif
2722 
2723  #if BSP_FEATURE_CGC_HAS_MEMWAIT && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
2724 
2725     /* Set the wait state to MEMWAIT */
2726     bsp_clock_set_memwait(updated_freq_hz);
2727  #endif
2728 
2729  #if BSP_FEATURE_CGC_HAS_FLDWAITR && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
2730     if (updated_freq_hz <= BSP_PRV_FLDWAITR_MAX_ONE_WAIT_FREQ)
2731     {
2732         BSP_PRV_FLDWAITR_REG_ACCESS = BSP_PRV_FLDWAITR_ONE_WAIT_CYCLES;
2733     }
2734  #endif
2735 }
2736 
2737 #endif
2738 
2739 /*******************************************************************************************************************//**
2740  * Set the wait state to MEMWAIT.
2741  **********************************************************************************************************************/
2742 #if BSP_FEATURE_CGC_HAS_MEMWAIT && !BSP_PRV_CLOCK_SUPPLY_TYPE_B
bsp_clock_set_memwait(uint32_t updated_freq_hz)2743 static void bsp_clock_set_memwait (uint32_t updated_freq_hz)
2744 {
2745     uint8_t memwait;
2746 
2747     if (updated_freq_hz > BSP_PRV_MEMWAIT_MAX_ONE_WAIT_FREQ)
2748     {
2749         /* The MCU must be in high speed mode to set wait states to 2. The MCU should already be in high speed mode as
2750          * a precondition to bsp_prv_clock_set. */
2751         memwait = BSP_PRV_MEMWAIT_TWO_WAIT_CYCLES;
2752     }
2753     else if (updated_freq_hz > BSP_PRV_MEMWAIT_MAX_ZERO_WAIT_FREQ)
2754     {
2755         memwait = BSP_PRV_MEMWAIT_ONE_WAIT_CYCLES;
2756     }
2757     else
2758     {
2759         memwait = BSP_PRV_MEMWAIT_ZERO_WAIT_CYCLES;
2760     }
2761 
2762     R_SYSTEM->MEMWAIT = memwait;
2763 }
2764 
2765 #endif
2766 
2767 /*******************************************************************************************************************//**
2768  * Initializes sub-clock according to the BSP configuration.
2769  **********************************************************************************************************************/
bsp_prv_sosc_init(void)2770 static void bsp_prv_sosc_init (void)
2771 {
2772 #if BSP_FEATURE_CGC_HAS_SOSC
2773  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
2774   #if BSP_FEATURE_RTC_IS_IRTC
2775    #if ((BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_CLOCK_SOURCE) || (BSP_PRV_HOCO_USE_FLL))
2776 
2777     /* If sub-clock is used as system clock source or HOCO FLL source, wait for VRTC-domain become valid */
2778     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->VRTSR_b.VRTVLD, 1);
2779    #else
2780 
2781     /* Check if VRTC-domain area is valid. */
2782     if (1U == R_SYSTEM->VRTSR_b.VRTVLD)
2783    #endif
2784   #endif
2785     {
2786   #if !BSP_FEATURE_CGC_REGISTER_SET_B
2787         if (R_SYSTEM->SOSCCR || (BSP_CLOCK_CFG_SUBCLOCK_DRIVE != R_SYSTEM->SOMCR_b.SODRV))
2788         {
2789             /* If Sub-Clock Oscillator is started at reset, stop it before configuring the subclock drive. */
2790             if (0U == R_SYSTEM->SOSCCR)
2791             {
2792                 /* Stop the Sub-Clock Oscillator to update the SOMCR register. */
2793                 R_SYSTEM->SOSCCR = 1U;
2794 
2795                 /* Allow a stop interval of at least 5 SOSC clock cycles before configuring the drive capacity
2796                  * and restarting Sub-Clock Oscillator. */
2797                 R_BSP_SoftwareDelay(BSP_PRV_SUBCLOCK_STOP_INTERVAL_US, BSP_DELAY_UNITS_MICROSECONDS);
2798 
2799                 /*
2800                  * r01uh0893ej0120-ra4m3 8.2.9 SOSCCR : Sub-Clock Oscillator Control Register:
2801                  * When changing the value of the SOSTP bit, execute subsequent instructions
2802                  * only after reading the bit to check that the value is updated.
2803                  */
2804                 FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->SOSCCR, 1U);
2805             }
2806 
2807             /* Configure the subclock drive as subclock is not running. */
2808             R_SYSTEM->SOMCR =
2809                 ((BSP_CLOCK_CFG_SUBCLOCK_DRIVE << BSP_FEATURE_CGC_SODRV_SHIFT) & BSP_FEATURE_CGC_SODRV_MASK);
2810   #else
2811         if (R_SYSTEM->SOSCCR)
2812         {
2813   #endif
2814 
2815             R_SYSTEM->SOSCCR = 0U;
2816 
2817             /* r01uh0893ej0120-ra4m3 8.2.9 SOSCCR : Sub-Clock Oscillator Control Register:
2818              * After setting the SOSTP bit to 0, use the sub-clock only after the sub-clock
2819              * oscillation stabilization time has elapsed.
2820              */
2821   #if (BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_CLOCK_SOURCE) || (BSP_PRV_HOCO_USE_FLL)
2822             R_BSP_SubClockStabilizeWait(BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS);
2823   #endif
2824         }
2825         else
2826         {
2827             /*
2828              * RA MCUs like RA6M5 requires to use sub-clock after oscillation stabilization time
2829              * has elapsed on Power-On-Reset. But, POR is not well supported on EK boards, so BSP
2830              * has to wait on any reset. Please override this function in application if waiting
2831              * for stabilization is not required.
2832              */
2833             R_BSP_SubClockStabilizeWaitAfterReset(BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS);
2834         }
2835     }
2836 
2837  #else
2838     R_SYSTEM->SOSCCR = 1U;
2839  #endif
2840 #endif
2841 }
2842 
2843 /*******************************************************************************************************************//**
2844  * Octa-SPI clock update.
2845  * @param[in]   p_octaclk_setting   Pointer to Octaclk setting structure which provides information regarding
2846  *                                  Octaclk source and divider settings to be applied.
2847  * @note The requested Octaclk source must be started before calling this function.
2848  **********************************************************************************************************************/
2849 void R_BSP_OctaclkUpdate (bsp_octaclk_settings_t * p_octaclk_setting)
2850 {
2851 #if BSP_FEATURE_BSP_HAS_OCTASPI_CLOCK
2852 
2853     /* Store initial value of CGC and LPM protection registers. */
2854  #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_NONSECURE_BUILD == 1
2855     uint16_t bsp_prv_prcr_orig = R_SYSTEM->PRCR_NS;
2856  #else
2857     uint16_t bsp_prv_prcr_orig = R_SYSTEM->PRCR;
2858  #endif
2859 
2860     /* Unlock CGC and LPM protection registers. */
2861  #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_NONSECURE_BUILD == 1
2862     R_SYSTEM->PRCR_NS = (uint16_t) BSP_PRV_PRCR_UNLOCK;
2863  #else
2864     R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_UNLOCK;
2865  #endif
2866 
2867     /* Request to change the OCTASPI Clock. */
2868     R_SYSTEM->OCTACKCR_b.OCTACKSREQ = 1;
2869 
2870     /* Wait for the clock to be stopped. */
2871     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OCTACKCR_b.OCTACKSRDY, 1U);
2872 
2873     /* Write the settings. */
2874     R_SYSTEM->OCTACKDIVCR = (uint8_t) p_octaclk_setting->divider;
2875     R_SYSTEM->OCTACKCR    = (uint8_t) (p_octaclk_setting->source_clock | R_SYSTEM_OCTACKCR_OCTACKSREQ_Msk);
2876 
2877     /* Start the OCTASPI Clock by setting OCTACKSREQ to zero. */
2878     R_SYSTEM->OCTACKCR = (uint8_t) p_octaclk_setting->source_clock;
2879 
2880     /* Wait for the OCTASPI Clock to be started. */
2881     FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OCTACKCR_b.OCTACKSRDY, 0U);
2882 
2883     /* Restore CGC and LPM protection registers. */
2884  #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_NONSECURE_BUILD == 1
2885     R_SYSTEM->PRCR_NS = bsp_prv_prcr_orig;
2886  #else
2887     R_SYSTEM->PRCR = bsp_prv_prcr_orig;
2888  #endif
2889 #else
2890     FSP_PARAMETER_NOT_USED(p_octaclk_setting);
2891 #endif
2892 }
2893 
2894 /*******************************************************************************************************************//**
2895  * Gets the frequency of a source clock.
2896  * @param[in]   clock   Pointer to Octaclk setting structure which provides information regarding
2897  *                                  Octaclk source and divider settings to be applied.
2898  * @return     Frequency of requested clock in Hertz.
2899  **********************************************************************************************************************/
2900 uint32_t R_BSP_SourceClockHzGet (fsp_priv_source_clock_t clock)
2901 {
2902     uint32_t source_clock = g_clock_freq[clock];
2903 
2904     return source_clock;
2905 }
2906 
2907 #if BSP_FEATURE_RTC_IS_AVAILABLE || BSP_FEATURE_RTC_HAS_TCEN || BSP_FEATURE_SYSC_HAS_VBTICTLR
2908 
2909 /*******************************************************************************************************************//**
2910  * RTC Initialization
2911  *
2912  * Some RTC registers must be initialized after reset to ensure correct operation.
2913  * This reset is not performed automatically if the RTC is used in a project as it will
2914  * be handled by the RTC driver if needed.
2915  **********************************************************************************************************************/
2916 void R_BSP_Init_RTC (void)
2917 {
2918     /* RA4M3 UM r01uh0893ej0120: Figure 23.14 Initialization procedure */
2919 
2920     /* RCKSEL bit is not initialized after reset. Use LOCO as the default
2921      * clock source if it is available. Note RCR4.ROPSEL is also cleared.
2922      */
2923 
2924  #if BSP_FEATURE_RTC_IS_IRTC
2925     if (0U == R_SYSTEM->VRTSR_b.VRTVLD) // Return if VRTC-domain is invalid
2926     {
2927         return;
2928     }
2929  #endif
2930  #if !BSP_FEATURE_CGC_REGISTER_SET_B
2931   #if BSP_PRV_LOCO_USED && !BSP_FEATURE_RTC_IS_IRTC
2932     R_RTC->RCR4 = 1 << R_RTC_RCR4_RCKSEL_Pos;
2933   #else
2934 
2935     /* Sses SOSC as clock source, or there is no clock source. */
2936     R_RTC->RCR4 = 0;
2937   #endif
2938  #endif
2939 
2940  #if !BSP_CFG_RTC_USED
2941   #if BSP_PRV_LOCO_USED || (BSP_FEATURE_CGC_HAS_SOSC && BSP_CLOCK_CFG_SUBCLOCK_POPULATED)
2942    #if !BSP_FEATURE_CGC_REGISTER_SET_B
2943 
2944     /*Wait for 6 clocks: 200 > (6*1000000) / 32K */
2945     R_BSP_SoftwareDelay(BSP_PRV_RTC_RESET_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
2946 
2947     R_RTC->RCR2 = 0;
2948     FSP_HARDWARE_REGISTER_WAIT(R_RTC->RCR2, 0);
2949 
2950     R_RTC->RCR2_b.RESET = 1;
2951     FSP_HARDWARE_REGISTER_WAIT(R_RTC->RCR2_b.RESET, 0);
2952 
2953     /* Disable RTC interrupts */
2954     R_RTC->RCR1 = 0;
2955 
2956     /* When the RCR1 register is modified, check that all the bits are updated before proceeding
2957      * (see section 26.2.17 "RTC Control Register 1 (RCR1)" of the RA6M3 manual R01UH0886EJ0100)*/
2958     FSP_HARDWARE_REGISTER_WAIT(R_RTC->RCR1, 0);
2959    #endif
2960 
2961    #if BSP_FEATURE_RTC_HAS_TCEN
2962     for (uint8_t index = 0U; index < BSP_FEATURE_RTC_RTCCR_CHANNELS; index++)
2963     {
2964         /* RTCCRn.TCEN must be cleared after reset. */
2965         R_RTC->RTCCR[index].RTCCR_b.TCEN = 0U;
2966         FSP_HARDWARE_REGISTER_WAIT(R_RTC->RTCCR[index].RTCCR_b.TCEN, 0);
2967     }
2968    #endif
2969   #endif
2970  #endif
2971 
2972  #if BSP_FEATURE_SYSC_HAS_VBTICTLR
2973 
2974     /* VBTICTLR.VCHnINEN must be cleared after reset. */
2975     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT);
2976     R_SYSTEM->VBTICTLR = 0U;
2977     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT);
2978  #endif
2979 }
2980 
2981 #endif
2982 
2983 #if BSP_FEATURE_RTC_IS_IRTC
2984 
2985 /*******************************************************************************************************************//**
2986  * To check sub-clock status.
2987  *
2988  * @retval FSP_SUCCESS                  Sub-clock is ready to use.
2989  * @retval FSP_ERR_INVALID_HW_CONDITION VRTC-domain area is invalid.
2990  * @retval FSP_ERR_NOT_INITIALIZED      Sub-clock has not been inititalized yet.
2991  **********************************************************************************************************************/
2992 fsp_err_t R_BSP_SubclockStatusGet ()
2993 {
2994  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
2995 
2996     /* Check if VRTC-domain area is invalid */
2997     FSP_ERROR_RETURN(1U == R_SYSTEM->VRTSR_b.VRTVLD, FSP_ERR_INVALID_HW_CONDITION);
2998 
2999     /* Check if SOSC has been configured */
3000     if ((0U == R_SYSTEM->SOSCCR) && (BSP_CLOCK_CFG_SUBCLOCK_DRIVE == R_SYSTEM->SOMCR_b.SODRV))
3001     {
3002         return FSP_SUCCESS;
3003     }
3004  #endif
3005 
3006     return FSP_ERR_NOT_INITIALIZED;
3007 }
3008 
3009 /*******************************************************************************************************************//**
3010  * To initialize the sub-clock.
3011  *
3012  * @retval FSP_SUCCESS                  Sub-clock successfully initialized.
3013  * @retval FSP_ERR_INVALID_HW_CONDITION Sub-clock cannot be initialized.
3014  **********************************************************************************************************************/
3015 fsp_err_t R_BSP_SubclockInitialize ()
3016 {
3017  #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED
3018 
3019     /* Check if VRTC-domain area is valid */
3020     FSP_ERROR_RETURN(1U == R_SYSTEM->VRTSR_b.VRTVLD, FSP_ERR_INVALID_HW_CONDITION);
3021 
3022     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
3023     bsp_prv_sosc_init();
3024     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
3025 
3026     return FSP_SUCCESS;
3027  #else
3028 
3029     return FSP_ERR_INVALID_HW_CONDITION;
3030  #endif
3031 }
3032 
3033 #endif
3034 
3035 /** @} (end addtogroup BSP_MCU_PRV) */
3036