From ccd9833f264d6e20a9f2c81baebe162f07eec996 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Thu, 5 Aug 2010 21:43:41 -0400 Subject: Some refactoring --- libmaple/rcc.c | 159 +++++++++++++++++++++++---------------------------------- 1 file changed, 64 insertions(+), 95 deletions(-) (limited to 'libmaple/rcc.c') diff --git a/libmaple/rcc.c b/libmaple/rcc.c index 079c4d6..fbf9160 100644 --- a/libmaple/rcc.c +++ b/libmaple/rcc.c @@ -25,7 +25,7 @@ /** * @file rcc.c * - * @brief Implements pretty much only the basic clock setup on the maple, + * @brief Implements pretty much only the basic clock setup on the stm32, * exposes a handful of clock enable/disable and peripheral reset commands. */ @@ -33,105 +33,74 @@ #include "flash.h" #include "rcc.h" -static void set_ahb_prescaler(uint32 divider) { - uint32 cfgr = __read(RCC_CFGR); +#define RCC_CFGR_PPRE1 (0x7 << 8) +#define RCC_CFGR_PPRE2 (0x7 << 11) +#define RCC_CFGR_HPRE (0xF << 4) +#define RCC_CFGR_PLLSRC (0x1 << 16) - cfgr &= ~HPRE; +#define RCC_CFGR_SWS (0x3 << 2) +#define RCC_CFGR_SWS_PLL (0x2 << 2) +#define RCC_CFGR_SWS_HSE (0x1 << 2) - switch (divider) { - case SYSCLK_DIV_1: - cfgr |= SYSCLK_DIV_1; - break; - default: - ASSERT(0); - } +#define RCC_CFGR_SW (0x3 << 0) +#define RCC_CFGR_SW_PLL (0x2 << 0) +#define RCC_CFGR_SW_HSE (0x1 << 0) - __write(RCC_CFGR, cfgr); -} - -static void set_apb1_prescaler(uint32 divider) { - uint32 cfgr = __read(RCC_CFGR); - - cfgr &= ~PPRE1; - - switch (divider) { - case HCLK_DIV_2: - cfgr |= HCLK_DIV_2; - break; - default: - ASSERT(0); - } - - __write(RCC_CFGR, cfgr); -} - -static void set_apb2_prescaler(uint32 divider) { - uint32 cfgr = __read(RCC_CFGR); - - cfgr &= ~PPRE2; - - switch (divider) { - case HCLK_DIV_1: - cfgr |= HCLK_DIV_1; - break; - default: - ASSERT(0); - } - - __write(RCC_CFGR, cfgr); -} - -/* FIXME: magic numbers */ -static void pll_init(void) { - uint32 cfgr; - - cfgr = __read(RCC_CFGR); - cfgr &= (~PLLMUL | PLL_INPUT_CLK_HSE); +/* CR status bits */ +#define RCC_CR_HSEON (0x1 << 16) +#define RCC_CR_HSERDY (0x1 << 17) +#define RCC_CR_PLLON (0x1 << 24) +#define RCC_CR_PLLRDY (0x1 << 25) - /* pll multiplier 9, input clock hse */ - __write(RCC_CFGR, cfgr | PLL_MUL_9 | PLL_INPUT_CLK_HSE); +#define RCC_WRITE_CFGR(val) __write(RCC_CFGR, val) +#define RCC_READ_CFGR() __read(RCC_CFGR) - /* enable pll */ - __set_bits(RCC_CR, PLLON); - while(!__get_bits(RCC_CR, PLLRDY)) { - asm volatile("nop"); - } +#define RCC_WRITE_CR(val) __write(RCC_CR, val) +#define RCC_READ_CR() __read(RCC_CR) - /* select pll for system clock source */ - cfgr = __read(RCC_CFGR); +/** + * @brief Initialize the clock control system. Sets up only the basics: + * APB1 clock prescaler + * APB2 clock prescaler + * AHB clock prescaler + * System clock source (Must be PLL) + * PLL clock source (Must be high-speed external clock) + * PLL Multiplier + * @param dev initialization struct + * @sideeffect Switches clock source to PLL, clock speed to HSE_CLK*PLLMUL + */ +void rcc_init(struct rcc_device *dev) { + /* Assume that we're going to clock the chip off the PLL, fed by + * the HSE */ + ASSERT(dev->sysclk_src == RCC_CLKSRC_PLL && + dev->pll_src == RCC_PLLSRC_HSE); + + uint32 cfgr = 0; + uint32 cr = RCC_READ_CR(); + + cfgr = (dev->apb1_prescale | + dev->apb2_prescale | + dev->ahb_prescale | + dev->pll_src | + dev->pll_mul); + RCC_WRITE_CFGR(cfgr); + + /* Turn on the HSE */ + cr |= RCC_CR_HSEON; + RCC_WRITE_CR(cr); + while (!(RCC_READ_CR() & RCC_CR_HSERDY)) + ; + + /* Now the PLL */ + cr |= RCC_CR_PLLON; + RCC_WRITE_CR(cr); + while (!(RCC_READ_CR() & RCC_CR_PLLRDY)) + ; + + /* Finally, let's switch over to the PLL */ cfgr &= ~RCC_CFGR_SW; - __write(RCC_CFGR, cfgr | RCC_CFGR_SW_PLL); - - while (__get_bits(RCC_CFGR, 0x00000008) != 0x8) { - asm volatile("nop"); - } -} - -static void hse_init(void) { - __set_bits(RCC_CR, HSEON); - while (!HSERDY) { - asm volatile("nop"); - } -} - -void rcc_init(void) { - hse_init(); - - /* Leave this here for now... */ - /* Enable Prefetch Buffer */ - flash_enable_prefetch(); - - /* Flash 2 wait state */ - flash_set_latency(); - - set_ahb_prescaler(SYSCLK_DIV_1); - set_apb1_prescaler(HCLK_DIV_2); - set_apb2_prescaler(HCLK_DIV_1); - pll_init(); -} - -void rcc_set_adc_prescaler(uint32 divider) { - uint32 cfgr = __read(RCC_CFGR); - cfgr &= ~ADCPRE; - __write(RCC_CFGR, cfgr | PCLK2_DIV_2); + cfgr |= RCC_CFGR_SW_PLL; + RCC_WRITE_CFGR(cfgr); + while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) + ; } -- cgit v1.2.3