URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ARM7_STR75x_GCC/] [STLibrary/] [src/] [75x_mrcc.c] - Rev 584
Go to most recent revision | Compare with Previous | Blame | View Log
/******************** (C) COPYRIGHT 2006 STMicroelectronics ******************** * File Name : 75x_mrcc.c * Author : MCD Application Team * Date First Issued : 03/10/2006 * Description : This file provides all the MRCC software functions. ******************************************************************************** * History: * 07/17/2006 : V1.0 * 03/10/2006 : V0.1 ******************************************************************************** * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. *******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "75x_mrcc.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define MRCC_FLAG_Mask 0x1F /* MRCC Flag Mask */ /* MRCC_PWRCTRL mask bits */ #define MRCC_LP_Set_Mask 0x00000001 #define MRCC_LP_Reset_Mask 0xFFFFFFFE #define MRCC_SWRESET_Mask 0x00000002 #define MRCC_WFI_Mask 0x00000004 #define MRCC_STANDBY_Mask 0x00000006 #define MRCC_LPMC_Reset_Mask 0xFFFFFFF9 #define MRCC_LPDONE_Reset_Mask 0xFFFFFF7F #define MRCC_LPPARAM_Reset_Mask 0xFFFF1FFF #define MRCC_WFIParam_Reset_Mask 0xFFFF1FEF #define MRCC_CKRTCSEL_Set_Mask 0x03000000 #define MRCC_CKRTCSEL_Reset_Mask 0xFCFFFFFF #define MRCC_CKRTCOK_Mask 0x08000000 #define MRCC_LPOSCEN_Mask 0x10000000 #define MRCC_OSC32KEN_Mask 0x20000000 /* MRCC_CLKCTL mask bits */ #define MRCC_PPRESC_Set_Mask 0x00000003 #define MRCC_PPRESC_Reset_Mask 0xFFFFFFFC #define MRCC_PPRESC2_Mask 0x00000004 #define MRCC_HPRESC_Set_Mask 0x00000018 #define MRCC_HPRESC_Reset_Mask 0xFFFFFFE7 #define MRCC_MCOS_Reset_Mask 0xFFFFFF3F #define MRCC_XTDIV2_Set_Mask 0x00008000 #define MRCC_XTDIV2_Reset_Mask 0xFFFF7FFF #define MRCC_OSC4MBYP_Set_Mask 0x00010000 #define MRCC_OSC4MBYP_Reset_Mask 0xFFFEFFFF #define MRCC_OSC4MOFF_Set_Mask 0x00020000 #define MRCC_OSC4MOFF_Reset_Mask 0xFFFDFFFF #define MRCC_NCKDF_Set_Mask 0x00040000 #define MRCC_NCKDF_Reset_Mask 0xFFFBFFFF #define MRCC_CKOSCSEL_Set_Mask 0x00200000 #define MRCC_CKOSCSEL_Reset_Mask 0xFFDFFFFF #define MRCC_CKUSBSEL_Mask 0x00400000 #define MRCC_CKSEL_Set_Mask 0x00800000 #define MRCC_CKSEL_Reset_Mask 0xFF7FFFFF #define MRCC_CKSEL_CKOSCSEL_Mask 0x00A00000 #define MRCC_PLLEN_Set_Mask 0x01000000 #define MRCC_PLLEN_Reset_Mask 0xFEFFFFFF #define MRCC_PLL2EN_Set_Mask 0x02000000 #define MRCC_PLL2EN_Reset_Mask 0xFDFFFFFF #define MRCC_MX_Set_Mask 0x18000000 #define MRCC_MX_Reset_Mask 0xE7FFFFFF #define MRCC_LOCK_Mask 0x80000000 #define MRCC_PLLEN_LOCK_Mask 0x81000000 /* Typical Value of the OSC4M in Hz */ #define OSC4M_Value 4000000 /* Typical Value of the OSC4M divided by 128 (used to clock the RTC) in Hz */ #define OSC4M_Div128_Value 31250 /* Typical Value of the OS32K Oscillator Frequency in Hz */ #define OSC32K_Value 32768 /* Typical Reset Value of the Internal LPOSC Oscillator Frequency in Hz */ #define LPOSC_Value 245000 /* Typical Reset Value of the Internal FREEOSC Oscillator Frequency in Hz */ #define FREEOSC_Value 5000000 /* Time out for OSC4M start up */ #define OSC4MStartUp_TimeOut 0xFE /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static ErrorStatus SetCKSYS_FREEOSC(void); static ErrorStatus SetCKSYS_OSC4M(u32 PLL_State); static ErrorStatus SetCKSYS_OSC4MPLL(u32 PLL_Mul); static ErrorStatus SetCKSYS_RTC(u32 PLL_State); static void WriteLPBit(void); static void WriteCKOSCSELBit(void); /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : MRCC_DeInit * Description : Deinitializes the MRCC peripheral registers to their default * reset values. * - Depending on the system clock state, some bits in MRCC_CLKCTL * register can’t be reset. * - The OSC32K, LPOSC and RTC clock selection configuration * bits in MRCC_PWRCTRL register are not cleared by this * function. To reset those bits, use the dedicated functions * available within this driver. * - The MRCC_RFSR, MRCC_BKP0 and MRCC_BKP1 registers are not * reset by this function. * Input : None * Output : None * Return : None *******************************************************************************/ void MRCC_DeInit(void) { /* Try to clear NCKDF bit */ MRCC->CLKCTL &= MRCC_NCKDF_Reset_Mask; if((MRCC->CLKCTL & MRCC_NCKDF_Set_Mask) != RESET) {/* No clock detected on OSC4M */ /* Reset LOCKIE, LOCKIF, CKUSBSEL, NCKDIE, OSC4MOFF, OSC4MBYP, MCOS[1:0], MCOP, HPRESC[1:0], PPRES[2:0] bits */ MRCC->CLKCTL &= 0x9FB40000; if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { /* Clear CKOSCSEL bit --------------------------------------------------*/ /* Execute CKOSCSEL bit writing sequence */ WriteCKOSCSELBit(); } } else {/* Clock present on OSC4M */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { /* Reset CKSEL bit */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; /* Clear CKOSCSEL bit --------------------------------------------------*/ /* Execute CKOSCSEL bit writing sequence */ WriteCKOSCSELBit(); } if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) == RESET) { /* Set CKSEL bit */ MRCC->CLKCTL |= MRCC_CKSEL_Set_Mask; } /* Disable PLL */ MRCC->CLKCTL &= MRCC_PLLEN_Reset_Mask; /* Reset LOCKIE, LOCKIF, MX[1:0], CKUSBSEL, NCKDIE, MCOS[1:0], MCOP, HPRESC[1:0], PPRES[2:0] bits */ MRCC->CLKCTL &= 0x87B70000; /* Reset CKSEL bit */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; /* Reset OSC4MOFF and OSC4MBYP bits */ MRCC->CLKCTL &= 0xFFFCFFFF; } /* Reset RTCM, EN33V, LP_PARAM[15:13], WFI_FLASH_EN, LPMC_DBG and LPMC[1:0] bits */ MRCC->PWRCTRL &= 0xFBFE1FE1; /* Reset PCLKEN register bits */ MRCC->PCLKEN = 0x00; /* Reset PSWRES register bits */ MRCC->PSWRES = 0x00; /* Clear NCKDF bit */ MRCC->CLKCTL &= MRCC_NCKDF_Reset_Mask; } /******************************************************************************* * Function Name : MRCC_XTDIV2Config * Description : Enables or disables the oscillator divider by 2. This function * must not be used when the PLL is enabled. * Input : - MRCC_XTDIV2: specifies the new state of the oscillator * divider by 2. * This parameter can be one of the following values: * - MRCC_XTDIV2_Disable: oscillator divider by 2 disbaled * - MRCC_XTDIV2_Enable: oscillator divider by 2 enbaled * Output : None * Return : None *******************************************************************************/ void MRCC_XTDIV2Config(u32 MRCC_XTDIV2) { if(MRCC_XTDIV2 == MRCC_XTDIV2_Enable) { MRCC->CLKCTL |= MRCC_XTDIV2_Enable; } else { MRCC->CLKCTL &= MRCC_XTDIV2_Disable; } } /******************************************************************************* * Function Name : MRCC_CKSYSConfig * Description : Configures the system clock (CK_SYS). * Input : - MRCC_CKSYS: specifies the clock source used as system clock. * This parameter can be one of the following values: * - MRCC_CKSYS_FREEOSC * - MRCC_CKSYS_OSC4M * - MRCC_CKSYS_OSC4MPLL * - MRCC_CKSYS_RTC (RTC clock source must be previously * configured using MRCC_CKRTCConfig() function) * : - MRCC_PLL: specifies the PLL configuration. * This parameter can be one of the following values: * - MRCC_PLL_Disabled: PLL disabled * - MRCC_PLL_NoChange: No change on PLL configuration * - MRCC_PLL_Mul_12: Multiplication by 12 * - MRCC_PLL_Mul_14: Multiplication by 14 * - MRCC_PLL_Mul_15: Multiplication by 15 * - MRCC_PLL_Mul_16: Multiplication by 16 * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_CKSYSConfig(u32 MRCC_CKSYS, u32 MRCC_PLL) { ErrorStatus Status = ERROR; switch(MRCC_CKSYS) { case MRCC_CKSYS_FREEOSC: if((MRCC_PLL == MRCC_PLL_Disabled) || (MRCC_PLL == MRCC_PLL_NoChange)) { Status = SetCKSYS_FREEOSC(); } break; case MRCC_CKSYS_OSC4M: if((MRCC_PLL == MRCC_PLL_Disabled) || (MRCC_PLL == MRCC_PLL_NoChange)) { Status = SetCKSYS_OSC4M(MRCC_PLL); } break; case MRCC_CKSYS_OSC4MPLL: if((MRCC_PLL == MRCC_PLL_Mul_12) || (MRCC_PLL == MRCC_PLL_Mul_14) || (MRCC_PLL == MRCC_PLL_Mul_15) || (MRCC_PLL == MRCC_PLL_Mul_16)) { Status = SetCKSYS_OSC4MPLL(MRCC_PLL); } break; case MRCC_CKSYS_RTC: if((MRCC_PLL == MRCC_PLL_Disabled) || (MRCC_PLL == MRCC_PLL_NoChange)) { Status = SetCKSYS_RTC(MRCC_PLL); } break; default: Status = ERROR; break; } return Status; } /******************************************************************************* * Function Name : MRCC_HCLKConfig * Description : Configures the AHB clock (HCLK). * Input : - MRCC_HCLK: defines the AHB clock. This clock is derived * from the system clock(CK_SYS). * This parameter can be one of the following values: * - MRCC_CKSYS_Div1: AHB clock = CK_SYS * - MRCC_CKSYS_Div2: AHB clock = CK_SYS/2 * - MRCC_CKSYS_Div4: AHB clock = CK_SYS/4 * - MRCC_CKSYS_Div8: AHB clock = CK_SYS/8 * Output : None * Return : None *******************************************************************************/ void MRCC_HCLKConfig(u32 MRCC_HCLK) { u32 Temp = 0; /* Clear HPRESC[1:0] bits */ Temp = MRCC->CLKCTL & MRCC_HPRESC_Reset_Mask; /* Set HPRESC[1:0] bits according to MRCC_HCLK value */ Temp |= MRCC_HCLK; /* Store the new value */ MRCC->CLKCTL = Temp; } /******************************************************************************* * Function Name : MRCC_CKTIMConfig * Description : Configures the TIM clock (CK_TIM). * Input : - MRCC_CKTIM: defines the TIM clock. This clock is derived * from the AHB clock(HCLK). * This parameter can be one of the following values: * - MRCC_HCLK_Div1: TIM clock = HCLK * - MRCC_HCLK_Div2: TIM clock = HCLK/2 * - MRCC_HCLK_Div4: TIM clock = HCLK/4 * - MRCC_HCLK_Div8: TIM clock = HCLK/8 * Output : None * Return : None *******************************************************************************/ void MRCC_CKTIMConfig(u32 MRCC_CKTIM) { u32 Temp = 0; /* Clear PPRESC[1:0] bits */ Temp = MRCC->CLKCTL & MRCC_PPRESC_Reset_Mask; /* Set PPRESC[1:0] bits according to MRCC_CKTIM value */ Temp |= MRCC_CKTIM; /* Store the new value */ MRCC->CLKCTL = Temp; } /******************************************************************************* * Function Name : MRCC_PCLKConfig * Description : Configures the APB clock (PCLK). * Input : - MRCC_PCLK: defines the APB clock. This clock is derived * from the TIM clock(CK_TIM). * This parameter can be one of the following values: * - MRCC_CKTIM_Div1: APB clock = CKTIM * - MRCC_CKTIM_Div2: APB clock = CKTIM/2 * Output : None * Return : None *******************************************************************************/ void MRCC_PCLKConfig(u32 MRCC_PCLK) { if(MRCC_PCLK == MRCC_CKTIM_Div2) { MRCC->CLKCTL |= MRCC_CKTIM_Div2; } else { MRCC->CLKCTL &= MRCC_CKTIM_Div1; } } /******************************************************************************* * Function Name : MRCC_CKRTCConfig * Description : Configures the RTC clock (CK_RTC). * Input : - MRCC_CKRTC: specifies the clock source to be used as RTC * clock. * This parameter can be one of the following values: * - MRCC_CKRTC_OSC4M_Div128 * - MRCC_CKRTC_OSC32K (OSC32K must be previously enabled * using MRCC_OSC32KConfig() function) * - MRCC_CKRTC_LPOSC (LPOSC must be previously enabled * using MRCC_LPOSCConfig() function) * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_CKRTCConfig(u32 MRCC_CKRTC) { u32 Tmp = 0; if(((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) && ((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET)) { /* CK_RTC used as CK_SYS clock source */ return ERROR; } else { /* Clear CKRTCSEL[1:0] bits */ Tmp = MRCC->PWRCTRL & MRCC_CKRTCSEL_Reset_Mask; /* Set CKRTCSEL[1:0] bits according to MRCC_CKRTC value */ Tmp |= MRCC_CKRTC; /* Store the new value */ MRCC->PWRCTRL = Tmp; } return SUCCESS; } /******************************************************************************* * Function Name : MRCC_CKUSBConfig * Description : Configures the USB clock(CK_USB). * Input : - MRCC_CKUSB: specifies the clock source to be used as USB * clock. * This parameter can be one of the following values: * - MRCC_CKUSB_Internal(CK_PLL2 enabled) * - MRCC_CKUSB_External(CK_PLL2 disabled) * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_CKUSBConfig(u32 MRCC_CKUSB) { if(MRCC_CKUSB == MRCC_CKUSB_External) { /* Disable CK_PLL2 */ MRCC->CLKCTL &= MRCC_PLL2EN_Reset_Mask; /* External USB clock selected */ MRCC->CLKCTL |= MRCC_CKUSB_External; } else { if((MRCC->CLKCTL & MRCC_PLLEN_LOCK_Mask) != RESET) { /* PLL enabled and locked */ /* Enable CK_PLL2 */ MRCC->CLKCTL |= MRCC_PLL2EN_Set_Mask; /* Internal USB clock selected */ MRCC->CLKCTL &= MRCC_CKUSB_Internal; } else { /* PLL not enabled */ return ERROR; } } return SUCCESS; } /******************************************************************************* * Function Name : MRCC_ITConfig * Description : Enables or disables the specified MRCC interrupts. * Input : - MRCC_IT: specifies the MRCC interrupts sources to be * enabled or disabled. This parameter can be any combination * of the following values: * - MRCC_IT_LOCK: PLL lock interrupt * - MRCC_IT_NCKD: No Clock detected interrupt * - NewState: new state of the MRCC interrupts. * This parameter can be: ENABLE or DISABLE. * Output : None * Return : None *******************************************************************************/ void MRCC_ITConfig(u32 MRCC_IT, FunctionalState NewState) { if(NewState == ENABLE) { MRCC->CLKCTL |= MRCC_IT; } else { MRCC->CLKCTL &= ~MRCC_IT; } } /******************************************************************************* * Function Name : MRCC_PeripheralClockConfig * Description : Enables or disables the specified peripheral clock. * Input : - MRCC_Peripheral: specifies the peripheral to gates its * clock. More than one peripheral can be selected using * the “|” operator. * - NewState: new state of the specified peripheral clock. * This parameter can be one of the following values: * - ENABLE: the selected peripheral clock is enabled * - DISABLE: the selected peripheral clock is disabled * Output : None * Return : None *******************************************************************************/ void MRCC_PeripheralClockConfig(u32 MRCC_Peripheral, FunctionalState NewState) { if(NewState == ENABLE) { MRCC->PCLKEN |= MRCC_Peripheral; } else { MRCC->PCLKEN &= ~MRCC_Peripheral; } } /******************************************************************************* * Function Name : MRCC_PeripheralSWResetConfig * Description : Forces or releases peripheral software reset. * Input : - MRCC_Peripheral: specifies the peripheral to reset. More * than one peripheral can be selected using the “|” operator. * - NewState: new state of the specified peripheral software * reset. This parameter can be one of the following values: * - ENABLE: the selected peripheral is kept under reset * - DISABLE: the selected peripheral exits from reset * Output : None * Return : None *******************************************************************************/ void MRCC_PeripheralSWResetConfig(u32 MRCC_Peripheral, FunctionalState NewState) { if(NewState == ENABLE) { MRCC->PSWRES |= MRCC_Peripheral; } else { MRCC->PSWRES &= ~MRCC_Peripheral; } } /******************************************************************************* * Function Name : MRCC_GetClocksStatus * Description : Returns the status and frequencies of different on chip clocks. * Don’t use this function when CK_SYS is clocked by an external * clock source (OSC4M bypassed). * Input : - MRCC_ClocksStatus: pointer to a MRCC_ClocksTypeDef structure * which will hold the clocks information. * Output : None * Return : None *******************************************************************************/ void MRCC_GetClocksStatus(MRCC_ClocksTypeDef* MRCC_ClocksStatus) { u32 PLLMul = 0; u32 Temp = 0; u32 Presc = 0; /* Get the Status of PLL */ if((MRCC->CLKCTL & MRCC_PLLEN_Set_Mask) == RESET) { MRCC_ClocksStatus->PLL_Status = OFF; } else { MRCC_ClocksStatus->PLL_Status = ON; } /* Get the Status of OSC4M */ if((MRCC->CLKCTL & MRCC_OSC4MOFF_Set_Mask) == RESET) { MRCC_ClocksStatus->OSC4M_Status = ON; } else { MRCC_ClocksStatus->OSC4M_Status = OFF; } /* Get the Status of LPOSC */ if((MRCC->PWRCTRL & MRCC_LPOSCEN_Mask) == RESET) { MRCC_ClocksStatus->LPOSC_Status = OFF; } else { MRCC_ClocksStatus->LPOSC_Status = ON; } /* Get the Status of OSC32K */ if((MRCC->PWRCTRL & MRCC_OSC32KEN_Mask) == RESET) { MRCC_ClocksStatus->OSC32K_Status = OFF; } else { MRCC_ClocksStatus->OSC32K_Status = ON; } /* Get CKU_SB source ---------------------------------------------------------*/ if((MRCC->CLKCTL & MRCC_CKUSBSEL_Mask) != RESET) { MRCC_ClocksStatus->CKUSB_Source = External; } else { if((MRCC->CLKCTL & MRCC_PLL2EN_Set_Mask) != RESET) { MRCC_ClocksStatus->CKUSB_Source = Internal; } else { MRCC_ClocksStatus->CKUSB_Source = Disabled; } } /* Get CK_RTC source ---------------------------------------------------------*/ Temp = MRCC->PWRCTRL & MRCC_CKRTCSEL_Set_Mask; Temp = Temp >> 24; switch(Temp) { case 0x00: MRCC_ClocksStatus->CKRTC_Source = Disabled; break; case 0x01: MRCC_ClocksStatus->CKRTC_Source = OSC4M_Div128; break; case 0x02: MRCC_ClocksStatus->CKRTC_Source = OSC32K; break; case 0x03: MRCC_ClocksStatus->CKRTC_Source = LPOSC; break; default: MRCC_ClocksStatus->CKRTC_Source = Disabled; break; } /* Get CK_SYS source ---------------------------------------------------------*/ if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) {/* CK_OSC used as CK_SYS clock source */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { /* CK_RTC used as CK_OSC clock source */ MRCC_ClocksStatus->CKSYS_Source = CKRTC; if(MRCC_ClocksStatus->CKRTC_Source == OSC32K) { /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = OSC32K_Value; } else if(MRCC_ClocksStatus->CKRTC_Source == LPOSC) { /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = LPOSC_Value; } else if(MRCC_ClocksStatus->CKRTC_Source == OSC4M_Div128) { /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = OSC4M_Div128_Value; } } else { /* OSC4M used as CK_OSC clock source */ MRCC_ClocksStatus->CKSYS_Source = OSC4M; if((MRCC->CLKCTL & MRCC_XTDIV2_Set_Mask) != RESET) { /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = Main_Oscillator >> 1; } else { /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = Main_Oscillator; } } } else {/* CK_PLL1 used as CK_SYS clock */ if(MRCC_ClocksStatus->PLL_Status == OFF) { /* FREEOSC used as CK_PLL1 clock source */ MRCC_ClocksStatus->CKSYS_Source = FREEOSC; /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = FREEOSC_Value; } else { /* OSC4M followed by PLL used as CK_PLL1 clock source */ MRCC_ClocksStatus->CKSYS_Source = OSC4MPLL; /* Get PLL factor ------------------------------------------------------*/ Temp = MRCC->CLKCTL & MRCC_MX_Set_Mask; Temp = Temp >> 27; switch(Temp) { case 0x00: PLLMul = 16; break; case 0x01: PLLMul = 15; break; case 0x02: PLLMul = 14; break; case 0x03: PLLMul = 12; break; default: PLLMul = 16; break; } /* CK_SYS clock frequency */ MRCC_ClocksStatus->CKSYS_Frequency = OSC4M_Value * PLLMul; } } /* Compute HCLK, CKTIM and PCLK clocks frequencies ---------------------------*/ /* Get HCLK prescaler */ Presc = MRCC->CLKCTL & MRCC_HPRESC_Set_Mask; Presc = Presc >> 3; /* HCLK clock frequency */ MRCC_ClocksStatus->HCLK_Frequency = MRCC_ClocksStatus->CKSYS_Frequency >> Presc; /* Get CK_TIM prescaler */ Presc = MRCC->CLKCTL & MRCC_PPRESC_Set_Mask; /* CK_TIM clock frequency */ MRCC_ClocksStatus->CKTIM_Frequency = MRCC_ClocksStatus->HCLK_Frequency >> Presc; /* Get PCLK prescaler */ Presc = MRCC->CLKCTL & MRCC_PPRESC2_Mask; Presc = Presc >> 2; /* PCLK clock frequency */ MRCC_ClocksStatus->PCLK_Frequency = MRCC_ClocksStatus->CKTIM_Frequency >> Presc; } /******************************************************************************* * Function Name : MRCC_LPMC_DBGonfig * Description : Enables or disables the Low Power Debug Mode. * Input : - MRCC_LPDM: specifies the LPDM new state value. * This parameter can be one of the following values: * - MRCC_LPDM_Disable * - MRCC_LPDM_Enable * Output : None * Return : None *******************************************************************************/ void MRCC_LPMC_DBGConfig(u32 MRCC_LPDM) { if(MRCC_LPDM == MRCC_LPDM_Enable) { MRCC->PWRCTRL |= MRCC_LPDM_Enable; } else { MRCC->PWRCTRL &= MRCC_LPDM_Disable; } } /******************************************************************************* * Function Name : MRCC_EnterWFIMode * Description : Enters WFI mode. * If the Flash is used in Burst mode, it must be kept enabled * in WFI mode(use MRCC_WFIParam_FLASHOn as parameter) * Input : - MRCC_WFIParam: specifies the WFI mode control parameters. * This parameter can be one of the following values: * - MRCC_WFIParam_FLASHPowerDown(DMA not allowed during WFI) * - MRCC_WFIParam_FLASHOn(DMA allowed during WFI) * - MRCC_WFIParam_FLASHOff(DMA not allowed during WFI) * Output : None * Return : None *******************************************************************************/ void MRCC_EnterWFIMode(u32 MRCC_WFIParam) { /* Low Power mode configuration ----------------------------------------------*/ /* Clear LPMC[1:0] bits */ MRCC->PWRCTRL &= MRCC_LPMC_Reset_Mask; /* Select WFI mode */ MRCC->PWRCTRL |= MRCC_WFI_Mask; /* Low Power mode control parameters configuration ---------------------------*/ /* Clear LP_PARAM[15:13] and WFI_FLASH_EN bits */ MRCC->PWRCTRL &= MRCC_WFIParam_Reset_Mask; if(MRCC_WFIParam != MRCC_WFIParam_FLASHPowerDown) { /* Set LP_PARAM[15:13] and WFI_FLASH_EN bits according to MRCC_WFIParam value */ MRCC->PWRCTRL |= MRCC_WFIParam; } /* Execute the Low Power bit writing sequence --------------------------------*/ WriteLPBit(); } /******************************************************************************* * Function Name : MRCC_EnterSTOPMode * Description : Enters STOP mode. * Input : - MRCC_STOPParam: specifies the STOP mode control parameters. * This parameter can be one of the following values: * - MRCC_STOPParam_Default (OSC4M On, FLASH On, MVREG On) * - MRCC_STOPParam_OSC4MOff * - MRCC_STOPParam_FLASHOff * - MRCC_STOPParam_MVREGOff * Output : None * Return : None *******************************************************************************/ void MRCC_EnterSTOPMode(u32 MRCC_STOPParam) { /* Low Power mode configuration ----------------------------------------------*/ /* Clear LPMC[1:0] bits (STOP mode is selected) */ MRCC->PWRCTRL &= MRCC_LPMC_Reset_Mask; /* Low Power mode control parameters configuration ---------------------------*/ /* Clear LP_PARAM[15:13] bits */ MRCC->PWRCTRL &= MRCC_LPPARAM_Reset_Mask; if(MRCC_STOPParam != MRCC_STOPParam_Default) { /* Set LP_PARAM[15:13] bits according to MRCC_STOPParam value */ MRCC->PWRCTRL |= MRCC_STOPParam; } /* Execute the Low Power bit writing sequence --------------------------------*/ WriteLPBit(); } /******************************************************************************* * Function Name : MRCC_EnterSTANDBYMode * Description : Enters STANDBY mode. * Make sure that WKPF flag is cleared before using this function. * Input : None * Output : None * Return : None *******************************************************************************/ void MRCC_EnterSTANDBYMode(void) { /* Low Power mode configuration ----------------------------------------------*/ /* Clear LPMC[1:0] bits */ MRCC->PWRCTRL &= MRCC_LPMC_Reset_Mask; /* Select STANDBY mode */ MRCC->PWRCTRL |= MRCC_STANDBY_Mask; /* Execute the Low Power bit writing sequence --------------------------------*/ WriteLPBit(); } /******************************************************************************* * Function Name : MRCC_GenerateSWReset * Description : Generates a system software reset. * Input : None * Output : None * Return : None *******************************************************************************/ void MRCC_GenerateSWReset(void) { /* Low Power mode configuration ----------------------------------------------*/ /* Clear LPMC[1:0] bits */ MRCC->PWRCTRL &= MRCC_LPMC_Reset_Mask; /* Select software reset */ MRCC->PWRCTRL |= MRCC_SWRESET_Mask; /* Execute the Low Power bit writing sequence --------------------------------*/ WriteLPBit(); } /******************************************************************************* * Function Name : MRCC_WriteBackupRegister * Description : Writes user data to the specified backup register. * Input : - MRCC_BKP: specifies the backup register. * This parameter can be one of the following values: * - MRCC_BKP0 * - MRCC_BKP1 * - Data: data to write. * Output : None * Return : None *******************************************************************************/ void MRCC_WriteBackupRegister(MRCC_BKPReg MRCC_BKP, u32 Data) { if(MRCC_BKP == MRCC_BKP0) { MRCC->BKP0 = Data; } else { MRCC->BKP1 = Data; } } /******************************************************************************* * Function Name : MRCC_ReadBackupRegister * Description : Reads data from the specified backup register. * Input : - MRCC_BKP: specifies the backup register. * This parameter can be one of the following values: * - MRCC_BKP0 * - MRCC_BKP1 * Output : None * Return : The content of the specified backup register. *******************************************************************************/ u32 MRCC_ReadBackupRegister(MRCC_BKPReg MRCC_BKP) { if(MRCC_BKP == MRCC_BKP0) { return(MRCC->BKP0); } else { return(MRCC->BKP1); } } /******************************************************************************* * Function Name : MRCC_IOVoltageRangeConfig * Description : Configures the I/O pins voltage range. * Input : - MRCC_IOVoltageRange: specifies the I/O pins voltage range. * This parameter can be one of the following values: * - MRCC_IOVoltageRange_5V * - MRCC_IOVoltageRange_3V3 * Output : None * Return : None *******************************************************************************/ void MRCC_IOVoltageRangeConfig(u32 MRCC_IOVoltageRange) { if(MRCC_IOVoltageRange == MRCC_IOVoltageRange_3V3) { MRCC->PWRCTRL |= MRCC_IOVoltageRange_3V3; } else { MRCC->PWRCTRL &= MRCC_IOVoltageRange_5V; } } /******************************************************************************* * Function Name : MRCC_MCOConfig * Description : Selects the clock source to output on MCO pin (P0.1). * To output the clock, the associated alternate function must * be enabled in the I/O port controller. * Input : - MRCC_MCO: specifies the clock source to output. * This parameter can be one of the following values: * - MRCC_MCO_HCLK * - MRCC_MCO_PCLK * - MRCC_MCO_OSC4M * - MRCC_MCO_CKPLL2 * - MRCC_MCOPrescaler: specifies if prescaler, divide by 1 or 2, * is applied to this clock before outputting it to MCO pin. * This parameter can be one of the following values: * - MRCC_MCOPrescaler_1 * - MRCC_MCOPrescaler_2 * Output : None * Return : None *******************************************************************************/ void MRCC_MCOConfig(u32 MRCC_MCO, u32 MCO_MCOPrescaler) { u32 Temp = 0; /* MCO prescaler configuration -----------------------------------------------*/ if(MCO_MCOPrescaler == MRCC_MCOPrescaler_2) { MRCC->CLKCTL |= MRCC_MCOPrescaler_2; } else { MRCC->CLKCTL &= MRCC_MCOPrescaler_1; } /* MCO selection configuration -----------------------------------------------*/ /* Clear MCOS[1:0] bits */ Temp = MRCC->CLKCTL & MRCC_MCOS_Reset_Mask; /* Set MCOS[1:0] bits according to MRCC_MCO value */ Temp |= MRCC_MCO; /* Store the new value */ MRCC->CLKCTL = Temp; } /******************************************************************************* * Function Name : MRCC_OSC4MConfig * Description : Configures the 4MHz main oscillator (OSC4M). * This function must be used when the CK_SYS is not clocked * by the OSC4M and the PLL is not enabled. * Input : - MRCC_OSC4M: specifies the new state of the OSC4M oscillator. * This parameter can be one of the following values: * - MRCC_OSC4M_Default: OSC4M enabled, bypass disabled * - MRCC_OSC4M_Disable: OSC4M disabled * - MRCC_OSC4M_Bypass: OSC4M bypassed * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_OSC4MConfig(u32 MRCC_OSC4M) { ErrorStatus Status = SUCCESS; /* If CK_SYS is driven by OSC4M or the PLL is enabled, exit ------------------*/ if(((MRCC->CLKCTL & MRCC_CKSEL_CKOSCSEL_Mask) == MRCC_CKSEL_Set_Mask) || (((MRCC->CLKCTL & MRCC_CKSEL_CKOSCSEL_Mask) == MRCC_CKSEL_CKOSCSEL_Mask) && ((MRCC->PWRCTRL & MRCC_CKRTCSEL_Reset_Mask) != RESET))|| ((MRCC->CLKCTL & MRCC_PLLEN_Set_Mask) != RESET)) { Status = ERROR; } /* Else configure the OSC4MOFF and OSC4MBYP bits -----------------------------*/ else { switch(MRCC_OSC4M) { case MRCC_OSC4M_Default: MRCC->CLKCTL &= MRCC_OSC4MOFF_Reset_Mask & MRCC_OSC4MBYP_Reset_Mask; break; case MRCC_OSC4M_Disable: MRCC->CLKCTL &= MRCC_OSC4MBYP_Reset_Mask; MRCC->CLKCTL |= MRCC_OSC4MOFF_Set_Mask; break; case MRCC_OSC4M_Bypass: MRCC->CLKCTL &= MRCC_OSC4MOFF_Reset_Mask; MRCC->CLKCTL |= MRCC_OSC4MBYP_Set_Mask; break; default: Status = ERROR; break; } } return Status; } /******************************************************************************* * Function Name : MRCC_OSC32KConfig * Description : Configures the OSC32K oscillator. * This function must be used when the CK_SYS is not clocked by * the CK_RTC. * Input : - MRCC_OSC32K: specifies the new state of the OSC32K oscillator. * This parameter can be one of the following values: * - MRCC_OSC32K_Disable: OSC32K disabled * - MRCC_OSC32K_Enable: OSC32K enabled * - MRCC_OSC32KBypass: specifies if the OSC32K oscillator is * bypassed or not. * This parameter can be one of the following values: * - MRCC_OSC32KBypass_Disable: OSC32K selected * - MRCC_OSC32KBypass_Enable: OSC32K bypassed * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_OSC32KConfig(u32 MRCC_OSC32K, u32 MRCC_OSC32KBypass) { /* If CK_SYS is driven by CK_RTC, exit ---------------------------------------*/ if(((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) && ((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET)) { return ERROR; } /* Else configure the OSC32KEN and OSC32KBYP bits ----------------------------*/ else { /* Configure OSC32KEN bit */ if(MRCC_OSC32K == MRCC_OSC32K_Enable) { MRCC->PWRCTRL |= MRCC_OSC32K_Enable; } else { MRCC->PWRCTRL &= MRCC_OSC32K_Disable; } /* Configure OSC32KBYP bit */ if(MRCC_OSC32KBypass == MRCC_OSC32KBypass_Enable) { MRCC->PWRCTRL |= MRCC_OSC32KBypass_Enable; } else { MRCC->PWRCTRL &= MRCC_OSC32KBypass_Disable; } return SUCCESS; } } /******************************************************************************* * Function Name : MRCC_LPOSCConfig * Description : Enables or disables the LPOSC oscillator. * This function must be used when the CK_SYS is not clocked by * the CK_RTC. * Input : - MRCC_LPOSC: specifies the new state of the LPOSC oscillator. * This parameter can be one of the following values: * - MRCC_LPOSC_Disable: LPOSC disabled * - MRCC_LPOSC_Enable: LPOSC enabled * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ ErrorStatus MRCC_LPOSCConfig(u32 MRCC_LPOSC) { /* If CK_SYS is driven by CK_RTC or LPOSC is used as CK_RTC clock source, exit*/ if((((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) && ((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET)) || ((MRCC->PWRCTRL & MRCC_CKRTCSEL_Set_Mask) == MRCC_CKRTC_LPOSC)) { return ERROR; } /* Else configure the LPOSCEN bit --------------------------------------------*/ else { if(MRCC_LPOSC == MRCC_LPOSC_Enable) { MRCC->PWRCTRL |= MRCC_LPOSC_Enable; } else { MRCC->PWRCTRL &= MRCC_LPOSC_Disable; } return SUCCESS; } } /******************************************************************************* * Function Name : MRCC_RTCMConfig * Description : Enables or disables RTC clock measurement. * Input : - MRCC_RTCM: specifies whether CK_RTC is connected to TB * timer IC1 or not. * This parameter can be one of the following values: * - MRCC_RTCM_Disable: CK_RTC not connected to TB timer IC1 * - MRCC_RTCM_Enable: CK_RTC connected to TB timer IC1 * Output : None * Return : None *******************************************************************************/ void MRCC_RTCMConfig(u32 MRCC_RTCM) { if(MRCC_RTCM == MRCC_RTCM_Enable) { MRCC->PWRCTRL |= MRCC_RTCM_Enable; } else { MRCC->PWRCTRL &= MRCC_RTCM_Disable; } } /******************************************************************************* * Function Name : MRCC_SetBuilderCounter * Description : Sets the builder counter value which defines the delay for * the 4MHz main oscillator (OSC4M) clock to be stabilized. * Input : - BuilderCounter: defines the delay for the OSC4M oscillator * clock to be stabilized. * Output : None * Return : None *******************************************************************************/ void MRCC_SetBuilderCounter(u8 BuilderCounter) { *(u8 *) 0x60000026 = BuilderCounter; } /******************************************************************************* * Function Name : MRCC_GetCKSYSCounter * Description : Gets the result of the delay applied to CK_SYS before * starting the CPU. * Input : None * Output : None * Return : SCOUNT value. *******************************************************************************/ u16 MRCC_GetCKSYSCounter(void) { return((u16)(MRCC->RFSR & 0x0FFF)); } /******************************************************************************* * Function Name : MRCC_GetFlagStatus * Description : Checks whether the specified MRCC flag is set or not. * Input : - MRCC_FLAG: specifies the flag to check. * This parameter can be one of the following values: * - MRCC_FLAG_LOCK: PLL Locked flag * - MRCC_FLAG_LOCKIF: PLL Lock Interrupt status flag * - MRCC_FLAG_CKSEL: CK_SYS source staus flag * - MRCC_FLAG_CKOSCSEL: CK_OSC clock source staus flag * - MRCC_FLAG_NCKD: No Clock Detected flag * - MRCC_FLAG_SWR: Software Reset flag * - MRCC_FLAG_WDGR: Watchdog Reset flag * - MRCC_FLAG_EXTR: External Reset flag * - MRCC_FLAG_WKP: Wake-Up flag * - MRCC_FLAG_STDB: STANDBY flag * - MRCC_FLAG_BCOUNT: Builder Counter Flag * - MRCC_FLAG_OSC32KRDY: Oscillator 32K Ready * - MRCC_FLAG_CKRTCOK: CK_RTC OK * - MRCC_FLAG_LPDONE: Low Power Bit Sequence has been performed * - MRCC_FLAG_LP: Low Power Mode Entry * Output : None * Return : The new state of MRCC_FLAG (SET or RESET). *******************************************************************************/ FlagStatus MRCC_GetFlagStatus(u8 MRCC_FLAG) { u32 MRCCReg = 0, FlagPos = 0; u32 StatusReg = 0; /* Get the MRCC register index */ MRCCReg = MRCC_FLAG >> 5; /* Get the flag position */ FlagPos = MRCC_FLAG & MRCC_FLAG_Mask; if(MRCCReg == 1) /* The flag to check is in CLKCTL register */ { StatusReg = MRCC->CLKCTL; } else if (MRCCReg == 2) /* The flag to check is in RFSR register */ { StatusReg = MRCC->RFSR; } else if(MRCCReg == 3) /* The flag to check is in PWRCTRL register */ { StatusReg = MRCC->PWRCTRL; } if((StatusReg & (1 << FlagPos))!= RESET) { return SET; } else { return RESET; } } /******************************************************************************* * Function Name : MRCC_ClearFlag * Description : Clears the MRCC’s pending flags. * Input : - MRCC_FLAG: specifies the flag to clear. * This parameter can be one of the following values: * - MRCC_FLAG_NCKD: No Clock Detected flag * - MRCC_FLAG_SWR: Software Reset flag * - MRCC_FLAG_WDGR: Watchdog Reset flag * - MRCC_FLAG_EXTR: External Reset flag * - MRCC_FLAG_WKP: Wake-Up flag * - MRCC_FLAG_STDB: STANDBY flag * - MRCC_FLAG_LPDONE: Low Power Bit Sequence has been performed * Output : None * Return : None *******************************************************************************/ void MRCC_ClearFlag(u8 MRCC_FLAG) { u32 MRCCReg = 0, FlagPos = 0; /* Get the MRCC register index */ MRCCReg = MRCC_FLAG >> 5; /* Get the flag position */ FlagPos = MRCC_FLAG & MRCC_FLAG_Mask; if(MRCCReg == 1) /* The flag to clear is in CLKCTL register */ { MRCC->CLKCTL &= ~(1 << FlagPos); } else if (MRCCReg == 2) /* The flag to clear is in RFSR register */ { MRCC->RFSR &= ~(1 << FlagPos); } else if(MRCCReg == 3) /* The flag to clear is in PWRCTRL register */ { MRCC->PWRCTRL &= ~(1 << FlagPos); } } /******************************************************************************* * Function Name : MRCC_GetITStatus * Description : Checks whether the specified MRCC interrupt has occurred or not. * Input : - MRCC_IT: specifies the MRCC interrupt source to check. * This parameter can be one of the following values: * - MRCC_IT_LOCK: PLL lock interrupt * - MRCC_IT_NCKD: No Clock detected interrupt * Output : None * Return : The new state of MRCC_IT (SET or RESET). *******************************************************************************/ ITStatus MRCC_GetITStatus(u32 MRCC_IT) { /* Check the specified interrupt pending bit */ if((MRCC->CLKCTL & (MRCC_IT >> 1)) != RESET) { return SET; } else { return RESET; } } /******************************************************************************* * Function Name : MRCC_ClearITPendingBit * Description : Clears the MRCC’s interrupt pending bits. * Input : - MRCC_IT: specifies the interrupt pending bit to clear. * This parameter can be any combination of the following * values: * - MRCC_IT_LOCK: PLL lock interrupt * - MRCC_IT_NCKD: No Clock detected interrupt * Output : None * Return : None *******************************************************************************/ void MRCC_ClearITPendingBit(u32 MRCC_IT) { /* Clear the specified interrupt pending bit */ MRCC->CLKCTL &= ~(MRCC_IT >> 1); } /******************************************************************************* * Function Name : MRCC_WaitForOSC4MStartUp * Description : Waits for OSC4M start-up. * Input : None * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: OSC4M oscillator is stable and ready to use * - ERROR: no clock is detected on OSC4M *******************************************************************************/ ErrorStatus MRCC_WaitForOSC4MStartUp(void) { u32 StartUpCounter = 0; do { /* Clear No Clock Detected flag */ if(MRCC_GetFlagStatus(MRCC_FLAG_NCKD) != RESET) { MRCC_ClearFlag(MRCC_FLAG_NCKD); } StartUpCounter++; }while((MRCC_GetFlagStatus(MRCC_FLAG_BCOUNT) == RESET)&& (StartUpCounter != OSC4MStartUp_TimeOut)); if(MRCC_GetFlagStatus(MRCC_FLAG_BCOUNT) != RESET) { return SUCCESS; } else { return ERROR; } } /******************************************************************************* * Function Name : SetCKSYS_FREEOSC * Description : Selects FREEOSC as CK_SYS clock source. * Input : None * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ static ErrorStatus SetCKSYS_FREEOSC(void) { /* Check if the PLL is enabled */ if((MRCC->CLKCTL & MRCC_PLLEN_Set_Mask) != RESET) { if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) == RESET) { /* CK_PLL1 used as Ck_SYS clock source*/ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) {/* Check if CK_RTC source clock is present*/ if((MRCC->PWRCTRL & MRCC_CKRTCSEL_Set_Mask) == RESET) { /* CK_RTC disabled*/ return ERROR; } } /* Select CK_OSC as CK_SYS clock source */ MRCC->CLKCTL |= MRCC_CKSEL_Set_Mask; } /* Disable PLL */ MRCC->CLKCTL &= MRCC_PLLEN_Reset_Mask; } /* Select CK_PLL1 as CK_SYS clock source */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) == RESET) { return SUCCESS; } else { return ERROR; } } /******************************************************************************* * Function Name : SetCKSYS_OSC4M * Description : Selects 4MHz main oscillator (OSC4M) as CK_SYS clock source. * Input : PLL_State: specifies the PLL state. * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ static ErrorStatus SetCKSYS_OSC4M(u32 PLL_State) { /* If OSC4M is not present, exit ---------------------------------------------*/ if(((MRCC->CLKCTL & MRCC_NCKDF_Set_Mask) != RESET) || ((MRCC->CLKCTL & MRCC_OSC4MOFF_Set_Mask) != RESET) ) { /* OSC4M disabled or OSC4M clock is not present*/ return ERROR; } /* Else configure CKSEL and CKOSCSEL bits ------------------------------------*/ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { /* CK_RTC used as CK_OSC clock */ if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) { /* Select CK_PLL1 as CK_SYS clock source */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; } /* Clear CKOSCSEL bit ----------------------------------------------------*/ /* Execute CKOSCSEL bit writing sequence */ WriteCKOSCSELBit(); /* Check if CKOSCSEL is set to 0 */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { return ERROR; } } /* Select CK_OSC as CK_SYS clock source */ MRCC->CLKCTL |= MRCC_CKSEL_Set_Mask; if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) { if(PLL_State == MRCC_PLL_Disabled) { /* Disable PLL */ MRCC->CLKCTL &= MRCC_PLLEN_Reset_Mask; } return SUCCESS; } else { return ERROR; } } /******************************************************************************* * Function Name : SetCKSYS_OSC4MPLL * Description : Selects 4MHz main oscillator (OSC4M) followed by PLL as * CK_SYS clock source. * Input : PLL_Mul: specifies the PLL factor. * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ static ErrorStatus SetCKSYS_OSC4MPLL(u32 PLL_Mul) { /* Check if 4MHz main oscillator clock is present */ if(((MRCC->CLKCTL & MRCC_NCKDF_Set_Mask) == RESET) && ((MRCC->CLKCTL & MRCC_OSC4MOFF_Set_Mask) == RESET)) { if(((MRCC->CLKCTL & MRCC_PLLEN_Set_Mask) != RESET) && ((MRCC->CLKCTL & MRCC_MX_Set_Mask) == PLL_Mul)) { /* Select CK_PLL1 as CK_SYS clock source */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) == RESET) { return SUCCESS; } else { return ERROR; } } else { /* If CK_RTC is selected as CK_OSC clock source */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) { /* Clear CKSEL bit */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; } /* Clear CKOSCSEL bit ------------------------------------------------*/ /* Execute CKOSCSEL bit writing sequence */ WriteCKOSCSELBit(); /* Check if CKOSCSEL is set to 0 */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) != RESET) { return ERROR; } } /* Select CK_OSC as CK_SYS clock source */ MRCC->CLKCTL |= MRCC_CKSEL_Set_Mask; /* Disable PLL */ MRCC->CLKCTL &= MRCC_PLLEN_Reset_Mask; /* Configure PLL factor */ if(PLL_Mul == MRCC_PLL_Mul_16) { MRCC->CLKCTL &= MRCC_MX_Reset_Mask; } else if((PLL_Mul == MRCC_PLL_Mul_15) || (PLL_Mul == MRCC_PLL_Mul_14) || (PLL_Mul == MRCC_PLL_Mul_12)) { /* Clear MX[1:0] bits */ MRCC->CLKCTL &= MRCC_MX_Reset_Mask; /* Set MX[1:0] bits according to PLL_Mul value */ MRCC->CLKCTL |= PLL_Mul; } if(Main_Oscillator == 4000000) {/* 4 MHz external Quartz oscillator used as main oscillator */ /* Disable Oscillator Divider by 2 */ MRCC->CLKCTL &= MRCC_XTDIV2_Reset_Mask; } else if(Main_Oscillator == 8000000) {/* 8 MHz external Quartz oscillator used as main oscillator */ /* Enable Oscillator Divider by 2 */ MRCC->CLKCTL |= MRCC_XTDIV2_Set_Mask; } /* Enable PLL */ MRCC->CLKCTL |= MRCC_PLLEN_Set_Mask; /* Wait until the PLL is locked */ while((MRCC->CLKCTL & MRCC_LOCK_Mask) == RESET) { /* If OSC4M clock disapear or the PLL is disabled, exit */ if(((MRCC->CLKCTL & MRCC_NCKDF_Set_Mask) != RESET) || ((MRCC->CLKCTL & MRCC_PLLEN_Set_Mask) == RESET)) { return ERROR; } } /* Select CK_PLL1 as CK_SYS clock source */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) == RESET) { return SUCCESS; } else { return ERROR; } } } else { /* OSC4M disabled or OSC4M clock is not present*/ return ERROR; } } /******************************************************************************* * Function Name : SetCKSYS_RTC * Description : Selects RTC clock (CK_RTC) as CK_SYS clock source. * Input : PLL_State: specifies the PLL state. * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Clock configuration succeeded * - ERROR: Clock configuration failed *******************************************************************************/ static ErrorStatus SetCKSYS_RTC(u32 PLL_State) { /* Check if CK_RTC clock is enabled and ready to use */ if(((MRCC->PWRCTRL & MRCC_CKRTCSEL_Set_Mask) != RESET)|| ((MRCC->CLKCTL & MRCC_CKRTCOK_Mask) == RESET)) { /* Configure CK_RTC as Ck_SYS clock source -----------------------------------*/ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) == RESET) { /* Select CK_PLL1 as CK_SYS clock source */ MRCC->CLKCTL &= MRCC_CKSEL_Reset_Mask; /* Set CKOSCSEL bit ----------------------------------------------------*/ /* Execute CKOSCSEL bit writing sequence */ WriteCKOSCSELBit(); /* Check if CKOSCSEL is set to 1 */ if((MRCC->CLKCTL & MRCC_CKOSCSEL_Set_Mask) == RESET) { return ERROR; } } /* Select CK_OSC as CK_SYS clock source */ MRCC->CLKCTL |= MRCC_CKSEL_Set_Mask; if((MRCC->CLKCTL & MRCC_CKSEL_Set_Mask) != RESET) { if(PLL_State == MRCC_PLL_Disabled) { /* Disable PLL */ MRCC->CLKCTL &= MRCC_PLLEN_Reset_Mask; } return SUCCESS; } else { return ERROR; } } else { /* CK_RTC disabled */ return ERROR; } } /******************************************************************************* * Function Name : WriteLPBit * Description : Executes the Low Power bit writing sequence. * Input : None * Output : None * Return : None *******************************************************************************/ static void WriteLPBit(void) { u32 Tmp = 0, Tmp1 = 0, Tmp2 = 0; /* Clear LP_DONE flag */ MRCC->PWRCTRL &= MRCC_LPDONE_Reset_Mask; Tmp = MRCC->PWRCTRL; Tmp1 = Tmp | MRCC_LP_Set_Mask; Tmp2 = Tmp & MRCC_LP_Reset_Mask; /* Set LP bit */ MRCC->PWRCTRL = Tmp1; /* Set LP bit */ MRCC->PWRCTRL = Tmp1; /* Reset LP bit */ MRCC->PWRCTRL = Tmp2; /* Set LP bit */ MRCC->PWRCTRL = Tmp1; /* Read LP bit*/ Tmp = MRCC->PWRCTRL; } /******************************************************************************* * Function Name : WriteCKOSCSELBit * Description : Executes the CKOSCSEL bit writing sequence. * Input : None * Output : None * Return : None *******************************************************************************/ static void WriteCKOSCSELBit(void) { u32 Tmp = 0, Tmp1 = 0, Tmp2 = 0; Tmp = MRCC->CLKCTL; Tmp1 = Tmp | MRCC_CKOSCSEL_Set_Mask; Tmp2 = Tmp & MRCC_CKOSCSEL_Reset_Mask; /* Set CKOSCSEL bit */ MRCC->CLKCTL = Tmp1; /* Set CKOSCSEL bit */ MRCC->CLKCTL = Tmp1; /* Reset CKOSCSEL bit */ MRCC->CLKCTL = Tmp2; /* Set CKOSCSEL bit */ MRCC->CLKCTL = Tmp1; /* Read CKOSCSEL bit */ Tmp = MRCC->CLKCTL; } /******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/
Go to most recent revision | Compare with Previous | Blame | View Log