/* Write the Configuration Register. * This updates the states of the corresponding clocks. The bit values are not * saved - when the register is read, its value will be built using the clock * states. */ static void stm32_rcc_RCC_CR_write(Stm32Rcc *s, uint32_t new_value, bool init) { bool new_pllon, new_hseon, new_hsion; new_pllon = new_value & BIT(RCC_CR_PLLON_BIT); if((clktree_is_enabled(s->PLLCLK) && !new_pllon) && s->RCC_CFGR_SW == SW_PLL_SELECTED) { stm32_hw_warn("PLL cannot be disabled while it is selected as the system clock."); } clktree_set_enabled(s->PLL_VCO, new_pllon); clktree_set_enabled(s->PLLCLK, new_pllon); new_hseon = new_value & BIT(RCC_CR_HSEON_BIT); if((clktree_is_enabled(s->HSECLK) && !new_hseon) && (s->RCC_CFGR_SW == SW_HSE_SELECTED || (s->RCC_CFGR_SW == SW_PLL_SELECTED && s->RCC_PLLCFGR_PLLSRC == PLLSRC_HSE_SELECTED) ) ) { stm32_hw_warn("HSE oscillator cannot be disabled while it is driving the system clock."); } clktree_set_enabled(s->HSECLK, new_hseon); new_hsion = new_value & BIT(RCC_CR_HSION_BIT); if((clktree_is_enabled(s->HSECLK) && !new_hseon) && (s->RCC_CFGR_SW == SW_HSI_SELECTED || (s->RCC_CFGR_SW == SW_PLL_SELECTED && s->RCC_PLLCFGR_PLLSRC == PLLSRC_HSI_SELECTED) ) ) { stm32_hw_warn("HSI oscillator cannot be disabled while it is driving the system clock."); } clktree_set_enabled(s->HSICLK, new_hsion); }
/* Enable the peripheral clock if the specified bit is set in the value. */ static void stm32_rcc_periph_enable( Stm32Rcc *s, uint32_t new_value, bool init, int periph, uint32_t bit_pos) { if(s->PERIPHCLK[periph] == NULL) { stm32_hw_warn("Attempted to enable clock that isn't set: %s", stm32_periph_name(periph)); return; } if(new_value & BIT(bit_pos)) { if(!clktree_is_enabled(s->PERIPHCLK[periph])) DPRINT("Enabling periphial %s\n", stm32_periph_name(periph)); } else { if(clktree_is_enabled(s->PERIPHCLK[periph])) DPRINT("Disabling periphial %s\n", stm32_periph_name(periph)); } clktree_set_enabled(s->PERIPHCLK[periph], new_value & BIT(bit_pos)); }
/* Enable the peripheral clock if the specified bit is set in the value. */ static void stm32_rcc_periph_enable( Stm32Rcc *s, uint32_t new_value, bool init, int periph, uint32_t bit_mask) { clktree_set_enabled(s->PERIPHCLK[periph], IS_BIT_SET(new_value, bit_mask)); }
/* Works the same way as stm32_rcc_RCC_CR_write */ static void stm32_rcc_RCC_CSR_write(Stm32Rcc *s, uint32_t new_value, bool init) { clktree_set_enabled(s->LSICLK, IS_BIT_SET(new_value, RCC_CSR_LSION_BIT)); }