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