/** * @brief Return I2Sx clock frequency * @param I2SxSource This parameter can be one of the following values: * @arg @ref LL_RCC_I2S1_CLKSOURCE * @retval I2S clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that PLLI2S oscillator is not ready */ uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource) { uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource)); if (I2SxSource == LL_RCC_I2S1_CLKSOURCE) { /* I2S1 CLK clock frequency */ switch (LL_RCC_GetI2SClockSource(I2SxSource)) { case LL_RCC_I2S1_CLKSOURCE_PLLI2S: /* I2S1 Clock is PLLI2S */ if (LL_RCC_PLLI2S_IsReady()) { i2s_frequency = RCC_PLLI2S_GetFreqDomain_I2S(); } break; case LL_RCC_I2S1_CLKSOURCE_PIN: /* I2S1 Clock is External clock */ default: i2s_frequency = EXTERNAL_CLOCK_VALUE; break; } } return i2s_frequency; }
static int i2s_stm32_set_clock(struct device *dev, u32_t bit_clk_freq) { const struct i2s_stm32_cfg *cfg = DEV_CFG(dev); u32_t pll_src = LL_RCC_PLL_GetMainSource(); int freq_in; u8_t i2s_div, i2s_odd; freq_in = (pll_src == LL_RCC_PLLSOURCE_HSI) ? HSI_VALUE : CONFIG_CLOCK_STM32_HSE_CLOCK; #ifdef CONFIG_I2S_STM32_USE_PLLI2S_ENABLE /* Set PLLI2S */ LL_RCC_PLLI2S_Disable(); LL_RCC_PLLI2S_ConfigDomain_I2S(pll_src, CONFIG_I2S_STM32_PLLI2S_PLLM, CONFIG_I2S_STM32_PLLI2S_PLLN, pllr(CONFIG_I2S_STM32_PLLI2S_PLLR)); LL_RCC_PLLI2S_Enable(); /* wait until PLLI2S gets locked */ while (!LL_RCC_PLLI2S_IsReady()) { if (plli2s_ms_count++ > PLLI2S_MAX_MS_TIME) { return -EIO; } /* wait 1 ms */ k_sleep(1); } LOG_DBG("PLLI2S is locked"); /* Adjust freq_in according to PLLM, PLLN, PLLR */ float freq_tmp; freq_tmp = freq_in / CONFIG_I2S_STM32_PLLI2S_PLLM; freq_tmp *= CONFIG_I2S_STM32_PLLI2S_PLLN; freq_tmp /= CONFIG_I2S_STM32_PLLI2S_PLLR; freq_in = (int) freq_tmp; #endif /* CONFIG_I2S_STM32_USE_PLLI2S_ENABLE */ /* Select clock source */ LL_RCC_SetI2SClockSource(cfg->i2s_clk_sel); /* * The ratio between input clock (I2SxClk) and output * clock on the pad (I2S_CK) is obtained using the * following formula: * (i2s_div * 2) + i2s_odd */ i2s_div = div_round_closest(freq_in, bit_clk_freq); i2s_odd = (i2s_div & 0x1) ? 1 : 0; i2s_div >>= 1; LOG_DBG("i2s_div: %d - i2s_odd: %d", i2s_div, i2s_odd); LL_I2S_SetPrescalerLinear(cfg->i2s, i2s_div); LL_I2S_SetPrescalerParity(cfg->i2s, i2s_odd); return 0; }
/** * @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; }
/** * @brief Return SPDIFRX clock frequency * @param SPDIFRXxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SPDIFRX1_CLKSOURCE * @retval SPDIFRX clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSPDIFRXClockFreq(uint32_t SPDIFRXxSource) { uint32_t spdifrx_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_SPDIFRX_CLKSOURCE(SPDIFRXxSource)); if (LL_RCC_PLLI2S_IsReady()) { spdifrx_frequency = RCC_PLLI2S_GetFreqDomain_SPDIFRX(); } return spdifrx_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 * @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_PLLSAI: /* PLLSAI clock used as SAI1 clock source */ if (LL_RCC_PLLSAI_IsReady()) { sai_frequency = RCC_PLLSAI_GetFreqDomain_SAI(); } break; case LL_RCC_SAI1_CLKSOURCE_PLLI2S: /* PLLI2S clock used as SAI1 clock source */ if (LL_RCC_PLLI2S_IsReady()) { sai_frequency = RCC_PLLI2S_GetFreqDomain_SAI(); } break; #if defined(RCC_SAI1SEL_PLLSRC_SUPPORT) case LL_RCC_SAI1_CLKSOURCE_PLLSRC: switch (LL_RCC_PLL_GetMainSource()) { case LL_RCC_PLLSOURCE_HSE: /* HSE clock used as SAI1 clock source */ if (LL_RCC_HSE_IsReady()) { sai_frequency = HSE_VALUE; } break; case LL_RCC_PLLSOURCE_HSI: /* HSI clock used as SAI1 clock source */ default: if (LL_RCC_HSI_IsReady()) { sai_frequency = HSI_VALUE; } break; } break; #endif /* RCC_SAI1SEL_PLLSRC_SUPPORT */ 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 (SAIxSource == LL_RCC_SAI2_CLKSOURCE) { /* SAI2CLK clock frequency */ switch (LL_RCC_GetSAIClockSource(SAIxSource)) { case LL_RCC_SAI2_CLKSOURCE_PLLSAI: /* PLLSAI clock used as SAI2 clock source */ if (LL_RCC_PLLSAI_IsReady()) { sai_frequency = RCC_PLLSAI_GetFreqDomain_SAI(); } break; case LL_RCC_SAI2_CLKSOURCE_PLLI2S: /* PLLI2S clock used as SAI2 clock source */ if (LL_RCC_PLLI2S_IsReady()) { sai_frequency = RCC_PLLI2S_GetFreqDomain_SAI(); } break; #if defined(RCC_SAI2SEL_PLLSRC_SUPPORT) case LL_RCC_SAI2_CLKSOURCE_PLLSRC: switch (LL_RCC_PLL_GetMainSource()) { case LL_RCC_PLLSOURCE_HSE: /* HSE clock used as SAI2 clock source */ if (LL_RCC_HSE_IsReady()) { sai_frequency = HSE_VALUE; } break; case LL_RCC_PLLSOURCE_HSI: /* HSI clock used as SAI2 clock source */ default: if (LL_RCC_HSI_IsReady()) { sai_frequency = HSI_VALUE; } break; } break; #endif /* RCC_SAI2SEL_PLLSRC_SUPPORT */ case LL_RCC_SAI2_CLKSOURCE_PIN: /* External input clock used as SAI2 clock source */ default: sai_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; } } } return sai_frequency; }