From 522380097ea768e7474c0de8195cc0ced03904e8 Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Wed, 30 Jul 2014 12:52:48 +0900
Subject: Support Cortex-M0.

---
 example-led/sys.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 2 deletions(-)

(limited to 'example-led')

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.  */
-- 
cgit v1.2.3