aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/rcc.c142
-rw-r--r--src/lib/rcc.h1
-rw-r--r--src/lib/util.h6
-rw-r--r--src/stm32lib/inc/stm32f10x_map.h2
-rw-r--r--src/wiring/wiring.c56
5 files changed, 140 insertions, 67 deletions
diff --git a/src/lib/rcc.c b/src/lib/rcc.c
index e29b010..577f6e4 100644
--- a/src/lib/rcc.c
+++ b/src/lib/rcc.c
@@ -1,19 +1,137 @@
#include "libmaple.h"
#include "rcc.h"
+#include "stm32f10x_flash.h"
+
+#define RCC_BASE 0x40021000
+#define RCC_CR (RCC_BASE + 0x0)
+#define RCC_CFGR (RCC_BASE + 0x4)
+#define RCC_CIR (RCC_BASE + 0x8)
+#define RCC_APB2STR (RCC_BASE + 0xC)
+#define RCC_APB1RSTR (RCC_BASE + 0x10)
+#define RCC_AHBENR (RCC_BASE + 0x14)
+#define RCC_APB2ENR (RCC_BASE + 0x18)
+#define RCC_APB1ENR (RCC_BASE + 0x1C)
+#define RCC_BDCR (RCC_BASE + 0x20)
+#define RCC_CSR (RCC_BASE + 0x24)
+#define RCC_AHBSTR (RCC_BASE + 0x28)
+#define RCC_CFGR2 (RCC_BASE + 0x2C))
+
+#define HSEON BIT(16)
+
+#define HSERDY *(volatile uint32_t*)(BITBAND_PERI(RCC_CR + 2, 0))
+
+#define HPRE 0x000000F0
+#define PPRE 0x00000700
+#define PLLMUL 0x002C0000
+#define PLL_MUL_9 0x001C0000
+#define PLLSRC BIT(16)
+#define SYSCLK_DIV_1 (0x0 << 4)
+#define HCLK_DIV_1 0
+#define HCLK_DIV_2 0x00000400
+
+#define PLLRDY BIT(25)
+#define PLLON BIT(24)
+#define PLL_INPUT_CLK_HSE BIT(16)
+
+
+static void set_ahb_prescaler(uint32_t divider) {
+ uint32_t tmp = __read(RCC_CFGR);
+
+ switch (divider) {
+ case SYSCLK_DIV_1:
+ tmp &= ~HPRE;
+ tmp |= SYSCLK_DIV_1;
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ __write(RCC_CFGR, tmp);
+}
+
+static void set_apb1_prescaler(uint32_t divider) {
+ uint32_t tmp = __read(RCC_CFGR);
+
+ switch (divider) {
+ case HCLK_DIV_2:
+ tmp &= ~PPRE;
+ tmp |= HCLK_DIV_2;
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ __write(RCC_CFGR, tmp);
+}
+
+static void set_apb2_prescaler(uint32_t divider) {
+ uint32_t tmp = __read(RCC_CFGR);
+
+ switch (divider) {
+ case HCLK_DIV_1:
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+
+static void pll_init(void) {
+ uint32_t tmp;
+
+ /* set pll multiplier to 9 */
+ tmp = __read(RCC_CFGR);
+ tmp &= ~PLLMUL;
+ tmp |= PLL_MUL_9;
+
+ /* set pll clock to be hse */
+ tmp |= PLL_INPUT_CLK_HSE;
+ __write(RCC_CFGR, tmp);
+
+ /* turn on the pll */
+ __set_bits(RCC_CR, PLLON);
+
+ while(!__get_bits(RCC_CR, PLLRDY)) {
+ asm volatile("nop");
+ }
+
+ /* select pll for system clock source */
+ tmp = __read(RCC_CFGR);
+ tmp &= ~0x3;
+ tmp |= 0x2;
+ __write(RCC_CFGR, tmp);
+
+ while (__get_bits(RCC_CFGR, 0x00000008) != 0x8) {
+ asm volatile("nop");
+ }
+}
-typedef struct RCC {
- volatile uint32 CR;
- volatile uint32 CFGR;
- volatile uint32 CIR;
- volatile uint32 APB2STR;
- volatile uint32 APB1RSTR;
- volatile uint32 AHBENR;
- volatile uint32 APB2ENR;
- volatile uint32 APB1ENR;
- volatile uint32 BDCR;
- volatile uint32 CSR;
-} RCC;
void rcc_enable(uint32 p) {
+}
+
+void rcc_init(void) {
+
+
+__set_bits(RCC_CR, HSEON);
+
+ while (!HSERDY) {
+ asm volatile("nop");
+ }
+
+ /* 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();
+ __set_bits(RCC_APB2ENR, BIT(2));
+ __set_bits(RCC_APB2ENR, BIT(3));
+ __set_bits(RCC_APB2ENR, BIT(4));
+ __set_bits(RCC_APB2ENR, BIT(5));
}
diff --git a/src/lib/rcc.h b/src/lib/rcc.h
index 2338593..f06fb5f 100644
--- a/src/lib/rcc.h
+++ b/src/lib/rcc.h
@@ -13,6 +13,7 @@
#define RCC_TIMER4
void rcc_enable(uint32 p);
+void rcc_init(void);
#endif
diff --git a/src/lib/util.h b/src/lib/util.h
index e425cc0..c1ba15d 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -54,6 +54,12 @@
#define REG_GET(reg) *(volatile uint32_t*)(reg)
+#define __set_bits(addr, mask) *(volatile uint32_t*)(addr) |= (uint32_t)(mask)
+#define __clear_bits(addr, mask) (*(volatile uint32_t*)(addr) &= (uint32_t)~(mask))
+#define __get_bits(addr, mask) (*(volatile uint32_t*)(addr) & (uint32_t)(mask))
+
+#define __read(reg) *(volatile uint32_t*)(reg)
+#define __write(reg, value) *(volatile uint32_t*)(reg) = (value)
#ifdef __cplusplus
extern "C"{
diff --git a/src/stm32lib/inc/stm32f10x_map.h b/src/stm32lib/inc/stm32f10x_map.h
index 3dabb05..16dc479 100644
--- a/src/stm32lib/inc/stm32f10x_map.h
+++ b/src/stm32lib/inc/stm32f10x_map.h
@@ -665,7 +665,7 @@ typedef struct
#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430)
#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444)
#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458)
-#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
+//#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define CRC_BASE (AHBPERIPH_BASE + 0x3000)
/* Flash registers base address */
diff --git a/src/wiring/wiring.c b/src/wiring/wiring.c
index dc6796f..6ef1968 100644
--- a/src/wiring/wiring.c
+++ b/src/wiring/wiring.c
@@ -27,6 +27,7 @@
#include "stm32f10x_flash.h"
#include "stm32f10x_map.h"
#include "stm32f10x_nvic.h"
+#include "rcc.h"
#include "systick.h"
#include "gpio.h"
@@ -34,12 +35,7 @@ void RCC_Configuration(void);
void NVIC_Configuration(void);
void init(void) {
-// RCC_Configuration();
-// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
-// RCC_APB2Periph_GPIOB |
-// RCC_APB2Periph_GPIOC |
-// RCC_APB2Periph_AFIO
-// , ENABLE);
+ rcc_init();
NVIC_Configuration();
systick_init();
@@ -67,51 +63,3 @@ void NVIC_Configuration(void) {
#endif
}
-
-#if 0
-void RCC_Configuration(void) {
- ErrorStatus HSEStartUpStatus;
- /* RCC system reset(for debug purpose) */
- RCC_DeInit();
-
- /* Enable HSE */
- RCC_HSEConfig(RCC_HSE_ON);
-
- /* Wait till HSE is ready */
- HSEStartUpStatus = RCC_WaitForHSEStartUp();
-
- if(HSEStartUpStatus == SUCCESS) {
- /* Enable Prefetch Buffer */
- FLASH_PrefetchBufferCmd( (u32)FLASH_PrefetchBuffer_Enable);
-
- /* Flash 2 wait state */
- FLASH_SetLatency(FLASH_Latency_2);
-
- /* HCLK = SYSCLK */
- RCC_HCLKConfig(RCC_SYSCLK_Div1);
-
- /* PCLK2 = HCLK APB2 Periphs, no prescaler 72MHz */
- RCC_PCLK2Config(RCC_HCLK_Div1);
-
- /* PCLK1 = HCLK/2 APB1 periphs = 36MHZ*/
- RCC_PCLK1Config(RCC_HCLK_Div2);
-
- /* PLLCLK = 8MHz * 9 = 72 MHz */
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
-
- /* Enable PLL */
- RCC_PLLCmd(ENABLE);
-
- /* Wait till PLL is ready */
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
- ;
-
- /* Select PLL as system clock source */
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
-
- /* Wait till PLL is used as system clock source */
- while(RCC_GetSYSCLKSource() != 0x08)
- ;
- }
-}
-#endif