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. --- board/board-stm32f0-discovery.h | 47 ++++++++++++++ entry.c | 123 ++++++++++++++++++++++++++++++++++++- example-led/sys.c | 131 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 board/board-stm32f0-discovery.h 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 */ diff --git a/entry.c b/entry.c index 7abde4e..1a8e944 100644 --- a/entry.c +++ b/entry.c @@ -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. */ -- cgit v1.2.3 From 5137db82902ded4cabb4667ade17d1732f73c736 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Wed, 30 Jul 2014 16:09:39 +0900 Subject: Cortex-M0 works. --- chopstx.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++--- entry.c | 16 +++++++++++ example-led/Makefile | 5 ++-- example-led/sample.ld | 13 +++++++++ 4 files changed, 106 insertions(+), 6 deletions(-) diff --git a/chopstx.c b/chopstx.c index 29bea71..3f27832 100644 --- a/chopstx.c +++ b/chopstx.c @@ -61,6 +61,7 @@ #define CPU_EXCEPTION_PRIORITY_CLEAR 0 +#if 0 #define CPU_EXCEPTION_PRIORITY_SVC 0x30 #define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 0x40 @@ -68,6 +69,15 @@ #define CPU_EXCEPTION_PRIORITY_SYSTICK CPU_EXCEPTION_PRIORITY_INTERRUPT #define CPU_EXCEPTION_PRIORITY_INTERRUPT 0xb0 #define CPU_EXCEPTION_PRIORITY_PENDSV 0xc0 +#else +#define CPU_EXCEPTION_PRIORITY_SVC 0x00 + +#define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 0x40 +/* ... */ +#define CPU_EXCEPTION_PRIORITY_SYSTICK CPU_EXCEPTION_PRIORITY_INTERRUPT +#define CPU_EXCEPTION_PRIORITY_INTERRUPT 0x80 +#define CPU_EXCEPTION_PRIORITY_PENDSV 0xc0 +#endif /** * chx_fatal - Fatal error point. @@ -184,7 +194,9 @@ static volatile uint32_t *const SYST_CSR = (uint32_t *const)0xE000E010; static volatile uint32_t *const SYST_RVR = (uint32_t *const)0xE000E014; static volatile uint32_t *const SYST_CVR = (uint32_t *const)0xE000E018; +#ifndef MHZ #define MHZ 72 +#endif static uint32_t usec_to_ticks (uint32_t usec) { @@ -214,8 +226,12 @@ chx_cpu_sched_lock (void) { if (running->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION) { +#if __ARM_ARCH_6M__ + asm volatile ("cpsid i" : : : "memory"); +#else register uint32_t tmp = CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED; asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); +#endif } } @@ -224,8 +240,12 @@ chx_cpu_sched_unlock (void) { if (running->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION) { +#if __ARM_ARCH_6M__ + asm volatile ("cpsie i" : : : "memory"); +#else register uint32_t tmp = CPU_EXCEPTION_PRIORITY_CLEAR; asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); +#endif } } @@ -383,22 +403,42 @@ sched (void) "ldr r1, =running\n\t" /* Update running. */ "str r0, [r1]\n\t" +#if __ARM_ARCH_6M__ + "cmp r0, #0\n\t" + "beq 1f\n\t" +#else "cbz r0, 1f\n\t" +#endif /**/ "add r0, #8\n\t" "ldm r0!, {r4, r5, r6, r7}\n\t" +#if __ARM_ARCH_6M__ + "ldm r0!, {r1, r2, r3}\n\t" + "mov r8, r1\n\t" + "mov r9, r2\n\t" + "mov r10, r3\n\t" + "ldm r0!, {r1, r2}\n\t" + "mov r11, r1\n\t" + "msr PSP, r2\n\t" +#else "ldr r8, [r0], #4\n\t" "ldr r9, [r0], #4\n\t" "ldr r10, [r0], #4\n\t" "ldr r11, [r0], #4\n\t" "ldr r1, [r0], #4\n\t" "msr PSP, r1\n\t" +#endif "ldrb r1, [r0, #3]\n\t" /* ->PRIO field. */ "cmp r1, #247\n\t" "bhi 0f\n\t" /* Leave interrupt disabled if >= 248 */ /**/ + /* Unmask interrupts. */ "mov r0, #0\n\t" - "msr BASEPRI, r0\n" /* Unmask interrupts. */ +#if __ARM_ARCH_6M__ + "cpsie i\n" +#else + "msr BASEPRI, r0\n" +#endif /**/ "0:\n\t" "sub r0, #3\n\t" /* EXC_RETURN to a thread with PSP */ @@ -410,7 +450,12 @@ sched (void) "mov r0, #0\n\t" "mov r1, #0\n\t" "ldr r2, =idle\n\t" /* PC = idle */ +#if __ARM_ARCH_6M__ + "mov r3, #0x010\n\t" + "lsl r3, r3, #20\n\t" /* xPSR = T-flag set (Thumb) */ +#else "mov r3, #0x01000000\n\t" /* xPSR = T-flag set (Thumb) */ +#endif "push {r0, r1, r2, r3}\n\t" "mov r0, #0\n\t" "mov r1, #0\n\t" @@ -418,8 +463,13 @@ sched (void) "mov r3, #0\n\t" "push {r0, r1, r2, r3}\n" /**/ + /* Unmask interrupts. */ "mov r0, #0\n\t" - "msr BASEPRI, r0\n\t" /* Unmask interrupts. */ +#if __ARM_ARCH_6M__ + "cpsie i\n\t" +#else + "msr BASEPRI, r0\n\t" +#endif /**/ "sub r0, #7\n\t" /* EXC_RETURN to a thread with MSP */ "bx r0\n" @@ -430,18 +480,33 @@ void __attribute__ ((naked)) preempt (void) { register struct chx_thread *tp asm ("r0"); - tp = (struct chx_thread *)CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED; - asm ("msr BASEPRI, r0\n\t" + + asm ( +#if __ARM_ARCH_6M__ + "cpsid i\n\t" +#else + "msr BASEPRI, r0\n\t" +#endif "ldr r1, =running\n\t" "ldr r0, [r1]\n\t" +#if __ARM_ARCH_6M__ + "cmp r0, #0\n\t" + "bne 0f\n\t" +#else "cbnz r0, 0f\n\t" +#endif /* It's idle which was preempted. Discard saved registers on stack. */ "ldr r1, =__main_stack_end__\n\t" "msr MSP, r1\n\t" "b sched\n" "0:\n\t" +#if __ARM_ARCH_6M__ + "add r1, r0, #4\n\t" + "add r1, #4\n\t" +#else "add r1, r0, #8\n\t" +#endif /* Save registers onto CHX_THREAD struct. */ "stm r1!, {r4, r5, r6, r7}\n\t" "mov r2, r8\n\t" @@ -494,7 +559,12 @@ svc (void) asm ("ldr r1, =running\n\t" "ldr r0, [r1]\n\t" +#if __ARM_ARCH_6M__ + "add r1, r0, #4\n\t" + "add r1, #4\n\t" +#else "add r1, r0, #8\n\t" +#endif /* Save registers onto CHX_THREAD struct. */ "stm r1!, {r4, r5, r6, r7}\n\t" "mov r2, r8\n\t" diff --git a/entry.c b/entry.c index 1a8e944..0036a3a 100644 --- a/entry.c +++ b/entry.c @@ -379,9 +379,22 @@ static void nmi (void) for (;;); } +extern void svc (void); + static void hard_fault (void) { +#if 1 + register uint32_t primask; + + asm ("mrs %0, PRIMASK" : "=r" (primask)); + + if (primask) + asm volatile ("b svc"); + else + for (;;); +#else for (;;); +#endif } static void mem_manage (void) @@ -462,8 +475,11 @@ void entry (void) "bl chx_systick_init\n\t" "bl gpio_init\n\t" /* Enable interrupts. */ +#if __ARM_ARCH_6M__ +#else "mov r0, #0\n\t" "msr BASEPRI, r0\n\t" +#endif "cpsie i\n\t" /* Call main. */ "mov r1, r0\n\t" diff --git a/example-led/Makefile b/example-led/Makefile index 43c131a..14ff7ff 100644 --- a/example-led/Makefile +++ b/example-led/Makefile @@ -12,9 +12,10 @@ CC = $(CROSS)gcc LD = $(CROSS)gcc OBJCOPY = $(CROSS)objcopy -MCU = cortex-m3 +# MCU = cortex-m3 +MCU = cortex-m0 # -save-temps CWARN = -Wall -Wextra -Wstrict-prototypes -DEFS = -DHAVE_SYS_H -DFREE_STANDING +DEFS = -DHAVE_SYS_H -DFREE_STANDING -DMHZ=48 # DEFS = -DFREE_STANDING -DHAVE_SYS_H -DBUSY_LOOP -DCHX_FLAGS_MAIN=CHOPSTX_SCHED_RR OPT = -O3 -Os -g LIBS = diff --git a/example-led/sample.ld b/example-led/sample.ld index f98d789..07761e0 100644 --- a/example-led/sample.ld +++ b/example-led/sample.ld @@ -9,8 +9,12 @@ __process3_stack_size__ = 0x0100; /* third thread program */ MEMORY { +/* flash0 : org = 0x08000000, len = 4k flash : org = 0x08000000+0x1000, len = 60k +*/ + flash0 : org = 0x08000000, len = 1k + flash : org = 0x08000000+0x0400, len = 60k ram : org = 0x20000000, len = 20k } @@ -36,9 +40,11 @@ SECTIONS build/sys.o(.rodata) build/sys.o(.rodata.*) . = ALIGN(1024); +/* *(.sys.0) *(.sys.1) *(.sys.2) +*/ } > flash0 _text = .; @@ -78,6 +84,13 @@ SECTIONS _etext = .; _textdata = _etext; + .vectors_in_ram : + { + . = ALIGN(8); + __vector_ram_addr__ = .; + KEEP(*(.data.startup.*)) + } > ram + .process_stack : { . = ALIGN(8); -- cgit v1.2.3 From f865e5149c7c8c82f1b6a62511f5310845803986 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Thu, 31 Jul 2014 14:56:16 +0900 Subject: Add FSM-55. --- board/board-fsm-55.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 board/board-fsm-55.h diff --git a/board/board-fsm-55.h b/board/board-fsm-55.h new file mode 100644 index 0000000..9cb405e --- /dev/null +++ b/board/board-fsm-55.h @@ -0,0 +1,42 @@ +/* + * 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 5 + +/* + * Port A setup. + * PA5 - ON (LED 1:ON 0:OFF) + * PA4 - Pull DOWN + */ +#define VAL_GPIO_MODER 0x00145555 /* Output Pin0-7, Pin9 and Pin10 */ +#define VAL_GPIO_OTYPER 0x0000001f /* Open-drain for Pin0-4, Push-Pull*/ +#define VAL_GPIO_OSPEEDR 0x003cffff /* High speed */ +#define VAL_GPIO_PUPDR 0x00000000 /* No pull-up/pull-down */ + +#define GPIO_LED_BASE GPIOA_BASE + +#define RCC_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPFEN) +#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPFRST) + +/* ??? NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */ + +#define GPIO_OTHER_BASE GPIOF_BASE /* USER BUTTON */ +/* + * Port F setup. + * PF0 - USER Button + */ +#define VAL_GPIO_OTHER_MODER 0x00000000 /* Input Pin0 */ +#define VAL_GPIO_OTHER_OTYPER 0x00000000 +#define VAL_GPIO_OTHER_OSPEEDR 0x00000000 +#define VAL_GPIO_OTHER_PUPDR 0x00000001 /* Pull-up Pin0 */ -- cgit v1.2.3 From b05e4030d20d3b595fe9953a669ddf6991fd3874 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Thu, 31 Jul 2014 14:57:05 +0900 Subject: Add example-fsm-55. --- example-fsm-55/Makefile | 31 ++ example-fsm-55/hacker-emblem.c | 165 +++++++++ example-fsm-55/hacker-emblem.ld | 155 ++++++++ example-fsm-55/sys.c | 770 ++++++++++++++++++++++++++++++++++++++++ example-fsm-55/sys.h | 115 ++++++ 5 files changed, 1236 insertions(+) create mode 100644 example-fsm-55/Makefile create mode 100644 example-fsm-55/hacker-emblem.c create mode 100644 example-fsm-55/hacker-emblem.ld create mode 100644 example-fsm-55/sys.c create mode 100644 example-fsm-55/sys.h diff --git a/example-fsm-55/Makefile b/example-fsm-55/Makefile new file mode 100644 index 0000000..168d50e --- /dev/null +++ b/example-fsm-55/Makefile @@ -0,0 +1,31 @@ +# Makefile for Hacker Emblem application of Chopstx + +PROJECT = hacker-emblem + +CHOPSTX = .. +LDSCRIPT= hacker-emblem.ld +CSRC = sys.c hacker-emblem.c + +################################### +CROSS = arm-none-eabi- +CC = $(CROSS)gcc +LD = $(CROSS)gcc +OBJCOPY = $(CROSS)objcopy + +MCU = cortex-m0 # -save-temps +CWARN = -Wall -Wextra -Wstrict-prototypes +DEFS = -DHAVE_SYS_H -DFREE_STANDING -DMHZ=48 +OPT = -O3 -Os -g +LIBS = + +#################### +include ../rules.mk + +board.h: + @echo Please make a symbolic link \'board.h\' to a file in ../board; + @exit 1 + +sys.c: board.h + +distclean: clean + rm -f board.h diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c new file mode 100644 index 0000000..b66fe26 --- /dev/null +++ b/example-fsm-55/hacker-emblem.c @@ -0,0 +1,165 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> + +#include "board.h" + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) + +static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0; +static chopstx_cond_t cnd1; + +static uint8_t u; + +static uint8_t l_data[5]; + +static void +set_led_display (uint32_t data) +{ + if (data) + { + l_data[0] = l_data[1] = l_data[2] = l_data[3] = l_data[4] = 0x1f; + } + else + { + l_data[0] = l_data[1] = l_data[2] = l_data[3] = l_data[4] = 0x00; + } +} + + +static void +wait_for (uint32_t usec) +{ + chopstx_usec_wait (usec); +} + +static void +led_prepare_column (uint8_t data) +{ + GPIO_LED->ODR = data; +} + +static void +led_enable_row (uint8_t row) +{ + static const uint8_t row_to_pin[5] = { 5, 6, 7, 9, 10 }; + + GPIO_LED->BSRR = (1 << row_to_pin[row]); +} + +static void * +led (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + int i; + + for (i = 0; i < 5; i++) + { + led_prepare_column (l_data [i]); + led_enable_row (i); + wait_for (1000); + } + } + + return NULL; +} + +static void * +blk (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd1, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + set_led_display (0); + wait_for (200*1000); + set_led_display (u); + wait_for (200*1000); + } + + return NULL; +} + +#define PRIO_LED 3 +#define PRIO_BLK 2 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; +extern uint8_t __process2_stack_base__, __process2_stack_size__; +extern uint8_t __process3_stack_base__, __process3_stack_size__; + +const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_led = (size_t)&__process1_stack_size__; + +const uint32_t __stackaddr_blk = (uint32_t)&__process2_stack_base__; +const size_t __stacksize_blk = (size_t)&__process2_stack_size__; + + + +int +main (int argc, const char *argv[]) +{ + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + chopstx_cond_init (&cnd1); + + chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); + chopstx_create (PRIO_BLK, __stackaddr_blk, __stacksize_blk, blk, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_cond_signal (&cnd1); + chopstx_mutex_unlock (&mtx); + + while (1) + { + u ^= 1; + wait_for (200*1000*6); + } + + return 0; +} diff --git a/example-fsm-55/hacker-emblem.ld b/example-fsm-55/hacker-emblem.ld new file mode 100644 index 0000000..07761e0 --- /dev/null +++ b/example-fsm-55/hacker-emblem.ld @@ -0,0 +1,155 @@ +/* + * ST32F103 memory setup. + */ +__main_stack_size__ = 0x0100; /* Exception handlers */ +__process0_stack_size__ = 0x0100; /* Main program */ +__process1_stack_size__ = 0x0100; /* first thread program */ +__process2_stack_size__ = 0x0100; /* second thread program */ +__process3_stack_size__ = 0x0100; /* third thread program */ + +MEMORY +{ +/* + flash0 : org = 0x08000000, len = 4k + flash : org = 0x08000000+0x1000, len = 60k +*/ + flash0 : org = 0x08000000, len = 1k + flash : org = 0x08000000+0x0400, len = 60k + ram : org = 0x20000000, len = 20k +} + +__flash_start__ = 0x08001000; +__flash_end__ = 0x08020000; + +__ram_start__ = ORIGIN(ram); +__ram_size__ = 20k; +__ram_end__ = __ram_start__ + __ram_size__; + +SECTIONS +{ + . = 0; + + .sys : ALIGN(16) SUBALIGN(16) + { + _sys = .; + KEEP(*(.vectors)) + . = ALIGN(16); + *(.sys.version) + build/sys.o(.text) + build/sys.o(.text.*) + build/sys.o(.rodata) + build/sys.o(.rodata.*) + . = ALIGN(1024); +/* + *(.sys.0) + *(.sys.1) + *(.sys.2) +*/ + } > flash0 + + _text = .; + + .startup : ALIGN(128) SUBALIGN(128) + { + KEEP(*(.startup.vectors)) + . = ALIGN (16); + } > flash =0xffffffff + + .text : ALIGN(16) SUBALIGN(16) + { + *(.text.startup.*) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.glue_7t) + *(.glue_7) + *(.gcc*) + } > flash + + .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash + + .ARM.exidx : { + PROVIDE(__exidx_start = .); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE(__exidx_end = .); + } > flash + + .eh_frame_hdr : {*(.eh_frame_hdr)} > flash + + .eh_frame : ONLY_IF_RO {*(.eh_frame)} > flash + + .textalign : ONLY_IF_RO { . = ALIGN(8); } > flash + + _etext = .; + _textdata = _etext; + + .vectors_in_ram : + { + . = ALIGN(8); + __vector_ram_addr__ = .; + KEEP(*(.data.startup.*)) + } > ram + + .process_stack : + { + . = ALIGN(8); + __process3_stack_base__ = .; + . += __process3_stack_size__; + . = ALIGN(8); + __process_stack3_end__ = .; + __process2_stack_base__ = .; + . += __process2_stack_size__; + . = ALIGN(8); + __process_stack2_end__ = .; + __process1_stack_base__ = .; + . += __process1_stack_size__; + . = ALIGN(8); + __process_stack1_end__ = .; + __process0_stack_base__ = .; + . += __process0_stack_size__; + . = ALIGN(8); + __process0_stack_end__ = .; + } > ram + + .main_stack : + { + . = ALIGN(8); + __main_stack_base__ = .; + . += __main_stack_size__; + . = ALIGN(8); + __main_stack_end__ = .; + } > ram + + .data : + { + . = ALIGN(4); + PROVIDE(_data = .); + *(.data) + . = ALIGN(4); + *(.data.*) + . = ALIGN(4); + *(.ramtext) + . = ALIGN(4); + PROVIDE(_edata = .); + } > ram AT > flash + + .bss : + { + . = ALIGN(4); + PROVIDE(_bss_start = .); + *(.bss) + . = ALIGN(4); + *(.bss.*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + PROVIDE(_bss_end = .); + } > ram + + PROVIDE(end = .); + _end = .; +} + +__heap_base__ = _end; +__heap_end__ = __ram_end__; diff --git a/example-fsm-55/sys.c b/example-fsm-55/sys.c new file mode 100644 index 0000000..3171376 --- /dev/null +++ b/example-fsm-55/sys.c @@ -0,0 +1,770 @@ +/* + * sys.c - system routines for the initial page for STM32F030 / STM32F103. + * + * Copyright (C) 2013, 2014 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + * + * When the flash ROM is protected, we cannot modify the initial page. + * We put some system routines (which is useful for any program) here. + */ + +#include <stdint.h> +#include <stdlib.h> +#include "board.h" + + +#define CORTEX_PRIORITY_BITS 4 +#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS)) +#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) +#define STM32_PLLSRC_HSE (1 << 16) + +#define STM32_PLLXTPRE_DIV1 (0 << 17) +#define STM32_PLLXTPRE_DIV2 (1 << 17) + +#define STM32_HPRE_DIV1 (0 << 4) + +#define STM32_PPRE1_DIV1 (0 << 8) +#define STM32_PPRE1_DIV2 (4 << 8) + +#define STM32_PPRE2_DIV1 (0 << 11) +#define STM32_PPRE2_DIV2 (4 << 11) + +#define STM32_ADCPRE_DIV4 (1 << 14) +#define STM32_ADCPRE_DIV6 (2 << 14) + +#define STM32_USBPRE_DIV1P5 (0 << 22) + +#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 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_ADCPRE STM32_ADCPRE_DIV6 +#define STM32_MCOSEL STM32_MCO_NOCLOCK +#define STM32_USBPRE STM32_USBPRE_DIV1P5 + +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) +#define STM32_SYSCLK STM32_PLLCLKOUT +#define STM32_HCLK (STM32_SYSCLK / 1) + +struct NVIC { + uint32_t ISER[8]; + uint32_t unused1[24]; + uint32_t ICER[8]; + uint32_t unused2[24]; + uint32_t ISPR[8]; + uint32_t unused3[24]; + uint32_t ICPR[8]; + uint32_t unused4[24]; + uint32_t IABR[8]; + uint32_t unused5[56]; + uint32_t IPR[60]; +}; + +static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100); +#define NVIC_ISER(n) (NVICBase->ISER[n >> 5]) +#define NVIC_ICPR(n) (NVICBase->ICPR[n >> 5]) +#define NVIC_IPR(n) (NVICBase->IPR[n >> 2]) + +static void +nvic_enable_vector (uint32_t n, uint32_t prio) +{ + unsigned int sh = (n & 3) << 3; + + NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh); + NVIC_ICPR (n) = 1 << (n & 0x1F); + NVIC_ISER (n) = 1 << (n & 0x1F); +} + + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +struct RCC { + volatile uint32_t CR; + volatile uint32_t CFGR; + volatile uint32_t CIR; + volatile uint32_t APB2RSTR; + volatile uint32_t APB1RSTR; + volatile uint32_t AHBENR; + volatile uint32_t APB2ENR; + 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) +static struct RCC *const RCC = ((struct RCC *const)RCC_BASE); + +#define RCC_APB1ENR_USBEN 0x00800000 +#define RCC_APB1RSTR_USBRST 0x00800000 + +#define RCC_CR_HSION 0x00000001 +#define RCC_CR_HSIRDY 0x00000002 +#define RCC_CR_HSITRIM 0x000000F8 +#define RCC_CR_HSEON 0x00010000 +#define RCC_CR_HSERDY 0x00020000 +#define RCC_CR_PLLON 0x01000000 +#define RCC_CR_PLLRDY 0x02000000 + +#define RCC_CFGR_SWS 0x0000000C +#define RCC_CFGR_SWS_HSI 0x00000000 + +#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 +#define RCC_APB2RSTR_IOPCRST 0x00000010 +#define RCC_APB2RSTR_IOPDRST 0x00000020 + +#define RCC_APB2ENR_AFIOEN 0x00000001 +#define RCC_APB2ENR_IOPAEN 0x00000004 +#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; + volatile uint32_t KEYR; + volatile uint32_t OPTKEYR; + volatile uint32_t SR; + volatile uint32_t CR; + volatile uint32_t AR; + volatile uint32_t RESERVED; + volatile uint32_t OBR; + volatile uint32_t WRPR; +}; + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) +static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE); + +static void +clock_init (void) +{ + /* HSI setup */ + RCC->CR |= RCC_CR_HSION; + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; + /* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */ + RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION); + RCC->CFGR = 0; + 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; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; + + /* Clock settings */ + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE + | STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* Switching on the configured clock source. */ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; + + /* + * We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR. + */ + + /* Flash setup */ + FLASH->ACR = STM32_FLASHBITS; + + /* CRC */ + RCC->AHBENR |= RCC_AHBENR_CRCEN; + +#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; + volatile uint32_t MAPR; + volatile uint32_t EXTICR[4]; + uint32_t RESERVED0; + volatile uint32_t MAPR2; +}; + +#define AFIO_BASE 0x40010000 +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; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; +}; + +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#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 +static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE); +#endif +#ifdef GPIO_OTHER_BASE +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); +#endif + +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 + + GPIO_USB->ODR = VAL_GPIO_ODR; + GPIO_USB->CRH = VAL_GPIO_CRH; + GPIO_USB->CRL = VAL_GPIO_CRL; + +#if GPIO_USB_BASE != GPIO_LED_BASE + GPIO_LED->ODR = VAL_GPIO_LED_ODR; + GPIO_LED->CRH = VAL_GPIO_LED_CRH; + GPIO_LED->CRL = VAL_GPIO_LED_CRL; +#endif + +#ifdef GPIO_OTHER_BASE + GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR; + GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH; + GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL; +#endif +#endif +} + +static void +usb_cable_config (int enable) +{ +#if defined(GPIO_USB_SET_TO_ENABLE) + if (enable) + GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE); + else + GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE); +#elif defined(GPIO_USB_CLEAR_TO_ENABLE) + if (enable) + GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); + else + GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); +#else + (void)enable; +#endif +} + +void +set_led (int on) +{ +#if defined(GPIO_LED_CLEAR_TO_EMIT) + if (on) + GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT); + else + GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT); +#else + if (on) + GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT); + else + GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT); +#endif +} + +static void wait (int count) +{ + int i; + + for (i = 0; i < count; i++) + asm volatile ("" : : "r" (i) : "memory"); +} + + +static void +usb_lld_sys_shutdown (void) +{ + RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + usb_cable_config (0); +} + +static void +usb_lld_sys_init (void) +{ + if ((RCC->APB1ENR & RCC_APB1ENR_USBEN) + && (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0) + /* Make sure the device is disconnected, even after core reset. */ + { + usb_lld_sys_shutdown (); + /* Disconnect requires SE0 (>= 2.5uS). */ + wait (300); + } + + usb_cable_config (1); + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + nvic_enable_vector (USB_LP_CAN1_RX0_IRQn, + CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY)); + /* + * Note that we also have other IRQ(s): + * USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous) + * USBWakeUp_IRQn (suspend/resume) + */ + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + RCC->APB1RSTR = 0; +} + +#define FLASH_KEY1 0x45670123UL +#define FLASH_KEY2 0xCDEF89ABUL + +enum flash_status +{ + FLASH_BUSY = 1, + FLASH_ERROR_PG, + FLASH_ERROR_WRP, + FLASH_COMPLETE, + FLASH_TIMEOUT +}; + +static void __attribute__ ((used)) +flash_unlock (void) +{ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; +} + + +#define intr_disable() asm volatile ("cpsid i" : : : "memory") +#define intr_enable() asm volatile ("cpsie i" : : : "memory") + +#define FLASH_SR_BSY 0x01 +#define FLASH_SR_PGERR 0x04 +#define FLASH_SR_WRPRTERR 0x10 +#define FLASH_SR_EOP 0x20 + +#define FLASH_CR_PG 0x0001 +#define FLASH_CR_PER 0x0002 +#define FLASH_CR_MER 0x0004 +#define FLASH_CR_OPTPG 0x0010 +#define FLASH_CR_OPTER 0x0020 +#define FLASH_CR_STRT 0x0040 +#define FLASH_CR_LOCK 0x0080 +#define FLASH_CR_OPTWRE 0x0200 +#define FLASH_CR_ERRIE 0x0400 +#define FLASH_CR_EOPIE 0x1000 + +static int +flash_wait_for_last_operation (uint32_t timeout) +{ + int status; + + do + { + status = FLASH->SR; + if (--timeout == 0) + break; + } + while ((status & FLASH_SR_BSY) != 0); + + return status & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR); +} + +#define FLASH_PROGRAM_TIMEOUT 0x00010000 +#define FLASH_ERASE_TIMEOUT 0x01000000 + +static int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PG; + + *(volatile uint16_t *)addr = data; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PG; + } + intr_enable (); + + return status; +} + +static int +flash_erase_page (uint32_t addr) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = addr; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PER; + } + intr_enable (); + + return status; +} + +static int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + const uint8_t *p; + + for (p = p_start; p < p_start + size; p++) + if (*p != 0xff) + return 0; + + return 1; +} + +extern uint8_t __flash_start__, __flash_end__; + +static int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int status; + uint32_t flash_start = (uint32_t)&__flash_start__; + uint32_t flash_end = (uint32_t)&__flash_end__; + + if (dst_addr < flash_start || dst_addr + len > flash_end) + return 0; + + while (len) + { + uint16_t hw = *src++; + + hw |= (*src++ << 8); + status = flash_program_halfword (dst_addr, hw); + if (status != 0) + return 0; /* error return */ + + dst_addr += 2; + len -= 2; + } + + return 1; +} + +#define OPTION_BYTES_ADDR 0x1ffff800 + +static int +flash_protect (void) +{ + int status; + uint32_t option_bytes_value; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + FLASH->CR |= FLASH_CR_OPTER; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_OPTER; + } + intr_enable (); + + if (status != 0) + return 0; + + option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR; + return (option_bytes_value & 0xff) == 0xff ? 1 : 0; +} + +static void __attribute__((naked)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + uint32_t addr = (uint32_t)&__flash_start__; + uint32_t end = (uint32_t)&__flash_end__; + int r; + + while (addr < end) + { + r = flash_erase_page (addr); + if (r != 0) + break; + + addr += FLASH_PAGE_SIZE; + } + + if (addr >= end) + (*entry) (); + + for (;;); +} + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); + +#define SYSRESETREQ 0x04 +static void +nvic_system_reset (void) +{ + SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); + asm volatile ("dsb"); + for (;;); +} + +static void __attribute__ ((naked)) +reset (void) +{ + /* + * This code may not be at 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 + extern const unsigned long *FT0, *FT1, *FT2; + 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 */ + "mov r2, #0x1000\n\t" + "add r1, r1, r2\n\t" + "sub r2, r2, #1\n\t" + "bic r1, r1, r2\n\t" + "str r1, [r0, #8]\n\t" /* Set SCR->VCR */ + "ldr r0, [r1], #4\n\t" + "msr MSP, r0\n\t" /* Main (exception handler) stack. */ + "ldr r0, [r1]\n\t" /* Reset handler. */ + "bx r0\n\t" + ".align 2\n" + "1: .word 0xe000ed00" + : /* no output */ : /* no input */ : "memory"); + /* Artificial entry to refer FT0, FT1, and FT2. */ + asm volatile ("" + : : "r" (FT0), "r" (FT1), "r" (FT2)); +#endif + /* Never reach here. */ +} + +typedef void (*handler)(void); +extern uint8_t __ram_end__; + +handler vector[] __attribute__ ((section(".vectors"))) = { + (handler)&__ram_end__, + reset, + (handler)set_led, + flash_unlock, + (handler)flash_program_halfword, + (handler)flash_erase_page, + (handler)flash_check_blank, + (handler)flash_write, + (handler)flash_protect, + (handler)flash_erase_all_and_exec, + usb_lld_sys_init, + usb_lld_sys_shutdown, + nvic_system_reset, + clock_init, + gpio_init, + NULL, +}; + +const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = { + 3*2+2, /* bLength */ + 0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/ + /* sys version: "2.0" */ + '2', 0, '.', 0, '0', 0, +}; diff --git a/example-fsm-55/sys.h b/example-fsm-55/sys.h new file mode 100644 index 0000000..25d33f1 --- /dev/null +++ b/example-fsm-55/sys.h @@ -0,0 +1,115 @@ +extern const uint8_t sys_version[8]; + +typedef void (*handler)(void); +extern handler vector[16]; + +static inline const uint8_t * +unique_device_id (void) +{ + /* STM32F103 has 96-bit unique device identifier */ + const uint8_t *addr = (const uint8_t *)0x1ffff7e8; + + return addr; +} + +static inline void +set_led (int on) +{ + void (*func) (int) = (void (*)(int))vector[2]; + + return (*func) (on); +} + +static inline void +flash_unlock (void) +{ + (*vector[3]) (); +} + +static inline int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[4]; + + return (*func) (addr, data); +} + +static inline int +flash_erase_page (uint32_t addr) +{ + int (*func) (uint32_t) = (int (*)(uint32_t))vector[5]; + + return (*func) (addr); +} + +static inline int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + int (*func) (const uint8_t *, int) = (int (*)(const uint8_t *, int))vector[6]; + + return (*func) (p_start, size); +} + +static inline int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int (*func) (uint32_t, const uint8_t *, size_t) + = (int (*)(uint32_t, const uint8_t *, size_t))vector[7]; + + return (*func) (dst_addr, src, len); +} + +static inline int +flash_protect (void) +{ + int (*func) (void) = (int (*)(void))vector[8]; + + return (*func) (); +} + +static inline void __attribute__((noreturn)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9]; + + (*func) (entry); + for (;;); +} + +static inline void +usb_lld_sys_init (void) +{ + (*vector[10]) (); +} + +static inline void +usb_lld_sys_shutdown (void) +{ + (*vector[11]) (); +} + +static inline void +nvic_system_reset (void) +{ + (*vector[12]) (); +} + +/* + * Users can override INLINE by 'attribute((used))' to have an + * implementation defined. + */ +#if !defined(INLINE) +#define INLINE __inline__ +#endif + +static INLINE void +clock_init (void) +{ + (*vector[13]) (); +} + +static INLINE void +gpio_init (void) +{ + (*vector[14]) (); +} -- cgit v1.2.3 From dffcf2d4bf9bf3e78a85fde704659be2b8384d40 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 4 Aug 2014 11:23:43 +0900 Subject: fix col/row. --- example-fsm-55/gnu.txt | 179 +++++++++++++++++++++++++ example-fsm-55/hacker-emblem.c | 149 ++++++++++++++------- example-fsm-55/hh.txt | 59 +++++++++ example-fsm-55/hiroshi-ayumi.c | 217 +++++++++++++++++++++++++++++++ example-fsm-55/l55.txt | 119 +++++++++++++++++ example-fsm-55/name.txt | 287 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 961 insertions(+), 49 deletions(-) create mode 100644 example-fsm-55/gnu.txt create mode 100644 example-fsm-55/hh.txt create mode 100644 example-fsm-55/hiroshi-ayumi.c create mode 100644 example-fsm-55/l55.txt create mode 100644 example-fsm-55/name.txt diff --git a/example-fsm-55/gnu.txt b/example-fsm-55/gnu.txt new file mode 100644 index 0000000..feb789a --- /dev/null +++ b/example-fsm-55/gnu.txt @@ -0,0 +1,179 @@ +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +____* 01 +____* 01 +____* 01 +_____ 00 + +____* 01 +___*_ 02 +___*_ 02 +___*_ 02 +____* 01 + +___** 03 +__*__ 04 +__*__ 04 +__*__ 04 +___** 03 + +__*** 07 +_*___ 08 +_*__* 09 +_*___ 08 +__*** 07 + +_***_ 0e +*____ 10 +*__** 13 +*___* 11 +_***_ 0e + +***__ 1c +_____ 00 +__**_ 06 +___*_ 02 +***__ 1c + +**__* 19 +____* 01 +_**_* 0d +__*_* 05 +**__* 19 + +*__*_ 12 + __** 03 +**_*_ 1a +_*_*_ 0a +*__*_ 12 + +__*__ 04 + _**_ 06 +*_*_* 15 +*_*__ 14 +__*__ 04 + +_*___ 08 +_**__ 0c +_*_*_ 0a +_*__* 09 +_*___ 08 + +*___* 11 +**__* 19 +*_*_* 15 +*__** 13 +*___* 11 + +___*_ 02 +*__*_ 12 +_*_*_ 0a +__**_ 06 +___*_ 02 + +__*_* 05 +__*_* 05 +*_*_* 15 +_**_* 0d +__*__ 04 + +_*_*_ 0a +_*_*_ 0a +_*_*_ 0a +**_*_ 1a +_*__* 09 + +*_*__ 14 +*_*__ 14 +*_*__ 14 +*_*__ 14 +*__** 13 + +_*___ 08 +_*___ 08 +_*___ 08 +_*___ 08 +__*** 07 + +*___* 11 +*___* 11 +*___* 11 +*___* 11 +_***_ 0e + +___*_ 02 +___*_ 02 +___*_ 02 +___*_ 02 +***__ 1c + +__*__ 04 +__*__ 04 +__*__ 04 +__*__ 04 +**___ 18 + +_*___ 08 +_*___ 08 +_*___ 08 +_*___ 08 +*____ 10 + +*___* 11 +*___* 11 +*___* 11 +*____ 10 +____* 01 + +___** 03 +___** 03 +___** 03 +_____ 00 +___*_ 02 + +__**_ 06 +__**_ 06 +__**_ 06 +_____ 00 +__*__ 04 + +_**__ 0c +_**__ 0c +_**__ 0c +_____ 00 +_*___ 08 + +**___ 18 +**___ 18 +**___ 18 +_____ 00 +*____ 10 + +*____ 10 +*____ 10 +*____ 10 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index b66fe26..ddf83db 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -33,26 +33,27 @@ struct GPIO { #define GPIOF ((struct GPIO *) GPIOF_BASE) static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); - +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); + static chopstx_mutex_t mtx; static chopstx_cond_t cnd0; -static chopstx_cond_t cnd1; -static uint8_t u; +static uint8_t +user_button (void) +{ + return (GPIO_OTHER->IDR & 1) == 0; +} static uint8_t l_data[5]; static void set_led_display (uint32_t data) { - if (data) - { - l_data[0] = l_data[1] = l_data[2] = l_data[3] = l_data[4] = 0x1f; - } - else - { - l_data[0] = l_data[1] = l_data[2] = l_data[3] = l_data[4] = 0x00; - } + l_data[0] = (data >> 0) & 0x1f; + l_data[1] = (data >> 5) & 0x1f; + l_data[2] = (data >> 10) & 0x1f; + l_data[3] = (data >> 15) & 0x1f; + l_data[4] = (data >> 20) & 0x1f; } @@ -63,17 +64,22 @@ wait_for (uint32_t usec) } static void -led_prepare_column (uint8_t data) +led_prepare_row (uint8_t col) { + uint16_t data = 0x1f; + + data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; + data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; + data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; + data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; + data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; GPIO_LED->ODR = data; } static void -led_enable_row (uint8_t row) +led_enable_column (uint8_t col) { - static const uint8_t row_to_pin[5] = { 5, 6, 7, 9, 10 }; - - GPIO_LED->BSRR = (1 << row_to_pin[row]); + GPIO_LED->BRR = (1 << col); } static void * @@ -91,8 +97,8 @@ led (void *arg) for (i = 0; i < 5; i++) { - led_prepare_column (l_data [i]); - led_enable_row (i); + led_prepare_row (i); + led_enable_column (i); wait_for (1000); } } @@ -100,65 +106,110 @@ led (void *arg) return NULL; } -static void * -blk (void *arg) -{ - (void)arg; - - chopstx_mutex_lock (&mtx); - chopstx_cond_wait (&cnd1, &mtx); - chopstx_mutex_unlock (&mtx); - - while (1) - { - set_led_display (0); - wait_for (200*1000); - set_led_display (u); - wait_for (200*1000); - } - - return NULL; -} - #define PRIO_LED 3 -#define PRIO_BLK 2 extern uint8_t __process1_stack_base__, __process1_stack_size__; -extern uint8_t __process2_stack_base__, __process2_stack_size__; -extern uint8_t __process3_stack_base__, __process3_stack_size__; const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; const size_t __stacksize_led = (size_t)&__process1_stack_size__; -const uint32_t __stackaddr_blk = (uint32_t)&__process2_stack_base__; -const size_t __stacksize_blk = (size_t)&__process2_stack_size__; - +#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) + +static uint32_t l55[20] = { + DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), + DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), + DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), + DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00), + DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00), + DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04), + DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06), + DATA55 (0x00, 0x00, 0x04, 0x03, 0x06), + DATA55 (0x00, 0x00, 0x02, 0x01, 0x07), + DATA55 (0x02, 0x00, 0x00, 0x05, 0x03), + DATA55 (0x03, 0x00, 0x00, 0x01, 0x05), + DATA55 (0x03, 0x00, 0x00, 0x02, 0x11), + DATA55 (0x13, 0x00, 0x00, 0x01, 0x10), + DATA55 (0x11, 0x01, 0x00, 0x00, 0x12), + DATA55 (0x12, 0x11, 0x00, 0x00, 0x10), + DATA55 (0x18, 0x11, 0x00, 0x00, 0x01), + DATA55 (0x08, 0x19, 0x00, 0x00, 0x10), + DATA55 (0x09, 0x18, 0x10, 0x00, 0x00), + DATA55 (0x08, 0x09, 0x18, 0x00, 0x00), + DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), +}; +static uint32_t gnu[30] = { + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x01, 0x01, 0x01, 0x00), + DATA55 (0x01, 0x02, 0x02, 0x02, 0x01), + DATA55 (0x03, 0x04, 0x04, 0x04, 0x03), + DATA55 (0x07, 0x08, 0x09, 0x08, 0x07), + DATA55 (0x0e, 0x10, 0x13, 0x11, 0x0e), + DATA55 (0x1c, 0x00, 0x06, 0x02, 0x1c), + DATA55 (0x19, 0x01, 0x0d, 0x05, 0x19), + DATA55 (0x12, 0x03, 0x1a, 0x0a, 0x12), + DATA55 (0x04, 0x06, 0x15, 0x14, 0x04), + DATA55 (0x08, 0x0c, 0x0a, 0x09, 0x08), + DATA55 (0x11, 0x19, 0x15, 0x13, 0x11), + DATA55 (0x02, 0x12, 0x0a, 0x06, 0x02), + DATA55 (0x05, 0x05, 0x15, 0x0d, 0x04), + DATA55 (0x0a, 0x0a, 0x0a, 0x1a, 0x09), + DATA55 (0x14, 0x14, 0x14, 0x14, 0x13), + DATA55 (0x08, 0x08, 0x08, 0x08, 0x07), + DATA55 (0x11, 0x11, 0x11, 0x11, 0x0e), + DATA55 (0x02, 0x02, 0x02, 0x02, 0x1c), + DATA55 (0x04, 0x04, 0x04, 0x04, 0x18), + DATA55 (0x08, 0x08, 0x08, 0x08, 0x10), + DATA55 (0x11, 0x11, 0x11, 0x10, 0x01), + DATA55 (0x03, 0x03, 0x03, 0x00, 0x02), + DATA55 (0x06, 0x06, 0x06, 0x00, 0x04), + DATA55 (0x0c, 0x0c, 0x0c, 0x00, 0x08), + DATA55 (0x18, 0x18, 0x18, 0x00, 0x10), + DATA55 (0x10, 0x10, 0x10, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), +}; int main (int argc, const char *argv[]) { + uint8_t state = 0; + (void)argc; (void)argv; chopstx_mutex_init (&mtx); chopstx_cond_init (&cnd0); - chopstx_cond_init (&cnd1); chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); - chopstx_create (PRIO_BLK, __stackaddr_blk, __stacksize_blk, blk, NULL); chopstx_usec_wait (200*1000); chopstx_mutex_lock (&mtx); chopstx_cond_signal (&cnd0); - chopstx_cond_signal (&cnd1); chopstx_mutex_unlock (&mtx); while (1) { - u ^= 1; - wait_for (200*1000*6); + int i; + + if (state) + for (i = 0; i < 20; i++) + { + if (user_button ()) + state = 0; + set_led_display (l55[i]); + wait_for (500*1000); + } + else + for (i = 0; i < 30; i++) + { + if (user_button ()) + state = 1; + set_led_display (gnu[i]); + wait_for (200*1000); + } } return 0; diff --git a/example-fsm-55/hh.txt b/example-fsm-55/hh.txt new file mode 100644 index 0000000..72f51e4 --- /dev/null +++ b/example-fsm-55/hh.txt @@ -0,0 +1,59 @@ +o...o +o...o +ooooo +o...o +o...o + +..o. +.o.o. +o...o +ooooo +o...o + +ooooo +o...o +oooo. +o.... +o.... + +o...o +o...o +.ooo. +..o.. +..o.. + +.ooo. +o.... +o.... +o...o +.ooo. + +o..o. +o.o.. +ooo.. +o..o. +o...o + +ooo +.o. +.o. +.o. +ooo + +o...o 11 +oo..o 19 +o.o.o 15 +o..oo 13 +o...o 11 + +.ooo. 0e +o.... 10 +o..oo 13 +o...o 11 +.ooo. 0e + +oo +oo +oo +.. +o. diff --git a/example-fsm-55/hiroshi-ayumi.c b/example-fsm-55/hiroshi-ayumi.c new file mode 100644 index 0000000..8c47d54 --- /dev/null +++ b/example-fsm-55/hiroshi-ayumi.c @@ -0,0 +1,217 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> + +#include "board.h" + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) + +static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0; + +static uint8_t +user_button (void) +{ + return (GPIO_OTHER->IDR & 1) == 0; +} + +static uint8_t l_data[5]; + +static void +set_led_display (uint32_t data) +{ + l_data[0] = (data >> 0) & 0x1f; + l_data[1] = (data >> 5) & 0x1f; + l_data[2] = (data >> 10) & 0x1f; + l_data[3] = (data >> 15) & 0x1f; + l_data[4] = (data >> 20) & 0x1f; +} + + +static void +wait_for (uint32_t usec) +{ + chopstx_usec_wait (usec); +} + +static void +led_prepare_row (uint8_t col) +{ + uint16_t data = 0x1f; + + data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; + data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; + data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; + data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; + data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; + GPIO_LED->ODR = data; +} + +static void +led_enable_column (uint8_t col) +{ + GPIO_LED->BRR = (1 << col); +} + +static void * +led (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + int i; + + for (i = 0; i < 5; i++) + { + led_prepare_row (i); + led_enable_column (i); + wait_for (1000); + } + } + + return NULL; +} + +#define PRIO_LED 3 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; + +const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_led = (size_t)&__process1_stack_size__; + +#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) +#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) + +static uint32_t image0[] = { + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x01,0x00,0x00,0x00), + DATA55 (0x01,0x03,0x01,0x01,0x00), + DATA55 (0x02,0x06,0x02,0x02,0x01), + DATA55 (0x05,0x0d,0x05,0x05,0x03), + DATA55 (0x0b,0x1a,0x0a,0x0a,0x06), + DATA55 (0x16,0x14,0x14,0x14,0x0c), + DATA55 (0x0d,0x08,0x09,0x08,0x19), + DATA55 (0x1b,0x11,0x12,0x10,0x13), + DATA55 (0x17,0x03,0x04,0x00,0x07), + DATA55 (0x0f,0x06,0x09,0x01,0x0e), + DATA55 (0x1e,0x0c,0x12,0x02,0x1c), + DATA55 (0x1d,0x19,0x05,0x05,0x18), + DATA55 (0x1a,0x12,0x0a,0x0a,0x11), + DATA55 (0x14,0x04,0x14,0x14,0x03), + DATA55 (0x08,0x08,0x08,0x09,0x06), + DATA55 (0x10,0x10,0x10,0x12,0x0c), + DATA55 (0x00,0x00,0x00,0x04,0x18), + DATA55 (0x00,0x00,0x00,0x08,0x10), + DATA55 (0x00,0x00,0x00,0x10,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), +}; + +static uint32_t image1[] = { + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x01,0x00,0x00,0x00,0x01), + DATA55 (0x03,0x00,0x00,0x01,0x03), + DATA55 (0x07,0x01,0x01,0x03,0x06), + DATA55 (0x0f,0x02,0x02,0x06,0x0c), + DATA55 (0x1f,0x05,0x05,0x0c,0x18), + DATA55 (0x1e,0x0a,0x0a,0x18,0x11), + DATA55 (0x1d,0x14,0x14,0x10,0x03), + DATA55 (0x1b,0x08,0x08,0x00,0x07), + DATA55 (0x17,0x11,0x11,0x01,0x0f), + DATA55 (0x0e,0x02,0x02,0x02,0x1f), + DATA55 (0x1c,0x04,0x04,0x04,0x1e), + DATA55 (0x19,0x08,0x09,0x08,0x1d), + DATA55 (0x13,0x10,0x13,0x10,0x1b), + DATA55 (0x07,0x00,0x07,0x00,0x17), + DATA55 (0x0f,0x00,0x0f,0x00,0x0f), + DATA55 (0x1e,0x00,0x1e,0x00,0x1e), + DATA55 (0x1c,0x00,0x1c,0x00,0x1c), + DATA55 (0x18,0x00,0x18,0x00,0x18), + DATA55 (0x10,0x00,0x10,0x00,0x10), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), + DATA55 (0x00,0x00,0x00,0x00,0x00), +}; + +int +main (int argc, const char *argv[]) +{ + uint8_t state = 0; + + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + + chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_mutex_unlock (&mtx); + + while (1) + { + unsigned int i; + + if (state) + for (i = 0; i < SIZE55 (image0); i++) + { + if (user_button ()) + state = 0; + set_led_display (image0[i]); + wait_for (200*1000); + } + else + for (i = 0; i < SIZE55 (image1); i++) + { + if (user_button ()) + state = 1; + set_led_display (image1[i]); + wait_for (200*1000); + } + } + + return 0; +} diff --git a/example-fsm-55/l55.txt b/example-fsm-55/l55.txt new file mode 100644 index 0000000..701248e --- /dev/null +++ b/example-fsm-55/l55.txt @@ -0,0 +1,119 @@ +_*___ 08 +__*__ 04 +***__ 1c +_____ 00 +_____ 00 + +_____ 00 +*_*__ 14 +_**__ 0c +_*___ 08 +_____ 00 + +_____ 00 +__*__ 04 +*_*__ 14 +_**__ 0c +_____ 00 + +_____ 00 +_*__ 08 +__**_ 06 +_**__ 0c +_____ 00 + +_____ 00 +__*__ 04 +___*_ 02 +_***_ 0e +_____ 00 + +_____ 00 +_____ 00 +_*_*_ 0a +__**_ 06 +__*__ 04 + +_____ 00 +_____ 00 +___*_ 02 +_*_*_ 0a +__**_ 06 + +_____ 00 +_____ 00 +__*__ 04 +___** 03 +__**_ 06 + +_____ 00 +_____ 00 + __*_ 02 +____* 01 +__*** 07 + +___*_ 02 +_____ 00 +_____ 00 +__*_* 05 +___** 03 + +___** 03 +_____ 00 +_____ 00 +____* 01 +__*_* 05 + +___** 03 +_____ 00 +_____ 00 +_ _*_ 02 +*___* 11 + +*__** 13 +_____ 00 +_____ 00 +____* 01 +*____ 10 + +*___* 11 +____* 01 +_____ 00 +_____ 00 +*__*_ 12 + +*__*_ 12 +*___* 11 +_____ 00 +_____ 00 +*____ 10 + +**___ 18 +*___* 11 +_____ 00 +_____ 00 +____* 01 + +_*___ 08 +**__* 19 +_____ 00 +_____ 00 +*____ 10 + +_*__* 09 +**___ 18 +*____ 10 +_____ 00 +_____ 00 + +_*___ 08 +_*__* 09 +**___ 18 +_____ 00 +_____ 00 + +*____ 10 +_**__ 0c +**___ 18 +_____ 00 +_____ 00 diff --git a/example-fsm-55/name.txt b/example-fsm-55/name.txt new file mode 100644 index 0000000..e54ee58 --- /dev/null +++ b/example-fsm-55/name.txt @@ -0,0 +1,287 @@ +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +____* 01 +_____ 00 +_____ 00 +_____ 00 + +____* 01 +___** 03 +____* 01 +____* 01 +_____ 00 + +___*_ 02 +__**_ 06 +___*_ 02 +___*_ 02 +____* 01 + +__*_* 05 +_**_* 0d +__*_* 05 +__*_* 05 +___** 03 + +_*_** 0b +**_*_ 1a +_*_*_ 0a +_*_*_ 0a +__**_ 06 + +*_**_ 16 +*_*__ 14 +*_*__ 14 +*_*__ 14 +_**__ 0c + +_**_* 0d +_*___ 08 +_*__* 09 +_*___ 08 +**__* 19 + +**_** 1b +*___* 11 +*__*_ 12 +*____ 10 +*__** 13 + +*_*** 17 +___** 03 +__*__ 04 +_____ 00 +__*** 07 + +_**** 0f +__**_ 06 +_*__* 09 +____* 01 +_***_ 0e + +****_ 1e +_**__ 0c +*__*_ 12 +___*_ 02 +***__ 1c + +***_* 1d +**__* 19 +__*_* 05 +__*_* 05 +**___ 18 + +**_*_ 1a +*__*_ 12 +_*_*_ 0a +_*_*_ 0a +*___* 11 + +*_*__ 14 +__*__ 04 +*_*__ 14 +*_*__ 14 +___** 03 + +_*___ 08 +_*___ 08 +_*___ 08 +_*__* 09 +__**_ 06 + +*____ 10 +*____ 10 +*____ 10 +*__*_ 12 +_**__ 0c + +_____ 00 +_____ 00 +_____ 00 +__*__ 04 +**___ 18 + +_____ 00 +_____ 00 +_____ 00 +_*___ 08 +*____ 10 + +_____ 00 +_____ 00 +_____ 00 +*____ 10 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +____* 01 +_____ 00 +_____ 00 +_____ 00 +____* 01 + +___** 03 +_____ 00 +_____ 00 +____* 01 +___** 03 + +__*** 07 +____* 01 +____* 01 +___** 03 +__**_ 06 + +_**** 0f +___*_ 02 +___*_ 02 +__**_ 06 +_**__ 0c + +***** 1f +__*_* 05 +__*_* 05 +_**__ 0c +**___ 18 + +****_ 1e +_*_*_ 0a +_*_*_ 0a +**___ 18 +*___* 11 + +***_* 1d +*_*__ 14 +*_*__ 14 +*____ 10 +___** 03 + +**_** 1b +_*___ 08 +_*___ 08 +_____ 00 +__*** 07 + +*_*** 17 +*___* 11 +*___* 11 +____* 01 +_**** 0f + +_***_ 0e +___*_ 02 +___*_ 02 +___*_ 02 +***** 1f + +***__ 1c +__*__ 04 +__*__ 04 +__*__ 04 +****_ 1e + +**__* 19 +_*___ 08 +_*__* 09 +_*___ 08 +***_* 1d + +*__** 13 +*____ 10 +*__** 13 +*____ 10 +**_** 1b + +__*** 07 +_____ 00 +__*** 07 +_____ 00 +*_*** 17 + +_**** 0f +_____ 00 +_**** 0f +_____ 00 +_**** 0f + +****_ 1e +_____ 00 +****_ 1e +_____ 00 +****_ 1e + +***__ 1c +_____ 00 +***__ 1c +_____ 00 +***__ 1c + +**___ 18 +_____ 00 +**___ 18 +_____ 00 +**___ 18 + +*____ 10 +_____ 00 +*____ 10 +_____ 00 +*____ 10 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 + +_____ 00 +_____ 00 +_____ 00 +_____ 00 +_____ 00 -- cgit v1.2.3 From f4f2afd0ad7e1162b4161a61b15e12eb55e969b7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 4 Aug 2014 11:25:53 +0900 Subject: Use SIZE55. --- example-fsm-55/hacker-emblem.c | 11 +- example-fsm-55/hacker-emblem.c~ | 216 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 example-fsm-55/hacker-emblem.c~ diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index ddf83db..0f6ccd9 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -114,8 +114,9 @@ const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; const size_t __stacksize_led = (size_t)&__process1_stack_size__; #define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) +#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) -static uint32_t l55[20] = { +static uint32_t l55[] = { DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), @@ -138,7 +139,7 @@ static uint32_t l55[20] = { DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), }; -static uint32_t gnu[30] = { +static uint32_t gnu[] = { DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), DATA55 (0x00, 0x01, 0x01, 0x01, 0x00), DATA55 (0x01, 0x02, 0x02, 0x02, 0x01), @@ -192,10 +193,10 @@ main (int argc, const char *argv[]) while (1) { - int i; + unsigned int i; if (state) - for (i = 0; i < 20; i++) + for (i = 0; i < SIZE55 (l55); i++) { if (user_button ()) state = 0; @@ -203,7 +204,7 @@ main (int argc, const char *argv[]) wait_for (500*1000); } else - for (i = 0; i < 30; i++) + for (i = 0; i < SIZE55 (gnu); i++) { if (user_button ()) state = 1; diff --git a/example-fsm-55/hacker-emblem.c~ b/example-fsm-55/hacker-emblem.c~ new file mode 100644 index 0000000..ddf83db --- /dev/null +++ b/example-fsm-55/hacker-emblem.c~ @@ -0,0 +1,216 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> + +#include "board.h" + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) + +static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0; + +static uint8_t +user_button (void) +{ + return (GPIO_OTHER->IDR & 1) == 0; +} + +static uint8_t l_data[5]; + +static void +set_led_display (uint32_t data) +{ + l_data[0] = (data >> 0) & 0x1f; + l_data[1] = (data >> 5) & 0x1f; + l_data[2] = (data >> 10) & 0x1f; + l_data[3] = (data >> 15) & 0x1f; + l_data[4] = (data >> 20) & 0x1f; +} + + +static void +wait_for (uint32_t usec) +{ + chopstx_usec_wait (usec); +} + +static void +led_prepare_row (uint8_t col) +{ + uint16_t data = 0x1f; + + data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; + data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; + data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; + data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; + data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; + GPIO_LED->ODR = data; +} + +static void +led_enable_column (uint8_t col) +{ + GPIO_LED->BRR = (1 << col); +} + +static void * +led (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + int i; + + for (i = 0; i < 5; i++) + { + led_prepare_row (i); + led_enable_column (i); + wait_for (1000); + } + } + + return NULL; +} + +#define PRIO_LED 3 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; + +const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_led = (size_t)&__process1_stack_size__; + +#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) + +static uint32_t l55[20] = { + DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), + DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), + DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), + DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00), + DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00), + DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04), + DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06), + DATA55 (0x00, 0x00, 0x04, 0x03, 0x06), + DATA55 (0x00, 0x00, 0x02, 0x01, 0x07), + DATA55 (0x02, 0x00, 0x00, 0x05, 0x03), + DATA55 (0x03, 0x00, 0x00, 0x01, 0x05), + DATA55 (0x03, 0x00, 0x00, 0x02, 0x11), + DATA55 (0x13, 0x00, 0x00, 0x01, 0x10), + DATA55 (0x11, 0x01, 0x00, 0x00, 0x12), + DATA55 (0x12, 0x11, 0x00, 0x00, 0x10), + DATA55 (0x18, 0x11, 0x00, 0x00, 0x01), + DATA55 (0x08, 0x19, 0x00, 0x00, 0x10), + DATA55 (0x09, 0x18, 0x10, 0x00, 0x00), + DATA55 (0x08, 0x09, 0x18, 0x00, 0x00), + DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), +}; + +static uint32_t gnu[30] = { + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x01, 0x01, 0x01, 0x00), + DATA55 (0x01, 0x02, 0x02, 0x02, 0x01), + DATA55 (0x03, 0x04, 0x04, 0x04, 0x03), + DATA55 (0x07, 0x08, 0x09, 0x08, 0x07), + DATA55 (0x0e, 0x10, 0x13, 0x11, 0x0e), + DATA55 (0x1c, 0x00, 0x06, 0x02, 0x1c), + DATA55 (0x19, 0x01, 0x0d, 0x05, 0x19), + DATA55 (0x12, 0x03, 0x1a, 0x0a, 0x12), + DATA55 (0x04, 0x06, 0x15, 0x14, 0x04), + DATA55 (0x08, 0x0c, 0x0a, 0x09, 0x08), + DATA55 (0x11, 0x19, 0x15, 0x13, 0x11), + DATA55 (0x02, 0x12, 0x0a, 0x06, 0x02), + DATA55 (0x05, 0x05, 0x15, 0x0d, 0x04), + DATA55 (0x0a, 0x0a, 0x0a, 0x1a, 0x09), + DATA55 (0x14, 0x14, 0x14, 0x14, 0x13), + DATA55 (0x08, 0x08, 0x08, 0x08, 0x07), + DATA55 (0x11, 0x11, 0x11, 0x11, 0x0e), + DATA55 (0x02, 0x02, 0x02, 0x02, 0x1c), + DATA55 (0x04, 0x04, 0x04, 0x04, 0x18), + DATA55 (0x08, 0x08, 0x08, 0x08, 0x10), + DATA55 (0x11, 0x11, 0x11, 0x10, 0x01), + DATA55 (0x03, 0x03, 0x03, 0x00, 0x02), + DATA55 (0x06, 0x06, 0x06, 0x00, 0x04), + DATA55 (0x0c, 0x0c, 0x0c, 0x00, 0x08), + DATA55 (0x18, 0x18, 0x18, 0x00, 0x10), + DATA55 (0x10, 0x10, 0x10, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), +}; + +int +main (int argc, const char *argv[]) +{ + uint8_t state = 0; + + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + + chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_mutex_unlock (&mtx); + + while (1) + { + int i; + + if (state) + for (i = 0; i < 20; i++) + { + if (user_button ()) + state = 0; + set_led_display (l55[i]); + wait_for (500*1000); + } + else + for (i = 0; i < 30; i++) + { + if (user_button ()) + state = 1; + set_led_display (gnu[i]); + wait_for (200*1000); + } + } + + return 0; +} -- cgit v1.2.3 From 447b11fd1c1311a6c2619bc57b8b4b334c52fa4d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 4 Aug 2014 12:38:20 +0900 Subject: Add Happy Hacking. --- example-fsm-55/hacker-emblem.c | 86 ++++++++++++++++++++++++++++++++++++++---- example-fsm-55/hh.txt | 22 +++++------ 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index 0f6ccd9..b209ff9 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -56,6 +56,16 @@ set_led_display (uint32_t data) l_data[4] = (data >> 20) & 0x1f; } +static void +scroll_led_display (uint8_t row) +{ + l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1); + l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1); + l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1); + l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1); + l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1); +} + static void wait_for (uint32_t usec) @@ -172,11 +182,71 @@ static uint32_t gnu[] = { DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), }; +#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20) + +#define CHAR_SPC 0 +#define CHAR_H 1 +#define CHAR_A 2 +#define CHAR_P 3 +#define CHAR_Y 4 +#define CHAR_C 5 +#define CHAR_K 6 +#define CHAR_I 7 +#define CHAR_N 8 +#define CHAR_G 9 +#define CHAR_EXC 10 + +static uint8_t hh[] = { + CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y, + CHAR_SPC, + CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G, + CHAR_EXC, + CHAR_SPC, CHAR_SPC, CHAR_SPC, +}; + +struct { uint8_t width; uint32_t data; } chargen[] = { + { 5, 0 }, /* SPACE */ + { 5, DATA55V (0x1f, 0x04, 0x04, 0x04, 0x1f) }, /* H */ + { 5, DATA55V (0x07, 0x0a, 0x12, 0x0a, 0x07) }, /* A */ + { 5, DATA55V (0x1f, 0x14, 0x14, 0x14, 0x18) }, /* P */ + { 5, DATA55V (0x18, 0x04, 0x07, 0x04, 0x18) }, /* Y */ + { 5, DATA55V (0x0e, 0x11, 0x11, 0x11, 0x02) }, /* C */ + { 5, DATA55V (0x1f, 0x04, 0x0c, 0x12, 0x01) }, /* K */ + { 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */ + { 5, DATA55V (0x1f, 0x08, 0x04, 0x02, 0x1f) }, /* N */ + { 5, DATA55V (0x0e, 0x11, 0x11, 0x15, 0x06) }, /* G */ + { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ +}; + +static uint8_t state = 0; + +#define CHECK_USER() if (user_button ()) state = 0 + +static void +happy_hacking (void) +{ + unsigned int i, j; + + set_led_display (0); + for (i = 0; i < sizeof (hh); i++) + { + for (j = 0; j < chargen[hh[i]].width; j++) + { + CHECK_USER (); + scroll_led_display ((chargen[hh[i]].data >> j * 5) & 0x1f); + wait_for (150*1000); + } + + CHECK_USER (); + scroll_led_display (0); + wait_for (200*1000); + } +} + + int main (int argc, const char *argv[]) { - uint8_t state = 0; - (void)argc; (void)argv; @@ -195,22 +265,24 @@ main (int argc, const char *argv[]) { unsigned int i; - if (state) + if (state == 0) for (i = 0; i < SIZE55 (l55); i++) { if (user_button ()) - state = 0; + state = 1; set_led_display (l55[i]); wait_for (500*1000); } - else + else if (state == 1) for (i = 0; i < SIZE55 (gnu); i++) { if (user_button ()) - state = 1; + state = 2; set_led_display (gnu[i]); - wait_for (200*1000); + wait_for (250*1000); } + else + happy_hacking (); } return 0; diff --git a/example-fsm-55/hh.txt b/example-fsm-55/hh.txt index 72f51e4..49493a5 100644 --- a/example-fsm-55/hh.txt +++ b/example-fsm-55/hh.txt @@ -40,17 +40,17 @@ ooo .o. ooo -o...o 11 -oo..o 19 -o.o.o 15 -o..oo 13 -o...o 11 - -.ooo. 0e -o.... 10 -o..oo 13 -o...o 11 -.ooo. 0e +o...o +oo..o +o.o.o +o..oo +o...o + +.ooo. +o.... +o..oo +o...o +.ooo. oo oo -- cgit v1.2.3 From aeb8bd5a95051d081edc2423207319f718ae0691 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 4 Aug 2014 13:38:42 +0900 Subject: l55 and hh only. --- example-fsm-55/Makefile | 2 +- example-fsm-55/hacker-emblem.c | 124 +++++++++++++---------- example-fsm-55/hacker-emblem.c~ | 216 ---------------------------------------- example-fsm-55/hh.txt | 92 ++++++++--------- 4 files changed, 120 insertions(+), 314 deletions(-) delete mode 100644 example-fsm-55/hacker-emblem.c~ diff --git a/example-fsm-55/Makefile b/example-fsm-55/Makefile index 168d50e..755639c 100644 --- a/example-fsm-55/Makefile +++ b/example-fsm-55/Makefile @@ -14,7 +14,7 @@ OBJCOPY = $(CROSS)objcopy MCU = cortex-m0 # -save-temps CWARN = -Wall -Wextra -Wstrict-prototypes -DEFS = -DHAVE_SYS_H -DFREE_STANDING -DMHZ=48 +DEFS = -DHAVE_SYS_H -DFREE_STANDING -DMHZ=48 -DUSE_WFI_FOR_IDLE OPT = -O3 -Os -g LIBS = diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index b209ff9..bc9594e 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -149,39 +149,6 @@ static uint32_t l55[] = { DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), }; -static uint32_t gnu[] = { - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x01, 0x01, 0x01, 0x00), - DATA55 (0x01, 0x02, 0x02, 0x02, 0x01), - DATA55 (0x03, 0x04, 0x04, 0x04, 0x03), - DATA55 (0x07, 0x08, 0x09, 0x08, 0x07), - DATA55 (0x0e, 0x10, 0x13, 0x11, 0x0e), - DATA55 (0x1c, 0x00, 0x06, 0x02, 0x1c), - DATA55 (0x19, 0x01, 0x0d, 0x05, 0x19), - DATA55 (0x12, 0x03, 0x1a, 0x0a, 0x12), - DATA55 (0x04, 0x06, 0x15, 0x14, 0x04), - DATA55 (0x08, 0x0c, 0x0a, 0x09, 0x08), - DATA55 (0x11, 0x19, 0x15, 0x13, 0x11), - DATA55 (0x02, 0x12, 0x0a, 0x06, 0x02), - DATA55 (0x05, 0x05, 0x15, 0x0d, 0x04), - DATA55 (0x0a, 0x0a, 0x0a, 0x1a, 0x09), - DATA55 (0x14, 0x14, 0x14, 0x14, 0x13), - DATA55 (0x08, 0x08, 0x08, 0x08, 0x07), - DATA55 (0x11, 0x11, 0x11, 0x11, 0x0e), - DATA55 (0x02, 0x02, 0x02, 0x02, 0x1c), - DATA55 (0x04, 0x04, 0x04, 0x04, 0x18), - DATA55 (0x08, 0x08, 0x08, 0x08, 0x10), - DATA55 (0x11, 0x11, 0x11, 0x10, 0x01), - DATA55 (0x03, 0x03, 0x03, 0x00, 0x02), - DATA55 (0x06, 0x06, 0x06, 0x00, 0x04), - DATA55 (0x0c, 0x0c, 0x0c, 0x00, 0x08), - DATA55 (0x18, 0x18, 0x18, 0x00, 0x10), - DATA55 (0x10, 0x10, 0x10, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), -}; - #define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20) #define CHAR_SPC 0 @@ -205,16 +172,16 @@ static uint8_t hh[] = { }; struct { uint8_t width; uint32_t data; } chargen[] = { - { 5, 0 }, /* SPACE */ - { 5, DATA55V (0x1f, 0x04, 0x04, 0x04, 0x1f) }, /* H */ - { 5, DATA55V (0x07, 0x0a, 0x12, 0x0a, 0x07) }, /* A */ - { 5, DATA55V (0x1f, 0x14, 0x14, 0x14, 0x18) }, /* P */ - { 5, DATA55V (0x18, 0x04, 0x07, 0x04, 0x18) }, /* Y */ - { 5, DATA55V (0x0e, 0x11, 0x11, 0x11, 0x02) }, /* C */ - { 5, DATA55V (0x1f, 0x04, 0x0c, 0x12, 0x01) }, /* K */ + { 3, 0 }, /* SPACE */ + { 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */ + { 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* A */ + { 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */ + { 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */ + { 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */ + { 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */ { 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */ - { 5, DATA55V (0x1f, 0x08, 0x04, 0x02, 0x1f) }, /* N */ - { 5, DATA55V (0x0e, 0x11, 0x11, 0x15, 0x06) }, /* G */ + { 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */ + { 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */ { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ }; @@ -244,9 +211,14 @@ happy_hacking (void) } +#define REPEAT_COUNT 10 + +static void setup_scr_sleepdeep (void); + int main (int argc, const char *argv[]) { + uint8_t count = 0; (void)argc; (void)argv; @@ -264,6 +236,7 @@ main (int argc, const char *argv[]) while (1) { unsigned int i; + uint8_t state_prev = state; if (state == 0) for (i = 0; i < SIZE55 (l55); i++) @@ -273,17 +246,66 @@ main (int argc, const char *argv[]) set_led_display (l55[i]); wait_for (500*1000); } - else if (state == 1) - for (i = 0; i < SIZE55 (gnu); i++) - { - if (user_button ()) - state = 2; - set_led_display (gnu[i]); - wait_for (250*1000); - } - else + if (state == 1) happy_hacking (); + + if (state_prev != state) + count = 0; + else + if (++count > REPEAT_COUNT) + break; } + setup_scr_sleepdeep (); + for (;;) + asm volatile ("wfi" : : : "memory"); + return 0; } + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); + +#define SCB_SCR_SLEEPDEEP (1 << 2) + +struct PWR +{ + volatile uint32_t CR; + volatile uint32_t CSR; +}; +#define PWR_CR_PDDS 0x0002 +#define PWR_CR_CWUF 0x0004 + +#define PWR_BASE (APBPERIPH_BASE + 0x00007000) +#define PWR ((struct PWR *) PWR_BASE) + +static void setup_scr_sleepdeep (void) +{ + PWR->CR |= PWR_CR_CWUF; + PWR->CR |= PWR_CR_PDDS; + SCB->SCR |= SCB_SCR_SLEEPDEEP; +} diff --git a/example-fsm-55/hacker-emblem.c~ b/example-fsm-55/hacker-emblem.c~ deleted file mode 100644 index ddf83db..0000000 --- a/example-fsm-55/hacker-emblem.c~ +++ /dev/null @@ -1,216 +0,0 @@ -#include <stdint.h> -#include <stdlib.h> -#include <chopstx.h> - -#include "board.h" - -#define PERIPH_BASE 0x40000000 -#define APBPERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) -#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) - -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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) -#define GPIOF ((struct GPIO *) GPIOF_BASE) - -static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); -static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); - -static chopstx_mutex_t mtx; -static chopstx_cond_t cnd0; - -static uint8_t -user_button (void) -{ - return (GPIO_OTHER->IDR & 1) == 0; -} - -static uint8_t l_data[5]; - -static void -set_led_display (uint32_t data) -{ - l_data[0] = (data >> 0) & 0x1f; - l_data[1] = (data >> 5) & 0x1f; - l_data[2] = (data >> 10) & 0x1f; - l_data[3] = (data >> 15) & 0x1f; - l_data[4] = (data >> 20) & 0x1f; -} - - -static void -wait_for (uint32_t usec) -{ - chopstx_usec_wait (usec); -} - -static void -led_prepare_row (uint8_t col) -{ - uint16_t data = 0x1f; - - data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; - data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; - data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; - data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; - data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; - GPIO_LED->ODR = data; -} - -static void -led_enable_column (uint8_t col) -{ - GPIO_LED->BRR = (1 << col); -} - -static void * -led (void *arg) -{ - (void)arg; - - chopstx_mutex_lock (&mtx); - chopstx_cond_wait (&cnd0, &mtx); - chopstx_mutex_unlock (&mtx); - - while (1) - { - int i; - - for (i = 0; i < 5; i++) - { - led_prepare_row (i); - led_enable_column (i); - wait_for (1000); - } - } - - return NULL; -} - -#define PRIO_LED 3 - -extern uint8_t __process1_stack_base__, __process1_stack_size__; - -const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; -const size_t __stacksize_led = (size_t)&__process1_stack_size__; - -#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) - -static uint32_t l55[20] = { - DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), - DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), - DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), - DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00), - DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00), - DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04), - DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06), - DATA55 (0x00, 0x00, 0x04, 0x03, 0x06), - DATA55 (0x00, 0x00, 0x02, 0x01, 0x07), - DATA55 (0x02, 0x00, 0x00, 0x05, 0x03), - DATA55 (0x03, 0x00, 0x00, 0x01, 0x05), - DATA55 (0x03, 0x00, 0x00, 0x02, 0x11), - DATA55 (0x13, 0x00, 0x00, 0x01, 0x10), - DATA55 (0x11, 0x01, 0x00, 0x00, 0x12), - DATA55 (0x12, 0x11, 0x00, 0x00, 0x10), - DATA55 (0x18, 0x11, 0x00, 0x00, 0x01), - DATA55 (0x08, 0x19, 0x00, 0x00, 0x10), - DATA55 (0x09, 0x18, 0x10, 0x00, 0x00), - DATA55 (0x08, 0x09, 0x18, 0x00, 0x00), - DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), -}; - -static uint32_t gnu[30] = { - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x01, 0x01, 0x01, 0x00), - DATA55 (0x01, 0x02, 0x02, 0x02, 0x01), - DATA55 (0x03, 0x04, 0x04, 0x04, 0x03), - DATA55 (0x07, 0x08, 0x09, 0x08, 0x07), - DATA55 (0x0e, 0x10, 0x13, 0x11, 0x0e), - DATA55 (0x1c, 0x00, 0x06, 0x02, 0x1c), - DATA55 (0x19, 0x01, 0x0d, 0x05, 0x19), - DATA55 (0x12, 0x03, 0x1a, 0x0a, 0x12), - DATA55 (0x04, 0x06, 0x15, 0x14, 0x04), - DATA55 (0x08, 0x0c, 0x0a, 0x09, 0x08), - DATA55 (0x11, 0x19, 0x15, 0x13, 0x11), - DATA55 (0x02, 0x12, 0x0a, 0x06, 0x02), - DATA55 (0x05, 0x05, 0x15, 0x0d, 0x04), - DATA55 (0x0a, 0x0a, 0x0a, 0x1a, 0x09), - DATA55 (0x14, 0x14, 0x14, 0x14, 0x13), - DATA55 (0x08, 0x08, 0x08, 0x08, 0x07), - DATA55 (0x11, 0x11, 0x11, 0x11, 0x0e), - DATA55 (0x02, 0x02, 0x02, 0x02, 0x1c), - DATA55 (0x04, 0x04, 0x04, 0x04, 0x18), - DATA55 (0x08, 0x08, 0x08, 0x08, 0x10), - DATA55 (0x11, 0x11, 0x11, 0x10, 0x01), - DATA55 (0x03, 0x03, 0x03, 0x00, 0x02), - DATA55 (0x06, 0x06, 0x06, 0x00, 0x04), - DATA55 (0x0c, 0x0c, 0x0c, 0x00, 0x08), - DATA55 (0x18, 0x18, 0x18, 0x00, 0x10), - DATA55 (0x10, 0x10, 0x10, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), - DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), -}; - -int -main (int argc, const char *argv[]) -{ - uint8_t state = 0; - - (void)argc; - (void)argv; - - chopstx_mutex_init (&mtx); - chopstx_cond_init (&cnd0); - - chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); - - chopstx_usec_wait (200*1000); - - chopstx_mutex_lock (&mtx); - chopstx_cond_signal (&cnd0); - chopstx_mutex_unlock (&mtx); - - while (1) - { - int i; - - if (state) - for (i = 0; i < 20; i++) - { - if (user_button ()) - state = 0; - set_led_display (l55[i]); - wait_for (500*1000); - } - else - for (i = 0; i < 30; i++) - { - if (user_button ()) - state = 1; - set_led_display (gnu[i]); - wait_for (200*1000); - } - } - - return 0; -} diff --git a/example-fsm-55/hh.txt b/example-fsm-55/hh.txt index 49493a5..c9c60fc 100644 --- a/example-fsm-55/hh.txt +++ b/example-fsm-55/hh.txt @@ -1,38 +1,38 @@ -o...o -o...o -ooooo -o...o -o...o - -..o. -.o.o. -o...o -ooooo -o...o - -ooooo -o...o -oooo. -o.... -o.... - -o...o -o...o -.ooo. -..o.. -..o.. - -.ooo. -o.... -o.... -o...o -.ooo. - -o..o. -o.o.. -ooo.. -o..o. -o...o +o..o +o..o +oooo +o..o +o..o + +.oo. +...o +.ooo +o..o +.ooo + +ooo. +o..o +ooo. +o... +o... + +o..o +o..o +.ooo +...o +ooo. + +.oo. +o..o +o... +o..o +.oo. + +o..o +o.o. +ooo. +o..o +o..o ooo .o. @@ -40,17 +40,17 @@ ooo .o. ooo -o...o -oo..o -o.o.o -o..oo -o...o - -.ooo. -o.... -o..oo -o...o -.ooo. +o..o +oo.o +o.oo +o.oo +o..o + +.oo. +o... +o.oo +o..o +.ooo oo oo -- cgit v1.2.3 From 98e25c1cb2e2aafdc6d06398883e5d4ef026efe4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 4 Aug 2014 14:19:13 +0900 Subject: Add GNU as hidden command. --- example-fsm-55/gnu.txt | 233 ++++++++++------------------------------- example-fsm-55/hacker-emblem.c | 70 +++++++++++-- example-fsm-55/hh.txt | 10 +- 3 files changed, 119 insertions(+), 194 deletions(-) diff --git a/example-fsm-55/gnu.txt b/example-fsm-55/gnu.txt index feb789a..974c8a8 100644 --- a/example-fsm-55/gnu.txt +++ b/example-fsm-55/gnu.txt @@ -1,179 +1,54 @@ -_____ 00 -_____ 00 -_____ 00 -_____ 00 -_____ 00 - -_____ 00 -____* 01 -____* 01 -____* 01 -_____ 00 - -____* 01 -___*_ 02 -___*_ 02 -___*_ 02 -____* 01 - -___** 03 -__*__ 04 -__*__ 04 -__*__ 04 -___** 03 - -__*** 07 -_*___ 08 -_*__* 09 -_*___ 08 -__*** 07 - -_***_ 0e -*____ 10 -*__** 13 -*___* 11 -_***_ 0e - -***__ 1c -_____ 00 -__**_ 06 -___*_ 02 -***__ 1c - -**__* 19 -____* 01 -_**_* 0d -__*_* 05 -**__* 19 - -*__*_ 12 - __** 03 -**_*_ 1a -_*_*_ 0a -*__*_ 12 - -__*__ 04 - _**_ 06 -*_*_* 15 -*_*__ 14 -__*__ 04 - -_*___ 08 -_**__ 0c -_*_*_ 0a -_*__* 09 -_*___ 08 - -*___* 11 -**__* 19 -*_*_* 15 -*__** 13 -*___* 11 - -___*_ 02 -*__*_ 12 -_*_*_ 0a -__**_ 06 -___*_ 02 - -__*_* 05 -__*_* 05 -*_*_* 15 -_**_* 0d -__*__ 04 - -_*_*_ 0a -_*_*_ 0a -_*_*_ 0a -**_*_ 1a -_*__* 09 - -*_*__ 14 -*_*__ 14 -*_*__ 14 -*_*__ 14 -*__** 13 - -_*___ 08 -_*___ 08 -_*___ 08 -_*___ 08 -__*** 07 - -*___* 11 -*___* 11 -*___* 11 -*___* 11 -_***_ 0e - -___*_ 02 -___*_ 02 -___*_ 02 -___*_ 02 -***__ 1c - -__*__ 04 -__*__ 04 -__*__ 04 -__*__ 04 -**___ 18 - -_*___ 08 -_*___ 08 -_*___ 08 -_*___ 08 -*____ 10 - -*___* 11 -*___* 11 -*___* 11 -*____ 10 -____* 01 - -___** 03 -___** 03 -___** 03 -_____ 00 -___*_ 02 - -__**_ 06 -__**_ 06 -__**_ 06 -_____ 00 -__*__ 04 - -_**__ 0c -_**__ 0c -_**__ 0c -_____ 00 -_*___ 08 - -**___ 18 -**___ 18 -**___ 18 -_____ 00 -*____ 10 - -*____ 10 -*____ 10 -*____ 10 -_____ 00 -_____ 00 - -_____ 00 -_____ 00 -_____ 00 -_____ 00 -_____ 00 - -_____ 00 -_____ 00 -_____ 00 -_____ 00 -_____ 00 - -_____ 00 -_____ 00 -_____ 00 -_____ 00 -_____ 00 +o...o +o.o.o +o.o.o +o.o.o +.o.o. + +o.. +o.. +ooo +o.o +o.o + +.o.. +oooo +.o.. +.o.. +..oo + +.oo +.oo +o.. +... +... + +.... +.ooo +o... +.oo. +...o +ooo. + +o..o +o..o +o..o +o..o +.oo. + +.oo. +o..o +..o. +.... +..o. + +.... +.oo. +o..o +o..o +.oo. + +o...o +.o.o. +..o.. +.o.o. +o...o diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index bc9594e..bcd5c08 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -162,6 +162,15 @@ static uint32_t l55[] = { #define CHAR_N 8 #define CHAR_G 9 #define CHAR_EXC 10 +#define CHAR_W 11 +#define CHAR_h 12 +#define CHAR_t 13 +#define CHAR_AP 14 +#define CHAR_s 15 +#define CHAR_U 16 +#define CHAR_QT 17 +#define CHAR_o 18 +#define CHAR_X 19 static uint8_t hh[] = { CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y, @@ -171,10 +180,21 @@ static uint8_t hh[] = { CHAR_SPC, CHAR_SPC, CHAR_SPC, }; +static uint8_t gnu[] = { + CHAR_W, CHAR_h, CHAR_A, CHAR_t, CHAR_AP, CHAR_s, CHAR_SPC, + CHAR_G, CHAR_N, CHAR_U, CHAR_QT, + CHAR_SPC, CHAR_SPC, + CHAR_G, CHAR_N, CHAR_U, CHAR_AP, CHAR_s, CHAR_SPC, + CHAR_N, CHAR_o, CHAR_t, CHAR_SPC, + CHAR_U, CHAR_N, CHAR_I, CHAR_X, + CHAR_EXC, + CHAR_SPC, CHAR_SPC, +}; + struct { uint8_t width; uint32_t data; } chargen[] = { { 3, 0 }, /* SPACE */ { 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */ - { 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* A */ + { 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */ { 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */ { 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */ { 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */ @@ -183,6 +203,15 @@ struct { uint8_t width; uint32_t data; } chargen[] = { { 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */ { 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */ { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ + { 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */ + { 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */ + { 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */ + { 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */ + { 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */ + { 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */ + { 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */ + { 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */ + { 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */ }; static uint8_t state = 0; @@ -190,23 +219,36 @@ static uint8_t state = 0; #define CHECK_USER() if (user_button ()) state = 0 static void -happy_hacking (void) +text_display (uint8_t kind) { unsigned int i, j; + uint8_t *text; + uint8_t len; + + if (kind) + { + text = hh; + len = sizeof (hh); + } + else + { + text = gnu; + len = sizeof (gnu); + } set_led_display (0); - for (i = 0; i < sizeof (hh); i++) + for (i = 0; i < len; i++) { - for (j = 0; j < chargen[hh[i]].width; j++) + for (j = 0; j < chargen[text[i]].width; j++) { CHECK_USER (); - scroll_led_display ((chargen[hh[i]].data >> j * 5) & 0x1f); - wait_for (150*1000); + scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); + wait_for (120*1000); } CHECK_USER (); scroll_led_display (0); - wait_for (200*1000); + wait_for (120*1000); } } @@ -219,6 +261,7 @@ int main (int argc, const char *argv[]) { uint8_t count = 0; + uint8_t happy = 1; (void)argc; (void)argv; @@ -233,6 +276,13 @@ main (int argc, const char *argv[]) chopstx_cond_signal (&cnd0); chopstx_mutex_unlock (&mtx); + if (user_button ()) + { + while (user_button ()); + happy = 0; + state = 1; + } + while (1) { unsigned int i; @@ -244,10 +294,10 @@ main (int argc, const char *argv[]) if (user_button ()) state = 1; set_led_display (l55[i]); - wait_for (500*1000); + wait_for (350*1000); } - if (state == 1) - happy_hacking (); + else if (state == 1) + text_display (happy); if (state_prev != state) count = 0; diff --git a/example-fsm-55/hh.txt b/example-fsm-55/hh.txt index c9c60fc..95b2bbe 100644 --- a/example-fsm-55/hh.txt +++ b/example-fsm-55/hh.txt @@ -4,11 +4,11 @@ oooo o..o o..o -.oo. -...o -.ooo -o..o -.ooo +oo. +..o +ooo +o.o +ooo ooo. o..o -- cgit v1.2.3 From f4fb26a56ae0ce2d09d8245fac3b6023882f27b6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 11 Aug 2014 16:00:03 +0900 Subject: add button thread and join on exit. --- example-fsm-55/hacker-emblem.c | 85 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index bcd5c08..c87ff9c 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -4,6 +4,8 @@ #include "board.h" +static uint8_t main_finished; + #define PERIPH_BASE 0x40000000 #define APBPERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) @@ -36,14 +38,18 @@ static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); static chopstx_mutex_t mtx; -static chopstx_cond_t cnd0; +static chopstx_cond_t cnd0, cnd1; + +#define BUTTON_PUSHED 1 +static uint8_t button_state; static uint8_t user_button (void) { - return (GPIO_OTHER->IDR & 1) == 0; + return button_state; } + static uint8_t l_data[5]; static void @@ -86,6 +92,12 @@ led_prepare_row (uint8_t col) GPIO_LED->ODR = data; } +static void +led_prepare_row_full (void) +{ + GPIO_LED->ODR = 0x06ff; +} + static void led_enable_column (uint8_t col) { @@ -101,28 +113,76 @@ led (void *arg) chopstx_cond_wait (&cnd0, &mtx); chopstx_mutex_unlock (&mtx); - while (1) + while (!main_finished) { int i; + int display_full = user_button (); for (i = 0; i < 5; i++) { - led_prepare_row (i); + if (display_full) + led_prepare_row_full (); + else + led_prepare_row (i); led_enable_column (i); wait_for (1000); } } + GPIO_LED->ODR = 0x0000; /* Off all LEDs. */ + GPIO_LED->OSPEEDR = 0; + GPIO_LED->OTYPER = 0; + GPIO_LED->MODER = 0; /* Input mode. */ + GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */ + + return NULL; +} + + +static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; } + +static void * +button (void *arg) +{ + uint8_t last_button = 0; + + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd1, &mtx); + chopstx_mutex_unlock (&mtx); + + while (!main_finished) + { + uint8_t button = get_button_sw (); + + if (last_button == button && button != button_state) + { + wait_for (1000); + button = get_button_sw (); + if (last_button == button) + button_state = button; + } + + wait_for (2000); + last_button = button; + } + return NULL; } #define PRIO_LED 3 +#define PRIO_BUTTON 2 extern uint8_t __process1_stack_base__, __process1_stack_size__; +extern uint8_t __process2_stack_base__, __process2_stack_size__; const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; const size_t __stacksize_led = (size_t)&__process1_stack_size__; +const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__; +const size_t __stacksize_button = (size_t)&__process2_stack_size__; + #define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) #define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) @@ -260,6 +320,8 @@ static void setup_scr_sleepdeep (void); int main (int argc, const char *argv[]) { + chopstx_t led_thd; + chopstx_t button_thd; uint8_t count = 0; uint8_t happy = 1; (void)argc; @@ -267,18 +329,23 @@ main (int argc, const char *argv[]) chopstx_mutex_init (&mtx); chopstx_cond_init (&cnd0); + chopstx_cond_init (&cnd1); - chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL); + led_thd = chopstx_create (PRIO_LED, __stackaddr_led, + __stacksize_led, led, NULL); + button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button, + __stacksize_button, button, NULL); chopstx_usec_wait (200*1000); chopstx_mutex_lock (&mtx); chopstx_cond_signal (&cnd0); + chopstx_cond_signal (&cnd1); chopstx_mutex_unlock (&mtx); - if (user_button ()) + if (get_button_sw ()) { - while (user_button ()); + while (get_button_sw ()); happy = 0; state = 1; } @@ -306,6 +373,10 @@ main (int argc, const char *argv[]) break; } + main_finished = 1; + chopstx_join (button_thd, NULL); + chopstx_join (led_thd, NULL); + setup_scr_sleepdeep (); for (;;) asm volatile ("wfi" : : : "memory"); -- cgit v1.2.3 From 1fcfc846b80f5ac75ca04d6c23effd0add9c0867 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 18 Aug 2014 14:13:26 +0900 Subject: Button pushed, then another demo. --- example-fsm-55/hacker-emblem.c | 123 ++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c index c87ff9c..b8e7409 100644 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -51,6 +51,7 @@ user_button (void) static uint8_t l_data[5]; +#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f) static void set_led_display (uint32_t data) @@ -92,11 +93,6 @@ led_prepare_row (uint8_t col) GPIO_LED->ODR = data; } -static void -led_prepare_row_full (void) -{ - GPIO_LED->ODR = 0x06ff; -} static void led_enable_column (uint8_t col) @@ -116,14 +112,10 @@ led (void *arg) while (!main_finished) { int i; - int display_full = user_button (); for (i = 0; i < 5; i++) { - if (display_full) - led_prepare_row_full (); - else - led_prepare_row (i); + led_prepare_row (i); led_enable_column (i); wait_for (1000); } @@ -274,16 +266,43 @@ struct { uint8_t width; uint32_t data; } chargen[] = { { 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */ }; -static uint8_t state = 0; -#define CHECK_USER() if (user_button ()) state = 0 +#define REPEAT_COUNT 10 + +static int +life_display (void) +{ + unsigned int i; + uint8_t count = 0; + uint8_t state = 0; -static void + while (count++ < REPEAT_COUNT) + for (i = 0; i < SIZE55 (l55); i++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + set_led_display (l55[i]); + wait_for (350*1000); + } + + return 1; +} + + +static int text_display (uint8_t kind) { unsigned int i, j; uint8_t *text; uint8_t len; + uint8_t count = 0; + uint8_t state = 0; if (kind) { @@ -297,24 +316,39 @@ text_display (uint8_t kind) } set_led_display (0); - for (i = 0; i < len; i++) - { - for (j = 0; j < chargen[text[i]].width; j++) - { - CHECK_USER (); - scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); - wait_for (120*1000); - } + while (count++ < REPEAT_COUNT) + for (i = 0; i < len; i++) + { + for (j = 0; j < chargen[text[i]].width; j++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); + wait_for (120*1000); + } - CHECK_USER (); - scroll_led_display (0); - wait_for (120*1000); - } + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display (0); + wait_for (120*1000); + } + + return 1; } -#define REPEAT_COUNT 10 - static void setup_scr_sleepdeep (void); int @@ -322,7 +356,6 @@ main (int argc, const char *argv[]) { chopstx_t led_thd; chopstx_t button_thd; - uint8_t count = 0; uint8_t happy = 1; (void)argc; (void)argv; @@ -343,34 +376,24 @@ main (int argc, const char *argv[]) chopstx_cond_signal (&cnd1); chopstx_mutex_unlock (&mtx); - if (get_button_sw ()) + wait_for (100*1000); + if (user_button ()) { - while (get_button_sw ()); + /* Wait button release. */ + while (user_button ()) + wait_for (100*1000); + happy = 0; - state = 1; + goto do_text; } while (1) { - unsigned int i; - uint8_t state_prev = state; - - if (state == 0) - for (i = 0; i < SIZE55 (l55); i++) - { - if (user_button ()) - state = 1; - set_led_display (l55[i]); - wait_for (350*1000); - } - else if (state == 1) - text_display (happy); - - if (state_prev != state) - count = 0; - else - if (++count > REPEAT_COUNT) - break; + if (life_display ()) + break; + do_text: + if (text_display (happy)) + break; } main_finished = 1; -- cgit v1.2.3 From 5f4cca00fcd84ee778d2397c700cad8249359486 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 25 Aug 2014 01:39:26 +0900 Subject: It should be BSS section not to output data to .hex. --- entry.c | 2 +- example-fsm-55/hacker-emblem.ld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/entry.c b/entry.c index 0036a3a..1170c6a 100644 --- a/entry.c +++ b/entry.c @@ -420,7 +420,7 @@ static void none (void) #define COMPOSE_STATEMENT(arg0,arg1,arg2) C_S_SUB (arg0, arg1, arg2) #if MCU_STM32F0 -__attribute__ ((used,section(".data.startup.0"))) +__attribute__ ((used,section(".bss.startup.0"))) uint32_t vectors_in_ram[48]; #endif diff --git a/example-fsm-55/hacker-emblem.ld b/example-fsm-55/hacker-emblem.ld index 07761e0..bce4e00 100644 --- a/example-fsm-55/hacker-emblem.ld +++ b/example-fsm-55/hacker-emblem.ld @@ -88,7 +88,7 @@ SECTIONS { . = ALIGN(8); __vector_ram_addr__ = .; - KEEP(*(.data.startup.*)) + KEEP(*(.bss.startup.*)) } > ram .process_stack : -- cgit v1.2.3 From b0992073d73408b38baa560c398a9042378b3c7e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Mon, 25 Aug 2014 10:35:04 +0900 Subject: Add debian-logo.c (from Portland). --- example-fsm-55/debian-logo.c | 473 ++++++++++++++++++++++++++++++++ example-fsm-55/debian-logo.txt | 594 +++++++++++++++++++++++++++++++++++++++++ example-fsm-55/hacker-emblem.c | 456 +------------------------------ example-fsm-55/hh.c | 461 ++++++++++++++++++++++++++++++++ 4 files changed, 1529 insertions(+), 455 deletions(-) create mode 100644 example-fsm-55/debian-logo.c create mode 100644 example-fsm-55/debian-logo.txt mode change 100644 => 120000 example-fsm-55/hacker-emblem.c create mode 100644 example-fsm-55/hh.c diff --git a/example-fsm-55/debian-logo.c b/example-fsm-55/debian-logo.c new file mode 100644 index 0000000..a3f78fd --- /dev/null +++ b/example-fsm-55/debian-logo.c @@ -0,0 +1,473 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> + +#include "board.h" + +static uint8_t main_finished; + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) + +static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0, cnd1; + +#define BUTTON_PUSHED 1 +static uint8_t button_state; + +static uint8_t +user_button (void) +{ + return button_state; +} + + +static uint8_t l_data[5]; +#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f) + +static void +set_led_display (uint32_t data) +{ + l_data[0] = (data >> 0) & 0x1f; + l_data[1] = (data >> 5) & 0x1f; + l_data[2] = (data >> 10) & 0x1f; + l_data[3] = (data >> 15) & 0x1f; + l_data[4] = (data >> 20) & 0x1f; +} + +static void +scroll_led_display (uint8_t row) +{ + l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1); + l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1); + l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1); + l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1); + l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1); +} + + +static void +wait_for (uint32_t usec) +{ + chopstx_usec_wait (usec); +} + +static void +led_prepare_row (uint8_t col) +{ + uint16_t data = 0x1f; + + data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; + data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; + data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; + data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; + data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; + GPIO_LED->ODR = data; +} + + +static void +led_enable_column (uint8_t col) +{ + GPIO_LED->BRR = (1 << col); +} + +static void * +led (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (!main_finished) + { + int i; + + for (i = 0; i < 5; i++) + { + led_prepare_row (i); + led_enable_column (i); + wait_for (1000); + } + } + + GPIO_LED->ODR = 0x0000; /* Off all LEDs. */ + GPIO_LED->OSPEEDR = 0; + GPIO_LED->OTYPER = 0; + GPIO_LED->MODER = 0; /* Input mode. */ + GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */ + + return NULL; +} + + +static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; } + +static void * +button (void *arg) +{ + uint8_t last_button = 0; + + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd1, &mtx); + chopstx_mutex_unlock (&mtx); + + while (!main_finished) + { + uint8_t button = get_button_sw (); + + if (last_button == button && button != button_state) + { + wait_for (1000); + button = get_button_sw (); + if (last_button == button) + button_state = button; + } + + wait_for (2000); + last_button = button; + } + + return NULL; +} + +#define PRIO_LED 3 +#define PRIO_BUTTON 2 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; +extern uint8_t __process2_stack_base__, __process2_stack_size__; + +const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_led = (size_t)&__process1_stack_size__; + +const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__; +const size_t __stacksize_button = (size_t)&__process2_stack_size__; + +#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) +#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) + +static uint32_t logo55[] = { + DATA55 (0x00, 0x00, 0x00, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x04, 0x00, 0x00), + DATA55 (0x00, 0x00, 0x04, 0x02, 0x00), + DATA55 (0x00, 0x00, 0x05, 0x02, 0x00), + DATA55 (0x00, 0x01, 0x05, 0x02, 0x00), + DATA55 (0x02, 0x01, 0x05, 0x02, 0x00), + DATA55 (0x06, 0x01, 0x05, 0x02, 0x00), + DATA55 (0x0e, 0x01, 0x05, 0x02, 0x00), + DATA55 (0x0e, 0x11, 0x05, 0x02, 0x00), + DATA55 (0x0e, 0x11, 0x15, 0x02, 0x00), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x00), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08), + DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0c), + DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0c), + DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0e), + DATA55 (0x0c, 0x12, 0x14, 0x10, 0x0f), + DATA55 (0x0c, 0x12, 0x14, 0x11, 0x0e), + DATA55 (0x08, 0x14, 0x15, 0x11, 0x0e), + DATA55 (0x08, 0x15, 0x15, 0x11, 0x0e), + DATA55 (0x01, 0x09, 0x15, 0x11, 0x0e), + DATA55 (0x02, 0x09, 0x15, 0x11, 0x0e), + DATA55 (0x06, 0x01, 0x0d, 0x11, 0x0e), + DATA55 (0x0e, 0x01, 0x0d, 0x11, 0x0e), + DATA55 (0x1e, 0x01, 0x0d, 0x11, 0x0e), + DATA55 (0x0e, 0x11, 0x05, 0x09, 0x06), + DATA55 (0x0e, 0x11, 0x15, 0x05, 0x02), + DATA55 (0x0e, 0x11, 0x15, 0x15, 0x02), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x10), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08), + DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08), +}; + +#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20) + +#define CHAR_SPC 0 +#define CHAR_H 1 +#define CHAR_A 2 +#define CHAR_P 3 +#define CHAR_Y 4 +#define CHAR_C 5 +#define CHAR_K 6 +#define CHAR_I 7 +#define CHAR_N 8 +#define CHAR_G 9 +#define CHAR_EXC 10 +#define CHAR_W 11 +#define CHAR_h 12 +#define CHAR_t 13 +#define CHAR_AP 14 +#define CHAR_s 15 +#define CHAR_U 16 +#define CHAR_QT 17 +#define CHAR_o 18 +#define CHAR_X 19 +#define CHAR_D 20 +#define CHAR_e 21 +#define CHAR_b 22 +#define CHAR_i 23 +#define CHAR_a 24 +#define CHAR_n 25 + +static uint8_t hh[] = { + CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y, + CHAR_SPC, + CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G, + CHAR_EXC, + CHAR_SPC, CHAR_SPC, CHAR_SPC, +}; + +static uint8_t debian[] = { + CHAR_SPC, + CHAR_D, CHAR_e, CHAR_b, CHAR_i, CHAR_a, CHAR_n, + CHAR_SPC, CHAR_SPC, +}; + +struct { uint8_t width; uint32_t data; } chargen[] = { + { 3, 0 }, /* SPACE */ + { 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */ + { 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */ + { 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */ + { 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */ + { 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */ + { 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */ + { 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */ + { 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */ + { 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */ + { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ + { 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */ + { 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */ + { 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */ + { 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */ + { 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */ + { 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */ + { 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */ + { 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */ + { 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */ + { 4, DATA55V (0x1f, 0x11, 0x11, 0x0e, 0x00) }, /* D */ + { 4, DATA55V (0x0e, 0x15, 0x15, 0x0d, 0x00) }, /* e */ + { 4, DATA55V (0x1f, 0x05, 0x05, 0x06, 0x00) }, /* b */ + { 1, DATA55V (0x17, 0x00, 0x00, 0x00, 0x00) }, /* i */ + { 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* a */ + { 4, DATA55V (0x1f, 0x08, 0x10, 0x1f, 0x00) }, /* n */ +}; + + +#define REPEAT_COUNT 10 + +static int +logo_display (void) +{ + unsigned int i; + uint8_t state = 0; + + for (i = 0; i < SIZE55 (logo55); i++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + set_led_display (logo55[i]); + wait_for (350*1000); + } + + return 1; +} + + +static int +text_display (uint8_t kind) +{ + unsigned int i, j; + uint8_t *text; + uint8_t len; + uint8_t state = 0; + + if (kind) + { + text = debian; + len = sizeof (debian); + } + else + { + text = hh; + len = sizeof (hh); + } + +#if 0 + set_led_display (0); +#endif + for (i = 0; i < len; i++) + { + for (j = 0; j < chargen[text[i]].width; j++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); + wait_for (120*1000); + } + + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display (0); + wait_for (120*1000); + } + + return 1; +} + + +static void setup_scr_sleepdeep (void); + +int +main (int argc, const char *argv[]) +{ + chopstx_t led_thd; + chopstx_t button_thd; + uint8_t happy = 1; + uint8_t count = 0; + + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + chopstx_cond_init (&cnd1); + + led_thd = chopstx_create (PRIO_LED, __stackaddr_led, + __stacksize_led, led, NULL); + button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button, + __stacksize_button, button, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_cond_signal (&cnd1); + chopstx_mutex_unlock (&mtx); + + wait_for (100*1000); + if (user_button ()) + { + /* Wait button release. */ + while (user_button ()) + wait_for (100*1000); + + happy = 0; + goto do_text; + } + + while (count++ < REPEAT_COUNT) + { + if (!logo_display ()) + break; + do_text: + if (!text_display (happy)) + break; + } + + main_finished = 1; + chopstx_join (button_thd, NULL); + chopstx_join (led_thd, NULL); + + setup_scr_sleepdeep (); + for (;;) + asm volatile ("wfi" : : : "memory"); + + return 0; +} + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); + +#define SCB_SCR_SLEEPDEEP (1 << 2) + +struct PWR +{ + volatile uint32_t CR; + volatile uint32_t CSR; +}; +#define PWR_CR_PDDS 0x0002 +#define PWR_CR_CWUF 0x0004 + +#define PWR_BASE (APBPERIPH_BASE + 0x00007000) +#define PWR ((struct PWR *) PWR_BASE) + +static void setup_scr_sleepdeep (void) +{ + PWR->CR |= PWR_CR_CWUF; + PWR->CR |= PWR_CR_PDDS; + SCB->SCR |= SCB_SCR_SLEEPDEEP; +} diff --git a/example-fsm-55/debian-logo.txt b/example-fsm-55/debian-logo.txt new file mode 100644 index 0000000..c540526 --- /dev/null +++ b/example-fsm-55/debian-logo.txt @@ -0,0 +1,594 @@ +..... +..... +..... +..... +..... + +..... +..... +..o.. +..... +..... + +..... +..... +..o.. +...o. +..... + +..... +..... +..o.o +...o. +..... + +..... +....o +..o.o +...o. +..... + +...o. +....o +..o.o +...o. +..... + +..oo. +....o +..o.o +...o. +..... + +.ooo. +....o +..o.o +...o. +..... + +.ooo. +o...o +..o.o +...o. +..... + +.ooo. +o...o +o.o.o +...o. +..... + +.ooo. +o...o +o.o.o +o..o. +..... + +.ooo. +o...o +o.o.o +o..o. +.o... + +.ooo. +o...o +o.o.o +o..o. +.o... + +.ooo. +o...o +o.oo. +o.... +.oo.. + +.ooo. +o...o +o.oo. +o.... +.ooo. + +.oo.. +o..o. +o.o.. +o.... +.oooo + +.oo.. +o..o. +o.o.. +o...o +.ooo. + +.oo.. +o.o.. +o.o.o +o...o +.ooo. + +.o... +o.o.o +o.o.o +o...o +.ooo. + +....o +.o..o +o.o.o +o...o +.ooo. + +...o. +....o +.oo.o +o...o +.ooo. + +.ooo. +....o +.oo.o +o...o +.ooo. + +oooo. +....o +.oo.o +o...o +.ooo. + +.ooo. +o...o +..o.o +.o..o +..oo. + +.ooo. +o...o +o.o.o +..o.o +...o. + +.ooo. +o...o +o.o.o +o.o.o +...o. + +.ooo. +o...o +o.o.o +o..o. +o.... + +.ooo. +o...o +o.o.o +o..o. +.o... + +.ooo. +o...o +o.o.o +o..o. +.o... + +ooo. +o..o +o..o +o..o +ooo. + +.oo. +o..o +oooo +o... +.ooo + +o... +o... +oooo +o..o +ooo. + +o +. +o +o +o + +.oo. +...o +.ooo +o..o +oooo + +.... +oooo +o..o +o..o +o..o + +..... 00 +..... 00 +..... 00 +..... 00 +..... 00 + +..... 00 +..... 00 +..o.. 04 +..... 00 +..... 00 + +..... 00 +..... 00 +..o.. 04 +...o. 02 +..... 00 + +..... 00 +..... 00 +..o.o 05 +...o. 02 +..... 00 + +..... 00 +....o 01 +..o.o 05 +...o. 02 +..... 00 + +...o. 02 +....o 01 +..o.o 05 +...o. 02 +..... 00 + +..oo. 06 +....o 01 +..o.o 05 +...o. 02 +..... 00 + +.ooo. 0e +....o 01 +..o.o 05 +...o. 02 +..... 00 + +.ooo. 0e +o...o 11 +..o.o 05 +...o. 02 +..... 00 + +.ooo. 0e +o...o 11 +o.o.o 15 +...o. 02 +..... 00 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +..... 00 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +.o... 08 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +.o... 08 + +.ooo. 0e +o...o 11 +o.oo. 16 +o.... 10 +.oo.. 0c + +.ooo. 0e +o...o 11 +o.oo. 16 +o.... 10 +.ooo. 0e + +.oo.. 0c +o..o. 12 +o.o.. 14 +o.... 10 +.oooo 0f + +.oo.. 0c +o..o. 12 +o.o.. 14 +o...o 11 +.ooo. 0e + +.o... 08 +o.o.. 14 +o.o.o 15 +o...o 11 +.ooo. 0e + +.o... 08 +o.o.o 15 +o.o.o 15 +o...o 11 +.ooo. 0e + +...o. 02 +.o..o 09 +o.o.o 15 +o...o 11 +.ooo. 0e + +....o 01 +.o..o 09 +o.o.o 15 +o...o 11 +.ooo. 0e + +...o. 02 +.o..o 09 +o.o.o 15 +o...o 11 +.ooo. 0e + +..oo. 06 +....o 01 +.oo.o 0d +o...o 11 +.ooo. 0e + +.ooo. 0e +....o 01 +.oo.o 0d +o...o 11 +.ooo. 0e + +oooo. 1e +....o 01 +.oo.o 0d +o...o 11 +.ooo. 0e + +.ooo. 0e +o...o 11 +..o.o 05 +.o..o 09 +..oo. 06 + +.ooo. 0e +o...o 11 +o.o.o 15 +..o.o 05 +...o. 02 + +.ooo. 0e +o...o 11 +o.o.o 15 +o.o.o 15 +...o. 02 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +o.... 10 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +.o... 08 + +.ooo. 0e +o...o 11 +o.o.o 15 +o..o. 12 +.o... 08 + +ooo. +o..o +o..o +o..o +ooo. + +.oo. +o..o +oooo +o... +.ooo + +o... +o... +oooo +o..o +ooo. + +o +. +o +o +o + +.oo. +...o +.ooo +o..o +.ooo + +o.oo +oo.o +o..o +o..o +o..o + + +00 +00 +00 +00 +00 + +00 +00 +04 +00 +00 + +00 +00 +04 +02 +00 + +00 +00 +05 +02 +00 + +00 +01 +05 +02 +00 + +02 +01 +05 +02 +00 + +06 +01 +05 +02 +00 + +0e +01 +05 +02 +00 + +0e +11 +05 +02 +00 + +0e +11 +15 +02 +00 + +0e +11 +15 +12 +00 + +0e +11 +15 +12 +08 + +0e +11 +15 +12 +08 + +0e +11 +16 +10 +0e + +0c +12 +14 +11 +0e + +0c +14 +15 +11 +0e + +08 +15 +15 +11 +0e + +02 +09 +15 +11 +0e + +06 +01 +0d +11 +0e + +0e +01 +1d +11 +0e + +1e +01 +0d +11 +0e + +0e +11 +05 +09 +0e + +0e +11 +15 +05 +06 + +0e +11 +15 +15 +02 + +0e +11 +15 +13 +08 + +0e +11 +15 +12 +08 + +0e +11 +15 +12 +08 diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c deleted file mode 100644 index b8e7409..0000000 --- a/example-fsm-55/hacker-emblem.c +++ /dev/null @@ -1,455 +0,0 @@ -#include <stdint.h> -#include <stdlib.h> -#include <chopstx.h> - -#include "board.h" - -static uint8_t main_finished; - -#define PERIPH_BASE 0x40000000 -#define APBPERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) -#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) - -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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) -#define GPIOF ((struct GPIO *) GPIOF_BASE) - -static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); -static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); - -static chopstx_mutex_t mtx; -static chopstx_cond_t cnd0, cnd1; - -#define BUTTON_PUSHED 1 -static uint8_t button_state; - -static uint8_t -user_button (void) -{ - return button_state; -} - - -static uint8_t l_data[5]; -#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f) - -static void -set_led_display (uint32_t data) -{ - l_data[0] = (data >> 0) & 0x1f; - l_data[1] = (data >> 5) & 0x1f; - l_data[2] = (data >> 10) & 0x1f; - l_data[3] = (data >> 15) & 0x1f; - l_data[4] = (data >> 20) & 0x1f; -} - -static void -scroll_led_display (uint8_t row) -{ - l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1); - l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1); - l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1); - l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1); - l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1); -} - - -static void -wait_for (uint32_t usec) -{ - chopstx_usec_wait (usec); -} - -static void -led_prepare_row (uint8_t col) -{ - uint16_t data = 0x1f; - - data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; - data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; - data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; - data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; - data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; - GPIO_LED->ODR = data; -} - - -static void -led_enable_column (uint8_t col) -{ - GPIO_LED->BRR = (1 << col); -} - -static void * -led (void *arg) -{ - (void)arg; - - chopstx_mutex_lock (&mtx); - chopstx_cond_wait (&cnd0, &mtx); - chopstx_mutex_unlock (&mtx); - - while (!main_finished) - { - int i; - - for (i = 0; i < 5; i++) - { - led_prepare_row (i); - led_enable_column (i); - wait_for (1000); - } - } - - GPIO_LED->ODR = 0x0000; /* Off all LEDs. */ - GPIO_LED->OSPEEDR = 0; - GPIO_LED->OTYPER = 0; - GPIO_LED->MODER = 0; /* Input mode. */ - GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */ - - return NULL; -} - - -static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; } - -static void * -button (void *arg) -{ - uint8_t last_button = 0; - - (void)arg; - - chopstx_mutex_lock (&mtx); - chopstx_cond_wait (&cnd1, &mtx); - chopstx_mutex_unlock (&mtx); - - while (!main_finished) - { - uint8_t button = get_button_sw (); - - if (last_button == button && button != button_state) - { - wait_for (1000); - button = get_button_sw (); - if (last_button == button) - button_state = button; - } - - wait_for (2000); - last_button = button; - } - - return NULL; -} - -#define PRIO_LED 3 -#define PRIO_BUTTON 2 - -extern uint8_t __process1_stack_base__, __process1_stack_size__; -extern uint8_t __process2_stack_base__, __process2_stack_size__; - -const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; -const size_t __stacksize_led = (size_t)&__process1_stack_size__; - -const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__; -const size_t __stacksize_button = (size_t)&__process2_stack_size__; - -#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) -#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) - -static uint32_t l55[] = { - DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), - DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), - DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), - DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00), - DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00), - DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04), - DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06), - DATA55 (0x00, 0x00, 0x04, 0x03, 0x06), - DATA55 (0x00, 0x00, 0x02, 0x01, 0x07), - DATA55 (0x02, 0x00, 0x00, 0x05, 0x03), - DATA55 (0x03, 0x00, 0x00, 0x01, 0x05), - DATA55 (0x03, 0x00, 0x00, 0x02, 0x11), - DATA55 (0x13, 0x00, 0x00, 0x01, 0x10), - DATA55 (0x11, 0x01, 0x00, 0x00, 0x12), - DATA55 (0x12, 0x11, 0x00, 0x00, 0x10), - DATA55 (0x18, 0x11, 0x00, 0x00, 0x01), - DATA55 (0x08, 0x19, 0x00, 0x00, 0x10), - DATA55 (0x09, 0x18, 0x10, 0x00, 0x00), - DATA55 (0x08, 0x09, 0x18, 0x00, 0x00), - DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), -}; - -#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20) - -#define CHAR_SPC 0 -#define CHAR_H 1 -#define CHAR_A 2 -#define CHAR_P 3 -#define CHAR_Y 4 -#define CHAR_C 5 -#define CHAR_K 6 -#define CHAR_I 7 -#define CHAR_N 8 -#define CHAR_G 9 -#define CHAR_EXC 10 -#define CHAR_W 11 -#define CHAR_h 12 -#define CHAR_t 13 -#define CHAR_AP 14 -#define CHAR_s 15 -#define CHAR_U 16 -#define CHAR_QT 17 -#define CHAR_o 18 -#define CHAR_X 19 - -static uint8_t hh[] = { - CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y, - CHAR_SPC, - CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G, - CHAR_EXC, - CHAR_SPC, CHAR_SPC, CHAR_SPC, -}; - -static uint8_t gnu[] = { - CHAR_W, CHAR_h, CHAR_A, CHAR_t, CHAR_AP, CHAR_s, CHAR_SPC, - CHAR_G, CHAR_N, CHAR_U, CHAR_QT, - CHAR_SPC, CHAR_SPC, - CHAR_G, CHAR_N, CHAR_U, CHAR_AP, CHAR_s, CHAR_SPC, - CHAR_N, CHAR_o, CHAR_t, CHAR_SPC, - CHAR_U, CHAR_N, CHAR_I, CHAR_X, - CHAR_EXC, - CHAR_SPC, CHAR_SPC, -}; - -struct { uint8_t width; uint32_t data; } chargen[] = { - { 3, 0 }, /* SPACE */ - { 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */ - { 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */ - { 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */ - { 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */ - { 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */ - { 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */ - { 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */ - { 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */ - { 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */ - { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ - { 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */ - { 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */ - { 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */ - { 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */ - { 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */ - { 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */ - { 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */ - { 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */ - { 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */ -}; - - -#define REPEAT_COUNT 10 - -static int -life_display (void) -{ - unsigned int i; - uint8_t count = 0; - uint8_t state = 0; - - while (count++ < REPEAT_COUNT) - for (i = 0; i < SIZE55 (l55); i++) - { - if (user_button ()) - { - set_led_display (LED_FULL); - state = 1; - } - else if (state == 1) - return 0; - else - set_led_display (l55[i]); - wait_for (350*1000); - } - - return 1; -} - - -static int -text_display (uint8_t kind) -{ - unsigned int i, j; - uint8_t *text; - uint8_t len; - uint8_t count = 0; - uint8_t state = 0; - - if (kind) - { - text = hh; - len = sizeof (hh); - } - else - { - text = gnu; - len = sizeof (gnu); - } - - set_led_display (0); - while (count++ < REPEAT_COUNT) - for (i = 0; i < len; i++) - { - for (j = 0; j < chargen[text[i]].width; j++) - { - if (user_button ()) - { - set_led_display (LED_FULL); - state = 1; - } - else if (state == 1) - return 0; - else - scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); - wait_for (120*1000); - } - - if (user_button ()) - { - set_led_display (LED_FULL); - state = 1; - } - else if (state == 1) - return 0; - else - scroll_led_display (0); - wait_for (120*1000); - } - - return 1; -} - - -static void setup_scr_sleepdeep (void); - -int -main (int argc, const char *argv[]) -{ - chopstx_t led_thd; - chopstx_t button_thd; - uint8_t happy = 1; - (void)argc; - (void)argv; - - chopstx_mutex_init (&mtx); - chopstx_cond_init (&cnd0); - chopstx_cond_init (&cnd1); - - led_thd = chopstx_create (PRIO_LED, __stackaddr_led, - __stacksize_led, led, NULL); - button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button, - __stacksize_button, button, NULL); - - chopstx_usec_wait (200*1000); - - chopstx_mutex_lock (&mtx); - chopstx_cond_signal (&cnd0); - chopstx_cond_signal (&cnd1); - chopstx_mutex_unlock (&mtx); - - wait_for (100*1000); - if (user_button ()) - { - /* Wait button release. */ - while (user_button ()) - wait_for (100*1000); - - happy = 0; - goto do_text; - } - - while (1) - { - if (life_display ()) - break; - do_text: - if (text_display (happy)) - break; - } - - main_finished = 1; - chopstx_join (button_thd, NULL); - chopstx_join (led_thd, NULL); - - setup_scr_sleepdeep (); - for (;;) - asm volatile ("wfi" : : : "memory"); - - return 0; -} - -struct SCB -{ - volatile uint32_t CPUID; - volatile uint32_t ICSR; - volatile uint32_t VTOR; - volatile uint32_t AIRCR; - volatile uint32_t SCR; - volatile uint32_t CCR; - volatile uint8_t SHP[12]; - volatile uint32_t SHCSR; - volatile uint32_t CFSR; - volatile uint32_t HFSR; - volatile uint32_t DFSR; - volatile uint32_t MMFAR; - volatile uint32_t BFAR; - volatile uint32_t AFSR; - volatile uint32_t PFR[2]; - volatile uint32_t DFR; - volatile uint32_t ADR; - volatile uint32_t MMFR[4]; - volatile uint32_t ISAR[5]; -}; - -#define SCS_BASE (0xE000E000) -#define SCB_BASE (SCS_BASE + 0x0D00) -static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); - -#define SCB_SCR_SLEEPDEEP (1 << 2) - -struct PWR -{ - volatile uint32_t CR; - volatile uint32_t CSR; -}; -#define PWR_CR_PDDS 0x0002 -#define PWR_CR_CWUF 0x0004 - -#define PWR_BASE (APBPERIPH_BASE + 0x00007000) -#define PWR ((struct PWR *) PWR_BASE) - -static void setup_scr_sleepdeep (void) -{ - PWR->CR |= PWR_CR_CWUF; - PWR->CR |= PWR_CR_PDDS; - SCB->SCR |= SCB_SCR_SLEEPDEEP; -} diff --git a/example-fsm-55/hacker-emblem.c b/example-fsm-55/hacker-emblem.c new file mode 120000 index 0000000..d2bfd5f --- /dev/null +++ b/example-fsm-55/hacker-emblem.c @@ -0,0 +1 @@ +debian-logo.c \ No newline at end of file diff --git a/example-fsm-55/hh.c b/example-fsm-55/hh.c new file mode 100644 index 0000000..1567c41 --- /dev/null +++ b/example-fsm-55/hh.c @@ -0,0 +1,461 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> + +#include "board.h" + +static uint8_t main_finished; + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) + +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 GPIOF_BASE (AHB2PERIPH_BASE + 0x1400) +#define GPIOF ((struct GPIO *) GPIOF_BASE) + +static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0, cnd1; + +#define BUTTON_PUSHED 1 +static uint8_t button_state; + +static uint8_t +user_button (void) +{ + return button_state; +} + + +static uint8_t l_data[5]; +#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f) + +static void +set_led_display (uint32_t data) +{ + l_data[0] = (data >> 0) & 0x1f; + l_data[1] = (data >> 5) & 0x1f; + l_data[2] = (data >> 10) & 0x1f; + l_data[3] = (data >> 15) & 0x1f; + l_data[4] = (data >> 20) & 0x1f; +} + +static void +scroll_led_display (uint8_t row) +{ + l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1); + l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1); + l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1); + l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1); + l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1); +} + + +static void +wait_for (uint32_t usec) +{ + chopstx_usec_wait (usec); +} + +static void +led_prepare_row (uint8_t col) +{ + uint16_t data = 0x1f; + + data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5; + data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6; + data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7; + data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9; + data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10; + GPIO_LED->ODR = data; +} + + +static void +led_enable_column (uint8_t col) +{ + GPIO_LED->BRR = (1 << col); +} + +static void * +led (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (!main_finished) + { + int i; + + for (i = 0; i < 5; i++) + { + led_prepare_row (i); + led_enable_column (i); + wait_for (1000); + } + } + + GPIO_LED->ODR = 0x0000; /* Off all LEDs. */ + GPIO_LED->OSPEEDR = 0; + GPIO_LED->OTYPER = 0; + GPIO_LED->MODER = 0; /* Input mode. */ + GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */ + + return NULL; +} + + +static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; } + +static void * +button (void *arg) +{ + uint8_t last_button = 0; + + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd1, &mtx); + chopstx_mutex_unlock (&mtx); + + while (!main_finished) + { + uint8_t button = get_button_sw (); + + if (last_button == button && button != button_state) + { + wait_for (1000); + button = get_button_sw (); + if (last_button == button) + button_state = button; + } + + wait_for (2000); + last_button = button; + } + + return NULL; +} + +#define PRIO_LED 3 +#define PRIO_BUTTON 2 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; +extern uint8_t __process2_stack_base__, __process2_stack_size__; + +const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_led = (size_t)&__process1_stack_size__; + +const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__; +const size_t __stacksize_button = (size_t)&__process2_stack_size__; + +#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) +#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) + +static uint32_t l55[] = { + DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00), + DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00), + DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00), + DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00), + DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00), + DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04), + DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06), + DATA55 (0x00, 0x00, 0x04, 0x03, 0x06), + DATA55 (0x00, 0x00, 0x02, 0x01, 0x07), + DATA55 (0x02, 0x00, 0x00, 0x05, 0x03), + DATA55 (0x03, 0x00, 0x00, 0x01, 0x05), + DATA55 (0x03, 0x00, 0x00, 0x02, 0x11), + DATA55 (0x13, 0x00, 0x00, 0x01, 0x10), + DATA55 (0x11, 0x01, 0x00, 0x00, 0x12), + DATA55 (0x12, 0x11, 0x00, 0x00, 0x10), + DATA55 (0x18, 0x11, 0x00, 0x00, 0x01), + DATA55 (0x08, 0x19, 0x00, 0x00, 0x10), + DATA55 (0x09, 0x18, 0x10, 0x00, 0x00), + DATA55 (0x08, 0x09, 0x18, 0x00, 0x00), + DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00), +}; + +#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20) + +#define CHAR_SPC 0 +#define CHAR_H 1 +#define CHAR_A 2 +#define CHAR_P 3 +#define CHAR_Y 4 +#define CHAR_C 5 +#define CHAR_K 6 +#define CHAR_I 7 +#define CHAR_N 8 +#define CHAR_G 9 +#define CHAR_EXC 10 +#define CHAR_W 11 +#define CHAR_h 12 +#define CHAR_t 13 +#define CHAR_AP 14 +#define CHAR_s 15 +#define CHAR_U 16 +#define CHAR_QT 17 +#define CHAR_o 18 +#define CHAR_X 19 + +static uint8_t hh[] = { + CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y, + CHAR_SPC, + CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G, + CHAR_EXC, + CHAR_SPC, CHAR_SPC, CHAR_SPC, +}; + +static uint8_t gnu[] = { + CHAR_W, CHAR_h, CHAR_A, CHAR_t, CHAR_AP, CHAR_s, CHAR_SPC, + CHAR_G, CHAR_N, CHAR_U, CHAR_QT, + CHAR_SPC, CHAR_SPC, + CHAR_G, CHAR_N, CHAR_U, CHAR_AP, CHAR_s, CHAR_SPC, + CHAR_N, CHAR_o, CHAR_t, CHAR_SPC, + CHAR_U, CHAR_N, CHAR_I, CHAR_X, + CHAR_EXC, + CHAR_SPC, CHAR_SPC, +}; + +struct { uint8_t width; uint32_t data; } chargen[] = { + { 3, 0 }, /* SPACE */ + { 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */ + { 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */ + { 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */ + { 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */ + { 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */ + { 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */ + { 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */ + { 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */ + { 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */ + { 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */ + { 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */ + { 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */ + { 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */ + { 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */ + { 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */ + { 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */ + { 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */ + { 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */ + { 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */ + { 4, DATA55V (0x1f, 0x11, 0x11, 0x0e, 0x00) }, /* D */ + { 4, DATA55V (0x0e, 0x15, 0x15, 0x0d, 0x00) }, /* e */ + { 4, DATA55V (0x1f, 0x05, 0x05, 0x06, 0x00) }, /* b */ + { 1, DATA55V (0x17, 0x00, 0x00, 0x00, 0x00) }, /* i */ + { 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* a */ + { 4, DATA55V (0x0f, 0x08, 0x08, 0x0f, 0x00) }, /* n */ +}; + + +#define REPEAT_COUNT 10 + +static int +life_display (void) +{ + unsigned int i; + uint8_t count = 0; + uint8_t state = 0; + + while (count++ < REPEAT_COUNT) + for (i = 0; i < SIZE55 (l55); i++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + set_led_display (l55[i]); + wait_for (350*1000); + } + + return 1; +} + + +static int +text_display (uint8_t kind) +{ + unsigned int i, j; + uint8_t *text; + uint8_t len; + uint8_t count = 0; + uint8_t state = 0; + + if (kind) + { + text = hh; + len = sizeof (hh); + } + else + { + text = gnu; + len = sizeof (gnu); + } + + set_led_display (0); + while (count++ < REPEAT_COUNT) + for (i = 0; i < len; i++) + { + for (j = 0; j < chargen[text[i]].width; j++) + { + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f); + wait_for (120*1000); + } + + if (user_button ()) + { + set_led_display (LED_FULL); + state = 1; + } + else if (state == 1) + return 0; + else + scroll_led_display (0); + wait_for (120*1000); + } + + return 1; +} + + +static void setup_scr_sleepdeep (void); + +int +main (int argc, const char *argv[]) +{ + chopstx_t led_thd; + chopstx_t button_thd; + uint8_t happy = 1; + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + chopstx_cond_init (&cnd1); + + led_thd = chopstx_create (PRIO_LED, __stackaddr_led, + __stacksize_led, led, NULL); + button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button, + __stacksize_button, button, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_cond_signal (&cnd1); + chopstx_mutex_unlock (&mtx); + + wait_for (100*1000); + if (user_button ()) + { + /* Wait button release. */ + while (user_button ()) + wait_for (100*1000); + + happy = 0; + goto do_text; + } + + while (1) + { + if (life_display ()) + break; + do_text: + if (text_display (happy)) + break; + } + + main_finished = 1; + chopstx_join (button_thd, NULL); + chopstx_join (led_thd, NULL); + + setup_scr_sleepdeep (); + for (;;) + asm volatile ("wfi" : : : "memory"); + + return 0; +} + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); + +#define SCB_SCR_SLEEPDEEP (1 << 2) + +struct PWR +{ + volatile uint32_t CR; + volatile uint32_t CSR; +}; +#define PWR_CR_PDDS 0x0002 +#define PWR_CR_CWUF 0x0004 + +#define PWR_BASE (APBPERIPH_BASE + 0x00007000) +#define PWR ((struct PWR *) PWR_BASE) + +static void setup_scr_sleepdeep (void) +{ + PWR->CR |= PWR_CR_CWUF; + PWR->CR |= PWR_CR_PDDS; + SCB->SCR |= SCB_SCR_SLEEPDEEP; +} -- cgit v1.2.3 From 7c022432d19351dfc9553585ea6614b47fcd0c06 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Wed, 10 Dec 2014 18:53:00 +0900 Subject: fix rebase --- entry.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/entry.c b/entry.c index 1170c6a..bd43d48 100644 --- a/entry.c +++ b/entry.c @@ -379,8 +379,6 @@ static void nmi (void) for (;;); } -extern void svc (void); - static void hard_fault (void) { #if 1 -- cgit v1.2.3