diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2014-07-30 12:52:48 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2014-12-10 18:49:02 +0900 |
commit | 522380097ea768e7474c0de8195cc0ced03904e8 (patch) | |
tree | 1336ca40ff9b995778d88a38f8d10bebaeed3a59 | |
parent | 23893d9b73ebc28ff111d21827122677c27bee55 (diff) |
Support Cortex-M0.
-rw-r--r-- | board/board-stm32f0-discovery.h | 47 | ||||
-rw-r--r-- | entry.c | 123 | ||||
-rw-r--r-- | example-led/sys.c | 131 |
3 files changed, 298 insertions, 3 deletions
diff --git a/board/board-stm32f0-discovery.h b/board/board-stm32f0-discovery.h new file mode 100644 index 0000000..15b8b51 --- /dev/null +++ b/board/board-stm32f0-discovery.h @@ -0,0 +1,47 @@ +/* + * Running at 48MHz with HSI as clock source. + * + */ +#define MCU_STM32F0 1 +/* __ARM_ARCH_6M__ */ + + +#define FLASH_PAGE_SIZE 1024 + +#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 +#define STM32_PLLMUL_VALUE 12 +#define STM32_HSICLK 8000000 + +#define GPIO_LED_SET_TO_EMIT 8 + +/* + * Port C setup. + * PC9 - LED3 (LED 1:ON 0:OFF) + * PC8 - LED4 (LED 1:ON 0:OFF) + */ +#define VAL_GPIO_MODER 0x00050000 /* Output Pin9 and Pin8 */ +#define VAL_GPIO_OTYPER 0x00000000 /* Push-Pull */ +#define VAL_GPIO_OSPEEDR 0x000f0000 /* High speed: Pin9 and Pin8 */ +#define VAL_GPIO_PUPDR 0x00000000 /* No pull-up/pull-down */ + +#define GPIO_LED_BASE GPIOC_BASE + +#if 0 +#define RCC_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPCEN) +#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPCRST) +#else +#define RCC_ENR_IOP_EN RCC_AHBENR_IOPCEN +#define RCC_RSTR_IOP_RST RCC_AHBRSTR_IOPCRST +#endif + +/* ??? NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */ + +#define GPIO_OTHER_BASE GPIOA_BASE /* USER BUTTON */ +/* + * Port A setup. + * PA0 - USER Button + */ +#define VAL_GPIO_OTHER_MODER 0x00000000 /* Input Pin0 */ +#define VAL_GPIO_OTHER_OTYPER 0x00000000 /* Push-Pull */ +#define VAL_GPIO_OTHER_OSPEEDR 0x00000000 +#define VAL_GPIO_OTHER_PUPDR 0x00000000 /* No pull-up/pull-down */ @@ -60,10 +60,17 @@ #define STM32_MCO_NOCLOCK (0 << 24) +#if MCU_STM32F0 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PLLSRC STM32_PLLSRC_HSI +#define STM32_FLASHBITS 0x00000011 +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else #define STM32_PPRE1 STM32_PPRE1_DIV2 #define STM32_PLLSRC STM32_PLLSRC_HSE #define STM32_FLASHBITS 0x00000012 #define STM32_PLLCLKIN (STM32_HSECLK / 1) +#endif #define STM32_SW STM32_SW_PLL #define STM32_HPRE STM32_HPRE_DIV1 @@ -95,6 +102,12 @@ struct RCC { volatile uint32_t APB1ENR; volatile uint32_t BDCR; volatile uint32_t CSR; +#if MCU_STM32F0 + volatile uint32_t AHBRSTR; + volatile uint32_t CFGR2; + volatile uint32_t CFGR3; + volatile uint32_t CR2; +#endif }; #define RCC_BASE (AHBPERIPH_BASE + 0x1000) @@ -116,6 +129,22 @@ static struct RCC *const RCC = ((struct RCC *const)RCC_BASE); #define RCC_AHBENR_CRCEN 0x0040 +#if MCU_STM32F0 +#define RCC_AHBRSTR_IOPARST 0x00020000 +#define RCC_AHBRSTR_IOPBRST 0x00040000 +#define RCC_AHBRSTR_IOPCRST 0x00080000 +#define RCC_AHBRSTR_IOPDRST 0x00100000 +#define RCC_AHBRSTR_IOPFRST 0x00400000 + +#define RCC_AHBENR_IOPAEN 0x00020000 +#define RCC_AHBENR_IOPBEN 0x00040000 +#define RCC_AHBENR_IOPCEN 0x00080000 +#define RCC_AHBENR_IOPDEN 0x00100000 +#define RCC_AHBENR_IOPFEN 0x00400000 + +#define RCC_APB2RSTR_SYSCFGRST 0x00000001 +#define RCC_APB2ENR_SYSCFGEN 0x00000001 +#else #define RCC_APB2RSTR_AFIORST 0x00000001 #define RCC_APB2RSTR_IOPARST 0x00000004 #define RCC_APB2RSTR_IOPBRST 0x00000008 @@ -127,6 +156,20 @@ static struct RCC *const RCC = ((struct RCC *const)RCC_BASE); #define RCC_APB2ENR_IOPBEN 0x00000008 #define RCC_APB2ENR_IOPCEN 0x00000010 #define RCC_APB2ENR_IOPDEN 0x00000020 +#endif + +#if MCU_STM32F0 +struct SYSCFG { + volatile uint32_t CFGR1; + uint32_t dummy0; + volatile uint32_t EXTICR[4]; + volatile uint32_t CFGR2; +}; +#define SYSCFG_CFGR1_MEM_MODE 0x03 + +#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000) +static struct SYSCFG *const SYSCFG = ((struct SYSCFG *const) SYSCFG_BASE); +#endif struct FLASH { volatile uint32_t ACR; @@ -156,10 +199,12 @@ clock_init (void) while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) ; +#if !MCU_STM32F0 /* HSE setup */ RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)) ; +#endif /* PLL setup */ RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; @@ -185,9 +230,48 @@ clock_init (void) RCC->CFGR |= STM32_SW; while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) ; + +#if MCU_STM32F0 + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + RCC->APB2RSTR = RCC_APB2RSTR_SYSCFGRST; + RCC->APB2RSTR = 0; + + /* Use vectors on RAM */ + SYSCFG->CFGR1 = (SYSCFG->CFGR1 & ~SYSCFG_CFGR1_MEM_MODE) | 3; +#endif } +#if MCU_STM32F0 +struct GPIO { + volatile uint32_t MODER; + volatile uint16_t OTYPER; + uint16_t dummy0; + volatile uint32_t OSPEEDR; + volatile uint32_t PUPDR; + volatile uint16_t IDR; + uint16_t dummy1; + volatile uint16_t ODR; + uint16_t dummy2; + volatile uint16_t BSRR; + uint16_t dummy3; + volatile uint32_t LCKR; + volatile uint32_t AFR[2]; + volatile uint16_t BRR; + uint16_t dummy4; +}; + +#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) +#else struct AFIO { volatile uint32_t EVCR; @@ -203,7 +287,6 @@ static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE; #define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800 #define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000 - struct GPIO { volatile uint32_t CRL; volatile uint32_t CRH; @@ -224,6 +307,7 @@ struct GPIO { #define GPIOD ((struct GPIO *) GPIOD_BASE) #define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) #define GPIOE ((struct GPIO *) GPIOE_BASE) +#endif static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); #ifdef GPIO_USB_BASE @@ -237,10 +321,29 @@ static void __attribute__((used)) gpio_init (void) { /* Enable GPIO clock. */ +#if MCU_STM32F0 + RCC->AHBENR |= RCC_ENR_IOP_EN; + RCC->AHBRSTR = RCC_RSTR_IOP_RST; + RCC->AHBRSTR = 0; +#else RCC->APB2ENR |= RCC_ENR_IOP_EN; RCC->APB2RSTR = RCC_RSTR_IOP_RST; RCC->APB2RSTR = 0; +#endif +#if MCU_STM32F0 + GPIO_LED->OSPEEDR = VAL_GPIO_OSPEEDR; + GPIO_LED->OTYPER = VAL_GPIO_OTYPER; + GPIO_LED->MODER = VAL_GPIO_MODER; + GPIO_LED->PUPDR = VAL_GPIO_PUPDR; + +#ifdef GPIO_OTHER_BASE + GPIO_OTHER->OSPEEDR = VAL_GPIO_OTHER_OSPEEDR; + GPIO_OTHER->OTYPER = VAL_GPIO_OTHER_OTYPER; + GPIO_OTHER->MODER = VAL_GPIO_OTHER_MODER; + GPIO_OTHER->PUPDR = VAL_GPIO_OTHER_PUPDR; +#endif +#else #ifdef AFIO_MAPR_SOMETHING AFIO->MAPR |= AFIO_MAPR_SOMETHING; #endif @@ -260,6 +363,7 @@ gpio_init (void) GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH; GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL; #endif +#endif } #endif @@ -302,6 +406,11 @@ static void none (void) #define C_S_SUB(arg0, arg1, arg2) arg0 #arg1 arg2 #define COMPOSE_STATEMENT(arg0,arg1,arg2) C_S_SUB (arg0, arg1, arg2) +#if MCU_STM32F0 +__attribute__ ((used,section(".data.startup.0"))) +uint32_t vectors_in_ram[48]; +#endif + /* * This routine only changes PSP and not MSP. */ @@ -316,7 +425,12 @@ void entry (void) "0:\n\t" "cmp r1, r2\n\t" "beq 1f\n\t" +#if __ARM_ARCH_6M__ + "str r0, [r1]\n\t" + "add r1, #4\n\t" +#else "str r0, [r1], #4\n\t" +#endif "b 0b\n" "1:\n\t" /* Copy data section. */ @@ -326,8 +440,15 @@ void entry (void) "2:\n\t" "cmp r1, r2\n\t" "beq 3f\n\t" +#if __ARM_ARCH_6M__ + "ldr r0, [r3]\n\t" + "str r0, [r1]\n\t" + "add r3, #4\n\t" + "add r1, #4\n\t" +#else "ldr r0, [r3], #4\n\t" "str r0, [r1], #4\n\t" +#endif "b 2b\n" "3:\n\t" /* Switch to PSP. */ diff --git a/example-led/sys.c b/example-led/sys.c index 264df5e..c86a08e 100644 --- a/example-led/sys.c +++ b/example-led/sys.c @@ -1,5 +1,5 @@ /* - * sys.c - system routines for the initial page for STM32F103. + * sys.c - system routines for the initial page for STM32F030 / STM32F103. * * Copyright (C) 2013, 2014 Flying Stone Technology * Author: NIIBE Yutaka <gniibe@fsij.org> @@ -23,7 +23,6 @@ #define USB_LP_CAN1_RX0_IRQn 20 #define STM32_USB_IRQ_PRIORITY 11 - #define STM32_SW_HSI (0 << 0) #define STM32_SW_PLL (2 << 0) #define STM32_PLLSRC_HSI (0 << 16) @@ -47,10 +46,17 @@ #define STM32_MCO_NOCLOCK (0 << 24) +#if MCU_STM32F0 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PLLSRC STM32_PLLSRC_HSI +#define STM32_FLASHBITS 0x00000011 +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else #define STM32_PPRE1 STM32_PPRE1_DIV2 #define STM32_PLLSRC STM32_PLLSRC_HSE #define STM32_FLASHBITS 0x00000012 #define STM32_PLLCLKIN (STM32_HSECLK / 1) +#endif #define STM32_SW STM32_SW_PLL #define STM32_HPRE STM32_HPRE_DIV1 @@ -111,6 +117,12 @@ struct RCC { volatile uint32_t APB1ENR; volatile uint32_t BDCR; volatile uint32_t CSR; +#if MCU_STM32F0 + volatile uint32_t AHBRSTR; + volatile uint32_t CFGR2; + volatile uint32_t CFGR3; + volatile uint32_t CR2; +#endif }; #define RCC_BASE (AHBPERIPH_BASE + 0x1000) @@ -132,6 +144,22 @@ static struct RCC *const RCC = ((struct RCC *const)RCC_BASE); #define RCC_AHBENR_CRCEN 0x0040 +#if MCU_STM32F0 +#define RCC_AHBRSTR_IOPARST 0x00020000 +#define RCC_AHBRSTR_IOPBRST 0x00040000 +#define RCC_AHBRSTR_IOPCRST 0x00080000 +#define RCC_AHBRSTR_IOPDRST 0x00100000 +#define RCC_AHBRSTR_IOPFRST 0x00400000 + +#define RCC_AHBENR_IOPAEN 0x00020000 +#define RCC_AHBENR_IOPBEN 0x00040000 +#define RCC_AHBENR_IOPCEN 0x00080000 +#define RCC_AHBENR_IOPDEN 0x00100000 +#define RCC_AHBENR_IOPFEN 0x00400000 + +#define RCC_APB2RSTR_SYSCFGRST 0x00000001 +#define RCC_APB2ENR_SYSCFGEN 0x00000001 +#else #define RCC_APB2RSTR_AFIORST 0x00000001 #define RCC_APB2RSTR_IOPARST 0x00000004 #define RCC_APB2RSTR_IOPBRST 0x00000008 @@ -143,6 +171,20 @@ static struct RCC *const RCC = ((struct RCC *const)RCC_BASE); #define RCC_APB2ENR_IOPBEN 0x00000008 #define RCC_APB2ENR_IOPCEN 0x00000010 #define RCC_APB2ENR_IOPDEN 0x00000020 +#endif + +#if MCU_STM32F0 +struct SYSCFG { + volatile uint32_t CFGR1; + uint32_t dummy0; + volatile uint32_t EXTICR[4]; + volatile uint32_t CFGR2; +}; +#define SYSCFG_CFGR1_MEM_MODE 0x03 + +#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000) +static struct SYSCFG *const SYSCFG = ((struct SYSCFG *const) SYSCFG_BASE); +#endif struct FLASH { volatile uint32_t ACR; @@ -172,10 +214,12 @@ clock_init (void) while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) ; +#if !MCU_STM32F0 /* HSE setup */ RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)) ; +#endif /* PLL setup */ RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; @@ -201,9 +245,48 @@ clock_init (void) RCC->CFGR |= STM32_SW; while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) ; + +#if MCU_STM32F0 + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + RCC->APB2RSTR = RCC_APB2RSTR_SYSCFGRST; + RCC->APB2RSTR = 0; + + /* Use vectors on RAM */ + SYSCFG->CFGR1 = (SYSCFG->CFGR1 & ~SYSCFG_CFGR1_MEM_MODE) | 3; +#endif } +#if MCU_STM32F0 +struct GPIO { + volatile uint32_t MODER; + volatile uint16_t OTYPER; + uint16_t dummy0; + volatile uint32_t OSPEEDR; + volatile uint32_t PUPDR; + volatile uint16_t IDR; + uint16_t dummy1; + volatile uint16_t ODR; + uint16_t dummy2; + volatile uint16_t BSRR; + uint16_t dummy3; + volatile uint32_t LCKR; + volatile uint32_t AFR[2]; + volatile uint16_t BRR; + uint16_t dummy4; +}; + +#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) +#else struct AFIO { volatile uint32_t EVCR; @@ -240,6 +323,7 @@ struct GPIO { #define GPIOD ((struct GPIO *) GPIOD_BASE) #define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) #define GPIOE ((struct GPIO *) GPIOE_BASE) +#endif static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); #ifdef GPIO_USB_BASE @@ -253,10 +337,29 @@ static void gpio_init (void) { /* Enable GPIO clock. */ +#if MCU_STM32F0 + RCC->AHBENR |= RCC_ENR_IOP_EN; + RCC->AHBRSTR = RCC_RSTR_IOP_RST; + RCC->AHBRSTR = 0; +#else RCC->APB2ENR |= RCC_ENR_IOP_EN; RCC->APB2RSTR = RCC_RSTR_IOP_RST; RCC->APB2RSTR = 0; +#endif + +#if MCU_STM32F0 + GPIO_LED->OSPEEDR = VAL_GPIO_OSPEEDR; + GPIO_LED->OTYPER = VAL_GPIO_OTYPER; + GPIO_LED->MODER = VAL_GPIO_MODER; + GPIO_LED->PUPDR = VAL_GPIO_PUPDR; +#ifdef GPIO_OTHER_BASE + GPIO_OTHER->OSPEEDR = VAL_GPIO_OTHER_OSPEEDR; + GPIO_OTHER->OTYPER = VAL_GPIO_OTHER_OTYPER; + GPIO_OTHER->MODER = VAL_GPIO_OTHER_MODER; + GPIO_OTHER->PUPDR = VAL_GPIO_OTHER_PUPDR; +#endif +#else #ifdef AFIO_MAPR_SOMETHING AFIO->MAPR |= AFIO_MAPR_SOMETHING; #endif @@ -276,6 +379,7 @@ gpio_init (void) GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH; GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL; #endif +#endif } static void @@ -594,6 +698,28 @@ reset (void) * This code may not be at the start of flash ROM, because of DFU. * So, we take the address from PC. */ +#if __ARM_ARCH_6M__ + asm volatile ("cpsid i\n\t" /* Mask all interrupts. */ + "ldr r0, 1f\n\t" /* r0 = RAM start */ + "mov r1, pc\n\t" /* r1 = (PC + 0x0400) & ~0x03ff */ + "mov r2, #0x04\n\t" + "lsl r2, #8\n\t" + "add r1, r1, r2\n\t" + "sub r2, r2, #1\n\t" + "bic r1, r1, r2\n\t" + "mov r2, #188\n" + "2:\n\t" /* Copy vectors. It will be enabled later by clock_init. */ + "ldr r3, [r1, r2]\n\t" + "str r3, [r0, r2]\n\t" + "sub r2, #4\n\t" + "bcs 2b\n\t" + "msr MSP, r3\n\t" /* Main (exception handler) stack. */ + "ldr r0, [r1, #4]\n\t" /* Reset handler. */ + "bx r0\n\t" + ".align 2\n" + "1: .word 0x20000000" + : /* no output */ : /* no input */ : "memory"); +#else asm volatile ("cpsid i\n\t" /* Mask all interrupts. */ "ldr r0, 1f\n\t" /* r0 = SCR */ "mov r1, pc\n\t" /* r1 = (PC + 0x1000) & ~0x0fff */ @@ -609,6 +735,7 @@ reset (void) ".align 2\n" "1: .word 0xe000ed00" : /* no output */ : /* no input */ : "memory"); +#endif /* Never reach here. */ /* Artificial entry to refer FT0, FT1, and FT2. */ |