diff options
| -rw-r--r-- | src/lib/rcc.c | 142 | ||||
| -rw-r--r-- | src/lib/rcc.h | 1 | ||||
| -rw-r--r-- | src/lib/util.h | 6 | ||||
| -rw-r--r-- | src/stm32lib/inc/stm32f10x_map.h | 2 | ||||
| -rw-r--r-- | src/wiring/wiring.c | 56 | 
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  | 
