diff options
-rw-r--r-- | libmaple/flash.c | 43 | ||||
-rw-r--r-- | libmaple/flash.h | 17 | ||||
-rw-r--r-- | libmaple/rcc.c | 159 | ||||
-rw-r--r-- | libmaple/rcc.h | 101 | ||||
-rw-r--r-- | libmaple/usb/usb.c | 3 | ||||
-rw-r--r-- | libmaple/usb/usb_config.h | 4 | ||||
-rw-r--r-- | support/ld/jtag.ld | 4 | ||||
-rw-r--r-- | support/ld/ram.ld | 4 | ||||
-rw-r--r-- | support/openocd/flash.cfg | 6 | ||||
-rw-r--r-- | wirish/wirish.c | 35 |
10 files changed, 217 insertions, 159 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 diff --git a/support/ld/jtag.ld b/support/ld/jtag.ld index 67fbe85..64d049d 100644 --- a/support/ld/jtag.ld +++ b/support/ld/jtag.ld @@ -8,8 +8,8 @@ /* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
- rom (rx) : ORIGIN = 0x08000000, LENGTH = 120K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
diff --git a/support/ld/ram.ld b/support/ld/ram.ld index 6398ea4..872d6f2 100644 --- a/support/ld/ram.ld +++ b/support/ld/ram.ld @@ -25,8 +25,8 @@ /* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x00000000, LENGTH = 0K
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
diff --git a/support/openocd/flash.cfg b/support/openocd/flash.cfg index eceac32..25fe23f 100644 --- a/support/openocd/flash.cfg +++ b/support/openocd/flash.cfg @@ -62,15 +62,15 @@ jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME proc flash_chip {} { echo "Halting..." halt - echo "Erasing 128KB..." - flash erase_address 0x08000000 0x20000 + echo "Erasing..." + flash erase_address 0x08000000 0x80000 echo "Flashing image..." flash write_bank 0 build/maple.bin 0 echo "Verifying image..." diff --git a/wirish/wirish.c b/wirish/wirish.c index e21f792..28e7130 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -27,21 +27,40 @@ */ #include "wirish.h" -#include "rcc.h" #include "systick.h" #include "gpio.h" #include "nvic.h" #include "usb.h" +#include "rcc.h" +#include "flash.h" + +static void inline maple_flash_init(void) { + flash_enable_prefetch(); + flash_set_latency(FLASH_WAIT_STATE_2); +} + +static void inline maple_rcc_init(void) { + struct rcc_device maple_rcc_dev = { + .apb1_prescale = RCC_APB1_HCLK_DIV_2, + .apb2_prescale = RCC_APB2_HCLK_DIV_1, + .ahb_prescale = RCC_AHB_SYSCLK_DIV_1, + .sysclk_src = RCC_CLKSRC_PLL, + .pll_src = RCC_PLLSRC_HSE, + .pll_mul = RCC_PLLMUL_9 + }; + rcc_init(&maple_rcc_dev); +} void init(void) { - rcc_init(); + maple_flash_init(); + maple_rcc_init(); nvic_init(); systick_init(); gpio_init(); - adc_init(); - timer_init(1, 1); - timer_init(2, 1); - timer_init(3, 1); - timer_init(4, 1); - setupUSB(); +// adc_init(); +// timer_init(1, 1); +// timer_init(2, 1); +// timer_init(3, 1); +// timer_init(4, 1); +// setupUSB(); } |