C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 1 C51 COMPILER V9.60.7.0, COMPILATION OF MODULE RCC OBJECT MODULE PLACED IN .\Objects\rcc.obj COMPILER INVOKED BY: d:\Keil_v5\C51\BIN\C51.EXE ..\..\..\..\driver\src\rcc.c OBJECTADVANCED OPTIMIZE(9,SPEED) BROWSE ORD -ER NOAREGS MODC2 INCDIR(..\..\..\..\driver\inc;..\..\..\..\mcu;..\..\..\..\middleware\log;..\..\..\..\middleware\delay;. -.\..\..\..\middleware\rf_basis) DEFINE(IS_CLIENT_BOARD=1) DEBUG PRINT(.\Listings\rcc.lst) TABS(2) OBJECT(.\Objects\rcc.o -bj) line level source 1 /** 2 ************************************************************************ 3 * @file rcc.c 4 * @author Panchip Team 5 * @version V0.5 6 * @date 2024-04-28 7 * @brief This file provides all the rcc firmware functions. 8 * @note 9 * Copyright (C) 2024 Panchip Technology Corp. All rights reserved. 10 **************************************************************************** 11 */ 12 13 #include "rcc.h" 14 15 /** @addtogroup PAN262x_Std_Driver 16 * @{ 17 */ 18 19 /** @defgroup RCC 20 * @brief RCC driver modules 21 * @{ 22 */ 23 24 /** @defgroup RCC_Private_Functions 25 * @{ 26 */ 27 28 /** 29 * @brief Reset one or more peripheral. 30 * @param RCC_Periph: specifies the peripheral to be reset. 31 * This parameter can be any combination of the following values: 32 * @arg RCC_PERIPH_WDT: WDT peripheral 33 * @arg RCC_PERIPH_SPI: SPI peripheral 34 * @arg RCC_PERIPH_I2C: I2C peripheral 35 * @arg RCC_PERIPH_TIMER2: TIMER2 peripheral 36 * @arg RCC_PERIPH_TIMER1: TIMER1 peripheral 37 * @arg RCC_PERIPH_TIMER0: TIMER2 peripheral 38 * @arg RCC_PERIPH_UART: UART peripheral 39 * @arg RCC_PERIPH_PORT: PORT peripheral 40 * @arg RCC_PERIPH_USB: USB peripheral 41 * @arg RCC_PERIPH_PWM: PWM peripheral 42 * @arg RCC_PERIPH_ADC: ADC peripheral 43 * @arg RCC_PERIPH_RF: RF peripheral 44 * @retval None 45 */ 46 void RCC_PeriphReset(u16 RCC_Periph) 47 { 48 1 RCC_Periph &= 0x0F7F; /**< Clear bit 7 of RCC_Periph to avoid to reset wdt peripheral */ 49 1 50 1 if ((RCC_Periph & 0xFF) != 0) 51 1 { 52 2 RCC_SEL = PERRST0; C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 2 53 2 RCC_DAT |= (u8)RCC_Periph; 54 2 RCC_DAT &= ~((u8)RCC_Periph); 55 2 } 56 1 else 57 1 { 58 2 RCC_Periph >>= 8; 59 2 60 2 RCC_SEL = PERRST1; 61 2 RCC_DAT |= (u8)RCC_Periph; 62 2 RCC_DAT &= ~((u8)RCC_Periph); 63 2 } 64 1 } 65 66 /** 67 * @brief Enables or disables the peripheral clock. 68 * @param RCC_Periph: specifies the peripheral to gates its clock. 69 * This parameter can be any combination of the following values: 70 * @arg RCC_PERIPH_WDT: WDT clock 71 * @arg RCC_PERIPH_SPI: SPI clock 72 * @arg RCC_PERIPH_I2C: I2C clock 73 * @arg RCC_PERIPH_TIMER2: TIMER2 clock 74 * @arg RCC_PERIPH_TIMER1: TIMER1 clock 75 * @arg RCC_PERIPH_TIMER0: TIMER2 clock 76 * @arg RCC_PERIPH_UART: UART clock 77 * @arg RCC_PERIPH_PORT: PORT clock 78 * @arg RCC_PERIPH_USB: USB clock 79 * @arg RCC_PERIPH_PWM: PWM clock 80 * @arg RCC_PERIPH_ADC: ADC clock 81 * @arg RCC_PERIPH_RF: RF clock 82 * @param NewState: new state of the specified peripheral clock. 83 * This parameter can be: ENABLE or DISABLE. 84 * @retval None 85 */ 86 void RCC_PeriphClockCmd(u16 RCC_Periph, u8 NewState) 87 { 88 1 if ((RCC_Periph & 0xFF) != 0) 89 1 { 90 2 RCC_SEL = PERCLKEN0; 91 2 92 2 if (NewState) 93 2 { 94 3 RCC_DAT |= (u8)RCC_Periph; 95 3 } 96 2 else 97 2 { 98 3 RCC_DAT &= ~((u8)RCC_Periph); 99 3 } 100 2 } 101 1 else 102 1 { 103 2 RCC_SEL = PERCLKEN1; 104 2 105 2 if (NewState) 106 2 { 107 3 RCC_DAT |= (u8)(RCC_Periph >> 8); 108 3 } 109 2 else 110 2 { 111 3 RCC_DAT &= ~((u8)(RCC_Periph >> 8)); 112 3 } 113 2 } 114 1 } C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 3 115 116 /** 117 * @brief This function ENABLE or DISABLE the peripheral 118 * @param sel: peripheral 119 * @arg: RCH 120 * @arg: RCL 121 * @arg: XTH 122 * @arg: DPLL 123 * @param NewState: enable or disable 124 * @arg: DISABLE 125 * @arg: ENABLE 126 * @retval None 127 */ 128 void RCC_Ctrl(u8 sel, u8 NewState) 129 { 130 1 u16 count = 0; 131 1 132 1 RCC_SEL = CLK_TOP_CTRL; 133 1 134 1 switch (sel) 135 1 { 136 2 case RCH: 137 2 if (NewState) 138 2 { 139 3 RCC_DAT |= RCH_EN; 140 3 ANA_RCH_SYNC; 141 3 RCC_SEL = RCH_CTRL0; 142 3 while ((RCC_DAT & RCH_RDY) == FALSE) 143 3 { 144 4 if(count++>65530) 145 4 { 146 5 MCU_REBOOT(); 147 5 } 148 4 } 149 3 } 150 2 else 151 2 { 152 3 RCC_DAT &= ~RCH_EN; 153 3 ANA_RCH_SYNC; 154 3 } 155 2 break; 156 2 157 2 case RCL: 158 2 if (NewState) 159 2 { 160 3 RCC_DAT |= RCL_EN; 161 3 ANA_RCH_SYNC; 162 3 } 163 2 else 164 2 { 165 3 RCC_DAT &= ~RCL_EN; 166 3 ANA_RCH_SYNC; 167 3 } 168 2 break; 169 2 170 2 case XTH: 171 2 if (NewState) 172 2 { 173 3 u8 Temp;// = RCC_DAT|XTH_EN; /**< Stroe CLK_TOP_CTRL to Temp */ 174 3 175 3 if((RCC_DAT&XTH_EN) != 0) //XTH is already opened 176 3 { C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 4 177 4 return; 178 4 } 179 3 180 3 Temp = RCC_DAT | XTH_EN; /**< Stroe CLK_TOP_CTRL to Temp */ 181 3 182 3 if ((RCC_DAT & 0x80) != 0) /**< System clock is from XTH or DPLL_16M */ 183 3 { 184 4 RCC_DAT |= RCH_EN; /**< Enable interal RCH clock */ 185 4 ANA_RCH_SYNC; 186 4 187 4 /** Wait RCH_RDY flag until it becomes to 1 */ 188 4 while ((GET_WREG(RCC, RCH_CTRL0) & RCH_RDY) == FALSE) 189 4 { 190 5 if(count++>65530) 191 5 { 192 6 MCU_REBOOT(); 193 6 } 194 5 } 195 4 AND_WREG(RCC, CLK_TOP_CTRL, 0x3F); /**< Select RCH as system clock */ 196 4 } 197 3 198 3 OR_WREG(RCC, XTH_CTRL, 0x0C); /**< Enable FAST_TRIM */ 199 3 AND_WREG(RCC, XTH_CTRL, 0xEF); /**< Disable EN_XTAL_RDY */ 200 3 OR_WREG(RCC, CLK_TOP_CTRL, XTH_EN); /**< Enable external XTAL clock */ 201 3 OR_WREG(RCC, XTH_CTRL, 0x10); /**< Enable EN_XTAL_RDY */ 202 3 203 3 /** Wait XTAL_RDY flag until it becomes to 1 */ 204 3 while ((GET_WREG(RCC, XTH_CTRL) & XTH_RDY) == FALSE) 205 3 { 206 4 if(count++ > 65530) 207 4 { 208 5 MCU_REBOOT(); 209 5 } 210 4 } 211 3 212 3 AND_WREG(RCC, XTH_CTRL, 0xFB); /**< Disable EN_FAST */ 213 3 // SET_WREG(RCC, CLK_TOP_CTRL, Temp); /**< Restroe CLK_TOP_CTRL */ 214 3 } 215 2 else 216 2 { 217 3 RCC_DAT &= ~XTH_EN; 218 3 } 219 2 break; 220 2 221 2 case DPLL: 222 2 if (NewState) 223 2 { 224 3 if((RCC_DAT&DPLL_EN) != 0) //DPLL is already opened 225 3 { 226 4 return; 227 4 } 228 3 229 3 RCC_DAT |= DPLL_EN; 230 3 RCC_SEL = DPLL_CTRL; 231 3 while ((RCC_DAT & DPLL_RDY) == FALSE) 232 3 { 233 4 if(count++>65530) 234 4 { 235 5 MCU_REBOOT(); 236 5 } 237 4 } 238 3 } C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 5 239 2 else 240 2 { 241 3 RCC_DAT &= ~DPLL_EN; 242 3 } 243 2 break; 244 2 } 245 1 } 246 247 /** 248 * @brief Turn on external crystal oscillator in non-blocking mode. 249 * 250 * This function turns on the external crystal oscillator in non-blocking mode. The function 251 * returns immediately and the caller should check the status of the crystal oscillator using 252 * the appropriate status register. 253 * 254 * @return None. 255 */ 256 void RCC_XTALTurnOnNoneBlock(void) 257 { 258 1 OR_WREG(RCC, XTH_CTRL, 0x0C); /**< Enable FAST_TRIM */ 259 1 AND_WREG(RCC, XTH_CTRL, 0xEF); /**< Disable EN_XTAL_RDY */ 260 1 OR_WREG(RCC, CLK_TOP_CTRL, XTH_EN); /**< Enable external XTAL clock */ 261 1 OR_WREG(RCC, XTH_CTRL, 0x10); /**< Enable EN_XTAL_RDY */ 262 1 } 263 264 /** 265 * @brief Get the status of clock source. 266 * 267 * This function returns the status of external crystal oscillator. If the oscillator is stable, 268 * the function returns @c TRUE, otherwise it returns @c FALSE. 269 * 270 * @param[in] ClockSource Specifies the clock source to check. Valid values are: 271 * - RCH: internal high-speed oscillator 272 * - RCL: internal low-speed oscillator 273 * - XTAL: external crystal oscillator 274 * - DPLL: digital phase-locked loop 275 * 276 * @return @c TRUE if the specified clock source is stable, @c FALSE otherwise. 277 * 278 */ 279 bool RCC_GetClockReadyStatus(u8 ClockSource) 280 { 281 1 bool ReadyFlag = FALSE; 282 1 283 1 if (RCH == ClockSource) 284 1 { 285 2 ReadyFlag = (GET_WREG(RCC, RCH_CTRL0) & RCH_RDY) ? TRUE : FALSE; 286 2 } 287 1 else if (XTH == ClockSource) 288 1 { 289 2 ReadyFlag = (GET_WREG(RCC, XTH_CTRL) & XTH_RDY) ? TRUE : FALSE; 290 2 } 291 1 else if (DPLL == ClockSource) 292 1 { 293 2 ReadyFlag = (GET_WREG(RCC, DPLL_CTRL) & DPLL_RDY) ? TRUE : FALSE; 294 2 } 295 1 296 1 return ReadyFlag; 297 1 } 298 299 /** 300 * @brief Enable or disable external crystal oscillator fast ready function. C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 6 301 * 302 * This function enables or disables the external crystal oscillator fast ready function. 303 * If the function is enabled, the system will use the fast ready function to speed up the 304 * startup time of the external crystal oscillator. If the function is disabled, the system 305 * will use the normal startup time. 306 * 307 * @param[in] enable Specifies whether to enable or disable the fast ready function. Valid values 308 * are: 309 * - ENABLE: enable the fast ready function 310 * - DISABLE: disable the fast ready function 311 * 312 * @return None. 313 * 314 */ 315 void RCC_XTALFastRdyEnable(u8 NewState) 316 { 317 1 if (NewState) 318 1 { 319 2 OR_WREG(RCC, XTH_CTRL, 0x04); /**< Enable EN_FAST */ 320 2 } 321 1 else 322 1 { 323 2 AND_WREG(RCC, XTH_CTRL, 0xFB); /**< Disable EN_FAST */ 324 2 } 325 1 } 326 327 /** 328 * @brief This function select clock source 329 * @param sel: peripheral 330 * @arg: RCH 331 * @arg: XTH 332 * @arg: DPLL 333 * @retval None 334 */ 335 void RCC_Source(u8 sel) 336 { 337 1 RCC_SEL = CLK_TOP_CTRL; 338 1 RCC_DAT = ((RCC_DAT & CLK_SEL) | (sel << 6)); 339 1 } 340 341 /** 342 * @brief This function select clock source 343 * @param Division: System clock division 344 * @arg: SYS_CLK_DIV_1 345 * @arg: SYS_CLK_DIV_2 346 * @arg: SYS_CLK_DIV_4 347 * @arg: SYS_CLK_DIV_6 348 * @retval None 349 */ 350 void RCC_SysDiv(u8 Division) 351 { 352 1 RCC_SEL = CLK_TOP_CTRL; 353 1 RCC_DAT = ((RCC_DAT & SYS_DIV_Msk) | Division); 354 1 } 355 356 /** 357 * @brief This function calibrate RCH 358 * @param None 359 * @retval None 360 */ 361 void RCC_RchCali(u8 rch_cap_trim, u8 rch_cal_code_cfg) 362 { C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 7 363 1 u8 trim = rch_cap_trim; 364 1 u8 cal = rch_cal_code_cfg; 365 1 366 1 RCC_SEL = RCH_CTRL0; 367 1 RCC_DAT = ((RCC_DAT & RCH_CAP_TRIM) | rch_cap_trim); 368 1 369 1 RCC_SEL = RCHCAL_2H; 370 1 RCC_DAT = ((rch_cal_code_cfg << 1) | (EN_RCHCAL_CODE)); // rch_cal_code_cfg 6BIT(1~6) 371 1 } 372 373 /** 374 * @brief This function calibrate RCH Disable 375 * @param None 376 * @retval None 377 */ 378 void RCC_RchCaliDisable(void) 379 { 380 1 RCC_SEL = RCHCAL_2H; 381 1 RCC_DAT &= ~EN_RCHCAL_CODE; 382 1 } 383 384 /** 385 * @brief This function calibrate RCH automatic 386 * @param None 387 * @retval None 388 */ 389 void RCC_RchCaliAuto(void) 390 { 391 1 RCC_SEL = RCHCAL_EN; 392 1 RCC_DAT |= EN_RCHCAL_AUTO; 393 1 } 394 395 /** 396 * @brief This function calibrate RCH 397 * @param None 398 * @retval None 399 */ 400 void RCC_RclCali_EN(u8 NewState) 401 { 402 1 RCC_SEL = RCL_CTRL0; 403 1 if (NewState) 404 1 { 405 2 RCC_DAT |= RCL_CAL_EN; 406 2 } 407 1 else 408 1 { 409 2 RCC_DAT &= ~RCL_CAL_EN; 410 2 } 411 1 ANA_RCH_SYNC; 412 1 } 413 414 /** 415 * @brief This function calibrate rcl manually 416 * 417 * @param NewState 418 */ 419 void RCC_RclCali_MANU(u8 NewState) 420 { 421 1 RCC_SEL = RCL_CTRL1; 422 1 if (NewState) 423 1 { 424 2 RCC_DAT |= 0x30; C51 COMPILER V9.60.7.0 RCC 11/21/2025 17:14:04 PAGE 8 425 2 } 426 1 else 427 1 { 428 2 RCC_DAT &= 0xCF; 429 2 } 430 1 ANA_RCH_SYNC; 431 1 } 432 433 /** 434 * @brief This function set LVR voltage level 435 * 436 * @param VoltLevel 437 * @arg LVR_VOLT_1V85 438 * @arg LVR_VOLT_2V 439 * @arg LVR_VOLT_2V2 440 * @arg LVR_VOLT_2V5 441 * @arg LVR_VOLT_2V65 442 * @arg LVR_VOLT_2V35 443 * @arg LVR_VOLT_2V8 444 * @retval None 445 */ 446 void RCC_SetLvrVoltLevel(RCC_LvrVoltLevel_t VoltLevel) 447 { 448 1 u8 Level = (u8)1<