/****************************************************************************** *Copyright(C)2018, Huada Semiconductor Co.,Ltd All rights reserved. * * This software is owned and published by: * Huada Semiconductor Co.,Ltd("HDSC"). * * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT. * * This software contains source code for use with HDSC * components. This software is licensed by HDSC to be adapted only * for use in systems utilizing HDSC components. HDSC shall not be * responsible for misuse or illegal use of this software for devices not * supported herein. HDSC is providing this software "AS IS" and will * not be responsible for issues arising from incorrect user implementation * of the software. * * Disclaimer: * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE, * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS), * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING, * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED * WARRANTY OF NONINFRINGEMENT. * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT, * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA, * SAVINGS OR PROFITS, * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED * FROM, THE SOFTWARE. * * This software may be replicated in part or whole for the licensed use, * with the restriction that this Disclaimer and Copyright notice must be * included with each copy of this software, whether used in part or whole, * at all times. */ /** \file sysctrl.c ** ** Common API of sysctrl. ** @link SysctrlGroup Some description @endlink ** ** - 2018-04-22 Lux ** ******************************************************************************/ /******************************************************************************* * Include files ******************************************************************************/ #include "hc32l196_sysctrl.h" /** ******************************************************************************* ** \addtogroup SysctrlGroup ******************************************************************************/ //@{ /******************************************************************************* * Local pre-processor symbols/macros ('#define') ******************************************************************************/ #define CLK_TIMEOUT (1000000u) #define IS_VALID_SRC(x) ( ClkRCH == (x)||\ ClkXTH == (x)||\ ClkRCL == (x)||\ ClkXTL == (x) ) #define IS_VALID_FUNC(x) ( ClkFuncWkupRCH == (x)||\ ClkFuncXTHEn == (x)||\ ClkFuncXTLEn == (x)||\ ClkFuncXTLAWSON == (x)||\ ClkFuncFaultEn == (x)||\ ClkFuncRtcLPWEn == (x)||\ ClkFuncLockUpEn == (x)||\ ClkFuncRstPinIOEn == (x)||\ ClkFuncSwdPinIOEn == (x) ) #define RC_TRIM_BASE_ADDR ((volatile uint16_t*) (0x00100C00ul)) #define RCH_CR_TRIM_24M_VAL (*((volatile uint16_t*) (0x00100C00ul))) #define RCH_CR_TRIM_22_12M_VAL (*((volatile uint16_t*) (0x00100C02ul))) #define RCH_CR_TRIM_16M_VAL (*((volatile uint16_t*) (0x00100C04ul))) #define RCH_CR_TRIM_8M_VAL (*((volatile uint16_t*) (0x00100C06ul))) #define RCH_CR_TRIM_4M_VAL (*((volatile uint16_t*) (0x00100C08ul))) #define RCL_CR_TRIM_38400_VAL (*((volatile uint16_t*) (0x00100C20ul))) #define RCL_CR_TRIM_32768_VAL (*((volatile uint16_t*) (0x00100C22ul))) /******************************************************************************* * Global variable definitions (declared in header file with 'extern') ******************************************************************************/ extern uint32_t SystemCoreClock; /******************************************************************************* * Local type definitions ('typedef') ******************************************************************************/ /******************************************************************************* * Local variable definitions ('static') ******************************************************************************/ /******************************************************************************* * Local function prototypes ('static') ******************************************************************************/ /******************************************************************************* * Function implementation - global ('extern') and local ('static') ******************************************************************************/ /** ******************************************************************************* ** \brief SYSCTRL0\SYSCTRL1寄存器操作解锁 ** ** \retval None ******************************************************************************/ static void _SysctrlUnlock(void) { M0P_SYSCTRL->SYSCTRL2 = 0x5A5A; M0P_SYSCTRL->SYSCTRL2 = 0xA5A5; } /** ******************************************************************************* ** \brief 系统时钟源使能 ** \param [in] enSource 目标时钟源 ** \param [in] bFlag 使能1-开/0-关 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag) { en_result_t enRet = Ok; uint32_t u32Temp; _SysctrlUnlock(); bFlag = !!bFlag; u32Temp = M0P_SYSCTRL->PERI_CLKEN0; switch (enSource) { case SysctrlClkRCH: M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = bFlag; while(bFlag && (1 != M0P_SYSCTRL->RCH_CR_f.STABLE)) { ; } break; case SysctrlClkXTH: M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE; M0P_GPIO->PFADS |= 3u; M0P_SYSCTRL->SYSCTRL0_f.XTH_EN = bFlag; while(bFlag && (1 != M0P_SYSCTRL->XTH_CR_f.STABLE)) { ; } break; case SysctrlClkRCL: M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag; while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE)) { ; } break; case SysctrlClkXTL: M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE; M0P_GPIO->PCADS |= 0xC000; M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag; while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE)) { ; } break; case SysctrlClkPLL: M0P_SYSCTRL->PERI_CLKEN0_f.ADC = TRUE; M0P_BGR->CR_f.BGR_EN = TRUE; delay10us(20); M0P_SYSCTRL->SYSCTRL0_f.PLL_EN = bFlag; while(bFlag && (1 != M0P_SYSCTRL->PLL_CR_f.STABLE)) { ; } break; default: enRet = ErrorInvalidParameter; break; } M0P_SYSCTRL->PERI_CLKEN0 = u32Temp; return enRet; } /** ******************************************************************************* ** \brief 外部高速晶振驱动配置 ** \param [in] enFreq 外部高速晶振频率范围选择 ** \param [in] enDriver 外部高速晶振驱动能力选择 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver) { en_result_t enRet = Ok; M0P_SYSCTRL->XTH_CR_f.DRIVER = enDriver; return enRet; } /** ******************************************************************************* ** \brief 外部低速晶振驱动配置 ** \param [in] enFreq 外部低速晶振频率范围选择 ** \param [in] enDriver 外部低速晶振驱动能力选择 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver) { en_result_t enRet = Ok; M0P_SYSCTRL->XTL_CR_f.AMP_SEL = enAmp; M0P_SYSCTRL->XTL_CR_f.DRIVER = enDriver; return enRet; } /** ******************************************************************************* ** \brief 外部高速时钟稳定周期配置 ** \param [in] enCycle 外部高速时钟稳定周期设置 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle) { en_result_t enRet = Ok; M0P_SYSCTRL->XTH_CR_f.STARTUP = enCycle; return enRet; } /** ******************************************************************************* ** \brief 内部低速时钟稳定周期配置 ** \param [in] enCycle 内部低速时钟稳定周期设置 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle) { en_result_t enRet = Ok; M0P_SYSCTRL->RCL_CR_f.STARTUP = enCycle; return enRet; } /** ******************************************************************************* ** \brief 外部低速时钟稳定周期配置 ** \param [in] enCycle 外部低速时钟稳定周期设置 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle) { en_result_t enRet = Ok; M0P_SYSCTRL->XTL_CR_f.STARTUP = enCycle; return enRet; } /** ******************************************************************************* ** \brief PLL稳定周期配置 ** \param [in] enCycle PLL稳定周期设置 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle) { en_result_t enRet = Ok; M0P_SYSCTRL->PLL_CR_f.STARTUP = enCycle; return enRet; } /** ******************************************************************************* ** \brief 时钟源切换,该函数执行后会开启新时钟源 ** \note 选择时钟源之前,需根据需要配置目标时钟源的频率/驱动参数/使能时钟源等 ** \param [in] enSource 新时钟源 ** ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource) { en_result_t enRet = Ok; en_sysctrl_clk_source_t ClkNew = enSource; _SysctrlUnlock(); M0P_SYSCTRL->SYSCTRL0_f.CLKSW = ClkNew; //更新Core时钟(HCLK) SystemCoreClockUpdate(); return enRet; } /** ******************************************************************************* ** \brief 获得系统时钟(HCLK)频率值 ** \retval uint32_t HCLK频率值 ** ******************************************************************************/ uint32_t Sysctrl_GetHClkFreq(void) { uint32_t u32Val = 0; const uint32_t u32hcr_tbl[] = { 4000000, 8000000, 16000000, 22120000, 24000000}; const uint16_t u32lcr_tbl[] = { 32768, 38400}; en_sysctrl_clk_source_t enSrc; uint16_t u16Trim[5] = {0}; u16Trim[4] = RCH_CR_TRIM_24M_VAL; u16Trim[3] = RCH_CR_TRIM_22_12M_VAL; u16Trim[2] = RCH_CR_TRIM_16M_VAL; u16Trim[1] = RCH_CR_TRIM_8M_VAL; u16Trim[0] = RCL_CR_TRIM_38400_VAL; //获取当前系统时钟 enSrc = (en_sysctrl_clk_source_t)(M0P_SYSCTRL->SYSCTRL0_f.CLKSW); switch (enSrc) { case SysctrlClkRCH: { if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[4])) { u32Val = u32hcr_tbl[4]; } else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[3])) { u32Val = u32hcr_tbl[3]; } else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[2])) { u32Val = u32hcr_tbl[2]; } else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[1])) { u32Val = u32hcr_tbl[1]; } else { u32Val = u32hcr_tbl[0]; } } break; case SysctrlClkXTH: u32Val = SYSTEM_XTH; break; case SysctrlClkRCL: { if(u16Trim[0] == (M0P_SYSCTRL->RCL_CR_f.TRIM)) { u32Val = u32lcr_tbl[1]; } else { u32Val = u32lcr_tbl[0]; } } break; case SysctrlClkXTL: u32Val = SYSTEM_XTL; break; case SysctrlClkPLL: { if (SysctrlPllRch == M0P_SYSCTRL->PLL_CR_f.REFSEL) { if(u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) { u32Val = u32hcr_tbl[4]; } else if(u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) { u32Val = u32hcr_tbl[3]; } else if(u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) { u32Val = u32hcr_tbl[2]; } else if(u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) { u32Val = u32hcr_tbl[1]; } else { u32Val = u32hcr_tbl[0]; } } else { u32Val = SYSTEM_XTH; } u32Val = (u32Val * M0P_SYSCTRL->PLL_CR_f.DIVN); } break; default: u32Val = 0u; break; } u32Val = (u32Val >> M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS); return u32Val; } /** ******************************************************************************* ** \brief 获得外设时钟(PCLK)频率值 ** \retval uint32_t PCLK频率值(Hz) ** ******************************************************************************/ uint32_t Sysctrl_GetPClkFreq(void) { uint32_t u32Val = 0; u32Val = Sysctrl_GetHClkFreq(); u32Val = (u32Val >> (M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS)); return u32Val; } /** ******************************************************************************* ** \brief 时钟初始化函数 ** \param [in] pstcCfg 初始化配置参数 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t *pstcCfg) { en_result_t enRet = Ok; //系统时钟参数配置 switch(pstcCfg->enClkSrc) { case SysctrlClkRCH: break; case SysctrlClkXTH: Sysctrl_XTHDriverCfg(SysctrlXtalDriver3); Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384); break; case SysctrlClkRCL: Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256); break; case SysctrlClkXTL: Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3); Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384); break; case SysctrlClkPLL: Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384); break; default: enRet = ErrorInvalidParameter; break; } //时钟源使能 Sysctrl_ClkSourceEnable(pstcCfg->enClkSrc, TRUE); //时钟源切换 Sysctrl_SysClkSwitch(pstcCfg->enClkSrc); //时钟分频设置 Sysctrl_SetHCLKDiv(pstcCfg->enHClkDiv); Sysctrl_SetPCLKDiv(pstcCfg->enPClkDiv); return enRet; } /** ******************************************************************************* ** \brief 时钟去初始化函数 ** \param [in] ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_ClkDeInit(void) { en_result_t enRet = Ok; //配置RCH为内部4Hz Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz); //时钟源使能 Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE); //时钟源切换 Sysctrl_SysClkSwitch(SysctrlClkRCH); //其它时钟源使能关闭 Sysctrl_ClkSourceEnable(SysctrlClkXTH, FALSE); Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE); Sysctrl_ClkSourceEnable(SysctrlClkXTL, FALSE); Sysctrl_ClkSourceEnable(SysctrlClkPLL, FALSE); //时钟分频设置 Sysctrl_SetHCLKDiv(SysctrlHclkDiv1); Sysctrl_SetPCLKDiv(SysctrlPclkDiv1); return enRet; } /** ******************************************************************************* ** \brief 内部高速时钟频率TRIM值加载 ** \param [in] enRCHFreq 设定的RCH目标频率值 ** \retval Ok 设定成功 ** 其他 设定失败或时钟未稳定 ******************************************************************************/ en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq) { //加载RCH Trim值 M0P_SYSCTRL->RCH_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCHFreq); return Ok; } /** ******************************************************************************* ** \brief 外部高速时钟频率范围设定 ** \param [in] enXTHFreq 设定的频率值 ** \retval Ok 设定成功 ** 其他 设定失败或时钟未稳定 ******************************************************************************/ en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq) { en_result_t enRet = Ok; M0P_SYSCTRL->XTH_CR_f.XTH_FSEL = enXTHFreq; return enRet; } /** ******************************************************************************* ** \brief PLL时钟配置 ** \param [in] pstcPLLCfg PLL配置结构体指针 ** \retval Ok 设定成功 ** 其他 设定失败或参数值不匹配 ******************************************************************************/ en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t *pstcPLLCfg) { en_result_t enRet = Ok; uint16_t u16Trim[5] = {0}; u16Trim[4] = RCH_CR_TRIM_24M_VAL; u16Trim[3] = RCH_CR_TRIM_22_12M_VAL; u16Trim[2] = RCH_CR_TRIM_16M_VAL; u16Trim[1] = RCH_CR_TRIM_8M_VAL; ////PLL最高时钟不能超过48MHz //RCH作为PLL输入 if (SysctrlPllRch == pstcPLLCfg->enPllClkSrc) { if( ((u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) || ((u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) || ((u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 3)) || ((u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 6))) { return ErrorInvalidMode; } } else //XTH作为PLL输入 { if ((SYSTEM_XTH * pstcPLLCfg->enPllMul) > 48*1000*1000) { return ErrorInvalidMode; } } M0P_SYSCTRL->PLL_CR_f.FRSEL = pstcPLLCfg->enInFreq; M0P_SYSCTRL->PLL_CR_f.FOSC = pstcPLLCfg->enOutFreq; M0P_SYSCTRL->PLL_CR_f.DIVN = pstcPLLCfg->enPllMul; M0P_SYSCTRL->PLL_CR_f.REFSEL = pstcPLLCfg->enPllClkSrc; return enRet; } /** ******************************************************************************* ** \brief 内部低速时钟频率TRIM值加载 ** \param [in] enRCLFreq 设定的RCL目标频率值 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq) { M0P_SYSCTRL->RCL_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCLFreq); return Ok; } /** ******************************************************************************* ** \brief 系统时钟(HCLK)分频设定 ** \param [in] enHCLKDiv 分频设定值 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv) { _SysctrlUnlock(); M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS = enHCLKDiv; return Ok; } /** ******************************************************************************* ** \brief 外设时钟(PCLK)分频设定 ** \param [in] enPCLKDiv 分频设定值 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv) { _SysctrlUnlock(); M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS = enPCLKDiv; return Ok; } ///<< for Sysctrl_SetPeripheralGate() & Sysctrl_GetPeripheralGate() static volatile boolean_t bDacPeriBac = FALSE; /** ******************************************************************************* ** \brief 设置外设时钟门控开关 ** \param [in] enPeripheral 目标外设 ** \param [in] bFlag 使能开关 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag) { if(enPeripheral&0x20u) { enPeripheral &= ~0x20u; SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral, bFlag); if((SysctrlPeripheralDac & ~0x20u) == enPeripheral) { bDacPeriBac = bFlag; } else { SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), (SysctrlPeripheralDac & ~0x20u), bDacPeriBac); } } else { SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral, bFlag); } return Ok; } /** ******************************************************************************* ** \brief 获得外设时钟门控开关状态 ** \param [in] enPeripheral 目标外设 ** \retval TRUE 开 ** FALSE 关 ******************************************************************************/ boolean_t Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral) { if(enPeripheral&0x20u) { if(SysctrlPeripheralDac == enPeripheral) { return bDacPeriBac; } else { enPeripheral &= ~0x20u; return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral); } } else { return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral); } } /** ******************************************************************************* ** \brief 系统功能设定 ** \param [in] enFunc 系统功能枚举类型 ** \param [in] bFlag 1-开/0-关 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag) { _SysctrlUnlock(); SetBit((uint32_t)(&(M0P_SYSCTRL->SYSCTRL1)), enFunc, bFlag); return Ok; } /** ******************************************************************************* ** \brief 设定RTC校准时钟频率 ** \param [in] enRtcAdj 校准频率值 ** \retval Ok 设定成功 ** 其他 设定失败 ******************************************************************************/ en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj) { _SysctrlUnlock(); M0P_SYSCTRL->SYSCTRL1_f.RTC_FREQ_ADJUST = enRtcAdj; return Ok; } //@} // SysctrlGroup /******************************************************************************* * EOF (not truncated) ******************************************************************************/