aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/flash.c43
-rw-r--r--libmaple/flash.h17
-rw-r--r--libmaple/rcc.c159
-rw-r--r--libmaple/rcc.h101
-rw-r--r--libmaple/usb/usb.c3
-rw-r--r--libmaple/usb/usb_config.h4
6 files changed, 183 insertions, 144 deletions
diff --git a/libmaple/flash.c b/libmaple/flash.c
index 9442c44..3fd35d6 100644
--- a/libmaple/flash.c
+++ b/libmaple/flash.c
@@ -25,29 +25,40 @@
#include "libmaple.h"
#include "flash.h"
-#define ACR_PRFTBE ((uint32)0xFFFFFFEF)
-#define ACR_PRFTBE_ENABLE ((uint32)0x00000010) /* FLASH Prefetch Buffer Enable */
-#define ACR_PRFTBE_DISABLE ((uint32)0x00000000) /* FLASH Prefetch Buffer Disable */
+#define FLASH_BASE 0x40022000
+#define FLASH_ACR FLASH_BASE
-#define ACR_LATENCY ((uint32)0x00000038)
-#define ACR_LATENCY_0 ((uint32)0x00000000) /* FLASH Zero Latency cycle */
-#define ACR_LATENCY_1 ((uint32)0x00000001) /* FLASH One Latency cycle */
-#define ACR_LATENCY_2 ((uint32)0x00000002) /* FLASH Two Latency cycles */
+#define ACR_PRFTBE BIT(4)
+#define ACR_PRFTBE_ENABLE BIT(4)
+/* flash wait states */
+#define ACR_LATENCY (0x7)
+
+#define FLASH_WRITE_ACR(val) __write(FLASH_ACR, val)
+#define FLASH_READ_ACR() __read(FLASH_ACR)
+
+
+/**
+ * @brief turn on the hardware prefetcher
+ */
void flash_enable_prefetch(void) {
- uint32 acr = __read(FLASH_ACR);
+ uint32 val = FLASH_READ_ACR();
- acr &= ACR_PRFTBE;
- acr |= ACR_PRFTBE_ENABLE;
+ val |= ACR_PRFTBE_ENABLE;
- __write(FLASH_ACR, acr);
+ FLASH_WRITE_ACR(val);
}
-void flash_set_latency(void) {
- uint32 acr = __read(FLASH_ACR);
- acr &= ACR_LATENCY;
- acr |= ACR_LATENCY_2;
+/**
+ * @brief set flash wait states
+ * @param number of wait states
+ */
+void flash_set_latency(uint32 wait_states) {
+ uint32 val = FLASH_READ_ACR();
+
+ val &= ~ACR_LATENCY;
+ val |= wait_states;
- __write(FLASH_ACR, acr);
+ FLASH_WRITE_ACR(val);
}
diff --git a/libmaple/flash.h b/libmaple/flash.h
index dca5984..a1ae0a4 100644
--- a/libmaple/flash.h
+++ b/libmaple/flash.h
@@ -24,17 +24,26 @@
/**
- * @brief
+ * @brief basic stm32 flash setup routines
*/
#ifndef _FLASH_H_
#define _FLASH_H_
-#define FLASH_BASE 0x40022000
-#define FLASH_ACR FLASH_BASE
+#define FLASH_WAIT_STATE_0 0x0
+#define FLASH_WAIT_STATE_1 0x1
+#define FLASH_WAIT_STATE_2 0x2
+
+#ifdef __cplusplus
+extern "C"{
+#endif
void flash_enable_prefetch(void);
-void flash_set_latency(void);
+void flash_set_latency(uint32 wait_states);
+
+#ifdef __cplusplus
+}
+#endif
#endif
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)
+ ;
}
diff --git a/libmaple/rcc.h b/libmaple/rcc.h
index cb3c543..8e12032 100644
--- a/libmaple/rcc.h
+++ b/libmaple/rcc.h
@@ -31,6 +31,62 @@
#ifndef _RCC_H_
#define _RCC_H_
+struct rcc_device {
+ uint32 apb1_prescale;
+ uint32 apb2_prescale;
+ uint32 ahb_prescale;
+ uint32 sysclk_src;
+ uint32 pll_src;
+ uint32 pll_mul;
+};
+
+#define RCC_CLKSRC_HSI (0x0)
+#define RCC_CLKSRC_HSE (0x1)
+#define RCC_CLKSRC_PLL (0x2)
+
+#define RCC_PLLSRC_HSI_DIV_2 (0x0 << 16)
+#define RCC_PLLSRC_HSE (0x1 << 16)
+
+#define RCC_APB1_HCLK_DIV_1 (0x0 << 8)
+#define RCC_APB1_HCLK_DIV_2 (0x4 << 8)
+#define RCC_APB1_HCLK_DIV_4 (0x5 << 8)
+#define RCC_APB1_HCLK_DIV_8 (0x6 << 8)
+#define RCC_APB1_HCLK_DIV_16 (0x7 << 8)
+
+#define RCC_APB2_HCLK_DIV_1 (0x0 << 11)
+#define RCC_APB2_HCLK_DIV_2 (0x4 << 11)
+#define RCC_APB2_HCLK_DIV_4 (0x5 << 11)
+#define RCC_APB2_HCLK_DIV_8 (0x6 << 11)
+#define RCC_APB2_HCLK_DIV_16 (0x7 << 11)
+
+#define RCC_AHB_SYSCLK_DIV_1 (0x0 << 4)
+#define RCC_AHB_SYSCLK_DIV_2 (0x8 << 4)
+#define RCC_AHB_SYSCLK_DIV_4 (0x9 << 4)
+#define RCC_AHB_SYSCLK_DIV_8 (0xA << 4)
+#define RCC_AHB_SYSCLK_DIV_16 (0xB << 4)
+#define RCC_AHB_SYSCLK_DIV_32 (0xC << 4)
+#define RCC_AHB_SYSCLK_DIV_64 (0xD << 4)
+#define RCC_AHB_SYSCLK_DIV_128 (0xD << 4)
+#define RCC_AHB_SYSCLK_DIV_256 (0xE << 4)
+#define RCC_AHB_SYSCLK_DIV_512 (0xF << 4)
+
+#define RCC_PLLMUL_2 (0x0 << 18)
+#define RCC_PLLMUL_3 (0x1 << 18)
+#define RCC_PLLMUL_4 (0x2 << 18)
+#define RCC_PLLMUL_5 (0x3 << 18)
+#define RCC_PLLMUL_6 (0x4 << 18)
+#define RCC_PLLMUL_7 (0x5 << 18)
+#define RCC_PLLMUL_8 (0x6 << 18)
+#define RCC_PLLMUL_9 (0x7 << 18)
+#define RCC_PLLMUL_10 (0x8 << 18)
+#define RCC_PLLMUL_11 (0x9 << 18)
+#define RCC_PLLMUL_12 (0xA << 18)
+#define RCC_PLLMUL_13 (0xB << 18)
+#define RCC_PLLMUL_14 (0xC << 18)
+#define RCC_PLLMUL_15 (0xD << 18)
+#define RCC_PLLMUL_16 (0xE << 18)
+
+/* remove!! */
#define RCC_BASE 0x40021000
#define RCC_CR (RCC_BASE + 0x0)
#define RCC_CFGR (RCC_BASE + 0x4)
@@ -43,30 +99,7 @@
#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*)(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_SW 0x00000003
-#define RCC_CFGR_SW_PLL 0x00000002
+#define RCC_CFGR2 (RCC_BASE + 0x2C)
/* APB2 reset bits */
#define RCC_APB2RSTR_USART1RST BIT(14)
@@ -81,6 +114,8 @@
#define RCC_APB2RSTR_IOARST BIT(2)
#define RCC_APB2RSTR_AFIORST BIT(0)
+#define RCC_APB1RSTR_USB BIT(23)
+
/* APB2 peripheral clock enable bits */
#define RCC_APB2ENR_USART1EN BIT(14)
#define RCC_APB2ENR_SPI1EN BIT(12)
@@ -101,6 +136,7 @@
#define RCC_APB1ENR_USART2EN BIT(17)
#define RCC_APB1ENR_USART3EN BIT(18)
#define RCC_APB1ENR_SPI2EN BIT(14)
+#define RCC_APB1ENR_USB BIT(23)
#define rcc_enable_clk_spi1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_SPI1EN)
#define rcc_enable_clk_spi2() __set_bits(RCC_APB1ENR, RCC_APB1ENR_SPI2EN)
@@ -126,9 +162,22 @@
__clear_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \
}
+#define rcc_reset_usb() { __set_bits(RCC_APB1RSTR, RCC_APB1RSTR_USB); \
+ __clear_bits(RCC_APB1RSTR, RCC_APB1RSTR_USB); \
+ }
+
-void rcc_init(void);
-void rcc_set_adc_prescaler(uint32 divider);
+#define PCLK2_DIV_2 0x00008000
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+void rcc_init(struct rcc_device *dev);
+
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c
index 23cde00..026d7f0 100644
--- a/libmaple/usb/usb.c
+++ b/libmaple/usb/usb.c
@@ -118,7 +118,8 @@ void setupUSB (void) {
pRCC->APB1ENR |= 0x00800000;
/* initialize the usb application */
- gpio_write_bit(USB_DISC_BANK,USB_DISC_PIN,0); /* present ourselves to the host */
+ gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); /* present ourselves to the host */
+
USB_Init(); /* low level init routine provided by st lib */
}
diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h
index 06c81ff..9f6b600 100644
--- a/libmaple/usb/usb_config.h
+++ b/libmaple/usb/usb_config.h
@@ -46,8 +46,8 @@
CNTR_ESOFM | \
CNTR_RESETM )
-#define USB_DISC_BANK GPIOC_BASE
-#define USB_DISC_PIN 12
+#define USB_DISC_BANK GPIOB_BASE
+#define USB_DISC_PIN 8
#define F_SUSPEND_ENABLED 1