diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2014-08-25 10:35:04 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2014-12-10 18:50:11 +0900 |
commit | b0992073d73408b38baa560c398a9042378b3c7e (patch) | |
tree | 05274a5fceb0b36907828432f9e42b3eb81c67b3 /example-fsm-55 | |
parent | 5f4cca00fcd84ee778d2397c700cad8249359486 (diff) |
Add debian-logo.c (from Portland).
Diffstat (limited to 'example-fsm-55')
-rw-r--r-- | example-fsm-55/debian-logo.c | 473 | ||||
-rw-r--r-- | example-fsm-55/debian-logo.txt | 594 | ||||
l---------[-rw-r--r--] | example-fsm-55/hacker-emblem.c | 456 | ||||
-rw-r--r-- | example-fsm-55/hh.c | 461 |
4 files changed, 1529 insertions, 455 deletions
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 index b8e7409..d2bfd5f 100644..120000 --- a/example-fsm-55/hacker-emblem.c +++ b/example-fsm-55/hacker-emblem.c @@ -1,455 +1 @@ -#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; -} +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; +} |