xref: /btstack/port/renesas-tb-s1ja-cc256x/template/btstack_example/synergy/ssp/src/driver/r_cgc/r_cgc.c (revision 3b5c872a8c45689e8cc17891f01530f5aa5e911c)
1 /***********************************************************************************************************************
2  * Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
3  *
4  * This file is part of Renesas SynergyTM Software Package (SSP)
5  *
6  * The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
7  * and/or its licensors ("Renesas") and subject to statutory and contractual protections.
8  *
9  * This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
10  * Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
11  * or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
12  * MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
13  * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
15  * CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
16  * CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
17  * included in this file may be subject to different terms.
18  **********************************************************************************************************************/
19 
20 /**********************************************************************************************************************
21  * File Name    : r_cgc.c
22  * Description  : HAL driver for the Clock Generation circuit.
23  **********************************************************************************************************************/
24 
25 
26 /***********************************************************************************************************************
27 * Includes
28  **********************************************************************************************************************/
29 #include "r_cgc.h"
30 #include "r_cgc_private.h"
31 #include "r_cgc_private_api.h"
32 #include "./hw/hw_cgc_private.h"
33 /* Configuration for this package. */
34 #include "r_cgc_cfg.h"
35 #include "./hw/hw_cgc.h"
36 
37 #if (1 == BSP_CFG_RTOS)
38 #include "tx_api.h"
39 #endif
40 
41 
42 /***********************************************************************************************************************
43  * Macro definitions
44  **********************************************************************************************************************/
45 /** Macro for error logger. */
46 #ifndef CGC_ERROR_RETURN
47 /*LDRA_INSPECTED 77 S This macro does not work when surrounded by parentheses. */
48 #define CGC_ERROR_RETURN(a, err) SSP_ERROR_RETURN((a), (err), g_module_name, &g_cgc_version)
49 #endif
50 
51 #ifndef CGC_ERROR_LOG
52 /*LDRA_INSPECTED 77 S This macro does not work when surrounded by parentheses. */
53 #define CGC_ERROR_LOG(err) SSP_ERROR_LOG((err), g_module_name, &g_cgc_version)
54 #endif
55 
56 #define CGC_LDC_INVALID_CLOCK   (0xFFU)
57 
58 #define CGC_LCD_CFG_TIMEOUT     (0xFFFFFU)
59 #define CGC_SDADC_CFG_TIMEOUT   (0xFFFFFU)
60 
61 /* From user's manual and discussions with hardware group,
62  * using the maximum is safe for all MCUs, will be updated and restored in LPMV2 when entering
63  * low power mode on S7 and S5 MCUs (lowPowerModeEnter())
64  */
65 #define MAXIMUM_HOCOWTR_HSTS    ((uint8_t)0x6U)
66 
67 #define CGC_PLL_DIV_1_SETTING 0
68 #define CGC_PLL_DIV_2_SETTING 1
69 #define CGC_PLL_DIV_4_SETTING 2
70 
71 #if BSP_FEATURE_HAS_CGC_PLL
72 #define CGC_CLOCK_NUM_CLOCKS    ((uint8_t) CGC_CLOCK_PLL + 1U)
73 #else
74 #define CGC_CLOCK_NUM_CLOCKS    ((uint8_t) CGC_CLOCK_SUBCLOCK + 1U)
75 #endif
76 
77 /***********************************************************************************************************************
78  * Typedef definitions
79  **********************************************************************************************************************/
80 
81 /***********************************************************************************************************************
82  * Private function prototypes
83  **********************************************************************************************************************/
84 static ssp_err_t r_cgc_clock_start_stop(cgc_clock_change_t clock_state, cgc_clock_t clock_to_change, cgc_clocks_cfg_t const *p_clk_cfg);
85 static ssp_err_t r_cgc_stabilization_wait(cgc_clock_t clock);
86 
87 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
88 static ssp_err_t r_cgc_check_peripheral_clocks(cgc_system_clocks_t clock);
89 static ssp_err_t r_cgc_check_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg, uint32_t min_div);
90 static ssp_err_t r_cgc_check_config_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg);
91 #if BSP_FEATURE_HAS_CGC_PLL
92 static bool r_cgc_clockcfg_valid_check (cgc_clock_cfg_t * cfg);
93 #endif
94 #endif
95 
96 static bool r_cgc_subosc_mode_possible(void);
97 static bool r_cgc_low_speed_mode_possible(void);
98 static void r_cgc_operating_mode_set(cgc_clock_t const clock_source, uint32_t const current_system_clock);
99 static ssp_err_t r_cgc_wait_to_complete(cgc_clock_t const clock_source, cgc_clock_change_t option);
100 static ssp_err_t r_cgc_clock_running_status_check(cgc_clock_t const clock_source);
101 static void r_cgc_adjust_subosc_speed_mode(void);
102 static ssp_err_t r_cgc_apply_start_stop_options(cgc_clocks_cfg_t const * const p_clock_cfg, cgc_clock_change_t const * const options);
103 static void r_cgc_hw_init (void);
104 static void r_cgc_main_clock_drive_set (R_SYSTEM_Type * p_system_reg, uint8_t val);
105 static void r_cgc_subclock_drive_set (R_SYSTEM_Type * p_system_reg, uint8_t val);
106 static void r_cgc_clock_start (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock);
107 static void r_cgc_clock_stop (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock);
108 static bool r_cgc_clock_check (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock);
109 static void r_cgc_mainosc_source_set (R_SYSTEM_Type * p_system_reg, cgc_osc_source_t osc);
110 static void r_cgc_clock_wait_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, uint8_t time);
111 static void r_cgc_clock_source_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock);
112 static void r_cgc_system_dividers_get (R_SYSTEM_Type * p_system_reg, cgc_system_clock_cfg_t * cfg);
113 static uint32_t r_cgc_clock_divider_get (R_SYSTEM_Type * p_system_reg, cgc_system_clocks_t clock);
114 static uint32_t r_cgc_clock_hzget (R_SYSTEM_Type * p_system_reg, cgc_system_clocks_t clock);
115 static uint32_t r_cgc_clockhz_calculate (cgc_clock_t source_clock,  cgc_sys_clock_div_t divider);
116 static void r_cgc_oscstop_detect_enable (R_SYSTEM_Type * p_system_reg);
117 static void r_cgc_oscstop_detect_disable (R_SYSTEM_Type * p_system_reg);
118 static bool r_cgc_oscstop_status_clear (R_SYSTEM_Type * p_system_reg);
119 static void r_cgc_clockout_cfg (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, cgc_clockout_dividers_t divider);
120 static void r_cgc_clockout_enable (R_SYSTEM_Type * p_system_reg);
121 static void r_cgc_clockout_disable (R_SYSTEM_Type * p_system_reg);
122 static bool r_cgc_systick_update(uint32_t ticks_per_second);
123 static void r_cgc_system_dividers_set (R_SYSTEM_Type * p_system_reg, cgc_system_clock_cfg_t const * const cfg);
124 
125 #if BSP_FEATURE_HAS_CGC_PLL
126 static ssp_err_t r_cgc_prepare_pll_clock(cgc_clock_cfg_t * p_clock_cfg);
127 static void r_cgc_init_pllfreq (R_SYSTEM_Type * p_system_reg);
128 static cgc_clock_t r_cgc_pll_clocksource_get (R_SYSTEM_Type * p_system_reg);
129 #if BSP_FEATURE_HAS_CGC_PLL_SRC_CFG
130 static void r_cgc_pll_clocksource_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock);
131 #endif
132 /*LDRA_INSPECTED 90 s float used because float32_t is not part of the C99 standard integer definitions. */
133 static void r_cgc_pll_multiplier_set (R_SYSTEM_Type * p_system_reg, float multiplier);
134 /*LDRA_INSPECTED 90 s float used because float32_t is not part of the C99 standard integer definitions. */
135 static float r_cgc_pll_multiplier_get (R_SYSTEM_Type * p_system_reg);
136 static void r_cgc_pll_divider_set (R_SYSTEM_Type * p_system_reg, cgc_pll_div_t divider);
137 static uint16_t r_cgc_pll_divider_get (R_SYSTEM_Type * p_system_reg);
138 #endif /* #if BSP_FEATURE_HAS_CGC_PLL */
139 
140 #if (CGC_CFG_SUBCLOCK_AT_RESET_ENABLE == 1)
141 static void r_cgc_delay_cycles (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, uint16_t cycles);
142 #endif
143 
144 /***********************************************************************************************************************
145  * Private global variables
146  **********************************************************************************************************************/
147 #if defined(__GNUC__)
148 /* This structure is affected by warnings from a GCC compiler bug. This pragma suppresses the warnings in this
149  * structure only.*/
150 /*LDRA_INSPECTED 69 S */
151 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
152 #endif
153 /** Version data structure used by error logger macro. */
154 static const ssp_version_t g_cgc_version =
155 {
156     .api_version_minor  = CGC_API_VERSION_MINOR,
157     .api_version_major  = CGC_API_VERSION_MAJOR,
158     .code_version_major = CGC_CODE_VERSION_MAJOR,
159     .code_version_minor = CGC_CODE_VERSION_MINOR
160 };
161 #if defined(__GNUC__)
162 /* Restore warning settings for 'missing-field-initializers' to as specified on command line. */
163 /*LDRA_INSPECTED 69 S */
164 #pragma GCC diagnostic pop
165 #endif
166 
167 /** Name of module used by error logger macro */
168 #if BSP_CFG_ERROR_LOG != 0
169 static const char g_module_name[] = "cgc";
170 #endif
171 /*LDRA_NOANALYSIS LDRA_INSPECTED below not working. */
172 /* This is initialized in cgc_api_t::init, which is called before the C runtime environment is initialized. */
173 /*LDRA_INSPECTED 219 S */
174 bsp_feature_cgc_t const * gp_cgc_feature BSP_PLACE_IN_SECTION_V2(".noinit");
175 /*LDRA_ANALYSIS */
176 
177 /** Pointer to CGC base register. */
178 /* This variable is not initialized at declaration because it is initialized and used before C runtime initialization. */
179 /*LDRA_INSPECTED 57 D *//*LDRA_INSPECTED 57 D */
180 static R_SYSTEM_Type * gp_system_reg BSP_PLACE_IN_SECTION_V2(".noinit");
181 
182 #if BSP_FEATURE_HAS_CGC_LCD_CLK
183 /** LCD clock selection register values. */
184 static const uint8_t g_lcd_clock_settings[] =
185 {
186     [CGC_CLOCK_HOCO]      = 0x04U,     ///< The high speed on chip oscillator.
187     [CGC_CLOCK_MOCO]      = CGC_LDC_INVALID_CLOCK,
188     [CGC_CLOCK_LOCO]      = 0x00U,     ///< The low speed on chip oscillator.
189     [CGC_CLOCK_MAIN_OSC]  = 0x02U,     ///< The main oscillator.
190     [CGC_CLOCK_SUBCLOCK]  = 0x01U,     ///< The subclock oscillator.
191 #if BSP_FEATURE_HAS_CGC_PLL
192     [CGC_CLOCK_PLL]       = CGC_LDC_INVALID_CLOCK,
193 #endif /* #if BSP_FEATURE_HAS_CGC_PLL */
194 };
195 #endif /* #if BSP_FEATURE_HAS_CGC_LCD_CLK */
196 
197 
198 /** This section of RAM should not be initialized by the C runtime environment */
199 /*LDRA_NOANALYSIS LDRA_INSPECTED below not working. */
200 /* This is initialized in cgc_api_t::init, which is called before the C runtime environment is initialized. */
201 /*LDRA_INSPECTED 219 S */
202 static uint32_t           g_clock_freq[CGC_CLOCK_NUM_CLOCKS]  BSP_PLACE_IN_SECTION_V2(".noinit");
203 /*LDRA_ANALYSIS */
204 
205 #if BSP_FEATURE_HAS_CGC_PLL
206 /** These are the divisor values to use when calculating the system clock frequency, using the CGC_PLL_DIV enum type */
207 static const uint16_t g_pllccr_div_value[] =
208 {
209     [CGC_PLL_DIV_1] = 0x01U,
210     [CGC_PLL_DIV_2] = 0x02U,
211     [CGC_PLL_DIV_3] = 0x03U
212 };
213 /** These are the values to use to set the PLL divider register according to the CGC_PLL_DIV enum type */
214 static const uint16_t g_pllccr_div_setting[] =
215 {
216     [CGC_PLL_DIV_1] = 0x00U,
217     [CGC_PLL_DIV_2] = 0x01U,
218     [CGC_PLL_DIV_3] = 0x02U
219 };
220 /** These are the divisor values to use when calculating the system clock frequency, using the CGC_PLL_DIV enum type */
221 static const uint16_t g_pllccr2_div_value[] =
222 {
223     [CGC_PLL_DIV_1_SETTING]         = 0x01U,
224     [CGC_PLL_DIV_2_SETTING]         = 0x02U,
225     [CGC_PLL_DIV_4_SETTING]         = 0x04U
226 };
227 
228 /** These are the values to use to set the PLL divider register according to the CGC_PLL_DIV enum type */
229 static const uint16_t g_pllccr2_div_setting[] =
230 {
231     [CGC_PLL_DIV_1] = 0x00U,
232     [CGC_PLL_DIV_2] = 0x01U,
233     [CGC_PLL_DIV_4] = 0x02U
234 };
235 #endif
236 
237 
238 
239 /***********************************************************************************************************************
240  * Global Variables
241  **********************************************************************************************************************/
242 /*LDRA_INSPECTED 27 D This structure must be accessible in user code. It cannot be static. */
243 const cgc_api_t g_cgc_on_cgc =
244 {
245     .init                 = R_CGC_Init,
246     .clocksCfg            = R_CGC_ClocksCfg,
247     .clockStart           = R_CGC_ClockStart,
248     .clockStop            = R_CGC_ClockStop,
249     .systemClockSet       = R_CGC_SystemClockSet,
250     .systemClockGet       = R_CGC_SystemClockGet,
251     .systemClockFreqGet   = R_CGC_SystemClockFreqGet,
252     .clockCheck           = R_CGC_ClockCheck,
253     .oscStopDetect        = R_CGC_OscStopDetect,
254     .oscStopStatusClear   = R_CGC_OscStopStatusClear,
255     .busClockOutCfg       = R_CGC_BusClockOutCfg,
256     .busClockOutEnable    = R_CGC_BusClockOutEnable,
257     .busClockOutDisable   = R_CGC_BusClockOutDisable,
258     .clockOutCfg          = R_CGC_ClockOutCfg,
259     .clockOutEnable       = R_CGC_ClockOutEnable,
260     .clockOutDisable      = R_CGC_ClockOutDisable,
261     .lcdClockCfg          = R_CGC_LCDClockCfg,
262     .lcdClockEnable       = R_CGC_LCDClockEnable,
263     .lcdClockDisable      = R_CGC_LCDClockDisable,
264     .sdadcClockCfg        = R_CGC_SDADCClockCfg,
265     .sdadcClockEnable     = R_CGC_SDADCClockEnable,
266     .sdadcClockDisable    = R_CGC_SDADCClockDisable,
267     .sdramClockOutEnable  = R_CGC_SDRAMClockOutEnable,
268     .sdramClockOutDisable = R_CGC_SDRAMClockOutDisable,
269     .usbClockCfg          = R_CGC_USBClockCfg,
270     .systickUpdate        = R_CGC_SystickUpdate,
271     .versionGet           = R_CGC_VersionGet
272 };
273 
274 /*******************************************************************************************************************//**
275  * @ingroup HAL_Library
276  * @addtogroup CGC
277  * @brief Clock Generation Circuit Hardware Functions
278  *
279  * @{
280  **********************************************************************************************************************/
281 
282 /***********************************************************************************************************************
283  * Functions
284  **********************************************************************************************************************/
285 
286 /*******************************************************************************************************************//**
287  * @brief  Initialize the CGC API.
288  *
289  *                Configures the following for the clock generator module
290  *                   -If CGC_CFG_SUBCLOCK_AT_RESET_ENABLE is set to true:
291  *                      - SubClock drive capacity (Compile time configurable: CGC_CFG_SUBCLOCK_DRIVE)
292  *                      - Initial setting for the SubClock
293  *
294  *                THIS FUNCTION MUST BE EXECUTED ONCE AT STARTUP BEFORE ANY OF THE OTHER CGC FUNCTIONS
295  *                CAN BE USED OR THE CLOCK SOURCE IS CHANGED FROM THE MOCO.
296  * @retval SSP_SUCCESS                  Clock initialized successfully.
297  * @retval SSP_ERR_HARDWARE_TIMEOUT     Hardware timed out.
298  **********************************************************************************************************************/
R_CGC_Init(void)299 ssp_err_t R_CGC_Init (void)
300 {
301     /* Initialize MCU specific feature pointer. */
302     R_BSP_FeatureCgcGet(&gp_cgc_feature);
303 
304     ssp_feature_t ssp_feature= {{(ssp_ip_t) 0U}};
305     fmi_feature_info_t info = {0U};
306     ssp_feature.channel = 0U;
307     ssp_feature.unit = 0U;
308     ssp_feature.id = SSP_IP_CGC;
309     g_fmi_on_fmi.productFeatureGet(&ssp_feature, &info);
310     gp_system_reg = (R_SYSTEM_Type *) info.ptr;
311 
312     volatile uint32_t timeout;
313     timeout = MAX_REGISTER_WAIT_COUNT;
314     /* Update HOCOWTCR_b.HSTS */
315     if(true == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_HOCO))
316     {
317         /* Make sure the HOCO is stable before changing wait control register */
318         while ((false == r_cgc_clock_check(gp_system_reg, CGC_CLOCK_HOCO)) && (0U != timeout))
319         {
320             /* wait until the clock state is stable */
321             timeout--;
322         }
323         CGC_ERROR_RETURN(timeout, SSP_ERR_HARDWARE_TIMEOUT);
324     }
325 
326     /* Set HOCOWTCR_b.HSTS */
327     r_cgc_hoco_wait_control_set(gp_system_reg, MAXIMUM_HOCOWTR_HSTS);
328 
329     timeout = MAX_REGISTER_WAIT_COUNT;
330     r_cgc_hw_init(); // initialize hardware functions
331 
332     /** SubClock will stop only if configurable setting is Enabled */
333 #if (CGC_CFG_SUBCLOCK_AT_RESET_ENABLE == 1)
334     r_cgc_clock_stop(gp_system_reg, CGC_CLOCK_SUBCLOCK);  // stop SubClock
335     CGC_ERROR_RETURN((SSP_SUCCESS == r_cgc_wait_to_complete(CGC_CLOCK_SUBCLOCK, CGC_CLOCK_CHANGE_STOP)), SSP_ERR_HARDWARE_TIMEOUT);
336     r_cgc_delay_cycles(gp_system_reg, CGC_CLOCK_SUBCLOCK, SUBCLOCK_DELAY); // Delay for 5 SubClock cycles.
337     r_cgc_subclock_drive_set(gp_system_reg, CGC_CFG_SUBCLOCK_DRIVE);        // set the SubClock drive according to the configuration
338 #endif
339     return SSP_SUCCESS;
340 }
341 
342 /*******************************************************************************************************************//**
343  * @brief  Reconfigure all main system clocks.
344  *
345  * @retval SSP_SUCCESS                  Clock initialized successfully.
346  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid argument used.
347  * @retval SSP_ERR_MAIN_OSC_INACTIVE    PLL Initialization attempted with Main OCO turned off/unstable.
348  * @retval SSP_ERR_CLOCK_ACTIVE         Active clock source specified for modification. This applies specifically to the
349  *                                      PLL dividers/multipliers which cannot be modified if the PLL is active. It has
350  *                                      to be stopped first before modification.
351  * @retval SSP_ERR_NOT_STABILIZED       The Clock source is not stabilized after being turned off.
352  * @retval SSP_ERR_CLKOUT_EXCEEDED      The main oscillator can be only 8 or 16 MHz.
353  * @retval SSP_ERR_ASSERTION            A NULL is passed for configuration data when PLL is the clock_source.
354  * @retval SSP_ERR_INVALID_MODE         Attempt to start a clock in a restricted operating power control mode.
355  *
356  **********************************************************************************************************************/
R_CGC_ClocksCfg(cgc_clocks_cfg_t const * const p_clock_cfg)357 ssp_err_t R_CGC_ClocksCfg(cgc_clocks_cfg_t const * const p_clock_cfg)
358 {
359 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
360     SSP_ASSERT(NULL != p_clock_cfg);
361 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
362     ssp_err_t err = SSP_SUCCESS;
363     cgc_clock_t requested_system_clock = p_clock_cfg->system_clock;
364 #if CGC_CFG_PARAM_CHECKING_ENABLE
365 #if BSP_FEATURE_HAS_CGC_PLL
366     cgc_clock_cfg_t * p_pll_cfg = (cgc_clock_cfg_t *)&(p_clock_cfg->pll_cfg);
367 #endif /* BSP_FEATURE_HAS_CGC_PLL */
368 #endif
369     cgc_system_clock_cfg_t sys_cfg = {
370         .pclka_div = CGC_SYS_CLOCK_DIV_1,
371         .pclkb_div = CGC_SYS_CLOCK_DIV_1,
372         .pclkc_div = CGC_SYS_CLOCK_DIV_1,
373         .pclkd_div = CGC_SYS_CLOCK_DIV_1,
374         .bclk_div = CGC_SYS_CLOCK_DIV_1,
375         .fclk_div = CGC_SYS_CLOCK_DIV_1,
376         .iclk_div = CGC_SYS_CLOCK_DIV_1,
377     };
378     bool    power_mode_adjustment = false;
379     cgc_clock_t current_system_clock = CGC_CLOCK_HOCO;
380     R_CGC_SystemClockGet(&current_system_clock, &sys_cfg);
381 
382     cgc_clock_change_t options[CGC_CLOCK_NUM_CLOCKS];
383     options[CGC_CLOCK_HOCO] = p_clock_cfg->hoco_state;
384     options[CGC_CLOCK_LOCO] = p_clock_cfg->loco_state;
385     options[CGC_CLOCK_MOCO] = p_clock_cfg->moco_state;
386     options[CGC_CLOCK_MAIN_OSC] = p_clock_cfg->mainosc_state;
387     options[CGC_CLOCK_SUBCLOCK] = p_clock_cfg->subosc_state;
388 #if BSP_FEATURE_HAS_CGC_PLL
389     options[CGC_CLOCK_PLL] = p_clock_cfg->pll_state;
390 #endif /* BSP_FEATURE_HAS_CGC_PLL */
391 
392 #if CGC_CFG_PARAM_CHECKING_ENABLE
393     CGC_ERROR_RETURN(HW_CGC_ClockSourceValidCheck(requested_system_clock), SSP_ERR_INVALID_ARGUMENT);
394     CGC_ERROR_RETURN(CGC_CLOCK_CHANGE_STOP != options[p_clock_cfg->system_clock], SSP_ERR_INVALID_ARGUMENT);
395 #if BSP_FEATURE_HAS_CGC_PLL
396     if (CGC_CLOCK_CHANGE_START == options[CGC_CLOCK_PLL])
397     {
398         CGC_ERROR_RETURN(HW_CGC_ClockSourceValidCheck(p_pll_cfg->source_clock), SSP_ERR_INVALID_ARGUMENT);
399         CGC_ERROR_RETURN(CGC_CLOCK_CHANGE_STOP != options[p_pll_cfg->source_clock], SSP_ERR_INVALID_ARGUMENT);
400     }
401 #endif /* BSP_FEATURE_HAS_CGC_PLL */
402 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
403 
404     err = r_cgc_apply_start_stop_options(p_clock_cfg, &options[0]);
405     CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
406 
407     err = r_cgc_stabilization_wait(requested_system_clock);
408     CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
409 
410     /* Check if clocks PLL, MOSC, HOCO and MOCO are stopped as a precondition to enter Subosc Speed Mode */
411     /* If not, it will require to review the power mode after setting the clock, because the precondition can change */
412     power_mode_adjustment = (CGC_CLOCK_SUBCLOCK == requested_system_clock) && (!r_cgc_subosc_mode_possible());
413 
414     /* Set which clock to use for system clock and divisors for all system clocks. */
415     err = R_CGC_SystemClockSet(requested_system_clock, &(p_clock_cfg->sys_cfg));
416     CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
417 
418     /* If the system clock has changed, stop previous system clock if requested. */
419     if (requested_system_clock != current_system_clock)
420     {
421         if (CGC_CLOCK_CHANGE_STOP == options[current_system_clock])
422         {
423             err = r_cgc_clock_start_stop(CGC_CLOCK_CHANGE_STOP, current_system_clock, p_clock_cfg);
424             CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
425         }
426     }
427     if (power_mode_adjustment)
428     {
429         r_cgc_operating_mode_set(requested_system_clock, bsp_cpu_clock_get());
430     }
431 
432     return SSP_SUCCESS;
433 }
434 
435 /*******************************************************************************************************************//**
436  * @brief  Start the specified clock if it is not currently active.
437  *
438  *                Configures the following when starting the Main Clock Oscillator:
439  *                - MainClock drive capacity (Configured based on external clock frequency)
440  *                - MainClock stabilization wait time (Compile time configurable: CGC_CFG_MAIN_OSC_WAIT)
441  *                - To update the subclock driven capacity, stop the subclock first before calling this function.
442 **
443  * @retval SSP_SUCCESS                  Clock initialized successfully.
444  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid argument used.
445  * @retval SSP_ERR_MAIN_OSC_INACTIVE    PLL Initialization attempted with Main OCO turned off/unstable.
446  * @retval SSP_ERR_CLOCK_ACTIVE         Active clock source specified for modification. This applies specifically to the
447  *                                      PLL dividers/multipliers which cannot be modified if the PLL is active. It has
448  *                                      to be stopped first before modification.
449  * @retval SSP_ERR_NOT_STABILIZED       The Clock source is not stabilized after being turned off.
450  * @retval SSP_ERR_CLKOUT_EXCEEDED      The main oscillator can be only 8 or 16 MHz.
451  * @retval SSP_ERR_ASSERTION            A NULL is passed for configuration data when PLL is the clock_source.
452  * @retval SSP_ERR_INVALID_MODE         Attempt to start a clock in a restricted operating power control mode.
453  * @retval SSP_ERR_HARDWARE_TIMEOUT		Hardware timed out.
454  **********************************************************************************************************************/
455 
R_CGC_ClockStart(cgc_clock_t clock_source,cgc_clock_cfg_t * p_clock_cfg)456 ssp_err_t R_CGC_ClockStart (cgc_clock_t clock_source, cgc_clock_cfg_t * p_clock_cfg)
457 {
458 
459 
460 #if !BSP_FEATURE_HAS_CGC_PLL
461     SSP_PARAMETER_NOT_USED(p_clock_cfg);
462 #endif
463 
464     /* return error if invalid clock source or not supported by hardware */
465     CGC_ERROR_RETURN((HW_CGC_ClockSourceValidCheck(clock_source)), SSP_ERR_INVALID_ARGUMENT);
466 
467     if (true == r_cgc_clock_run_state_get(gp_system_reg, clock_source))
468     {
469 #if BSP_FEATURE_HAS_CGC_PLL
470         r_cgc_init_pllfreq(gp_system_reg);                                /* calculate  PLL clock frequency and save it */
471 #endif /* BSP_FEATURE_HAS_CGC_PLL */
472         CGC_ERROR_LOG(SSP_ERR_CLOCK_ACTIVE);
473         return SSP_ERR_CLOCK_ACTIVE;
474     }
475 
476     /* some clocks (other than LOCO and MOCO require some additional work before starting them */
477     if (CGC_CLOCK_SUBCLOCK == clock_source)
478     {
479         /* Set SubClockDrive only if clock is not running */
480         r_cgc_subclock_drive_set(gp_system_reg, CGC_CFG_SUBCLOCK_DRIVE);      //Set the SubClock Drive
481     }
482     else if (CGC_CLOCK_MOCO == clock_source)
483     {
484         r_cgc_adjust_subosc_speed_mode();
485     }
486     else if (CGC_CLOCK_HOCO == clock_source)
487     {
488         /* make sure the oscillator has stopped before starting again */
489         CGC_ERROR_RETURN(!(r_cgc_clock_check(gp_system_reg, CGC_CLOCK_HOCO)), SSP_ERR_NOT_STABILIZED);
490         r_cgc_adjust_subosc_speed_mode();
491     }
492     else if (CGC_CLOCK_MAIN_OSC == clock_source)
493     {
494         /* make sure the oscillator has stopped before starting again */
495         CGC_ERROR_RETURN(!(r_cgc_clock_check(gp_system_reg, CGC_CLOCK_MAIN_OSC)), SSP_ERR_NOT_STABILIZED);
496 
497         r_cgc_adjust_subosc_speed_mode();
498         r_cgc_main_clock_drive_set(gp_system_reg, gp_cgc_feature->mainclock_drive);          /* set the Main Clock drive according to
499                                                                      * the configuration */
500         r_cgc_mainosc_source_set(gp_system_reg, (cgc_osc_source_t) CGC_CFG_MAIN_OSC_CLOCK_SOURCE); /* set the main osc source
501                                                                                         * to resonator or
502                                                                                         * external osc. */
503         r_cgc_clock_wait_set(gp_system_reg, CGC_CLOCK_MAIN_OSC, CGC_CFG_MAIN_OSC_WAIT);            /* set the main osc wait time */
504     }
505 
506 #if BSP_FEATURE_HAS_CGC_PLL
507     /*  if clock source is PLL */
508     else if (CGC_CLOCK_PLL == clock_source)
509     {
510         ssp_err_t err;
511         err = r_cgc_prepare_pll_clock(p_clock_cfg);
512         CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
513 
514 #if BSP_FEATURE_HAS_CGC_MIDDLE_SPEED
515         /** See if we need to switch to Middle or High Speed mode before starting the PLL. */
516         cgc_system_clock_cfg_t  current_clock_cfg1;
517         r_cgc_system_dividers_get(gp_system_reg, &current_clock_cfg1); // Get the current iclk divider value.
518         uint32_t requested_frequency_hz = r_cgc_clockhz_calculate(CGC_CLOCK_PLL, current_clock_cfg1.iclk_div);
519         if (requested_frequency_hz > gp_cgc_feature->middle_speed_max_freq_hz)
520         {
521             HW_CGC_SetHighSpeedMode(gp_system_reg);
522         }
523         else
524         {
525             HW_CGC_SetMiddleSpeedMode(gp_system_reg);    // PLL will only run in High or Middle Speed modes.
526         }
527 #else
528         HW_CGC_SetHighSpeedMode(gp_system_reg);
529 #endif /* BSP_FEATURE_HAS_CGC_MIDDLE_SPEED */
530 
531     }
532 #endif /* BSP_FEATURE_HAS_CGC_PLL */
533 
534     else
535     {
536         /* statement here to follow coding standard */
537     }
538 
539     r_cgc_clock_start(gp_system_reg, clock_source);       // start the clock
540     CGC_ERROR_RETURN((SSP_SUCCESS == r_cgc_wait_to_complete(clock_source, CGC_CLOCK_CHANGE_START)), SSP_ERR_HARDWARE_TIMEOUT);
541 
542     return SSP_SUCCESS;
543 }
544 
545 /*******************************************************************************************************************//**
546  * @brief  Stop the specified clock if it is active and not configured as the system clock.
547  * @retval SSP_SUCCESS              		Clock stopped successfully.
548  * @retval SSP_ERR_CLOCK_ACTIVE     		Current System clock source specified for stopping. This is not allowed.
549  * @retval SSP_ERR_OSC_STOP_DET_ENABLED  	Illegal attempt to stop MOCO when Oscillation stop is enabled.
550  * @retval SSP_ERR_NOT_STABILIZED   		Clock not stabilized after starting. A finite stabilization time after starting the
551  *                                  		clock has to elapse before it can be stopped.
552  * @retval SSP_ERR_INVALID_ARGUMENT 		Invalid argument used.
553  * @retval SSP_ERR_HARDWARE_TIMEOUT			Hardware timed out.
554  **********************************************************************************************************************/
555 
R_CGC_ClockStop(cgc_clock_t clock_source)556 ssp_err_t R_CGC_ClockStop (cgc_clock_t clock_source)
557 {
558     cgc_clock_t current_clock;
559 
560     /*  return error if invalid clock source or not supported by hardware */
561     CGC_ERROR_RETURN(HW_CGC_ClockSourceValidCheck(clock_source), SSP_ERR_INVALID_ARGUMENT);
562 
563     current_clock = HW_CGC_ClockSourceGet(gp_system_reg);     // The currently active system clock source cannot be stopped
564 
565     /* if clock source is the current system clock, return error */
566     CGC_ERROR_RETURN((clock_source != current_clock), SSP_ERR_CLOCK_ACTIVE);
567 
568 #if BSP_FEATURE_HAS_CGC_PLL
569     /* If either PLL is the current system clock, or if PLL is not current system clock but it is operating, and the clock source of PLL is same as
570      * requested clock_source to stop, return an error.
571      */
572 
573     CGC_ERROR_RETURN(!(((CGC_CLOCK_PLL == current_clock) || (r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_PLL)))
574             && (r_cgc_pll_clocksource_get(gp_system_reg) == clock_source)), SSP_ERR_CLOCK_ACTIVE);
575 #endif /* BSP_FEATURE_HAS_CGC_PLL */
576 
577     /* MOCO cannot be stopped if OSC Stop Detect is enabled */
578     CGC_ERROR_RETURN(!((clock_source == CGC_CLOCK_MOCO) && ((HW_CGC_OscStopDetectEnabledGet(gp_system_reg)))), SSP_ERR_OSC_STOP_DET_ENABLED);
579 
580     if (!r_cgc_clock_run_state_get(gp_system_reg, clock_source))
581     {
582         return SSP_SUCCESS;    // if clock is already inactive, return success
583     }
584 
585     /*  make sure the oscillator is stable before stopping */
586     CGC_ERROR_RETURN(r_cgc_clock_check(gp_system_reg, clock_source), SSP_ERR_NOT_STABILIZED);
587 
588     r_cgc_clock_stop(gp_system_reg, clock_source);         // stop the clock
589     /* return error if timed out */
590     CGC_ERROR_RETURN((SSP_SUCCESS == r_cgc_wait_to_complete(clock_source, CGC_CLOCK_CHANGE_STOP)), SSP_ERR_HARDWARE_TIMEOUT);
591 
592     return SSP_SUCCESS;
593 }
594 
595 /*******************************************************************************************************************//**
596  * @brief  Set the specified clock as the system clock and configure the internal dividers for
597  *              ICLK, PCLKA, PCLKB, PCLKC, PCLKD and FCLK.
598  *
599  *              THIS FUNCTION DOES NOT CHECK TO SEE IF THE OPERATING MODE SUPPORTS THE SPECIFIED CLOCK SOURCE
600  *              AND DIVIDER VALUES. SETTING A CLOCK SOURCE AND DVIDER OUTSIDE THE RANGE SUPPORTED BY THE
601  *              CURRENT OPERATING MODE WILL RESULT IN UNDEFINED OPERATION.
602  *
603  *              IF THE LOCO MOCO OR SUBCLOCK ARE CHOSEN AS THE SYSTEM CLOCK, THIS FUNCTION WILL SET THOSE AS THE
604  *              SYSTEM CLOCK WITHOUT CHECKING FOR STABILIZATION. IT IS UP TO THE USER TO ENSURE THAT LOCO, MOCO
605  *              OR SUBCLOCK ARE STABLE BEFORE USING THEM AS THE SYSTEM CLOCK.
606  *
607  *              Additionally this function sets the RAM and ROM wait states for the MCU.
608  *              For the S7 MCU the ROMWT register controls ROM wait states.
609  *              For the S3 MCU the MEMWAIT register controls ROM wait states.
610  *
611  * @retval SSP_SUCCESS                  Operation performed successfully.
612  * @retval SSP_ERR_CLOCK_INACTIVE       The specified clock source is inactive.
613  * @retval SSP_ERR_ASSERTION            The p_clock_cfg parameter is NULL.
614  * @retval SSP_ERR_NOT_STABILIZED       The clock source has not stabilized
615  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid argument used. ICLK is not set as the fastest clock.
616  * @retval SSP_ERR_INVALID_MODE         Peripheral divisions are not valid in sub-osc mode
617  * @retval SSP_ERR_INVALID_MODE         Oscillator stop detect not allowed in sub-osc mode
618  **********************************************************************************************************************/
619 
R_CGC_SystemClockSet(cgc_clock_t clock_source,cgc_system_clock_cfg_t const * const p_clock_cfg)620 ssp_err_t R_CGC_SystemClockSet (cgc_clock_t clock_source, cgc_system_clock_cfg_t const * const p_clock_cfg)
621 {
622     cgc_clock_t current_clock;
623     bsp_clock_set_callback_args_t args;
624     ssp_err_t err;
625 
626     /* return error if invalid clock source or not supported by hardware */
627     CGC_ERROR_RETURN((HW_CGC_ClockSourceValidCheck(clock_source)), SSP_ERR_INVALID_ARGUMENT);
628 
629 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
630     SSP_ASSERT(NULL != p_clock_cfg);
631 
632     err = r_cgc_check_config_dividers(p_clock_cfg);
633     CGC_ERROR_RETURN((SSP_SUCCESS == err), err);
634 
635     /* Check if clock source is sub-oscillator clock */
636     if(CGC_CLOCK_SUBCLOCK == clock_source)
637     {
638         /* check if ICLK & FCLK divider is not 0 */
639         /* Peripheral divisions are not valid in sub-osc mode */
640         CGC_ERROR_RETURN(!(0U != p_clock_cfg->iclk_div), SSP_ERR_INVALID_MODE);
641 #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK
642         CGC_ERROR_RETURN(!(0U != p_clock_cfg->fclk_div), SSP_ERR_INVALID_MODE);
643 #endif /* BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
644 
645         /* Oscillator stop detect not allowed in sub-osc mode */
646         CGC_ERROR_RETURN(!(true == HW_CGC_OscStopDetectEnabledGet(gp_system_reg)), SSP_ERR_INVALID_MODE);
647     }
648 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
649 
650     /** In order to correctly set the ROM and RAM wait state registers we need to know the current (S3A7 only) and
651      * requested iclk frequencies.
652      */
653 
654     current_clock = HW_CGC_ClockSourceGet(gp_system_reg);
655     if (clock_source != current_clock)    // if clock_source is not the current system clock, check stabilization
656     {
657         err = r_cgc_clock_running_status_check(clock_source);
658         CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
659     }
660 
661     /* In order to avoid a system clock (momentarily) higher than expected, the order of switching the clock and
662      * dividers must be so that the frequency of the clock goes lower, instead of higher, before being correct.
663      */
664 
665     cgc_system_clock_cfg_t  current_clock_cfg;
666     r_cgc_system_dividers_get(gp_system_reg, &current_clock_cfg);
667 
668    /* Switch to high-speed to prevent any issues with the subsequent system clock change. */
669     HW_CGC_SetHighSpeedMode(gp_system_reg);
670 
671     /* Adjust the MCU specific wait state right before the system clock is set, if the system clock frequency to be set is higher than previous */
672     args.event = BSP_CLOCK_SET_EVENT_PRE_CHANGE;
673     args.new_rom_wait_state = 0U;
674     args.requested_freq_hz = r_cgc_clockhz_calculate(clock_source, p_clock_cfg->iclk_div);
675     args.current_freq_hz = r_cgc_clock_hzget(gp_system_reg, CGC_SYSTEM_CLOCKS_ICLK);
676     err = bsp_clock_set_callback(&args);
677     CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
678 
679     /* If the current ICLK divider is less (higher frequency) than the requested ICLK divider,
680      *  set the divider first.
681      */
682     if (current_clock_cfg.iclk_div < p_clock_cfg->iclk_div )
683     {
684         r_cgc_system_dividers_set(gp_system_reg, p_clock_cfg);
685         r_cgc_clock_source_set(gp_system_reg, clock_source);
686     }
687     /* The current ICLK divider is greater (lower frequency) than the requested ICLK divider, so
688      * set the clock source first.
689      */
690     else
691     {
692         r_cgc_clock_source_set(gp_system_reg, clock_source);
693         r_cgc_system_dividers_set(gp_system_reg, p_clock_cfg);
694     }
695 
696     /* Clock is now at requested frequency. */
697 
698     /* Adjust the MCU specific wait state soon after the system clock is set, if the system clock frequency to be set is lower than previous. */
699     args.current_freq_hz = r_cgc_clock_hzget(gp_system_reg, CGC_SYSTEM_CLOCKS_ICLK);
700     args.event = BSP_CLOCK_SET_EVENT_POST_CHANGE;
701     err = bsp_clock_set_callback(&args);
702     CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
703 
704     /* Update the CMSIS core clock variable so that it reflects the new Iclk freq */
705     SystemCoreClock = bsp_cpu_clock_get();
706 
707     /* Make sure SystemCoreClock frequency should not be zero */
708     CGC_ERROR_RETURN((0U != SystemCoreClock), SSP_ERR_CLOCK_INACTIVE);
709 
710     /* Set the Operating speed mode based on the new system clock source */
711     r_cgc_operating_mode_set(clock_source, SystemCoreClock);
712 
713 #if (1 == BSP_CFG_RTOS)
714     /* If an RTOS is in use, Update the Systick period based on the new frequency, using the ThreadX systick period in Microsecs */
715     R_CGC_SystickUpdate((1000000 / TX_TIMER_TICKS_PER_SECOND), CGC_SYSTICK_PERIOD_UNITS_MICROSECONDS);
716 #endif
717 
718     return SSP_SUCCESS;
719 }
720 
721 /*******************************************************************************************************************//**
722  * @brief Return the current system clock source and configuration.
723  * @retval SSP_SUCCESS          Parameters returned successfully.
724  * @retval SSP_ERR_ASSERTION    A NULL is passed for configuration data.
725  * @retval SSP_ERR_ASSERTION    A NULL is passed for clock source.
726  **********************************************************************************************************************/
727 
R_CGC_SystemClockGet(cgc_clock_t * clock_source,cgc_system_clock_cfg_t * p_set_clock_cfg)728 ssp_err_t R_CGC_SystemClockGet (cgc_clock_t * clock_source, cgc_system_clock_cfg_t * p_set_clock_cfg)
729 {
730 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
731     SSP_ASSERT(NULL != clock_source);
732     SSP_ASSERT(NULL != p_set_clock_cfg);
733 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
734     *clock_source = HW_CGC_ClockSourceGet(gp_system_reg);
735     r_cgc_system_dividers_get(gp_system_reg, p_set_clock_cfg);
736 
737     return SSP_SUCCESS;
738 }
739 
740 /*******************************************************************************************************************//**
741  * @brief  Return the requested internal clock frequency in Hz.
742  * @retval SSP_SUCCESS                  Operation performed successfully.
743  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid clock specified.
744  * @retval SSP_ERR_ASSERTION            A NULL is passed for frequency data.
745  **********************************************************************************************************************/
R_CGC_SystemClockFreqGet(cgc_system_clocks_t clock,uint32_t * p_freq_hz)746 ssp_err_t R_CGC_SystemClockFreqGet (cgc_system_clocks_t clock, uint32_t * p_freq_hz)
747 {
748 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
749     SSP_ASSERT(NULL != p_freq_hz);
750 
751     /* Return error if invalid system clock or not supported by hardware */
752     ssp_err_t err;
753     if (CGC_SYSTEM_CLOCKS_ICLK == clock)
754     {
755         /* Valid clock for all MCUs. Do nothing. */
756     }
757     else if (CGC_SYSTEM_CLOCKS_FCLK == clock)
758     {
759 #if !BSP_FEATURE_HAS_CGC_FLASH_CLOCK
760         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
761         return SSP_ERR_INVALID_ARGUMENT;
762 #endif /* if !BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
763     }
764     else if (CGC_SYSTEM_CLOCKS_BCLK == clock)
765     {
766 #if !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
767         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
768         return SSP_ERR_INVALID_ARGUMENT;
769 #endif /* if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
770     }
771     else
772     {
773         err = r_cgc_check_peripheral_clocks(clock);
774         CGC_ERROR_RETURN((SSP_SUCCESS == err), SSP_ERR_INVALID_ARGUMENT);
775     }
776 
777 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
778 
779     *p_freq_hz = 0x00U;
780     *p_freq_hz = r_cgc_clock_hzget(gp_system_reg, clock);
781     return SSP_SUCCESS;
782 }
783 
784 /*******************************************************************************************************************//**
785  * @brief  Check the specified clock for stability.
786  * @retval SSP_SUCCESS           		Operation performed successfully.
787  * @retval SSP_ERR_NOT_STABILIZED       Clock not stabilized.
788  * @retval SSP_ERR_CLOCK_ACTIVE         Clock active but not able to check for stability.
789  * @retval SSP_ERR_CLOCK_INACTIVE       Clock not turned on.
790  * @retval SSP_ERR_INVALID_ARGUMENT     Illegal parameter passed.
791  * @retval SSP_ERR_STABILIZED			Clock stabilized.
792  **********************************************************************************************************************/
R_CGC_ClockCheck(cgc_clock_t clock_source)793 ssp_err_t R_CGC_ClockCheck (cgc_clock_t clock_source)
794 {
795     /* return error if invalid clock source or not supported by hardware */
796     CGC_ERROR_RETURN((HW_CGC_ClockSourceValidCheck(clock_source)), SSP_ERR_INVALID_ARGUMENT);
797 
798     /*  There is no function to check for LOCO, MOCO or SUBCLOCK stability */
799     if (((clock_source == CGC_CLOCK_LOCO) || (clock_source == CGC_CLOCK_MOCO)) || (clock_source == CGC_CLOCK_SUBCLOCK))
800     {
801         if (true == r_cgc_clock_run_state_get(gp_system_reg, clock_source))
802         {
803             return SSP_ERR_CLOCK_ACTIVE;      // There is no hardware to check for stability so just check for state.
804         }
805         else
806         {
807             return SSP_ERR_CLOCK_INACTIVE;    // There is no hardware to check for stability so just check for state.
808         }
809     }
810 
811     /*  There is a function to check for HOCO, MAIN_OSC and PLL stability */
812 #if BSP_FEATURE_HAS_CGC_PLL
813     else if (((clock_source == CGC_CLOCK_HOCO) || (clock_source == CGC_CLOCK_MAIN_OSC))
814              || (clock_source == CGC_CLOCK_PLL))
815 #else
816     else if (((clock_source == CGC_CLOCK_HOCO) || (clock_source == CGC_CLOCK_MAIN_OSC)))
817 #endif /* BSP_FEATURE_HAS_CGC_PLL */
818     {
819         /* if clock is not active, can't check for stability, return error */
820         CGC_ERROR_RETURN(r_cgc_clock_run_state_get(gp_system_reg, clock_source), SSP_ERR_CLOCK_INACTIVE);
821 
822         /*  check oscillator for stability, return error if not stable */
823         CGC_ERROR_RETURN(r_cgc_clock_check(gp_system_reg, clock_source), SSP_ERR_NOT_STABILIZED);
824         return SSP_ERR_STABILIZED;              // otherwise, return affirmative, not really an error
825     }
826     else
827     {
828         /* statement here to follow coding standard */
829     }
830 
831     return SSP_SUCCESS;
832 }
833 
834 /*******************************************************************************************************************//**
835  * @brief  Enable or disable the oscillation stop detection for the main clock.
836  *  The MCU will automatically switch the system clock to MOCO when a stop is detected if Main Clock is
837  *  the system clock. If the system clock is the PLL, then the clock source will not be changed and the
838  *  PLL free running frequency will be the system clock frequency.
839  * @retval SSP_SUCCESS                  Operation performed successfully.
840  * @retval SSP_ERR_OSC_STOP_DETECTED    The Oscillation stop detect status flag is set. Under this condition it is not
841  *                                      possible to disable the Oscillation stop detection function.
842  * @retval SSP_ERR_ASSERTION            Null pointer passed for callback function when the second argument is "true".
843  * @retval SSP_ERR_ASSERTION            Cannot enable oscillator stop detect in sub-osc speed mode
844  * @retval SSP_ERR_ASSERTION            Invalid peripheral clock divisions for oscillator stop detect
845  * @retval SSP_ERR_INVALID_MODE         Invalid peripheral clock divider setting. Frequencies of peripherals should
846  *                                      follow certain conditions.
847  **********************************************************************************************************************/
R_CGC_OscStopDetect(void (* p_callback)(cgc_callback_args_t * p_args),bool enable)848 ssp_err_t R_CGC_OscStopDetect (void (* p_callback) (cgc_callback_args_t * p_args), bool enable)
849 {
850     if (true == enable)
851     {
852 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
853         SSP_ASSERT(NULL != p_callback);
854         cgc_operating_modes_t operating_mode = r_cgc_operating_mode_get(gp_system_reg);
855         SSP_ASSERT(CGC_SUBOSC_SPEED_MODE != operating_mode);
856         cgc_system_clock_cfg_t clock_cfg;
857         r_cgc_system_dividers_get(gp_system_reg, &clock_cfg);
858         if((0U != gp_cgc_feature->low_speed_max_freq_hz) && (CGC_LOW_SPEED_MODE == operating_mode))
859         {
860             CGC_ERROR_RETURN((SSP_SUCCESS == r_cgc_check_dividers(&clock_cfg, gp_cgc_feature->low_speed_pclk_div_min)), SSP_ERR_INVALID_MODE);
861         }
862         else if((0U != gp_cgc_feature->low_voltage_max_freq_hz) && (CGC_LOW_VOLTAGE_MODE == operating_mode))
863         {
864             CGC_ERROR_RETURN((SSP_SUCCESS == r_cgc_check_dividers(&clock_cfg, gp_cgc_feature->low_voltage_pclk_div_min)), SSP_ERR_INVALID_MODE);
865         }
866         else
867         {
868             /* Do nothing */
869         }
870 #endif
871         /* - add callback function to BSP */
872         R_BSP_GroupIrqWrite(BSP_GRP_IRQ_OSC_STOP_DETECT, (bsp_grp_irq_cb_t) p_callback);
873         r_cgc_oscstop_detect_enable(gp_system_reg);          // enable hardware oscillator stop detect
874     }
875     else
876     {
877         /* if oscillator stop detected, return error */
878         CGC_ERROR_RETURN(!(HW_CGC_OscStopDetectGet(gp_system_reg)), SSP_ERR_OSC_STOP_DETECTED);
879         r_cgc_oscstop_detect_disable(gp_system_reg);          // disable hardware oscillator stop detect
880     }
881 
882     return SSP_SUCCESS;
883 }
884 
885 /*******************************************************************************************************************//**
886  * @brief  Clear the Oscillation Stop Detection Status register.
887  *
888  *                This register is not cleared automatically if the stopped clock is restarted.
889  *                This function blocks for about 3 ICLK cycles until the status register is cleared.
890  * @retval SSP_SUCCESS 						Operation performed successfully.
891  * @retval SSP_ERR_OSC_STOP_CLOCK_ACTIVE    The Oscillation Detect Status flag cannot be cleared if the
892  *                                          Main Osc or PLL is set as the system clock. Change the
893  *                                          system clock before attempting to clear this bit.
894  **********************************************************************************************************************/
895 
R_CGC_OscStopStatusClear(void)896 ssp_err_t R_CGC_OscStopStatusClear (void)
897 {
898     cgc_clock_t current_clock;
899 
900     if (HW_CGC_OscStopDetectGet(gp_system_reg))               // if oscillator stop detected
901     {
902         current_clock = HW_CGC_ClockSourceGet(gp_system_reg); // The currently active system clock source
903 
904 #if BSP_FEATURE_HAS_CGC_PLL
905         /* MCU has PLL. */
906         if (gp_cgc_feature->pll_src_configurable)
907         {
908             cgc_clock_t alt_clock;
909             alt_clock = r_cgc_pll_clocksource_get(gp_system_reg);
910             /* cannot clear oscillator stop status if Main Osc is source of PLL */
911             CGC_ERROR_RETURN(!((CGC_CLOCK_PLL == current_clock) && (CGC_CLOCK_MAIN_OSC == alt_clock)), SSP_ERR_OSC_STOP_CLOCK_ACTIVE);
912         }
913         else
914         {
915             /* cannot clear oscillator stop status if PLL is current clock */
916             CGC_ERROR_RETURN(!(CGC_CLOCK_PLL == current_clock), SSP_ERR_OSC_STOP_CLOCK_ACTIVE);
917         }
918 #endif /* BSP_FEATURE_HAS_CGC_PLL */
919 
920         /* cannot clear oscillator stop status if Main Osc is current clock */
921         CGC_ERROR_RETURN(!(CGC_CLOCK_MAIN_OSC == current_clock), SSP_ERR_OSC_STOP_CLOCK_ACTIVE);
922     }
923 
924     r_cgc_oscstop_status_clear(gp_system_reg);          // clear hardware oscillator stop detect status
925 
926     return SSP_SUCCESS;
927 }
928 
929 /*******************************************************************************************************************//**
930  * @brief  Configure the secondary dividers for BCLKOUT. The primary divider is set using the
931  *           bsp clock configuration and the R_CGC_SystemClockSet function.
932  * @retval SSP_SUCCESS                  Operation performed successfully.
933  **********************************************************************************************************************/
934 
R_CGC_BusClockOutCfg(cgc_bclockout_dividers_t divider)935 ssp_err_t R_CGC_BusClockOutCfg (cgc_bclockout_dividers_t divider)
936 {
937     /* The application must set up the PFS register so the BCLK pin is an output */
938 
939 #if !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
940     SSP_PARAMETER_NOT_USED(divider);
941     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
942     return SSP_ERR_UNSUPPORTED;
943 #else
944     HW_CGC_BusClockOutCfg(gp_system_reg, divider);
945     return SSP_SUCCESS;
946 #endif /* !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
947 }
948 
949 /*******************************************************************************************************************//**
950  * @brief  Enable the BCLKOUT output.
951  * @retval SSP_SUCCESS  Operation performed successfully.
952  **********************************************************************************************************************/
953 
R_CGC_BusClockOutEnable(void)954 ssp_err_t R_CGC_BusClockOutEnable (void)
955 {
956 #if !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
957     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
958     return SSP_ERR_UNSUPPORTED;
959 #else
960     HW_CGC_BusClockOutEnable(gp_system_reg);
961     return SSP_SUCCESS;
962 #endif /* !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
963 }
964 
965 /*******************************************************************************************************************//**
966  * @brief Disable the BCLKOUT output.
967  * @retval SSP_SUCCESS  Operation performed successfully.
968  **********************************************************************************************************************/
969 
R_CGC_BusClockOutDisable(void)970 ssp_err_t R_CGC_BusClockOutDisable (void)
971 {
972 #if !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
973     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
974     return SSP_ERR_UNSUPPORTED;
975 #else
976     HW_CGC_BusClockOutDisable(gp_system_reg);
977     return SSP_SUCCESS;
978 #endif /* !BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
979 }
980 
981 /*******************************************************************************************************************//**
982  * @brief  Configure the dividers for CLKOUT.
983  * @retval SSP_SUCCESS                  Operation performed successfully.
984  * @retval SSP_ERR_INVALID_ARGUMENT     return error if PLL is used as source for clock out
985  * @retval SSP_ERR_CLOCK_INACTIVE       return error if sub clock is not started prior to using it for clock out
986  **********************************************************************************************************************/
R_CGC_ClockOutCfg(cgc_clock_t clock,cgc_clockout_dividers_t divider)987 ssp_err_t R_CGC_ClockOutCfg (cgc_clock_t clock, cgc_clockout_dividers_t divider)
988 {
989     /* The application must set up the PFS register so the CLKOUT pin is an output */
990     CGC_ERROR_RETURN(CGC_CLOCK_PLL != clock, SSP_ERR_INVALID_ARGUMENT); // return error if PLL is selected as source
991     /* Subclock needs to be started before using it for clock out return error if subclock is stopped */
992     CGC_ERROR_RETURN(((CGC_CLOCK_SUBCLOCK != clock) || ((CGC_CLOCK_SUBCLOCK == clock)
993                       &&(true == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_SUBCLOCK)))) , SSP_ERR_CLOCK_INACTIVE)
994     r_cgc_clockout_cfg(gp_system_reg, clock, divider);
995     return SSP_SUCCESS;
996 }
997 
998 /*******************************************************************************************************************//**
999  * @brief  Enable the CLKOUT output.
1000  * @retval SSP_SUCCESS  Operation performed successfully.
1001  **********************************************************************************************************************/
1002 
R_CGC_ClockOutEnable(void)1003 ssp_err_t R_CGC_ClockOutEnable (void)
1004 {
1005     r_cgc_clockout_enable(gp_system_reg);
1006     return SSP_SUCCESS;
1007 }
1008 
1009 /*******************************************************************************************************************//**
1010  * @brief  Disable the CLKOUT output.
1011  * @retval SSP_SUCCESS  Operation performed successfully.
1012  **********************************************************************************************************************/
1013 
R_CGC_ClockOutDisable(void)1014 ssp_err_t R_CGC_ClockOutDisable (void)
1015 {
1016     r_cgc_clockout_disable(gp_system_reg);
1017     return SSP_SUCCESS;
1018 }
1019 
1020 /*******************************************************************************************************************//**
1021  * @brief  Configure the source for the segment LCDCLK.
1022  * @retval SSP_SUCCESS                     Operation performed successfully.
1023  * @retval SSP_ERR_TIMEOUT                 Timed out.
1024  * @retval SSP_ERR_INVALID_ARGUMENT        lcd_clock settings are invalid
1025  * @retval SSP_ERR_UNSUPPORTED             lcd_clock configuration is not supported on this device
1026  **********************************************************************************************************************/
1027 
R_CGC_LCDClockCfg(cgc_clock_t clock)1028 ssp_err_t R_CGC_LCDClockCfg (cgc_clock_t clock)
1029 {
1030 #if !BSP_FEATURE_HAS_CGC_LCD_CLK
1031     SSP_PARAMETER_NOT_USED(clock);
1032     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1033     return SSP_ERR_UNSUPPORTED;
1034 #else
1035     /* The application must set up the PFS register so the LCDCLKOUT pin is an output */
1036     CGC_ERROR_RETURN(CGC_LDC_INVALID_CLOCK != g_lcd_clock_settings[clock], SSP_ERR_INVALID_ARGUMENT);
1037 
1038     /* Protect OFF for CGC. */
1039     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1040 
1041     bool lcd_clock_was_enabled = HW_CGC_LCDClockIsEnabled(gp_system_reg);
1042     R_CGC_LCDClockDisable();
1043     HW_CGC_LCDClockCfg(gp_system_reg, g_lcd_clock_settings[clock]);
1044     uint32_t timeout = CGC_LCD_CFG_TIMEOUT;
1045     while ((g_lcd_clock_settings[clock] != HW_CGC_LCDClockCfgGet(gp_system_reg)) && (0U != timeout))  /* wait for the bit to set */
1046     {
1047         timeout--;
1048     }
1049 
1050     if (lcd_clock_was_enabled)
1051     {
1052         R_CGC_LCDClockEnable();
1053     }
1054 
1055     /* Protect ON for CGC. */
1056     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1057 
1058     CGC_ERROR_RETURN(timeout > 0U, SSP_ERR_TIMEOUT);
1059     return SSP_SUCCESS;
1060 #endif /* !BSP_FEATURE_HAS_CGC_LCD_CLK */
1061 }
1062 
1063 /*******************************************************************************************************************//**
1064  * @brief  Enable the segment LCDCLK output.
1065  * @retval SSP_SUCCESS                  Operation performed successfully.
1066  * @retval SSP_ERR_TIMEOUT              Timed out.
1067  * @retval SSP_ERR_UNSUPPORTED          lcd_clock is not supported on this device
1068  **********************************************************************************************************************/
1069 
R_CGC_LCDClockEnable(void)1070 ssp_err_t R_CGC_LCDClockEnable (void)
1071 {
1072 #if !BSP_FEATURE_HAS_CGC_LCD_CLK
1073     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1074     return SSP_ERR_UNSUPPORTED;
1075 #else
1076     /* Protect OFF for CGC. */
1077     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1078 
1079     HW_CGC_LCDClockEnable(gp_system_reg);
1080     uint32_t timeout = CGC_LCD_CFG_TIMEOUT;
1081     while ((true != HW_CGC_LCDClockIsEnabled(gp_system_reg)) && (0U != timeout))  /* wait for the bit to set */
1082     {
1083         timeout--;
1084     }
1085 
1086     /* Protect ON for CGC. */
1087     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1088 
1089     CGC_ERROR_RETURN(timeout > 0U, SSP_ERR_TIMEOUT);
1090     return SSP_SUCCESS;
1091 #endif /* !BSP_FEATURE_HAS_CGC_LCD_CLK */
1092 }
1093 
1094 /*******************************************************************************************************************//**
1095  * @brief  Disable the segment LCDCLK output.
1096  * @retval SSP_SUCCESS                 Operation performed successfully.
1097  * @retval SSP_ERR_TIMEOUT             Timed out.
1098  * @retval SSP_ERR_UNSUPPORTED         lcd_clock is not supported on this device
1099  **********************************************************************************************************************/
1100 
R_CGC_LCDClockDisable(void)1101 ssp_err_t R_CGC_LCDClockDisable (void)
1102 {
1103 #if !BSP_FEATURE_HAS_CGC_LCD_CLK
1104     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1105     return SSP_ERR_UNSUPPORTED;
1106 #else
1107     /* Protect OFF for CGC. */
1108     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1109 
1110     HW_CGC_LCDClockDisable(gp_system_reg);
1111     uint32_t timeout = CGC_LCD_CFG_TIMEOUT;
1112     while ((false != HW_CGC_LCDClockIsEnabled(gp_system_reg)) && (0U != timeout))  /* wait for the bit to set */
1113     {
1114         timeout--;
1115     }
1116 
1117     /* Protect ON for CGC. */
1118     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1119 
1120     CGC_ERROR_RETURN(timeout > 0U, SSP_ERR_TIMEOUT);
1121     return SSP_SUCCESS;
1122 #endif /* !BSP_FEATURE_HAS_CGC_LCD_CLK */
1123 }
1124 
1125 
1126 
1127 /*******************************************************************************************************************//**
1128  * @brief  Configure the source for the SDADCCLK.
1129  * @retval SSP_SUCCESS                  Operation performed successfully.
1130  * @retval SSP_ERR_UNSUPPORTED          sdadc_clock configuration is not supported on this device
1131  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid clock used
1132   **********************************************************************************************************************/
1133 
R_CGC_SDADCClockCfg(cgc_clock_t clock)1134 ssp_err_t R_CGC_SDADCClockCfg (cgc_clock_t clock)
1135 {
1136 #if !BSP_FEATURE_HAS_CGC_SDADC_CLK
1137     SSP_PARAMETER_NOT_USED(clock);
1138     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1139     return SSP_ERR_UNSUPPORTED;
1140 #else
1141     /* check for valid clock source */
1142     CGC_ERROR_RETURN(!((CGC_CLOCK_MAIN_OSC != clock) && (CGC_CLOCK_HOCO != clock)), SSP_ERR_INVALID_ARGUMENT);
1143 
1144     /* Protect OFF for CGC. */
1145     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1146 
1147     bool sdadc_clock_was_enabled = HW_CGC_SDADCClockIsEnabled(gp_system_reg);
1148     R_CGC_SDADCClockDisable();
1149 
1150     HW_CGC_SDADCClockCfg(gp_system_reg, clock);
1151 
1152     if (sdadc_clock_was_enabled)
1153     {
1154         R_CGC_SDADCClockEnable();
1155     }
1156 
1157     /* Protect ON for CGC. */
1158     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1159 
1160     return SSP_SUCCESS;
1161 #endif /* !BSP_FEATURE_HAS_CGC_SDADC_CLK */
1162 }
1163 
1164 /*******************************************************************************************************************//**
1165  * @brief  Enable the SDADCCLK output.
1166  * @retval SSP_SUCCESS                  Operation performed successfully.
1167  * @retval SSP_ERR_UNSUPPORTED          sdadc_clock is not supported on this device
1168  **********************************************************************************************************************/
1169 
R_CGC_SDADCClockEnable(void)1170 ssp_err_t R_CGC_SDADCClockEnable (void)
1171 {
1172 #if !BSP_FEATURE_HAS_CGC_SDADC_CLK
1173     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1174     return SSP_ERR_UNSUPPORTED;
1175 #else
1176     /* Protect OFF for CGC. */
1177     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1178 
1179     HW_CGC_SDADCClockEnable(gp_system_reg);
1180 
1181     /* Protect ON for CGC. */
1182     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1183     return SSP_SUCCESS;
1184 #endif /* !BSP_FEATURE_HAS_CGC_SDADC_CLK */
1185 }
1186 
1187 /*******************************************************************************************************************//**
1188  * @brief  Disable the SDADCCLK output.
1189  * @retval SSP_SUCCESS                  Operation performed successfully.
1190  * @retval SSP_ERR_UNSUPPORTED          sdadc_clock is not supported on this device
1191  **********************************************************************************************************************/
1192 
R_CGC_SDADCClockDisable(void)1193 ssp_err_t R_CGC_SDADCClockDisable (void)
1194 {
1195 #if !BSP_FEATURE_HAS_CGC_SDADC_CLK
1196     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1197     return SSP_ERR_UNSUPPORTED;
1198 #else
1199     /* Protect OFF for CGC. */
1200     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
1201     HW_CGC_SDADCClockDisable(gp_system_reg);
1202     /* Protect ON for CGC. */
1203     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
1204     return SSP_SUCCESS;
1205 #endif /* !BSP_FEATURE_HAS_CGC_SDADC_CLK */
1206 }
1207 
1208 
1209 /*******************************************************************************************************************//**
1210  * @brief  Enable the SDCLK output.
1211  * @retval SSP_SUCCESS                    Operation performed successfully.
1212  * @retval SSP_ERR_UNSUPPORTED            sdram_clock is not supported on this device
1213  **********************************************************************************************************************/
1214 
R_CGC_SDRAMClockOutEnable(void)1215 ssp_err_t R_CGC_SDRAMClockOutEnable (void)
1216 {
1217 #if !BSP_FEATURE_HAS_CGC_SDRAM_CLK
1218     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1219     return SSP_ERR_UNSUPPORTED;
1220 #else
1221     HW_CGC_SDRAMClockOutEnable(gp_system_reg);
1222     return SSP_SUCCESS;
1223 #endif
1224 }
1225 
1226 /*******************************************************************************************************************//**
1227  * @brief  Disable the SDCLK output.
1228  * @retval SSP_SUCCESS                    Operation performed successfully.
1229  * @retval SSP_ERR_UNSUPPORTED            sdram_clock is not supported on this device
1230  **********************************************************************************************************************/
1231 
R_CGC_SDRAMClockOutDisable(void)1232 ssp_err_t R_CGC_SDRAMClockOutDisable (void)
1233 {
1234 #if !BSP_FEATURE_HAS_CGC_SDRAM_CLK
1235     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1236     return SSP_ERR_UNSUPPORTED;
1237 #else
1238     HW_CGC_SDRAMClockOutDisable(gp_system_reg);
1239     return SSP_SUCCESS;
1240 #endif
1241 }
1242 
1243 /*******************************************************************************************************************//**
1244  * @brief  Configure the dividers for UCLK.
1245  * @retval SSP_SUCCESS                  Operation performed successfully.
1246  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid usb_clock divider specified
1247  ***********************************************************************************************************************/
1248 
R_CGC_USBClockCfg(cgc_usb_clock_div_t divider)1249 ssp_err_t R_CGC_USBClockCfg (cgc_usb_clock_div_t divider)
1250 {
1251 #if !BSP_FEATURE_HAS_CGC_USB_CLK
1252     SSP_PARAMETER_NOT_USED(divider);
1253     CGC_ERROR_LOG(SSP_ERR_UNSUPPORTED);
1254     return SSP_ERR_UNSUPPORTED;
1255 #else
1256     /* The application must set up the PFS register so the USBCLKOUT pin is an output */
1257     HW_CGC_USBClockCfg(gp_system_reg, divider);
1258     return SSP_SUCCESS;
1259 #endif
1260 }
1261 
1262 /*******************************************************************************************************************//**
1263  * @brief  Re-Configure the systick based on the provided period and current system clock frequency.
1264  * @param[in]   period_count       The duration for the systick period.
1265  * @param[in]   units              The units for the provided period.
1266  * @retval SSP_SUCCESS                  Operation performed successfully.
1267  * @retval SSP_ERR_INVALID_ARGUMENT     Invalid period specified.
1268  * @retval SSP_ERR_ABORTED              Attempt to update systick timer failed.
1269  **********************************************************************************************************************/
R_CGC_SystickUpdate(uint32_t period_count,cgc_systick_period_units_t units)1270 ssp_err_t R_CGC_SystickUpdate(uint32_t period_count, cgc_systick_period_units_t units)
1271 {
1272     uint32_t requested_period_count = period_count;
1273     uint32_t reload_value;
1274     uint32_t freq;
1275     cgc_systick_period_units_t period_units = units;
1276 #if (__FPU_PRESENT != 0)
1277     /*LDRA_INSPECTED 90 s float used because float32_t is not part of the C99 standard integer definitions. */
1278     float period = 0.0f;
1279 #endif
1280 
1281 #if (CGC_CFG_PARAM_CHECKING_ENABLE)
1282     if (0 == period_count)
1283     {
1284         SSP_ERROR_LOG((SSP_ERR_INVALID_ARGUMENT), (g_module_name), (g_cgc_version));   // Invalid period provided
1285         return (SSP_ERR_INVALID_ARGUMENT);
1286     }
1287 #endif
1288 
1289     freq = bsp_cpu_clock_get();		                // Get the current ICLK frequency
1290 
1291     /* If an RTOS is in use then we want to set the Systick period to that defined by the RTOS. So we'll convert the macro
1292      * settings use the existing code and calculate the reload value
1293      */
1294 #if (1 == BSP_CFG_RTOS)
1295     period_units = CGC_SYSTICK_PERIOD_UNITS_MICROSECONDS;
1296     requested_period_count = (RELOAD_COUNT_FOR_1US) / TX_TIMER_TICKS_PER_SECOND;        // Convert ticks per sec to ticks per us
1297 #endif
1298 
1299 #if (__FPU_PRESENT == 0)
1300     reload_value = (uint32_t)(((uint64_t)(requested_period_count) * (uint64_t)(freq) + (uint64_t)(period_units/2)) / period_units);
1301 #else
1302     /*LDRA_INSPECTED 90 s *//*LDRA_INSPECTED 90 s */
1303     period = ((1.0f)/(float)freq) * (float)period_units;           // This is the period in the provided units
1304     /*LDRA_INSPECTED 90 s */
1305     reload_value = (uint32_t)((float)requested_period_count/period);
1306 #endif
1307 
1308     // Configure the systick period as requested
1309     CGC_ERROR_RETURN(r_cgc_systick_update(reload_value), SSP_ERR_ABORTED);
1310     return SSP_SUCCESS;
1311 }
1312 
1313 
1314 /*******************************************************************************************************************//**
1315  * @brief  Return the driver version.
1316  * @retval SSP_SUCCESS      	  Operation performed successfully.
1317  * @retval SSP_ERR_ASSERTION      The parameter p_version is NULL..
1318  **********************************************************************************************************************/
1319 
R_CGC_VersionGet(ssp_version_t * const p_version)1320 ssp_err_t R_CGC_VersionGet (ssp_version_t * const p_version)
1321 {
1322 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
1323     SSP_ASSERT(NULL != p_version);
1324 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
1325     p_version->version_id = g_cgc_version.version_id;
1326     return SSP_SUCCESS;
1327 }
1328 
1329 /*******************************************************************************************************************//**
1330  * @brief  Return the Stabilization Status.
1331  * @param[in]  clock                    clock to be checked
1332  * @retval     SSP_SUCCESS              Operation performed successfully.
1333  * @retval     SSP_ERR_STABILIZED       Clock stabilized
1334  * @retval     SSP_ERR_NOT_STABILIZED   CLock not stabilized
1335  * @retval     SPP_ERR_CLOCK_ACTIVE     Specified clock source is already stabilized
1336  **********************************************************************************************************************/
1337 
r_cgc_stabilization_wait(cgc_clock_t clock)1338 static ssp_err_t r_cgc_stabilization_wait(cgc_clock_t clock)
1339 {
1340     ssp_err_t err = SSP_ERR_NOT_STABILIZED;
1341 
1342     int32_t timeout = MAX_REGISTER_WAIT_COUNT;
1343     while (SSP_ERR_NOT_STABILIZED == err)
1344     {
1345         /* Wait for clock source to stabilize */
1346         timeout--;
1347         CGC_ERROR_RETURN(0 < timeout, SSP_ERR_NOT_STABILIZED);
1348         err = R_CGC_ClockCheck(clock);
1349     }
1350 
1351     CGC_ERROR_RETURN((SSP_SUCCESS == err) || (SSP_ERR_STABILIZED == err) ||
1352         (SSP_ERR_CLOCK_ACTIVE == err), err);
1353 
1354     return SSP_SUCCESS;
1355 }
1356 
1357 /*******************************************************************************************************************//**
1358  * @brief Functionality of this function is to change the clock state and modifies the clock source
1359  *        as per input parameters
1360  * @param[in]   clock_state                     required clock state
1361  * @param[in]   clock_to_change                 required clock source
1362  * @param[in]   p_clk_cfg                       Pointer to the clock configuration structure
1363  * @retval      SSP_SUCCESS                     Operation performed successfully.
1364  * @retval      SPP_ERR_CLOCK_ACTIVE            Specified clock is already running
1365  * @retval      SSP_ERR_OSC_STOP_DET_ENABLED  	Illegal attempt to stop MOCO when Oscillation stop is enabled.
1366  * @retval      SSP_ERR_NOT_STABILIZED   		Clock not stabilized after starting. A finite stabilization time after starting the
1367  *                                  		    clock has to elapse before it can be stopped.
1368  * @retval      SSP_ERR_INVALID_ARGUMENT 		Invalid argument used.
1369  * @retval      SSP_ERR_HARDWARE_TIMEOUT		Hardware timed out.
1370  **********************************************************************************************************************/
r_cgc_clock_start_stop(cgc_clock_change_t clock_state,cgc_clock_t clock_to_change,cgc_clocks_cfg_t const * p_clk_cfg)1371 static ssp_err_t r_cgc_clock_start_stop(cgc_clock_change_t clock_state, cgc_clock_t clock_to_change, cgc_clocks_cfg_t const *p_clk_cfg)
1372 {
1373     cgc_clock_cfg_t * p_pll_cfg = (cgc_clock_cfg_t *)&(p_clk_cfg->pll_cfg);
1374     ssp_err_t err = SSP_SUCCESS;
1375 
1376     if(CGC_CLOCK_CHANGE_STOP == clock_state)
1377     {
1378         err = R_CGC_ClockStop(clock_to_change);
1379         CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
1380     }
1381     else if(CGC_CLOCK_CHANGE_START == clock_state)
1382     {
1383 #if BSP_FEATURE_HAS_CGC_PLL
1384         if (CGC_CLOCK_PLL == clock_to_change)
1385         {
1386             /* Need to start PLL source clock and let it stabilize before starting PLL */
1387             err = R_CGC_ClockStart(p_pll_cfg->source_clock, (cgc_clock_cfg_t *)p_clk_cfg);
1388             CGC_ERROR_RETURN((SSP_SUCCESS == err) || (SSP_ERR_CLOCK_ACTIVE == err), err);
1389 
1390             err = r_cgc_stabilization_wait(p_pll_cfg->source_clock);
1391             CGC_ERROR_RETURN(SSP_SUCCESS == err, err);
1392         }
1393 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1394         err = R_CGC_ClockStart(clock_to_change, p_pll_cfg);
1395         CGC_ERROR_RETURN((SSP_SUCCESS == err) || (SSP_ERR_CLOCK_ACTIVE == err), err);
1396     }
1397     else /* CGC_CLOCK_OPTION_NO_CHANGE */
1398     {
1399         /* Do nothing */
1400     }
1401 
1402     return SSP_SUCCESS;
1403 }
1404 
1405 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
1406 /*******************************************************************************************************************//**
1407  * @brief  Check if the given peripheral clock is valid for the current MCU.
1408  * @param[in] clock                     current system clock
1409  * @retval SSP_SUCCESS                  Given peripheral clock is valid for the current MCU.
1410  * @retval SSP_ERR_INVALID_ARGUMENT     Given peripheral clock is invalid for the current MCU.
1411  **********************************************************************************************************************/
r_cgc_check_peripheral_clocks(cgc_system_clocks_t clock)1412 static ssp_err_t r_cgc_check_peripheral_clocks (cgc_system_clocks_t clock)
1413 {
1414     if (CGC_SYSTEM_CLOCKS_PCLKA == clock)
1415     {
1416 #if BSP_FEATURE_HAS_CGC_PCKA
1417         return SSP_SUCCESS;
1418 #else
1419         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
1420         return SSP_ERR_INVALID_ARGUMENT;
1421 #endif /* BSP_FEATURE_HAS_CGC_PCKA */
1422     }
1423     else if (CGC_SYSTEM_CLOCKS_PCLKB == clock)
1424     {
1425 #if BSP_FEATURE_HAS_CGC_PCKB
1426         return SSP_SUCCESS;
1427 #else
1428         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
1429         return SSP_ERR_INVALID_ARGUMENT;
1430 #endif /* BSP_FEATURE_HAS_CGC_PCKB */
1431     }
1432     else if (CGC_SYSTEM_CLOCKS_PCLKC == clock)
1433     {
1434 #if BSP_FEATURE_HAS_CGC_PCKC
1435         return SSP_SUCCESS;
1436 #else
1437         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
1438         return SSP_ERR_INVALID_ARGUMENT;
1439 #endif /* BSP_FEATURE_HAS_CGC_PCKC */
1440     }
1441     else if (CGC_SYSTEM_CLOCKS_PCLKD == clock)
1442     {
1443 #if BSP_FEATURE_HAS_CGC_PCKD
1444         return SSP_SUCCESS;
1445 #else
1446         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
1447         return SSP_ERR_INVALID_ARGUMENT;
1448 #endif /* BSP_FEATURE_HAS_CGC_PCKD */
1449     }
1450     else
1451     {
1452         CGC_ERROR_LOG(SSP_ERR_INVALID_ARGUMENT);
1453         return SSP_ERR_INVALID_ARGUMENT;
1454     }
1455 }
1456 #endif
1457 
1458 /*******************************************************************************************************************//**
1459  * @brief  Verifies if Sub-osc Mode is possible
1460  * @retval  true    Sub-osc mode is possible or feature does not exist (hence no reason to try it later)
1461  * @retval  false   Sub-osc mode feature is available but could not be used at this time (not meeting conditions)
1462  **********************************************************************************************************************/
r_cgc_subosc_mode_possible(void)1463 static bool r_cgc_subosc_mode_possible(void)
1464 {
1465 #if BSP_FEATURE_HAS_CGC_PLL
1466     if ((false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_PLL)) && (false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_MAIN_OSC)) &&
1467         (false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_HOCO)) && (false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_MOCO)))
1468     {
1469         return true;
1470     }
1471 #else
1472     if ((false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_MAIN_OSC)) &&
1473         (false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_HOCO)) && (false == r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_MOCO)))
1474     {
1475         return true;
1476     }
1477 #endif
1478     return false;
1479 }
1480 
1481 /*******************************************************************************************************************//**
1482  * @brief  Verifies if Low-speed Mode is possible
1483  * @retval  true    Low-speed mode is possible
1484  * @retval  false   Low-speed mode is not possible (not meeting conditions)
1485  **********************************************************************************************************************/
r_cgc_low_speed_mode_possible(void)1486 static bool r_cgc_low_speed_mode_possible(void)
1487 {
1488 #if BSP_FEATURE_HAS_CGC_PLL
1489     return !r_cgc_clock_run_state_get(gp_system_reg, CGC_CLOCK_PLL);
1490 #else /* BSP_FEATURE_HAS_CGC_PLL */
1491     return true;
1492 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1493 }
1494 
1495 
1496 /*******************************************************************************************************************//**
1497  * @brief  Set the optimum operating speed mode based on new system clock
1498  * @param[in] clock_source    		Clock that will have the operating mode prepared for
1499  * @param[in] current_system_clock	Current clock, as before changing the speed mode
1500   **********************************************************************************************************************/
r_cgc_operating_mode_set(cgc_clock_t const clock_source,uint32_t const current_system_clock)1501 static void r_cgc_operating_mode_set(cgc_clock_t const clock_source, uint32_t const current_system_clock)
1502 {
1503 #if BSP_FEATURE_HAS_CGC_PLL && BSP_FEATURE_HAS_CGC_MIDDLE_SPEED
1504     /* Checks if clock source is PLL */
1505     if (CGC_CLOCK_PLL == clock_source)
1506     {
1507         /* PLL will only run in High or Middle Speed modes. */
1508         if (current_system_clock <= gp_cgc_feature->middle_speed_max_freq_hz)
1509         {
1510             /* Switch to middle speed mode */
1511             HW_CGC_SetMiddleSpeedMode(gp_system_reg);
1512         }
1513         else
1514         {
1515             /* Nothing to do, stay in high speed mode */
1516         }
1517         return;
1518     }
1519 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1520     /* For all other remaining clock sources i.e., HOCO, MOCO, LOCO, SUBCLOCK, MOSC */
1521 #if CGC_CFG_USE_LOW_VOLTAGE_MODE
1522     /* System clock should be less than or equal to Low voltage max frequency */
1523     if (current_system_clock <= (gp_cgc_feature->low_voltage_max_freq_hz))
1524     {
1525         /* Switch to low voltage mode */
1526         HW_CGC_SetLowVoltageMode(gp_system_reg);
1527 
1528         /* Low voltage mode is conditionally compiled. If the Low voltage mode is executed,
1529          * no other operating power mode needs to be checked for execution, hence the function returns from here.
1530          * If the low voltage mode feature was not conditionally compiled, the next statement would be an 'else if()'
1531          * instead of an 'if()' would be added to choose the optimum power control mode */
1532         return;
1533     }
1534 #endif
1535 
1536     /* Checks if MCU supports sub oscillator speed mode and also clock source should be subclock or LOCO */
1537 #if BSP_FEATURE_HAS_CGC_SUBOSC_SPEED
1538     if ((CGC_CLOCK_SUBCLOCK == clock_source) || (CGC_CLOCK_LOCO == clock_source))
1539     {
1540         /* Verify that clocks PLL, MOSC, HOCO and MOCO are stopped as a precondition to enter Subosc Speed Mode */
1541         if (true == r_cgc_subosc_mode_possible())
1542         {
1543             /* Switch to sub oscillator mode */
1544             HW_CGC_SetSubOscSpeedMode(gp_system_reg);
1545             return;
1546         }
1547         /* If sub-osc mode was not available will try the lowest available */
1548     }
1549 #endif
1550 
1551     /* System clock should be less than or equal to Low speed max frequency */
1552     if (current_system_clock <= gp_cgc_feature->low_speed_max_freq_hz)
1553     {
1554         if(true == r_cgc_low_speed_mode_possible())
1555         {
1556             /* Switch to low speed mode */
1557             HW_CGC_SetLowSpeedMode(gp_system_reg);
1558             return;
1559         }
1560     }
1561 
1562 #if BSP_FEATURE_HAS_CGC_MIDDLE_SPEED
1563     /* System clock should be less than or equal to Middle speed max frequency */
1564     if (current_system_clock <= gp_cgc_feature->middle_speed_max_freq_hz)
1565     {
1566         /* Switch to middle speed mode */
1567         HW_CGC_SetMiddleSpeedMode(gp_system_reg);
1568     }
1569     else
1570     {
1571         /* Nothing to do, stay in high speed mode */
1572     }
1573 #endif /* BSP_FEATURE_HAS_CGC_MIDDLE_SPEED */
1574 }
1575 
1576 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
1577 /*******************************************************************************************************************//**
1578  * @brief  Check dividers values
1579  * @param[in] p_clock_cfg       pointer to the clock configuration structure
1580  * @param[in] min_div           minimum low speed clock divider value
1581  * @retval      SSP_SUCCESS     Operation performed successfully
1582  * @retval SSP_ERR_INVALID_MODE clock divider is divider is greater than minimum low speed clock divider and is invalid
1583   **********************************************************************************************************************/
r_cgc_check_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg,uint32_t min_div)1584 static ssp_err_t r_cgc_check_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg, uint32_t min_div)
1585 {
1586 #if BSP_FEATURE_HAS_CGC_PCKA
1587     /* check if the MCU has PCLKA and PCLKA divider is greater than minimum low speed clock divider*/
1588     CGC_ERROR_RETURN(!(p_clock_cfg->pclka_div < min_div), SSP_ERR_INVALID_MODE);
1589 #endif /* BSP_FEATURE_HAS_CGC_PCKA */
1590 
1591 #if BSP_FEATURE_HAS_CGC_PCKB
1592     /* check if the MCU has PCLKB and PCLKB divider is greater than minimum low speed clock divider*/
1593     CGC_ERROR_RETURN(!(p_clock_cfg->pclkb_div < min_div), SSP_ERR_INVALID_MODE);
1594 #endif /* BSP_FEATURE_HAS_CGC_PCKB */
1595 
1596 #if BSP_FEATURE_HAS_CGC_PCKC
1597     /* check if the MCU has PCLKC and PCLKC divider is greater than minimum low speed clock divider*/
1598     CGC_ERROR_RETURN(!(p_clock_cfg->pclkc_div < min_div), SSP_ERR_INVALID_MODE);
1599 #endif /* BSP_FEATURE_HAS_CGC_PCKC */
1600 
1601 #if BSP_FEATURE_HAS_CGC_PCKD
1602     /* check if the MCU has PCLKD and PCLKD divider is greater than minimum low speed clock divider*/
1603     CGC_ERROR_RETURN(!(p_clock_cfg->pclkd_div < min_div), SSP_ERR_INVALID_MODE);
1604 #endif /* BSP_FEATURE_HAS_CGC_PCKD */
1605 
1606 #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK
1607     /* check if the MCU has FCLK and FCLK divider is greater than minimum low speed clock divider*/
1608     CGC_ERROR_RETURN(!(p_clock_cfg->fclk_div < min_div), SSP_ERR_INVALID_MODE);
1609 #endif /* BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
1610 
1611 #if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
1612     /* check if the MCU has BCLK and BCLK divider is greater than minimum low speed clock divider*/
1613     CGC_ERROR_RETURN(!(p_clock_cfg->bclk_div < min_div), SSP_ERR_INVALID_MODE);
1614 #endif /* BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
1615 
1616     /* check if the ICLK  is greater than minimum low speed clock divider*/
1617     CGC_ERROR_RETURN(p_clock_cfg->iclk_div >= min_div, SSP_ERR_INVALID_MODE);
1618 
1619     return SSP_SUCCESS;
1620 }
1621 
1622 /*******************************************************************************************************************//**
1623  * @brief  Check config dividers values
1624  * @param[in]   p_clock_cfg              pointer to clock system configuration
1625  * @retval      SSP_SUCCESS              Operation performed successfully.
1626  * @retval      SSP_ERR_INVALID_ARGUMENT One or more divider values are not satisfying the conditions
1627  *                                       as per User Manual
1628  **********************************************************************************************************************/
r_cgc_check_config_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg)1629 static ssp_err_t r_cgc_check_config_dividers(cgc_system_clock_cfg_t const * const p_clock_cfg)
1630 {
1631     /* Check if MCU supports PCLKA */
1632 #if BSP_FEATURE_HAS_CGC_PCKA
1633     /* Note: Below conditions are based on divider checking, frequency is inversely proportional */
1634     /* Check if ICLK is greater than PCLKA */
1635     CGC_ERROR_RETURN(!(p_clock_cfg->pclka_div < p_clock_cfg->iclk_div), SSP_ERR_INVALID_ARGUMENT);
1636 
1637     /* check if PCLKA is greater than PCLKB */
1638     CGC_ERROR_RETURN(!(p_clock_cfg->pclkb_div < p_clock_cfg->pclka_div), SSP_ERR_INVALID_ARGUMENT);
1639 
1640     /* check if PCLKD is greater than PCLKA */
1641     CGC_ERROR_RETURN(!(p_clock_cfg->pclka_div < p_clock_cfg->pclkd_div), SSP_ERR_INVALID_ARGUMENT);
1642 #endif /* BSP_FEATURE_HAS_CGC_PCKA */
1643 
1644 #if BSP_FEATURE_HAS_CGC_PCKB && BSP_FEATURE_HAS_CGC_PCKD
1645     /* Check if PCLKD is greater than PCLKB */
1646     CGC_ERROR_RETURN(!(p_clock_cfg->pclkb_div < p_clock_cfg->pclkd_div), SSP_ERR_INVALID_ARGUMENT);
1647 #endif /* BSP_FEATURE_HAS_CGC_PCKB && BSP_FEATURE_HAS_CGC_PCKD */
1648 
1649 #if BSP_FEATURE_HAS_CGC_PCKB
1650     /* Check if ICLK is greater than PCLKB */
1651     CGC_ERROR_RETURN(!(p_clock_cfg->pclkb_div < p_clock_cfg->iclk_div), SSP_ERR_INVALID_ARGUMENT);
1652 #endif /* defined(BSP_FEATURE_HAS_CGC_PCKB) */
1653 
1654 #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK
1655     /* Check if MCU supports FCLK, then check if ICLK is greater than FCLK */
1656     CGC_ERROR_RETURN(!(p_clock_cfg->fclk_div < p_clock_cfg->iclk_div), SSP_ERR_INVALID_ARGUMENT);
1657 #endif /* BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
1658 
1659 #if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
1660     /* Check if MCU has BCLK, then check if ICLK > BCLK */
1661     CGC_ERROR_RETURN(!(p_clock_cfg->bclk_div < p_clock_cfg->iclk_div), SSP_ERR_INVALID_ARGUMENT);
1662 #endif /* BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
1663 
1664     return SSP_SUCCESS;
1665 }
1666 #endif
1667 
1668 /*******************************************************************************************************************//**
1669  * @brief  Wait for the specified clock to complete the start or stop operation
1670  * @param[in]   clock_source             clock source that is waited for to complete operation
1671  * @param[in]   option           	     clock status value
1672  * @retval      SSP_SUCCESS              Operation performed successfully.
1673  * @retval      SSP_ERR_HARDWARE_TIMEOUT Operation failed to complete
1674  **********************************************************************************************************************/
r_cgc_wait_to_complete(cgc_clock_t const clock_source,cgc_clock_change_t option)1675 static ssp_err_t r_cgc_wait_to_complete(cgc_clock_t const clock_source, cgc_clock_change_t option)
1676 {
1677     volatile uint32_t timeout;
1678     bool start_stop;
1679 
1680     timeout = MAX_REGISTER_WAIT_COUNT;
1681 
1682     if((option != CGC_CLOCK_CHANGE_NONE))
1683     {
1684         start_stop = (CGC_CLOCK_CHANGE_START == option);
1685         while((r_cgc_clock_run_state_get(gp_system_reg, clock_source) != start_stop) && (0U != timeout))
1686         {
1687             timeout--;
1688         }
1689         CGC_ERROR_RETURN(timeout, SSP_ERR_HARDWARE_TIMEOUT);    // return error if timed out
1690     }
1691 
1692     return SSP_SUCCESS;
1693 }
1694 
1695 /*******************************************************************************************************************//**
1696  * @brief  Check if the specified clock is running and stable
1697  * @param[in]   clock_source                    clock to be verified
1698  * @retval      SSP_SUCCESS                     Operation performed successfully.
1699  * @retval      SSP_ERR_CLOCK_INACTIVE          Specified clock is not running
1700  * @retval      SSP_ERR_NOT_STABILIZED   		Clock not stabilized after starting. A finite stabilization time after starting the
1701  **********************************************************************************************************************/
r_cgc_clock_running_status_check(cgc_clock_t const clock_source)1702 static ssp_err_t r_cgc_clock_running_status_check(cgc_clock_t const clock_source)
1703 {
1704 #if defined(BSP_FEATURE_HAS_CGC_PLL)
1705     if (((clock_source == CGC_CLOCK_HOCO) || (clock_source == CGC_CLOCK_MAIN_OSC))
1706         || (clock_source == CGC_CLOCK_PLL))
1707 #else
1708     if (((clock_source == CGC_CLOCK_HOCO) || (clock_source == CGC_CLOCK_MAIN_OSC)))
1709 #endif /* defined(BSP_FEATURE_HAS_CGC_PLL) */
1710     {
1711         /* make sure the oscillator is stable before setting as system clock */
1712         CGC_ERROR_RETURN(r_cgc_clock_check(gp_system_reg, clock_source), SSP_ERR_NOT_STABILIZED);
1713     }
1714     else  /* for CGC_CLOCK_MOCO, CGC_CLOCK_LOCO or CGC_CLOCK_SUBCLOCK */
1715     {
1716         /* Make sure the clock is not stopped before setting as system clock */
1717         /* There is no way to check stability for this clocks, we just check they are active */
1718         CGC_ERROR_RETURN(r_cgc_clock_run_state_get(gp_system_reg, clock_source), SSP_ERR_CLOCK_INACTIVE);
1719     }
1720 
1721     return SSP_SUCCESS;
1722 }
1723 
1724 /*******************************************************************************************************************//**
1725  * @brief  Check if the system needs to go out from sub-osc speed mode
1726   **********************************************************************************************************************/
r_cgc_adjust_subosc_speed_mode(void)1727 static void r_cgc_adjust_subosc_speed_mode(void)
1728 {
1729     /* If system was in subosc speed mode and we turn on other higher speed clocks, subosc speed mode needs to be turned off */
1730     /* Since running speed is still under 32KHz, we can go to low-speed mode */
1731     if (CGC_SUBOSC_SPEED_MODE == r_cgc_operating_mode_get(gp_system_reg))
1732     {
1733         HW_CGC_SetLowSpeedMode(gp_system_reg);
1734     }
1735 }
1736 
1737 /*******************************************************************************************************************//**
1738  * @brief Apply options set in configuration structure to all clocks
1739  * @param[in]   p_clock_cfg                     pointer to clock system configuration
1740  * @param[in]   options         		        pointer to array of clock status values for all clocks
1741  * @retval      SSP_SUCCESS                     Operation performed successfully.
1742  * @retval      SSP_ERR_OSC_STOP_DET_ENABLED  	Illegal attempt to stop MOCO when Oscillation stop is enabled.
1743  * @retval      SSP_ERR_NOT_STABILIZED   		Clock not stabilized after starting. A finite stabilization time after starting the
1744  *                                  		    clock has to elapse before it can be stopped.
1745  * @retval      SSP_ERR_INVALID_ARGUMENT 		Invalid argument used.
1746  * @retval      SSP_ERR_HARDWARE_TIMEOUT		Hardware timed out.
1747  **********************************************************************************************************************/
r_cgc_apply_start_stop_options(cgc_clocks_cfg_t const * const p_clock_cfg,cgc_clock_change_t const * const options)1748 static ssp_err_t r_cgc_apply_start_stop_options(cgc_clocks_cfg_t const * const p_clock_cfg, cgc_clock_change_t const * const options)
1749 {
1750     ssp_err_t err = SSP_SUCCESS;
1751 
1752     /* start with PLL clock, so that we may stop it before trying to stop the PLL source clk */
1753 #if BSP_FEATURE_HAS_CGC_PLL
1754     err = r_cgc_clock_start_stop(options[CGC_CLOCK_PLL], CGC_CLOCK_PLL, p_clock_cfg);
1755     CGC_ERROR_RETURN((SSP_SUCCESS == err) || (SSP_ERR_CLOCK_ACTIVE == err), err);
1756 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1757     for (uint32_t i = 0U; i < CGC_CLOCK_PLL; i++)
1758     {
1759         err = r_cgc_clock_start_stop(options[i], (cgc_clock_t) i, p_clock_cfg);
1760         CGC_ERROR_RETURN((SSP_SUCCESS == err) || (SSP_ERR_CLOCK_ACTIVE == err), err);
1761     }
1762 
1763     return SSP_SUCCESS;
1764 }
1765 
1766 #if BSP_FEATURE_HAS_CGC_PLL
1767 /*******************************************************************************************************************//**
1768  * @brief Check and prepare PLL registers for PLL clock start
1769  * @param[in]   p_clock_cfg             pointer to clock system configuration
1770  * @retval      SSP_SUCCESS             Operation performed successfully.
1771  * @retval      SSP_ERR_INVALID_ARGUMENT  configuration contains illegal parameters
1772  * @retval      SSP_ERR_MAIN_OSC_INACTIVE  PLL clock source is inactive
1773  * @retval      SSP_ERR_NOT_STABILIZED     PLL clock is not stabilized
1774  **********************************************************************************************************************/
r_cgc_prepare_pll_clock(cgc_clock_cfg_t * p_clock_cfg)1775 static ssp_err_t r_cgc_prepare_pll_clock(cgc_clock_cfg_t * p_clock_cfg)
1776 {
1777 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
1778     SSP_ASSERT(NULL != p_clock_cfg);          // return error if NULL pointer to configuration
1779 
1780     /* return error if configuration contains illegal parameters */
1781     CGC_ERROR_RETURN((r_cgc_clockcfg_valid_check(p_clock_cfg)), SSP_ERR_INVALID_ARGUMENT);
1782     /* if the PLL source clock isn't running, PLL cannot be turned on, return error */
1783     CGC_ERROR_RETURN(r_cgc_clock_run_state_get(gp_system_reg, p_clock_cfg->source_clock), SSP_ERR_MAIN_OSC_INACTIVE);
1784     /*  make sure the PLL has stopped before starting again */
1785     CGC_ERROR_RETURN(!(r_cgc_clock_check(gp_system_reg, CGC_CLOCK_PLL)), SSP_ERR_NOT_STABILIZED);
1786 #endif /* CGC_CFG_PARAM_CHECKING_ENABLE */
1787 
1788     r_cgc_adjust_subosc_speed_mode();
1789 
1790 #if BSP_FEATURE_HAS_CGC_PLL_SRC_CFG
1791     r_cgc_pll_clocksource_set(gp_system_reg, p_clock_cfg->source_clock); // configure PLL source clock when needed
1792 #endif /* BSP_FEATURE_HAS_CGC_PLL_SRC_CFG */
1793 
1794     r_cgc_pll_divider_set(gp_system_reg, p_clock_cfg->divider);          // configure PLL divider
1795     r_cgc_pll_multiplier_set(gp_system_reg, p_clock_cfg->multiplier);    // configure PLL multiplier
1796     r_cgc_init_pllfreq(gp_system_reg);                                // calculate  PLL clock frequency
1797 
1798     return SSP_SUCCESS;
1799 }
1800 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1801 
1802 
1803 
1804 
1805 /*******************************************************************************************************************//**
1806  * @brief      This function initializes CGC variables independent of the C runtime environment.
1807  * @retval     none
1808  **********************************************************************************************************************/
1809 
r_cgc_hw_init(void)1810 static void r_cgc_hw_init (void)
1811 {
1812     /** initialize the clock frequency array */
1813     g_clock_freq[CGC_CLOCK_HOCO]     = gp_cgc_feature->hoco_freq_hz;  // Initialize the HOCO value.
1814     g_clock_freq[CGC_CLOCK_MOCO]     = CGC_MOCO_FREQ;       // Initialize the MOCO value.
1815     g_clock_freq[CGC_CLOCK_LOCO]     = CGC_LOCO_FREQ;       // Initialize the LOCO value.
1816     g_clock_freq[CGC_CLOCK_MAIN_OSC] = gp_cgc_feature->main_osc_freq_hz;   // Initialize the Main oscillator value.
1817     g_clock_freq[CGC_CLOCK_SUBCLOCK] = CGC_SUBCLOCK_FREQ;   // Initialize the subclock value.
1818 #if BSP_FEATURE_HAS_CGC_PLL
1819     g_clock_freq[CGC_CLOCK_PLL]      = CGC_PLL_FREQ;        // The PLL value will be calculated at initialization.
1820 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1821 }
1822 
1823 #if BSP_FEATURE_HAS_CGC_PLL
1824 /*******************************************************************************************************************//**
1825  * @brief      This function initializes PLL frequency value
1826  * @param[in]  p_system_reg  pointer to system register structure
1827  * @retval     none
1828  **********************************************************************************************************************/
r_cgc_init_pllfreq(R_SYSTEM_Type * p_system_reg)1829 static void r_cgc_init_pllfreq (R_SYSTEM_Type * p_system_reg)
1830 {
1831     uint32_t divider = 0U;
1832     divider = r_cgc_pll_divider_get(p_system_reg);
1833     if (divider != 0U) /* prevent divide by 0 */
1834     {
1835         uint32_t clock_freq = 0U;
1836         if (1U == gp_cgc_feature->pllccr_type)
1837         {
1838             clock_freq = g_clock_freq[r_cgc_pll_clocksource_get(p_system_reg)];
1839         }
1840         if (2U == gp_cgc_feature->pllccr_type)
1841         {
1842             clock_freq = g_clock_freq[CGC_CLOCK_MAIN_OSC];
1843         }
1844         /* This casts the float result back to an integer.  The multiplier is always a multiple of 0.5, and the clock
1845          * frequency is always a multiple of 2, so casting to an integer is safe. */
1846         /* Float used because float32_t is not part of the C99 standard integer definitions. */
1847         /*LDRA_INSPECTED 90 s *//*LDRA_INSPECTED 90 s */
1848         g_clock_freq[CGC_CLOCK_PLL] = (uint32_t)
1849             (((float) clock_freq / (float)divider) * r_cgc_pll_multiplier_get(p_system_reg));
1850     }
1851 }
1852 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1853 
1854 /*******************************************************************************************************************//**
1855  * @brief      This function sets the main clock drive
1856  * @param[in]  p_system_reg  pointer to system register structure
1857  * @param[in]  setting  - clock drive setting
1858  * @retval     none
1859  **********************************************************************************************************************/
1860 
r_cgc_main_clock_drive_set(R_SYSTEM_Type * p_system_reg,uint8_t setting)1861 static void r_cgc_main_clock_drive_set (R_SYSTEM_Type * p_system_reg, uint8_t setting)
1862 {
1863     /*  Set the drive capacity for the main clock. */
1864     uint8_t modrv_mask = gp_cgc_feature->modrv_mask;
1865     uint8_t modrv_shift = gp_cgc_feature->modrv_shift;
1866     HW_CGC_HardwareUnLock();
1867     p_system_reg->MOMCR =
1868         (uint8_t) ((p_system_reg->MOMCR & (~modrv_mask)) | ((setting << modrv_shift) & modrv_mask));
1869     HW_CGC_HardwareLock();
1870 }
1871 
1872 /*******************************************************************************************************************//**
1873  * @brief      This function sets the subclock drive
1874  *
1875  * @param[in]  p_system_reg  pointer to system register structure
1876  * @param[in]  setting   clock drive setting
1877  *
1878  * @retval     none
1879  **********************************************************************************************************************/
1880 
r_cgc_subclock_drive_set(R_SYSTEM_Type * p_system_reg,uint8_t setting)1881 static void r_cgc_subclock_drive_set (R_SYSTEM_Type * p_system_reg, uint8_t setting)
1882 {
1883     /*  Set the drive capacity for the subclock. */
1884     uint8_t sodrv_mask = gp_cgc_feature->sodrv_mask;
1885     uint8_t sodrv_shift = gp_cgc_feature->sodrv_shift;
1886     HW_CGC_HardwareUnLock();
1887     /* Sub-Clock Drive Capability can be changed only if Sub-Clock is stopped */
1888     if (p_system_reg->SOSCCR_b.SOSTP)
1889     {
1890         p_system_reg->SOMCR =
1891             (uint8_t) ((p_system_reg->SOMCR & (~sodrv_mask)) | ((setting << sodrv_shift) & sodrv_mask));
1892     }
1893     HW_CGC_HardwareLock();
1894 }
1895 
1896 /*******************************************************************************************************************//**
1897  * @brief      This function starts the selected clock
1898  * @param[in]  p_system_reg  pointer to system register structure
1899  * @param[in]  clock  the clock to start
1900  * @retval     none
1901  **********************************************************************************************************************/
1902 
r_cgc_clock_start(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)1903 static void r_cgc_clock_start (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
1904 {
1905     /* Start the selected clock. */
1906     HW_CGC_HardwareUnLock();
1907 
1908     switch (clock)
1909     {
1910         case CGC_CLOCK_HOCO:
1911             p_system_reg->HOCOCR_b.HCSTP = 0U; /* Start the HOCO clock. */
1912             break;
1913 
1914         case CGC_CLOCK_MOCO:
1915             p_system_reg->MOCOCR_b.MCSTP = 0U; /* Start the MOCO clock.*/
1916             break;
1917 
1918         case CGC_CLOCK_LOCO:
1919             p_system_reg->LOCOCR_b.LCSTP = 0U; /* Start the LOCO clock.*/
1920             break;
1921 
1922         case CGC_CLOCK_MAIN_OSC:
1923             p_system_reg->MOSCCR_b.MOSTP = 0U; /* Start the Main oscillator.*/
1924             break;
1925 
1926         case CGC_CLOCK_SUBCLOCK:
1927             p_system_reg->SOSCCR_b.SOSTP = 0U; /* Start the subClock.*/
1928             break;
1929 
1930 #if BSP_FEATURE_HAS_CGC_PLL
1931         case CGC_CLOCK_PLL:
1932             p_system_reg->PLLCR_b.PLLSTP = 0U; /* Start the PLL clock.*/
1933             break;
1934 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1935 
1936         default:
1937             break;
1938     }
1939 
1940     HW_CGC_HardwareLock();
1941 }
1942 
1943 /*******************************************************************************************************************//**
1944  * @brief      This function stops the selected clock
1945  * @param[in]  p_system_reg  pointer to system register structure
1946  * @param[in]  clock the clock to stop
1947  * @retval     none
1948  **********************************************************************************************************************/
1949 
r_cgc_clock_stop(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)1950 static void r_cgc_clock_stop (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
1951 {
1952     /*  Stop the selected clock. */
1953     HW_CGC_HardwareUnLock();
1954     switch (clock)
1955     {
1956         case CGC_CLOCK_HOCO:
1957             p_system_reg->HOCOCR_b.HCSTP = 1U; /* Stop the HOCO clock.*/
1958             break;
1959 
1960         case CGC_CLOCK_MOCO:
1961             p_system_reg->MOCOCR_b.MCSTP = 1U; /* Stop the MOCO clock.*/
1962             break;
1963 
1964         case CGC_CLOCK_LOCO:
1965             p_system_reg->LOCOCR_b.LCSTP = 1U; /* Stop the LOCO clock.*/
1966             break;
1967 
1968         case CGC_CLOCK_MAIN_OSC:
1969             p_system_reg->MOSCCR_b.MOSTP = 1U; /* Stop the  main oscillator.*/
1970             break;
1971 
1972         case CGC_CLOCK_SUBCLOCK:
1973             p_system_reg->SOSCCR_b.SOSTP = 1U; /* Stop the subClock.*/
1974             break;
1975 
1976 #if BSP_FEATURE_HAS_CGC_PLL
1977         case CGC_CLOCK_PLL:
1978             p_system_reg->PLLCR_b.PLLSTP = 1U; /* Stop PLL clock.*/
1979             break;
1980 #endif /* BSP_FEATURE_HAS_CGC_PLL */
1981 
1982         default:
1983             break;
1984     }
1985 
1986     HW_CGC_HardwareLock();
1987 }
1988 
1989 /*******************************************************************************************************************//**
1990  * @brief      This function checks the selected clock for stability
1991  * @param[in]  p_system_reg  pointer to system register structure
1992  * @param[in]  clock the clock to check
1993  * @retval     bool   true if stable, false if not stable or stopped
1994  **********************************************************************************************************************/
1995 
r_cgc_clock_check(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)1996 static bool r_cgc_clock_check (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
1997 {
1998     /*  Check for stability of selected clock. */
1999     switch (clock)
2000     {
2001         case CGC_CLOCK_HOCO:
2002             if (p_system_reg->OSCSF_b.HOCOSF)
2003             {
2004                 return true; /* HOCO is stable */
2005             }
2006 
2007             break;
2008 
2009         case CGC_CLOCK_MAIN_OSC:
2010             if (p_system_reg->OSCSF_b.MOSCSF)
2011             {
2012                 return true; /* Main Osc is stable */
2013             }
2014 
2015             break;
2016 
2017 #if BSP_FEATURE_HAS_CGC_PLL
2018         case CGC_CLOCK_PLL:
2019             if (p_system_reg->OSCSF_b.PLLSF)
2020             {
2021                 return true; /* PLL is stable */
2022             }
2023 
2024             break;
2025 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2026 
2027         default:
2028             /* All other clocks don't have a stability flag, return true */
2029             return true;
2030             break;
2031     }
2032 
2033     return false;
2034 }
2035 
2036 #if (CGC_CFG_SUBCLOCK_AT_RESET_ENABLE == 1)
2037 /*******************************************************************************************************************//**
2038  * @brief      This function delays for a specified number of clock cycles, of the selected clock
2039  * @param[in]  p_system_reg  pointer to system register structure
2040  * @param[in]  clock the clock to time
2041  * @param[in]  cycles the number of cycles to delay
2042  * @retval     none
2043  **********************************************************************************************************************/
2044 
r_cgc_delay_cycles(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock,uint16_t cycles)2045 static void r_cgc_delay_cycles (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, uint16_t cycles)
2046 {
2047     /* delay for number of clock cycles specified */
2048 
2049     uint32_t               delay_count;
2050     uint32_t               clock_freq_in;
2051     uint32_t               system_clock_freq;
2052 
2053     system_clock_freq = r_cgc_clock_hzget(p_system_reg, CGC_SYSTEM_CLOCKS_ICLK);
2054     clock_freq_in     = g_clock_freq[clock];
2055     if (clock_freq_in != 0U)             // ensure divide by zero doesn't happen
2056     {
2057         delay_count = ((system_clock_freq / clock_freq_in) * cycles);
2058 
2059         while (delay_count > 0U)
2060         {
2061             delay_count--;
2062         }
2063     }
2064 }
2065 #endif
2066 
2067 /*******************************************************************************************************************//**
2068  * @brief      This function sets the source of the main oscillator
2069  * @param[in]  p_system_reg  pointer to system register structure
2070  * @param[in]  osc the source of the main clock oscillator
2071  * @retval     none
2072  **********************************************************************************************************************/
2073 
r_cgc_mainosc_source_set(R_SYSTEM_Type * p_system_reg,cgc_osc_source_t osc)2074 static void r_cgc_mainosc_source_set (R_SYSTEM_Type * p_system_reg, cgc_osc_source_t osc)
2075 {
2076     /* Set the source to resonator or external osc. */
2077     HW_CGC_HardwareUnLock();
2078     p_system_reg->MOMCR_b.MOSEL = osc;
2079     HW_CGC_HardwareLock();
2080 }
2081 
2082 /*******************************************************************************************************************//**
2083  * @brief      This function sets the clock wait time
2084  * @param[in]  p_system_reg  pointer to system register structure
2085  * @param[in]  clock  the clock to set the wait time for
2086  * @param[in]  setting is wait time
2087  * @retval     none
2088  **********************************************************************************************************************/
2089 
r_cgc_clock_wait_set(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock,uint8_t setting)2090 static void r_cgc_clock_wait_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, uint8_t setting)
2091 {
2092     SSP_PARAMETER_NOT_USED(clock);
2093     /* Set the clock wait time */
2094     HW_CGC_HardwareUnLock();
2095     p_system_reg->MOSCWTCR_b.MSTS = (uint8_t)(setting & 0x0F);
2096     HW_CGC_HardwareLock();
2097 }
2098 
2099 /*******************************************************************************************************************//**
2100  * @brief      This function sets the system clock source
2101  * @param[in]  p_system_reg  pointer to system register structure
2102  * @param[in]  clock         the clock to use for the system clock
2103  * @retval     none
2104  **********************************************************************************************************************/
2105 
r_cgc_clock_source_set(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)2106 static void r_cgc_clock_source_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
2107 {
2108     /* Set the system clock source */
2109     HW_CGC_HardwareUnLock();
2110     p_system_reg->SCKSCR_b.CKSEL = clock;    //set the system clock source
2111     HW_CGC_HardwareLock();
2112 }
2113 
2114 #if BSP_FEATURE_HAS_CGC_PLL
2115 /*******************************************************************************************************************//**
2116  * @brief      This function returns the PLL clock source
2117  * @param[in]  p_system_reg  pointer to system register structure
2118  * @retval     clock type   PLL clock source
2119  **********************************************************************************************************************/
2120 
r_cgc_pll_clocksource_get(R_SYSTEM_Type * p_system_reg)2121 static cgc_clock_t r_cgc_pll_clocksource_get (R_SYSTEM_Type * p_system_reg)
2122 {
2123     /*  PLL source selection only available on S7G2 */
2124     if (gp_cgc_feature->pll_src_configurable)
2125     {
2126         /* Get the PLL clock source */
2127         if (p_system_reg->PLLCCR_b.PLLSRCSEL == 1U)
2128         {
2129             return CGC_CLOCK_HOCO;
2130         }
2131     }
2132 
2133     return CGC_CLOCK_MAIN_OSC;
2134 }
2135 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2136 
2137 #if BSP_FEATURE_HAS_CGC_PLL
2138 /*******************************************************************************************************************//**
2139  * @brief      This function sets the PLL clock source
2140  * @param[in]  p_system_reg  pointer to system register structure
2141  * @param[in]  clock  current system clock
2142  * @retval     none
2143  **********************************************************************************************************************/
2144 #if BSP_FEATURE_HAS_CGC_PLL_SRC_CFG
r_cgc_pll_clocksource_set(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)2145 static void r_cgc_pll_clocksource_set (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
2146 {
2147     /* Set the PLL clock source */
2148     HW_CGC_HardwareUnLock();
2149     if (CGC_CLOCK_MAIN_OSC == clock)
2150     {
2151         p_system_reg->PLLCCR_b.PLLSRCSEL = CGC_PLL_MAIN_OSC;
2152     }
2153     else
2154     {
2155         /* The default value is HOCO. */
2156         p_system_reg->PLLCCR_b.PLLSRCSEL = CGC_PLL_HOCO;
2157     }
2158     HW_CGC_HardwareLock();
2159 }
2160 #endif
2161 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2162 #if BSP_FEATURE_HAS_CGC_PLL
2163 /*******************************************************************************************************************//**
2164  * @brief      This function sets the PLL multiplier
2165  * @param[in]  p_system_reg  pointer to system register structure
2166  * @param[in]  multiplier    multiplier value
2167  * @retval     none
2168  **********************************************************************************************************************/
2169 
2170 /*LDRA_INSPECTED 90 s float used because float32_t is not part of the C99 standard integer definitions. */
r_cgc_pll_multiplier_set(R_SYSTEM_Type * p_system_reg,float multiplier)2171 static void r_cgc_pll_multiplier_set (R_SYSTEM_Type * p_system_reg, float multiplier)
2172 {
2173     /* Set the PLL multiplier */
2174     if (1U == gp_cgc_feature->pllccr_type)
2175     {
2176         uint32_t write_val                  = (uint32_t) (multiplier * 2) - 1;
2177         HW_CGC_HardwareUnLock();
2178         p_system_reg->PLLCCR_b.PLLMUL  = (uint8_t)(write_val & 0x3F);
2179         HW_CGC_HardwareLock();
2180     }
2181     if (2U == gp_cgc_feature->pllccr_type)
2182     {
2183         uint32_t write_val                  = (uint32_t) multiplier - 1;
2184         HW_CGC_HardwareUnLock();
2185         p_system_reg->PLLCCR2_b.PLLMUL = (uint8_t)(write_val & 0x1F);
2186         HW_CGC_HardwareLock();
2187     }
2188 }
2189 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2190 
2191 
2192 #if BSP_FEATURE_HAS_CGC_PLL
2193 /*******************************************************************************************************************//**
2194  * @brief      This function gets the PLL multiplier
2195  * @param[in]  p_system_reg  pointer to system register structure
2196  * @retval     float multiplier value
2197  **********************************************************************************************************************/
2198 
2199 /*LDRA_INSPECTED 90 s float used because float32_t is not part of the C99 standard integer definitions. */
r_cgc_pll_multiplier_get(R_SYSTEM_Type * p_system_reg)2200 static float r_cgc_pll_multiplier_get (R_SYSTEM_Type * p_system_reg)
2201 {
2202     /* Get the PLL multiplier */
2203     /*LDRA_INSPECTED 90 s */
2204     float pll_mul = 0.0f;
2205 
2206     if (1U == gp_cgc_feature->pllccr_type)
2207     {
2208         /* This cast is used for compatibility with the S7 implementation. */
2209         /*LDRA_INSPECTED 90 s */
2210         pll_mul = ((float)(p_system_reg->PLLCCR_b.PLLMUL + 1U)) / 2.0f;
2211     }
2212     if (2U == gp_cgc_feature->pllccr_type)
2213     {
2214         /* This cast is used for compatibility with the S1 and S3 implementation. */
2215         /*LDRA_INSPECTED 90 s */
2216         pll_mul = (float) p_system_reg->PLLCCR2_b.PLLMUL + 1.0f;
2217     }
2218 
2219     return pll_mul;
2220 }
2221 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2222 
2223 #if BSP_FEATURE_HAS_CGC_PLL
2224 /*******************************************************************************************************************//**
2225  * @brief      This function sets the PLL divider
2226  * @param[in] p_system_reg  pointer to system register structure
2227  * @param[in] divider  divider value
2228  * @retval     none
2229  **********************************************************************************************************************/
2230 
r_cgc_pll_divider_set(R_SYSTEM_Type * p_system_reg,cgc_pll_div_t divider)2231 static void r_cgc_pll_divider_set (R_SYSTEM_Type * p_system_reg, cgc_pll_div_t divider)
2232 {
2233     /* Set the PLL divider */
2234     if (1U == gp_cgc_feature->pllccr_type)
2235     {
2236         uint16_t register_value = g_pllccr_div_setting[divider];
2237         HW_CGC_HardwareUnLock();
2238         p_system_reg->PLLCCR_b.PLIDIV  = (uint16_t)(register_value & 0x3);
2239         HW_CGC_HardwareLock();
2240     }
2241     if (2U == gp_cgc_feature->pllccr_type)
2242     {
2243         uint16_t register_value = g_pllccr2_div_setting[divider];
2244         HW_CGC_HardwareUnLock();
2245         p_system_reg->PLLCCR2_b.PLODIV = (uint8_t)(register_value & 0x3);
2246         HW_CGC_HardwareLock();
2247     }
2248 }
2249 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2250 
2251 #if BSP_FEATURE_HAS_CGC_PLL
2252 /*******************************************************************************************************************//**
2253  * @brief      This function gets the PLL divider
2254  * @param[in]  p_system_reg  pointer to system register structure
2255  * @retval     divider
2256  **********************************************************************************************************************/
2257 
r_cgc_pll_divider_get(R_SYSTEM_Type * p_system_reg)2258 static uint16_t r_cgc_pll_divider_get (R_SYSTEM_Type * p_system_reg)
2259 {
2260     /* Get the PLL divider */
2261     uint16_t ret = 1U;
2262     if (1U == gp_cgc_feature->pllccr_type)
2263     {
2264         /* This cast maps the register value to an enumerated list. */
2265         ret = g_pllccr_div_value[p_system_reg->PLLCCR_b.PLIDIV];
2266     }
2267     if (2U == gp_cgc_feature->pllccr_type)
2268     {
2269         /* This cast maps the register value to an enumerated list. */
2270         ret = g_pllccr2_div_value[p_system_reg->PLLCCR2_b.PLODIV];
2271     }
2272     return ret;
2273 }
2274 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2275 
2276 /*******************************************************************************************************************//**
2277  * @brief      This function gets the system dividers
2278  * @param[in]  p_system_reg  pointer to system register structure
2279  * @param[in]  cfg           a pointer to a cgc_system_clock_cfg_t struct
2280  * @param[out] cfg           a pointer to a cgc_system_clock_cfg_t struct
2281  * @retval     none
2282  **********************************************************************************************************************/
2283 
r_cgc_system_dividers_get(R_SYSTEM_Type * p_system_reg,cgc_system_clock_cfg_t * cfg)2284 static void r_cgc_system_dividers_get (R_SYSTEM_Type * p_system_reg, cgc_system_clock_cfg_t * cfg)
2285 {
2286     /* Get the system dividers */
2287     /* The cgc_sys_clock_div_t defines all valid values (3 bits each) for these registers as per the hardware manual,
2288      * and each of the elements of SCKDIVCR_b are 3 bits of a 32-bit value, so these casts are safe. */
2289 #if BSP_FEATURE_HAS_CGC_PCKA
2290     cfg->pclka_div = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.PCKA;
2291 #else
2292     /* Fill the structure field with 0 which is the value of corresponding reserved bits in register */
2293     cfg->pclka_div = CGC_SYS_CLOCK_DIV_1;
2294 #endif /* BSP_FEATURE_HAS_CGC_PCKA */
2295 #if BSP_FEATURE_HAS_CGC_PCKB
2296     cfg->pclkb_div = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.PCKB;
2297 #else
2298     /* Fill the structure field with 0 which is the value of corresponding reserved bits in register */
2299     cfg->pclkb_div = CGC_SYS_CLOCK_DIV_1;
2300 #endif /* BSP_FEATURE_HAS_CGC_PCKB */
2301 #if BSP_FEATURE_HAS_CGC_PCKC
2302     cfg->pclkc_div = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.PCKC;
2303 #else
2304     /* Fill the structure field with 0 which is the value of corresponding reserved bits in register */
2305     cfg->pclkc_div = CGC_SYS_CLOCK_DIV_1;
2306 #endif /* BSP_FEATURE_HAS_CGC_PCKC */
2307 #if BSP_FEATURE_HAS_CGC_PCKD
2308     cfg->pclkd_div = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.PCKD;
2309 #else
2310     /* Fill the structure field with 0 which is the value of corresponding reserved bits in register */
2311     cfg->pclkd_div = CGC_SYS_CLOCK_DIV_1;
2312 #endif /* BSP_FEATURE_HAS_CGC_PCKD */
2313     cfg->bclk_div  = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.BCK;
2314     cfg->fclk_div  = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.FCK;
2315     cfg->iclk_div  = (cgc_sys_clock_div_t) p_system_reg->SCKDIVCR_b.ICK;
2316 }
2317 
2318 #if (CGC_CFG_PARAM_CHECKING_ENABLE == 1)
2319 #if BSP_FEATURE_HAS_CGC_PLL
2320 /*******************************************************************************************************************//**
2321  * @brief      This function tests the clock configuration for validity (only for systems with PLL)
2322  * @param[in]  cfg  a pointer to a cgc_clock_cfg_t struct
2323  * @retval     bool  true if configuration is valid
2324  **********************************************************************************************************************/
2325 
r_cgc_clockcfg_valid_check(cgc_clock_cfg_t * cfg)2326 static bool r_cgc_clockcfg_valid_check (cgc_clock_cfg_t * cfg)
2327 {
2328 #if !BSP_FEATURE_HAS_CGC_PLL
2329     SSP_PARAMETER_NOT_USED(cfg);
2330 #else
2331     /* check for valid configuration */
2332 
2333     /* Check maximum and minimum divider values */
2334     if (gp_cgc_feature->pll_div_max < cfg->divider)
2335     {
2336         return false;    // Value is out of range.
2337     }
2338 
2339     /* Check maximum and minimum multiplier values */
2340     /* Float used because float32_t is not part of the C99 standard integer definitions. */
2341     /*LDRA_INSPECTED 90 s *//*LDRA_INSPECTED 90 s */
2342     if (((float)gp_cgc_feature->pll_mul_max < cfg->multiplier) || ((float)gp_cgc_feature->pll_mul_min > cfg->multiplier))
2343     {
2344         return false;   // Value is out of range.
2345     }
2346 
2347     if ((CGC_CLOCK_MAIN_OSC != cfg->source_clock) && (CGC_CLOCK_HOCO != cfg->source_clock))
2348     {
2349         return false;   // Value is out of range.
2350     }
2351 #endif /* #if BSP_FEATURE_HAS_CGC_PLL */
2352 
2353     return true;
2354 }
2355 #endif
2356 #endif
2357 
2358 /*******************************************************************************************************************//**
2359  * @brief      This function returns the divider of the selected clock
2360  * @param[in]  p_system_reg  pointer to system register structure
2361  * @param[in]  clock  the system clock to get the divider for
2362  * @retval     divider value
2363  **********************************************************************************************************************/
2364 
r_cgc_clock_divider_get(R_SYSTEM_Type * p_system_reg,cgc_system_clocks_t clock)2365 static uint32_t r_cgc_clock_divider_get (R_SYSTEM_Type * p_system_reg, cgc_system_clocks_t clock)
2366 {
2367     /*  get divider of selected clock */
2368     uint32_t divider;
2369     divider = 0U;
2370 
2371     switch (clock)
2372     {
2373 #if BSP_FEATURE_HAS_CGC_PCKA
2374         case CGC_SYSTEM_CLOCKS_PCLKA:
2375             divider = p_system_reg->SCKDIVCR_b.PCKA;
2376             break;
2377 #endif /* #if BSP_FEATURE_HAS_CGC_PCKA */
2378 
2379 #if BSP_FEATURE_HAS_CGC_PCKB
2380         case CGC_SYSTEM_CLOCKS_PCLKB:
2381             divider = p_system_reg->SCKDIVCR_b.PCKB;
2382             break;
2383 #endif /* #if BSP_FEATURE_HAS_CGC_PCKB */
2384 
2385 #if BSP_FEATURE_HAS_CGC_PCKC
2386         case CGC_SYSTEM_CLOCKS_PCLKC:
2387             divider = p_system_reg->SCKDIVCR_b.PCKC;
2388             break;
2389 #endif /* #if BSP_FEATURE_HAS_CGC_PCKC */
2390 
2391 #if BSP_FEATURE_HAS_CGC_PCKD
2392         case CGC_SYSTEM_CLOCKS_PCLKD:
2393             divider = p_system_reg->SCKDIVCR_b.PCKD;
2394             break;
2395 #endif /* #if BSP_FEATURE_HAS_CGC_PCKD */
2396 
2397 #if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
2398         case CGC_SYSTEM_CLOCKS_BCLK:
2399             divider = p_system_reg->SCKDIVCR_b.BCK;
2400             break;
2401 #endif /* #if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
2402 
2403 #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK
2404         case CGC_SYSTEM_CLOCKS_FCLK:
2405             divider = p_system_reg->SCKDIVCR_b.FCK;
2406             break;
2407 #endif /* #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
2408 
2409         case CGC_SYSTEM_CLOCKS_ICLK:
2410             divider = p_system_reg->SCKDIVCR_b.ICK;
2411             break;
2412         default:
2413             break;
2414     }
2415 
2416     return (divider);
2417 }
2418 
2419 /*******************************************************************************************************************//**
2420  * @brief      This function returns the frequency of the selected clock
2421  * @param[in]  p_system_reg  pointer to system register structure
2422  * @param[in]  clock  the system clock to get the freq for
2423  * @retval     frequency
2424  **********************************************************************************************************************/
2425 
r_cgc_clock_hzget(R_SYSTEM_Type * p_system_reg,cgc_system_clocks_t clock)2426 static uint32_t r_cgc_clock_hzget (R_SYSTEM_Type * p_system_reg, cgc_system_clocks_t clock)
2427 {
2428     /*  get frequency of selected clock */
2429     uint32_t divider;
2430     divider =  r_cgc_clock_divider_get(p_system_reg, clock);
2431     return (uint32_t) ((g_clock_freq[HW_CGC_ClockSourceGet(p_system_reg)]) >> divider);
2432 }
2433 
2434 
2435 /*******************************************************************************************************************//**
2436  * @brief      This function returns the frequency of the selected clock
2437  * @param[in]  source_clock  the source clock, such as the main osc or PLL
2438  * @param[in]  divider divider value
2439  * @retval     frequency
2440  **********************************************************************************************************************/
2441 
r_cgc_clockhz_calculate(cgc_clock_t source_clock,cgc_sys_clock_div_t divider)2442 static uint32_t r_cgc_clockhz_calculate (cgc_clock_t source_clock,  cgc_sys_clock_div_t divider)
2443 {
2444     /*  calculate frequency of selected system clock, given the source clock and divider */
2445     return (uint32_t) ((g_clock_freq[source_clock]) >> (uint32_t)divider);
2446 }
2447 
2448 /*******************************************************************************************************************//**
2449  * @brief      This function enables the osc stop detection function and interrupt
2450  * @param[in]  p_system_reg  pointer to system register structure
2451  * @retval     none
2452  **********************************************************************************************************************/
r_cgc_oscstop_detect_enable(R_SYSTEM_Type * p_system_reg)2453 static void r_cgc_oscstop_detect_enable (R_SYSTEM_Type * p_system_reg)
2454 {
2455     /* enable hardware oscillator stop detect function */
2456     HW_CGC_HardwareUnLock();
2457     p_system_reg->OSTDCR_b.OSTDE  = 1U;        // enable osc stop detection
2458     p_system_reg->OSTDCR_b.OSTDIE = 1U;        // enable osc stop detection interrupt
2459     HW_CGC_HardwareLock();
2460 }
2461 
2462 /*******************************************************************************************************************//**
2463  * @brief      This function disables the osc stop detection function and interrupt
2464  * @param[in]  p_system_reg  pointer to system register structure
2465  * @retval     none
2466  **********************************************************************************************************************/
r_cgc_oscstop_detect_disable(R_SYSTEM_Type * p_system_reg)2467 static void r_cgc_oscstop_detect_disable (R_SYSTEM_Type * p_system_reg)
2468 {
2469     /* disable hardware oscillator stop detect function */
2470     HW_CGC_HardwareUnLock();
2471     p_system_reg->OSTDCR_b.OSTDIE = 0U;        // disable osc stop detection interrupt
2472     p_system_reg->OSTDCR_b.OSTDE  = 0U;        // disable osc stop detection
2473     HW_CGC_HardwareLock();
2474 }
2475 
2476 /*******************************************************************************************************************//**
2477  * @brief      This function clear the status of the stop detection function
2478  * @param[in]  p_system_reg  pointer to system register structure
2479  * @retval     bool  true if oscillator stop detection flag cleared, false if no oscillator stop detected
2480  **********************************************************************************************************************/
2481 
r_cgc_oscstop_status_clear(R_SYSTEM_Type * p_system_reg)2482 static bool r_cgc_oscstop_status_clear (R_SYSTEM_Type * p_system_reg)
2483 {
2484     /* clear hardware oscillator stop detect status */
2485     if (p_system_reg->OSTDSR_b.OSTDF == 1U)
2486     {
2487         HW_CGC_HardwareUnLock();
2488         p_system_reg->OSTDSR_b.OSTDF = 0U;
2489         HW_CGC_HardwareLock();
2490         return true;            // stop detection cleared
2491     }
2492 
2493     return false;               // can't clear flag because no stop detected
2494 }
2495 
2496 
2497 /*******************************************************************************************************************//**
2498  * @brief      This function configures the ClockOut divider and clock source
2499  * @param[in]  p_system_reg  pointer to system register structure
2500  * @param[in]  clock  the clock out source
2501  * @param[in]  divider  the clock out divider
2502  * @retval     none
2503  **********************************************************************************************************************/
2504 
r_cgc_clockout_cfg(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock,cgc_clockout_dividers_t divider)2505 static void r_cgc_clockout_cfg (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock, cgc_clockout_dividers_t divider)
2506 {
2507     /*  */
2508     HW_CGC_HardwareUnLock();
2509     p_system_reg->CKOCR_b.CKOEN  = 0U;            // disable CLKOUT to change configuration
2510     p_system_reg->CKOCR_b.CKODIV = divider;       // set CLKOUT dividers
2511     p_system_reg->CKOCR_b.CKOSEL = clock;         // set CLKOUT clock source
2512     HW_CGC_HardwareLock();
2513 }
2514 
2515 /*******************************************************************************************************************//**
2516  * @brief      This function enables ClockOut
2517  * @param[in]  p_system_reg  pointer to system register structure
2518  * @retval     none
2519  **********************************************************************************************************************/
2520 
r_cgc_clockout_enable(R_SYSTEM_Type * p_system_reg)2521 static void r_cgc_clockout_enable (R_SYSTEM_Type * p_system_reg)
2522 {
2523     /* Enable CLKOUT output  */
2524     HW_CGC_HardwareUnLock();
2525     p_system_reg->CKOCR_b.CKOEN = 1U;
2526     HW_CGC_HardwareLock();
2527 }
2528 
2529 /*******************************************************************************************************************//**
2530  * @brief      This function disables ClockOut
2531  * @param[in]  p_system_reg  pointer to system register structure
2532  * @retval     none
2533  **********************************************************************************************************************/
2534 
r_cgc_clockout_disable(R_SYSTEM_Type * p_system_reg)2535 static void r_cgc_clockout_disable (R_SYSTEM_Type * p_system_reg)
2536 {
2537     /* Disable CLKOUT output */
2538     HW_CGC_HardwareUnLock();
2539     p_system_reg->CKOCR_b.CKOEN = 0U;
2540     HW_CGC_HardwareLock();
2541 }
2542 
2543 
2544 /*******************************************************************************************************************//**
2545  * @brief      This updates the Systick timer period
2546  * @param[in]  reload_value Reload value, calculated by caller
2547  * @retval     bool  true if reload is successful
2548  **********************************************************************************************************************/
r_cgc_systick_update(uint32_t reload_value)2549 static bool r_cgc_systick_update(uint32_t reload_value)
2550 {
2551     bool result = false;
2552     /* SysTick is defined by CMSIS and will not be modified. */
2553     /*LDRA_INSPECTED 93 S *//*LDRA_INSPECTED 96 S *//*LDRA_INSPECTED 330 S *//*LDRA_INSPECTED 330 S */
2554     uint32_t systick_ctrl = SysTick->CTRL;
2555 
2556     /** If there is an RTOS in place AND the Systick interrupt is not yet enabled, just return and do nothing */
2557 #if (1 == BSP_CFG_RTOS)
2558     /*LDRA_INSPECTED 93 S *//*LDRA_INSPECTED 96 S *//*LDRA_INSPECTED 330 S *//*LDRA_INSPECTED 330 S */
2559     if ((SysTick->CTRL & SysTick_CTRL_TICKINT_Msk) == 0)
2560     {
2561         return(true);           ///< Not really an error.
2562     }
2563 #endif
2564     /*LDRA_INSPECTED 93 S *//*LDRA_INSPECTED 96 S *//*LDRA_INSPECTED 330 S *//*LDRA_INSPECTED 330 S */
2565     SysTick->CTRL = 0U;          ///< Disable systick while we reset the counter
2566 
2567     // Number of ticks between two interrupts.
2568     /* Save the Priority for Systick Interrupt, will need to be restored after SysTick_Config() */
2569     uint32_t systick_priority = NVIC_GetPriority (SysTick_IRQn);
2570     if (0U == SysTick_Config(reload_value))
2571     {
2572         result = true;
2573         NVIC_SetPriority (SysTick_IRQn, systick_priority); ///< Restore systick priority
2574     }
2575     else
2576     {
2577         /*LDRA_INSPECTED 93 S *//*LDRA_INSPECTED 96 S *//*LDRA_INSPECTED 330 S *//*LDRA_INSPECTED 330 S */
2578         SysTick->CTRL = systick_ctrl;          ///< If we were provided an invalid (ie too large) reload value,
2579                                                ///< keep using prior value.
2580     }
2581     return(result);
2582 }
2583 
2584 
2585 /*******************************************************************************************************************//**
2586  * @brief      This function sets the system dividers
2587  * @param[in]  p_system_reg  pointer to system register structure
2588  * @param[in]  cfg pointer to a cgc_system_clock_cfg_t struct
2589  * @retval     none
2590  **********************************************************************************************************************/
2591 
r_cgc_system_dividers_set(R_SYSTEM_Type * p_system_reg,cgc_system_clock_cfg_t const * const cfg)2592 static void r_cgc_system_dividers_set (R_SYSTEM_Type * p_system_reg, cgc_system_clock_cfg_t const * const cfg)
2593 {
2594     sckdivcr_clone_t sckdivcr;
2595     /* The cgc_sys_clock_div_t fits in the 3 bits, and each of the elements of sckdivcr_b are 3 bits of a 32-bit value,
2596      * so these casts are safe. */
2597     sckdivcr.sckdivcr_w = (uint32_t) 0x00;
2598 
2599 #if BSP_FEATURE_HAS_CGC_PCKA
2600     sckdivcr.sckdivcr_b.pcka = (uint32_t)(cfg->pclka_div & 0x7);
2601 #endif /* BSP_FEATURE_HAS_CGC_PCKA */
2602 #if BSP_FEATURE_HAS_CGC_PCKB
2603     sckdivcr.sckdivcr_b.pckb = (uint32_t)(cfg->pclkb_div & 0x7);
2604 #endif /* BSP_FEATURE_HAS_CGC_PCKB */
2605 #if BSP_FEATURE_HAS_CGC_PCKC
2606     sckdivcr.sckdivcr_b.pckc = (uint32_t)(cfg->pclkc_div & 0x7);
2607 #endif /* BSP_FEATURE_HAS_CGC_PCKC */
2608 #if BSP_FEATURE_HAS_CGC_PCKD
2609     sckdivcr.sckdivcr_b.pckd = (uint32_t)(cfg->pclkd_div & 0x7);
2610 #endif /* BSP_FEATURE_HAS_CGC_PCKD */
2611 #if BSP_FEATURE_HAS_CGC_EXTERNAL_BUS
2612     sckdivcr.sckdivcr_b.bck  = (uint32_t)(cfg->bclk_div  & 0x7);
2613 #endif /* BSP_FEATURE_HAS_CGC_EXTERNAL_BUS */
2614 #if BSP_FEATURE_HAS_CGC_FLASH_CLOCK
2615     sckdivcr.sckdivcr_b.fck  = (uint32_t)(cfg->fclk_div  & 0x7);
2616 #endif /* BSP_FEATURE_HAS_CGC_FLASH_CLOCK */
2617 
2618     /* All MCUs have ICLK. */
2619     sckdivcr.sckdivcr_b.ick  = (uint32_t)(cfg->iclk_div  & 0x7);
2620 
2621     /* Set the system dividers */
2622     HW_CGC_HardwareUnLock();
2623     p_system_reg->SCKDIVCR       = sckdivcr.sckdivcr_w;
2624     HW_CGC_HardwareLock();
2625 }
2626 
2627 /**********************************************************************************************************************
2628 * Private Global Functions
2629  **********************************************************************************************************************/
2630 /*******************************************************************************************************************//**
2631  * @brief      This function returns the run state of the selected clock
2632  * @param[in]  clock  the clock to check
2633  * @param[in]  p_system_reg  pointer to system register structure
2634  * @param[in]  clock - the clock to check
2635  * @retval     bool  true if clock is running, false if stopped
2636  **********************************************************************************************************************/
2637 
r_cgc_clock_run_state_get(R_SYSTEM_Type * p_system_reg,cgc_clock_t clock)2638 bool r_cgc_clock_run_state_get (R_SYSTEM_Type * p_system_reg, cgc_clock_t clock)
2639 {
2640     /* Get clock run state. */
2641 
2642     switch (clock)
2643     {
2644         case CGC_CLOCK_HOCO:
2645             if (!(p_system_reg->HOCOCR_b.HCSTP))
2646             {
2647                 return true; /* HOCO clock is running */
2648             }
2649 
2650             break;
2651 
2652         case CGC_CLOCK_MOCO:
2653             if (!(p_system_reg->MOCOCR_b.MCSTP))
2654             {
2655                 return true; /* MOCO clock is running */
2656             }
2657 
2658             break;
2659 
2660         case CGC_CLOCK_LOCO:
2661             if (!(p_system_reg->LOCOCR_b.LCSTP))
2662             {
2663                 return true; /* LOCO clock is running */
2664             }
2665 
2666             break;
2667 
2668         case CGC_CLOCK_MAIN_OSC:
2669             if (!(p_system_reg->MOSCCR_b.MOSTP))
2670             {
2671                 return true; /* main osc clock is running */
2672             }
2673 
2674             break;
2675 
2676         case CGC_CLOCK_SUBCLOCK:
2677             if (!(p_system_reg->SOSCCR_b.SOSTP))
2678             {
2679                 return true; /* Subclock is running */
2680             }
2681 
2682             break;
2683 
2684 #if BSP_FEATURE_HAS_CGC_PLL
2685         case CGC_CLOCK_PLL:
2686             if (!(p_system_reg->PLLCR_b.PLLSTP))
2687             {
2688                 return true; /* PLL clock is running */
2689             }
2690 
2691             break;
2692 #endif /* BSP_FEATURE_HAS_CGC_PLL */
2693 
2694         default:
2695             break;
2696     }
2697 
2698     return false;
2699 }
2700 
2701 
2702 /*******************************************************************************************************************//**
2703  * @brief      This function checks the MCU for High Speed Mode
2704  * @param[in]  p_system_reg  pointer to system register structure
2705  * @retval     operating_mode  current mode of operation read from OPCCR register
2706  **********************************************************************************************************************/
2707 
r_cgc_operating_mode_get(R_SYSTEM_Type * p_system_reg)2708 cgc_operating_modes_t r_cgc_operating_mode_get (R_SYSTEM_Type * p_system_reg)
2709 {
2710     cgc_operating_modes_t operating_mode = CGC_HIGH_SPEED_MODE;
2711     if (1U == p_system_reg->SOPCCR_b.SOPCM)
2712     {
2713         operating_mode = CGC_SUBOSC_SPEED_MODE;
2714     }
2715     else
2716     {
2717         operating_mode = (cgc_operating_modes_t)p_system_reg->OPCCR_b.OPCM;
2718     }
2719     return operating_mode;
2720 }
2721 
2722 /*******************************************************************************************************************//**
2723  * @brief      This function changes the operating power control mode
2724  * @param[in]  p_system_reg  pointer to system register structure
2725  * @param[in]  operating_mode Operating power control mode
2726  **********************************************************************************************************************/
2727 
r_cgc_operating_hw_modeset(R_SYSTEM_Type * p_system_reg,cgc_operating_modes_t operating_mode)2728 void r_cgc_operating_hw_modeset (R_SYSTEM_Type * p_system_reg, cgc_operating_modes_t operating_mode)
2729 {
2730     bsp_cache_state_t cache_state;
2731     volatile uint32_t timeout;
2732     timeout = CGC_HW_MAX_REGISTER_WAIT_COUNT;
2733 
2734     /** Enable writing to OPCCR and SOPCCR registers. */
2735     HW_CGC_LPMHardwareUnLock();
2736 
2737     cache_state = BSP_CACHE_STATE_OFF;
2738     R_BSP_CacheOff(&cache_state);                           // Turn the cache off.
2739 
2740     while ((0U != p_system_reg->SOPCCR_b.SOPCMTSF) || (0U != p_system_reg->OPCCR_b.OPCMTSF))
2741     {
2742         /** Wait for transition to complete. */
2743         timeout--;
2744         if(0U == timeout)
2745         {
2746             /** Disable writing to OPCCR and SOPCCR registers. */
2747             HW_CGC_LPMHardwareLock();
2748             return;
2749         }
2750     }
2751 
2752     /** The Sub-osc bit has to be cleared first. */
2753     p_system_reg->SOPCCR_b.SOPCM = CGC_SOPCCR_CLEAR_SUBOSC_SPEED_MODE;
2754     timeout = CGC_HW_MAX_REGISTER_WAIT_COUNT;
2755     while (((0U != p_system_reg->SOPCCR_b.SOPCMTSF) || (0U != p_system_reg->OPCCR_b.OPCMTSF)) && (0U != timeout))
2756     {
2757         /** Wait for transition to complete. */
2758         timeout--;
2759     }
2760 
2761     /** Set OPCCR. */
2762     if(CGC_SUBOSC_SPEED_MODE == operating_mode)
2763     {
2764         p_system_reg->OPCCR_b.OPCM = CGC_OPPCR_OPCM_MASK & CGC_OPCCR_LOW_SPEED_MODE;
2765     }
2766     else
2767     {
2768         p_system_reg->OPCCR_b.OPCM = CGC_OPPCR_OPCM_MASK & (uint32_t)operating_mode;
2769     }
2770     timeout = CGC_HW_MAX_REGISTER_WAIT_COUNT;
2771     while (((0U != p_system_reg->SOPCCR_b.SOPCMTSF) || (0U != p_system_reg->OPCCR_b.OPCMTSF)) && (0U != timeout))
2772     {
2773         /** Wait for transition to complete. */
2774         timeout--;
2775     }
2776 
2777     /** Set SOPCCR. */
2778     if(CGC_SUBOSC_SPEED_MODE == operating_mode)
2779     {
2780         p_system_reg->SOPCCR_b.SOPCM = CGC_SOPPCR_SOPCM_MASK & CGC_SOPCCR_SET_SUBOSC_SPEED_MODE;
2781     }
2782     else
2783     {
2784         p_system_reg->SOPCCR_b.SOPCM = CGC_SOPPCR_SOPCM_MASK & CGC_SOPCCR_CLEAR_SUBOSC_SPEED_MODE;
2785     }
2786     timeout = CGC_HW_MAX_REGISTER_WAIT_COUNT;
2787     while (((0U != p_system_reg->SOPCCR_b.SOPCMTSF) || (0U != p_system_reg->OPCCR_b.OPCMTSF)) && (0U != timeout))
2788     {
2789         /** Wait for transition to complete. */
2790         timeout--;
2791     }
2792 
2793     R_BSP_CacheSet(cache_state);                            // Restore cache to previous state.
2794 
2795     /** Disable writing to OPCCR and SOPCCR registers. */
2796     HW_CGC_LPMHardwareLock();
2797 }
2798 
2799 
2800 /*******************************************************************************************************************//**
2801  * @brief      This function sets the HOCO wait time register
2802  * @param[in]  hoco_wait  HOCOWTCR HSTS setting
2803  * @param[in]  p_system_reg  pointer to system register structure
2804  * @retval     none
2805  **********************************************************************************************************************/
2806 
r_cgc_hoco_wait_control_set(R_SYSTEM_Type * p_system_reg,uint8_t hoco_wait)2807 void r_cgc_hoco_wait_control_set (R_SYSTEM_Type * p_system_reg, uint8_t hoco_wait)
2808 {
2809     /* Set the system clock source */
2810     HW_CGC_HardwareUnLock();
2811     /* Set HOCOWTCR_b.HSTS */
2812     p_system_reg->HOCOWTCR_b.HSTS = 0x7U & hoco_wait;
2813     HW_CGC_HardwareLock();
2814 }
2815 
2816 /*******************************************************************************************************************//**
2817  * @} (end addtogroup CGC)
2818  **********************************************************************************************************************/
2819