aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/rcc.c
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2010-08-05 21:43:41 -0400
committerbnewbold <bnewbold@robocracy.org>2010-08-05 21:43:58 -0400
commitccd9833f264d6e20a9f2c81baebe162f07eec996 (patch)
treec6d1d3077cf92b864297bf74230221b90c01f34a /libmaple/rcc.c
parentd0e353ca9f3a0986c54beab3948117bdaade700e (diff)
downloadlibrambutan-ccd9833f264d6e20a9f2c81baebe162f07eec996.tar.gz
librambutan-ccd9833f264d6e20a9f2c81baebe162f07eec996.zip
Some refactoring
Diffstat (limited to 'libmaple/rcc.c')
-rw-r--r--libmaple/rcc.c159
1 files changed, 64 insertions, 95 deletions
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)
+ ;
}