/** * @brief Return DSI clock frequency * @param DSIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_DSI_CLKSOURCE * @retval DSI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that external clock is used */ uint32_t LL_RCC_GetDSIClockFreq(uint32_t DSIxSource) { uint32_t dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_DSI_CLKSOURCE(DSIxSource)); /* DSICLK clock frequency */ switch (LL_RCC_GetDSIClockSource(DSIxSource)) { case LL_RCC_DSI_CLKSOURCE_PLL: /* DSI Clock is PLL Osc. */ if (LL_RCC_PLL_IsReady()) { dsi_frequency = RCC_PLL_GetFreqDomain_DSI(); } break; case LL_RCC_DSI_CLKSOURCE_PHY: /* DSI Clock is DSI physical clock. */ default: dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; } return dsi_frequency; }
/** * @brief Return USBx clock frequency * @param USBxSource This parameter can be one of the following values: * @arg @ref LL_RCC_USB_CLKSOURCE * @retval USB clock frequency (in Hz) * @arg @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI48) or PLL is not ready * @arg @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected */ uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource) { uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource)); /* USBCLK clock frequency */ switch (LL_RCC_GetUSBClockSource(USBxSource)) { case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */ if (LL_RCC_PLL_IsReady()) { usb_frequency = RCC_PLL_GetFreqDomain_SYS(); } break; case LL_RCC_USB_CLKSOURCE_HSI48: /* HSI48 clock used as USB clock source */ default: if (LL_RCC_HSI48_IsReady()) { usb_frequency = HSI48_VALUE; } break; } return usb_frequency; }
/** * @brief Return RNGx clock frequency * @param RNGxSource This parameter can be one of the following values: * @arg @ref LL_RCC_RNG_CLKSOURCE * @retval RNG clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource) { uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource)); /* RNGCLK clock frequency */ switch (LL_RCC_GetRNGClockSource(RNGxSource)) { case LL_RCC_RNG_CLKSOURCE_PLL: /* PLL clock used as RNG clock source */ if (LL_RCC_PLL_IsReady()) { rng_frequency = RCC_PLL_GetFreqDomain_48M(); } break; case LL_RCC_RNG_CLKSOURCE_PLLSAI: /* PLLSAI clock used as RNG clock source */ default: if (LL_RCC_PLLSAI_IsReady()) { rng_frequency = RCC_PLLSAI_GetFreqDomain_48M(); } break; } return rng_frequency; }
/** * @brief Reset the RCC clock configuration to the default reset state. * @note The default reset state of the clock configuration is given below: * - HSI ON and used as system clock source * - HSE, PLL, PLLI2S, PLLSAI OFF * - AHB, APB1 and APB2 prescaler set to 1. * - CSS, MCO OFF * - All interrupts disabled * @note This function doesn't modify the configuration of the * - Peripheral clocks * - LSI, LSE and RTC clocks * @retval An ErrorStatus enumeration value: * - SUCCESS: RCC registers are de-initialized * - ERROR: not applicable */ ErrorStatus LL_RCC_DeInit(void) { uint32_t vl_mask = 0xFFFFFFFFU; /* Set HSION bit */ LL_RCC_HSI_Enable(); /* Wait for HSI READY bit */ while(LL_RCC_HSI_IsReady() != 1U) {} /* Reset CFGR register */ LL_RCC_WriteReg(CFGR, 0x00000000U); /* Reset HSEON, HSEBYP, PLLON, CSSON, PLLI2SON and PLLSAION bits */ CLEAR_BIT(vl_mask, (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_PLLSAION | RCC_CR_PLLI2SON)); /* Write new mask in CR register */ LL_RCC_WriteReg(CR, vl_mask); /* Set HSITRIM bits to the reset value*/ LL_RCC_HSI_SetCalibTrimming(0x10U); /* Wait for PLL READY bit to be reset */ while(LL_RCC_PLL_IsReady() != 0U) {} /* Wait for PLLI2S READY bit to be reset */ while(LL_RCC_PLLI2S_IsReady() != 0U) {} /* Wait for PLLSAI READY bit to be reset */ while(LL_RCC_PLLSAI_IsReady() != 0U) {} /* Reset PLLCFGR register */ LL_RCC_WriteReg(PLLCFGR, 0x24003010U); /* Reset PLLI2SCFGR register */ LL_RCC_WriteReg(PLLI2SCFGR, 0x24003000U); /* Reset PLLSAICFGR register */ LL_RCC_WriteReg(PLLSAICFGR, 0x24003000U); /* Disable all interrupts */ CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE | RCC_CIR_PLLI2SRDYIE | RCC_CIR_PLLSAIRDYIE); /* Clear all interrupt flags */ SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_PLLI2SRDYC | RCC_CIR_PLLSAIRDYC | RCC_CIR_CSSC); /* Clear LSION bit */ CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); /* Reset all CSR flags */ SET_BIT(RCC->CSR, RCC_CSR_RMVF); return SUCCESS; }
void clock_config(void) { LL_RCC_HSE_Enable(); while (!LL_RCC_HSE_IsReady()); LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLL_MUL_9); LL_RCC_PLL_Disable(); LL_RCC_PLL_Enable(); while (!LL_RCC_PLL_IsReady()); LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2); LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_4); LL_FLASH_SetLatency(LL_FLASH_LATENCY_2); LL_FLASH_EnablePrefetch(); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); SystemCoreClockUpdate(); LL_Init1msTick(SystemCoreClock); }
/** * @brief Return RNGx clock frequency * @param RNGxSource This parameter can be one of the following values: * @arg @ref LL_RCC_RNG_CLKSOURCE * @retval RNG clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected */ uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource) { uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource)); /* RNGCLK clock frequency */ switch (LL_RCC_GetRNGClockSource(RNGxSource)) { case LL_RCC_RNG_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as RNG clock source */ if (LL_RCC_PLLSAI1_IsReady()) { rng_frequency = RCC_PLLSAI1_GetFreqDomain_48M(); } break; case LL_RCC_RNG_CLKSOURCE_PLL: /* PLL clock used as RNG clock source */ if (LL_RCC_PLL_IsReady()) { rng_frequency = RCC_PLL_GetFreqDomain_48M(); } break; case LL_RCC_RNG_CLKSOURCE_MSI: /* MSI clock used as RNG clock source */ if (LL_RCC_MSI_IsReady()) { rng_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), (LL_RCC_MSI_IsEnabledRangeSelect() ? LL_RCC_MSI_GetRange() : LL_RCC_MSI_GetRangeAfterStandby())); } break; case LL_RCC_RNG_CLKSOURCE_NONE: /* No clock used as RNG clock source */ default: rng_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; } return rng_frequency; }
/** * @brief Return SAIx clock frequency * @param SAIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SAI1_CLKSOURCE * @arg @ref LL_RCC_SAI2_CLKSOURCE (*) * * (*) value not defined in all devices. * @retval SAI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that PLL is not ready * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that external clock is used */ uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource) { uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource)); if (SAIxSource == LL_RCC_SAI1_CLKSOURCE) { /* SAI1CLK clock frequency */ switch (LL_RCC_GetSAIClockSource(SAIxSource)) { case LL_RCC_SAI1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI1 clock source */ if (LL_RCC_PLLSAI1_IsReady()) { sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI(); } break; #if defined(RCC_PLLSAI2_SUPPORT) case LL_RCC_SAI1_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI1 clock source */ if (LL_RCC_PLLSAI2_IsReady()) { sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI(); } break; #endif /* RCC_PLLSAI2_SUPPORT */ case LL_RCC_SAI1_CLKSOURCE_PLL: /* PLL clock used as SAI1 clock source */ if (LL_RCC_PLL_IsReady()) { sai_frequency = RCC_PLL_GetFreqDomain_SAI(); } break; case LL_RCC_SAI1_CLKSOURCE_PIN: /* External input clock used as SAI1 clock source */ default: sai_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; } } else { #if defined(RCC_CCIPR_SAI2SEL) if (SAIxSource == LL_RCC_SAI2_CLKSOURCE) { /* SAI2CLK clock frequency */ switch (LL_RCC_GetSAIClockSource(SAIxSource)) { case LL_RCC_SAI2_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI2 clock source */ if (LL_RCC_PLLSAI1_IsReady()) { sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI(); } break; #if defined(RCC_PLLSAI2_SUPPORT) case LL_RCC_SAI2_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI2 clock source */ if (LL_RCC_PLLSAI2_IsReady()) { sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI(); } break; #endif /* RCC_PLLSAI2_SUPPORT */ case LL_RCC_SAI2_CLKSOURCE_PLL: /* PLL clock used as SAI2 clock source */ if (LL_RCC_PLL_IsReady()) { sai_frequency = RCC_PLL_GetFreqDomain_SAI(); } break; case LL_RCC_SAI2_CLKSOURCE_PIN: /* External input clock used as SAI2 clock source */ default: sai_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; } } #endif /*RCC_CCIPR_SAI2SEL*/ } return sai_frequency; }
/** * @brief Return SDMMCx clock frequency * @param SDMMCxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SDMMC1_CLKSOURCE * @arg @ref LL_RCC_SDMMC2_CLKSOURCE (*) * * (*) value not defined in all devices. * @retval SDMMC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator PLL is not ready */ uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource) { uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_SDMMC_CLKSOURCE(SDMMCxSource)); if (SDMMCxSource == LL_RCC_SDMMC1_CLKSOURCE) { /* SDMMC1CLK clock frequency */ switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) { case LL_RCC_SDMMC1_CLKSOURCE_PLL48CLK: /* PLL48 clock used as SDMMC1 clock source */ switch (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE)) { case LL_RCC_CK48M_CLKSOURCE_PLL: /* PLL clock used as 48Mhz domain clock */ if (LL_RCC_PLL_IsReady()) { sdmmc_frequency = RCC_PLL_GetFreqDomain_48M(); } break; case LL_RCC_CK48M_CLKSOURCE_PLLSAI: /* PLLSAI clock used as 48Mhz domain clock */ default: if (LL_RCC_PLLSAI_IsReady()) { sdmmc_frequency = RCC_PLLSAI_GetFreqDomain_48M(); } break; } break; case LL_RCC_SDMMC1_CLKSOURCE_SYSCLK: /* PLL clock used as SDMMC1 clock source */ default: sdmmc_frequency = RCC_GetSystemClockFreq(); break; } } #if defined(SDMMC2) else { /* SDMMC2CLK clock frequency */ switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) { case LL_RCC_SDMMC2_CLKSOURCE_PLL48CLK: /* PLL48 clock used as SDMMC2 clock source */ switch (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE)) { case LL_RCC_CK48M_CLKSOURCE_PLL: /* PLL clock used as 48Mhz domain clock */ if (LL_RCC_PLL_IsReady()) { sdmmc_frequency = RCC_PLL_GetFreqDomain_48M(); } break; case LL_RCC_CK48M_CLKSOURCE_PLLSAI: /* PLLSAI clock used as 48Mhz domain clock */ default: if (LL_RCC_PLLSAI_IsReady()) { sdmmc_frequency = RCC_PLLSAI_GetFreqDomain_48M(); } break; } break; case LL_RCC_SDMMC2_CLKSOURCE_SYSCLK: /* PLL clock used as SDMMC2 clock source */ default: sdmmc_frequency = RCC_GetSystemClockFreq(); break; } } #endif /* SDMMC2 */ return sdmmc_frequency; }
static int usb_dc_stm32_clock_enable(void) { struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); struct stm32_pclken pclken = { #ifdef DT_USB_HS_BASE_ADDRESS .bus = STM32_CLOCK_BUS_AHB1, .enr = LL_AHB1_GRP1_PERIPH_OTGHS #else /* DT_USB_HS_BASE_ADDRESS */ #ifdef USB .bus = STM32_CLOCK_BUS_APB1, .enr = LL_APB1_GRP1_PERIPH_USB, #else /* USB_OTG_FS */ #ifdef CONFIG_SOC_SERIES_STM32F1X .bus = STM32_CLOCK_BUS_AHB1, .enr = LL_AHB1_GRP1_PERIPH_OTGFS, #else .bus = STM32_CLOCK_BUS_AHB2, .enr = LL_AHB2_GRP1_PERIPH_OTGFS, #endif /* CONFIG_SOC_SERIES_STM32F1X */ #endif /* USB */ #endif /* DT_USB_HS_BASE_ADDRESS */ }; /* * Some SoCs in STM32F0/L0/L4 series disable USB clock by * default. We force USB clock source to MSI or PLL clock for this * SoCs. However, if these parts have an HSI48 clock, use * that instead. Example reference manual RM0360 for * STM32F030x4/x6/x8/xC and STM32F070x6/xB. */ #if defined(RCC_HSI48_SUPPORT) /* * In STM32L0 series, HSI48 requires VREFINT and its buffer * with 48 MHz RC to be enabled. * See ENREF_HSI48 in referenc maual RM0367 section10.2.3: * "Reference control and status register (SYSCFG_CFGR3)" */ #ifdef CONFIG_SOC_SERIES_STM32L0X if (LL_APB2_GRP1_IsEnabledClock(LL_APB2_GRP1_PERIPH_SYSCFG)) { LL_SYSCFG_VREFINT_EnableHSI48(); } else { LOG_ERR("System Configuration Controller clock is " "disabled. Unable to enable VREFINT which " "is required by HSI48."); } #endif /* CONFIG_SOC_SERIES_STM32L0X */ LL_RCC_HSI48_Enable(); while (!LL_RCC_HSI48_IsReady()) { /* Wait for HSI48 to become ready */ } LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_HSI48); #elif defined(LL_RCC_USB_CLKSOURCE_NONE) /* When MSI is configured in PLL mode with a 32.768 kHz clock source, * the MSI frequency can be automatically trimmed by hardware to reach * better than ±0.25% accuracy. In this mode the MSI can feed the USB * device. For now, we only use MSI for USB if not already used as * system clock source. */ #if defined(CONFIG_CLOCK_STM32_MSI_PLL_MODE) && !defined(CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI) LL_RCC_MSI_Enable(); while (!LL_RCC_MSI_IsReady()) { /* Wait for MSI to become ready */ } /* Force 48 MHz mode */ LL_RCC_MSI_EnableRangeSelection(); LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11); LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_MSI); #else if (LL_RCC_PLL_IsReady()) { LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL); } else { LOG_ERR("Unable to set USB clock source to PLL."); } #endif /* CONFIG_CLOCK_STM32_MSI_PLL_MODE && !CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI */ #endif /* RCC_HSI48_SUPPORT / LL_RCC_USB_CLKSOURCE_NONE */ if (clock_control_on(clk, (clock_control_subsys_t *)&pclken) != 0) { LOG_ERR("Unable to enable USB clock"); return -EIO; } #ifdef DT_USB_HS_BASE_ADDRESS #ifdef DT_COMPAT_ST_STM32_USBPHYC LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_OTGHSULPI); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_OTGPHYC); #else /* Disable ULPI interface (for external high-speed PHY) clock */ LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_OTGHSULPI); LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI); #endif /* DT_COMPAT_ST_STM32_USBPHYC */ #endif /* DT_USB_HS_BASE_ADDRESS */ return 0; } #if defined(USB_OTG_FS) || defined(USB_OTG_HS) static u32_t usb_dc_stm32_get_maximum_speed(void) { /* * If max-speed is not passed via DT, set it to USB controller's * maximum hardware capability. */ #if defined(DT_COMPAT_ST_STM32_USBPHYC) && defined(DT_USB_HS_BASE_ADDRESS) u32_t speed = USB_OTG_SPEED_HIGH; #else u32_t speed = USB_OTG_SPEED_FULL; #endif /* DT_COMPAT_ST_STM32_USBPHYC && DT_USB_HS_BASE_ADDRESS */ #ifdef DT_USB_MAXIMUM_SPEED if (!strncmp(DT_USB_MAXIMUM_SPEED, "high-speed", 10)) { speed = USB_OTG_SPEED_HIGH; } else if (!strncmp(DT_USB_MAXIMUM_SPEED, "full-speed", 10)) { #if defined(DT_COMPAT_ST_STM32_USBPHYC) && defined(DT_USB_HS_BASE_ADDRESS) speed = USB_OTG_SPEED_HIGH_IN_FULL; #else speed = USB_OTG_SPEED_FULL; #endif /* DT_COMPAT_ST_STM32_USBPHYC && DT_USB_HS_BASE_ADDRESS */ } else if (!strncmp(DT_USB_MAXIMUM_SPEED, "low-speed", 9)) { speed = USB_OTG_SPEED_LOW; } else { LOG_DBG("Unsupported maximum speed defined in device tree. " "USB controller will default to its maximum HW " "capability"); } #endif /* DT_USB_MAXIMUM_SPEED */ return speed; }