aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/rcc.c
diff options
context:
space:
mode:
authorPerry Hung <iperry@alum.mit.edu>2010-03-30 22:03:00 -0400
committerPerry Hung <iperry@alum.mit.edu>2010-03-30 22:03:00 -0400
commit2c33d55bae8f9e0e009634072ab05302fc734a65 (patch)
tree63285f96e795fc423cd5bf573340d12f6c8d5513 /libmaple/rcc.c
parent23149e9706ff0a6a338e13804456dff4c655e34b (diff)
parent1d3861ef93f8423176c6010ab606abdab00a7cbd (diff)
downloadlibrambutan-2c33d55bae8f9e0e009634072ab05302fc734a65.tar.gz
librambutan-2c33d55bae8f9e0e009634072ab05302fc734a65.zip
Merge branch 'master' into rcc-dev
Conflicts: Makefile
Diffstat (limited to 'libmaple/rcc.c')
-rw-r--r--libmaple/rcc.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/libmaple/rcc.c b/libmaple/rcc.c
new file mode 100644
index 0000000..bf76eb0
--- /dev/null
+++ b/libmaple/rcc.c
@@ -0,0 +1,113 @@
+/**
+ * @file rcc.c
+ *
+ * @brief Implements pretty much only the basic clock setup on the maple,
+ * exposes a handful of clock enable/disable and peripheral reset commands.
+ */
+
+#include "libmaple.h"
+#include "rcc.h"
+#include "stm32f10x_flash.h"
+
+static void set_ahb_prescaler(uint32_t divider) {
+ uint32_t cfgr = __read(RCC_CFGR);
+
+ cfgr &= ~HPRE;
+
+ switch (divider) {
+ case SYSCLK_DIV_1:
+ cfgr |= SYSCLK_DIV_1;
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ __write(RCC_CFGR, cfgr);
+}
+
+static void set_apb1_prescaler(uint32_t divider) {
+ uint32_t 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_t divider) {
+ uint32_t 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_t cfgr;
+
+ cfgr = __read(RCC_CFGR);
+ cfgr &= (~PLLMUL | PLL_INPUT_CLK_HSE);
+
+ /* pll multiplier 9, input clock hse */
+ __write(RCC_CFGR, cfgr | PLL_MUL_9 | PLL_INPUT_CLK_HSE);
+
+ /* enable pll */
+ __set_bits(RCC_CR, PLLON);
+ while(!__get_bits(RCC_CR, PLLRDY)) {
+ asm volatile("nop");
+ }
+
+ /* select pll for system clock source */
+ cfgr = __read(RCC_CFGR);
+ cfgr &= ~RCC_CFGR_SWS;
+ __write(RCC_CFGR, cfgr | RCC_CFGR_SWS_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_PrefetchBufferCmd( (u32)FLASH_PrefetchBuffer_Enable);
+
+ /* Flash 2 wait state */
+ FLASH_SetLatency(FLASH_Latency_2);
+
+ 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_t divider) {
+ uint32_t cfgr = __read(RCC_CFGR);
+ cfgr &= ~ADCPRE;
+ __write(RCC_CFGR, cfgr | PCLK2_DIV_2);
+}