void rtt_poweroff(void) { #ifdef RCC_APB1ENR1_LPTIM1EN periph_clk_dis(APB1, RCC_APB1ENR1_LPTIM1EN); #else periph_clk_dis(APB1, RCC_APB1ENR_LPTIM1EN); #endif }
int i2c_release(i2c_t dev) { assert(dev < I2C_NUMOF); periph_clk_dis(i2c_config[dev].bus, i2c_config[dev].rcc_mask); mutex_unlock(&locks[dev]); return 0; }
void uart_poweroff(uart_t uart) { assert(uart < UART_NUMOF); periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcc_mask); #ifdef STM32_PM_STOP if (isr_ctx[uart].rx_cb) { pm_unblock(STM32_PM_STOP); } #endif }
void hwrng_read(void *buf, unsigned int num) { unsigned int count = 0; uint8_t *b = (uint8_t *)buf; /* power on and enable the device */ #if defined(CPU_MODEL_STM32F410RB) periph_clk_en(AHB1, RCC_AHB1ENR_RNGEN); #elif defined(CPU_FAM_STM32L0) periph_clk_en(AHB, RCC_AHBENR_RNGEN); #else periph_clk_en(AHB2, RCC_AHB2ENR_RNGEN); #endif RNG->CR = RNG_CR_RNGEN; /* get random data */ while (count < num) { /* wait for random data to be ready to read */ while (!(RNG->SR & RNG_SR_DRDY)) {} /* read next 4 bytes */ uint32_t tmp = RNG->DR; /* copy data into result vector */ for (int i = 0; i < 4 && count < num; i++) { b[count++] = (uint8_t)tmp; tmp = tmp >> 8; } } /* finally disable the device again */ RNG->CR = 0; #if defined(CPU_MODEL_STM32F410RB) periph_clk_dis(AHB1, RCC_AHB1ENR_RNGEN); #elif defined(CPU_FAM_STM32L0) periph_clk_dis(AHB, RCC_AHBENR_RNGEN); #else periph_clk_dis(AHB2, RCC_AHB2ENR_RNGEN); #endif }
int i2c_release(i2c_t dev) { assert(dev < I2C_NUMOF); periph_clk_dis(i2c_config[dev].bus, i2c_config[dev].rcc_mask); #ifdef STM32_PM_STOP /* unblock STOP mode */ pm_unblock(STM32_PM_STOP); #endif mutex_unlock(&locks[dev]); return 0; }
void stmclk_bdp_lock(void) { PWR->CR1 &= ~(PWR_CR1_DBP); periph_clk_dis(APB1, RCC_APB1ENR_PWREN); }
void uart_poweroff(uart_t uart) { periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcc_mask); }
static inline void done(adc_t line) { periph_clk_dis(APB2, (RCC_APB2ENR_ADC1EN << adc_config[line].dev)); mutex_unlock(&locks[adc_config[line].dev]); }
void pwm_poweroff(pwm_t pwm) { assert(pwm < PWM_NUMOF); periph_clk_dis(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask); }
/** * @brief Configure the STM32L4's clock system * * We use the following configuration: * - we always enable the 32kHz low speed clock (LSI or LSE) * - we configure the MSI clock to 48MHz (for USB and RNG) and enable it * - if LSE present, we use it to stabilize the 48MHz MSI clock (MSIPLLEN) * - use either MSI @ 48MHz or HSE (4 to 48MHZ) as base clock * - we use the PLL as main clock provider * - we don't enable any ASI clock * * For the computation of the PLL configuration, see defines above. */ static void cpu_clock_init(void) { /* disable any interrupts. Global interrupts could be enabled if this is * called from some kind of bootloader... */ unsigned is = irq_disable(); RCC->CIER = 0; /* for the duration of the configuration, we fall-back to the maximum number * of flash wait states */ FLASH->ACR = (FLASH_ACR_LATENCY_4WS); /* reset clock to MSI with 48MHz, disables all other clocks */ RCC->CR = (RCC_CR_MSIRANGE_11 | RCC_CR_MSION | RCC_CR_MSIRGSEL); while (!(RCC->CR & RCC_CR_MSIRDY)) {} /* use MSI as system clock while we do any further configuration and * configure the AHB and APB clock dividers as configure by the board */ RCC->CFGR = (RCC_CFGR_SW_MSI | CLOCK_AHB_DIV | CLOCK_APB1_DIV | CLOCK_APB2_DIV); while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_MSI) {} /* configure the low speed clock domain (LSE vs LSI) */ #if CLOCK_LSE /* allow write access to backup domain */ periph_clk_en(APB1, RCC_APB1ENR1_PWREN); PWR->CR1 |= PWR_CR1_DBP; /* enable LSE */ RCC->BDCR = RCC_BDCR_LSEON; while (!(RCC->BDCR & RCC_BDCR_LSERDY)) {} /* disable write access to back domain when done */ PWR->CR1 &= ~(PWR_CR1_DBP); periph_clk_dis(APB1, RCC_APB1ENR1_PWREN); /* now we can enable the MSI PLL mode */ RCC->CR |= RCC_CR_MSIPLLEN; while (!(RCC->CR & RCC_CR_MSIRDY)) {} #else RCC->CSR = RCC_CSR_LSION; while (!(RCC->CSR & RCC_CSR_LSIRDY)) {} #endif /* select the MSI clock for the 48MHz clock tree (USB, RNG) */ RCC->CCIPR = (RCC_CCIPR_CLK48SEL_0 | RCC_CCIPR_CLK48SEL_1); /* if configured: enable the HSE clock */ #if CLOCK_HSE RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)) {} #endif /* next we configure and enable the PLL */ RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_R | RCC_PLLCFGR_PLLREN); RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)) {} /* now tell the system to use the PLL as main clock */ RCC->CFGR |= RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL) {} /* finally we enable I+D cashes, pre-fetch, and we set the actual number of * needed flash wait states */ FLASH->ACR = (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES); irq_restore(is); }