diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | core/wiring.c | 66 | ||||
| -rw-r--r-- | libmaple/adc.c | 17 | ||||
| -rw-r--r-- | libmaple/gpio.c | 14 | ||||
| -rw-r--r-- | libmaple/rcc.c | 113 | ||||
| -rw-r--r-- | libmaple/rcc.h | 107 | ||||
| -rw-r--r-- | libmaple/timers.c | 10 | ||||
| -rw-r--r-- | libmaple/usart.c | 10 | ||||
| -rw-r--r-- | libmaple/util.h | 6 | ||||
| -rw-r--r-- | stm32lib/inc/stm32f10x_map.h | 2 | 
10 files changed, 255 insertions, 94 deletions
@@ -62,8 +62,7 @@ ODFLAGS = -S  MAIN=main.c  STM32SRCS = $(STM_SRC)/stm32f10x_flash.c    \ -	    $(STM_SRC)/stm32f10x_nvic.c     \ -	    $(STM_SRC)/stm32f10x_rcc.c +	    $(STM_SRC)/stm32f10x_nvic.c  CSRC = libmaple/systick.c                        \  	   libmaple/timers.c                     \ @@ -76,6 +75,7 @@ CSRC = libmaple/systick.c                        \  	   libmaple/usart.c 			    \  	   libmaple/util.c			    \  	   libmaple/usb.c                        \ +	   libmaple/rcc.c                        \  	   core/wiring.c 		    \  	   core/wiring_shift.c            \  	   core/wiring_analog.c           \ diff --git a/core/wiring.c b/core/wiring.c index 04de78a..488d15c 100644 --- a/core/wiring.c +++ b/core/wiring.c @@ -25,30 +25,20 @@  #include "wiring.h"  #include "stm32f10x_flash.h" -#include "stm32f10x_rcc.h"  #include "stm32f10x_map.h"  #include "stm32f10x_nvic.h" +#include "rcc.h"  #include "systick.h"  #include "gpio.h" -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(); -     gpio_init(); -     adc_init(); -     timer_init(1, 1);     timer_init(2, 1);     timer_init(3, 1); @@ -57,60 +47,14 @@ void init(void) {  void NVIC_Configuration(void) {  #ifdef VECT_TAB_ROM -  NVIC_SetVectorTable(USER_ADDR_ROM, 0x0); +   NVIC_SetVectorTable(USER_ADDR_ROM, 0x0);  #warning writing to ROM  #elif defined VECT_TAB_RAM -  NVIC_SetVectorTable(USER_ADDR_RAM, 0x0); +   NVIC_SetVectorTable(USER_ADDR_RAM, 0x0);  #warning writing to RAM  #else // VECT_TAB_BASE     /* Set the Vector Table base location at 0x08000000 */ -  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); +   NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  #endif  } - -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) -          ; -   } -} diff --git a/libmaple/adc.c b/libmaple/adc.c index 7169824..d584dba 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -23,10 +23,9 @@   *  @brief Analog to digital converter routines   */ -#include "stm32f10x_rcc.h" +#include "libmaple.h" +#include "rcc.h"  #include "adc.h" -#include <stdio.h> -#include <inttypes.h>  /* The ADC input clock is generated from PCLK2/APB2 divided by a prescaler   * and it must not exceed 14MHz. @@ -59,15 +58,9 @@   * At 55.5 cycles/sample, the external input impedance < 50kOhms*/  void adc_init(void) { -    /* PCLK2 is the APB2 clock */ -    RCC_ADCCLKConfig(RCC_PCLK2_Div6); - -    /* Enable ADC1 clock so that we can talk to it */ -    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); - -    /* Put everything back to power-on defaults */ -    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); -    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); +   rcc_set_adc_prescaler(PCLK2_DIV_2); +   rcc_enable_clk_adc1(); +   rcc_reset_adc1();      ADC_CR1  = 0;      ADC_CR2  = CR2_EXTSEL_SWSTART | CR2_EXTTRIG;  // Software triggers conversions diff --git a/libmaple/gpio.c b/libmaple/gpio.c index facb514..39341af 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -24,17 +24,15 @@   */  #include "libmaple.h" -#include "stm32f10x_rcc.h" +#include "rcc.h"  #include "gpio.h"  void gpio_init(void) { -   /* Turn on clocks for GPIO  */ -   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | -                          RCC_APB2Periph_GPIOB | -                          RCC_APB2Periph_GPIOC | -                          RCC_APB2Periph_GPIOD | -                          RCC_APB2Periph_AFIO, -                          ENABLE); +   rcc_enable_clk_gpioa(); +   rcc_enable_clk_gpiob(); +   rcc_enable_clk_gpioc(); +   rcc_enable_clk_gpiod(); +   rcc_enable_clk_afio();  }  void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, uint8 mode) { 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); +} diff --git a/libmaple/rcc.h b/libmaple/rcc.h new file mode 100644 index 0000000..5c9591b --- /dev/null +++ b/libmaple/rcc.h @@ -0,0 +1,107 @@ +/** + *  @file rcc.h + * + *  @brief  + */ + +#ifndef _RCC_H_ +#define _RCC_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_APB2RSTR           (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 ADCPRE                 0x0000C000 +#define HPRE                   0x000000F0 +#define PPRE2                  0x00003800  // apb2 high speed prescaler +#define PPRE1                  0x00000700  // apb1 low-speed prescaler + +#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 PCLK2_DIV_2            0x00008000 + +#define PLLRDY                 BIT(25) +#define PLLON                  BIT(24) +#define PLL_INPUT_CLK_HSE      BIT(16) + +#define RCC_CFGR_SWS           0x00000003 +#define RCC_CFGR_SWS_PLL       0x00000002 + +/* APB2 reset bits  */ +#define RCC_APB2RSTR_USART1RST   BIT(14) +#define RCC_APB2RSTR_SPI1RST     BIT(12) +#define RCC_APB2RSTR_TIM1RST     BIT(11) +#define RCC_APB2RSTR_ADC2RST     BIT(10) +#define RCC_APB2RSTR_ADC1RST     BIT(9) +#define RCC_APB2RSTR_IOERST      BIT(6) +#define RCC_APB2RSTR_IODRST      BIT(5) +#define RCC_APB2RSTR_IOCRST      BIT(4) +#define RCC_APB2RSTR_IOBRST      BIT(3) +#define RCC_APB2RSTR_IOARST      BIT(2) +#define RCC_APB2RSTR_AFIORST     BIT(0) + +/* APB2 peripheral clock enable bits  */ +#define RCC_APB2ENR_USART1EN   BIT(14) +#define RCC_APB2ENR_SPI1EN     BIT(12) +#define RCC_APB2ENR_TIM1EN     BIT(11) +#define RCC_APB2ENR_ADC2EN     BIT(10) +#define RCC_APB2ENR_ADC1EN     BIT(9) +#define RCC_APB2ENR_IOEEN      BIT(6) +#define RCC_APB2ENR_IODEN      BIT(5) +#define RCC_APB2ENR_IOCEN      BIT(4) +#define RCC_APB2ENR_IOBEN      BIT(3) +#define RCC_APB2ENR_IOAEN      BIT(2) +#define RCC_APB2ENR_AFIOEN     BIT(0) + +/* APB1 peripheral clock enable bits  */ +#define RCC_APB1ENR_TIM2EN     BIT(0) +#define RCC_APB1ENR_TIM3EN     BIT(1) +#define RCC_APB1ENR_TIM4EN     BIT(2) +#define RCC_APB1ENR_USART2EN   BIT(17) +#define RCC_APB1ENR_USART3EN   BIT(18) + +#define rcc_enable_clk_timer1()   __set_bits(RCC_APB2ENR, RCC_APB2ENR_TIM1EN) +#define rcc_enable_clk_timer2()   __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM2EN) +#define rcc_enable_clk_timer3()   __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM3EN) +#define rcc_enable_clk_timer4()   __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM4EN) + +#define rcc_enable_clk_gpioa()    __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOAEN) +#define rcc_enable_clk_gpiob()    __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOBEN) +#define rcc_enable_clk_gpioc()    __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOCEN) +#define rcc_enable_clk_gpiod()    __set_bits(RCC_APB2ENR, RCC_APB2ENR_IODEN) +#define rcc_enable_clk_afio()     __set_bits(RCC_APB2ENR, RCC_APB2ENR_AFIOEN) + +#define rcc_enable_clk_usart1()   __set_bits(RCC_APB2ENR, RCC_APB2ENR_USART1EN) +#define rcc_enable_clk_usart2()   __set_bits(RCC_APB1ENR, RCC_APB1ENR_USART2EN) +#define rcc_enable_clk_usart3()   __set_bits(RCC_APB1ENR, RCC_APB1ENR_USART3EN) + +#define rcc_enable_clk_adc1()     __set_bits(RCC_APB2ENR, RCC_APB2ENR_ADC1EN) + +#define rcc_reset_adc1()          { __set_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST);   \ +                                    __clear_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \ +                                  } + + +void rcc_init(void); +void rcc_set_adc_prescaler(uint32_t divider); + +#endif + + diff --git a/libmaple/timers.c b/libmaple/timers.c index 773ae36..e187428 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -24,7 +24,7 @@   */  #include "libmaple.h" -#include "stm32f10x_rcc.h" +#include "rcc.h"  #include "timers.h"  typedef struct { @@ -79,20 +79,20 @@ void timer_init(uint8_t timer_num, uint16_t prescale) {      switch(timer_num) {      case 1:          timer = (Timer*)TIMER1_BASE; -        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); +        rcc_enable_clk_timer1();          is_advanced = 1;          break;      case 2:          timer = (Timer*)TIMER2_BASE; -        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); +        rcc_enable_clk_timer2();          break;      case 3:          timer = (Timer*)TIMER3_BASE; -        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); +        rcc_enable_clk_timer3();          break;      case 4:          timer = (Timer*)TIMER4_BASE; -        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); +        rcc_enable_clk_timer4();          break;      } diff --git a/libmaple/usart.c b/libmaple/usart.c index 9987641..545f64a 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -24,9 +24,9 @@   */  #include "libmaple.h" -#include "stm32f10x_rcc.h" -#include "usart.h" +#include "rcc.h"  #include "nvic.h" +#include "usart.h"  #define USART1_BASE         0x40013800  #define USART2_BASE         0x40004400 @@ -123,21 +123,21 @@ void usart_init(uint8 usart_num, uint32 baud) {          port = (usart_port*)USART1_BASE;          ring_buf = &ring_buf1;          clk_speed = USART1_CLK; -        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); +        rcc_enable_clk_usart1();          REG_SET(NVIC_ISER1, BIT(5));          break;      case 2:          port = (usart_port*)USART2_BASE;          ring_buf = &ring_buf2;          clk_speed = USART2_CLK; -        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); +        rcc_enable_clk_usart2();          REG_SET(NVIC_ISER1, BIT(6));          break;      case 3:          port = (usart_port*)USART3_BASE;          ring_buf = &ring_buf3;          clk_speed = USART3_CLK; -        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); +        rcc_enable_clk_usart3();          REG_SET(NVIC_ISER1, BIT(7));          break;      default: diff --git a/libmaple/util.h b/libmaple/util.h index e425cc0..c1ba15d 100644 --- a/libmaple/util.h +++ b/libmaple/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/stm32lib/inc/stm32f10x_map.h b/stm32lib/inc/stm32f10x_map.h index 3dabb05..16dc479 100644 --- a/stm32lib/inc/stm32f10x_map.h +++ b/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 */
  | 
