From a7f0732d9e384e39d95c7007cb1f51a133654bad Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Wed, 22 Jul 2020 17:55:21 +0200 Subject: [PATCH] Matrix display & snake --- protab/matrix/Makefile | 6 ++ protab/matrix/matrix.c | 167 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 protab/matrix/Makefile create mode 100644 protab/matrix/matrix.c diff --git a/protab/matrix/Makefile b/protab/matrix/Makefile new file mode 100644 index 0000000..4da665f --- /dev/null +++ b/protab/matrix/Makefile @@ -0,0 +1,6 @@ +ROOT=../.. +BINARY=matrix +OBJS=matrix.o +LIB_OBJS= + +include $(ROOT)/mk/bluepill.mk diff --git a/protab/matrix/matrix.c b/protab/matrix/matrix.c new file mode 100644 index 0000000..b4b368d --- /dev/null +++ b/protab/matrix/matrix.c @@ -0,0 +1,167 @@ +#include +#include + +#include + +typedef unsigned char byte; + +static void wait(void) +{ + for (int i=0; i<7200; i++) + asm volatile (""); +} + +static void set_reg(int reg, int data) +{ + data |= reg << 8; + + gpio_clear(GPIOB, GPIO13); + wait(); + + for (int mask=0x8000; mask; mask >>= 1) { + if (data & mask) + gpio_set(GPIOB, GPIO12); + else + gpio_clear(GPIOB, GPIO12); + wait(); + gpio_set(GPIOB, GPIO14); + wait(); + gpio_clear(GPIOB, GPIO14); + wait(); + } + + gpio_set(GPIOB, GPIO13); + wait(); +} + +byte display[8]; + +#if 0 +static unsigned char smile[8] = { + 0x66, /* .##..##. */ + 0x66, /* .##..##. */ + 0x00, /* ........ */ + 0x18, /* ...##... */ + 0x00, /* ........ */ + 0xc3, /* ##....## */ + 0x66, /* .##..##. */ + 0x3c, /* ..####.. */ +}; +#endif + +static void refresh_display(void) +{ + for (int i=1; i<=8; i++) + set_reg(i, display[8-i]); +} + +static signed char dirs[4][2] = {{1,0}, {0,-1}, {-1,0}, {0,1}}; + +static byte snake_dir; +#define SNAKE_MAX 65 +static byte snake[SNAKE_MAX][2]; +static byte snake_tail, snake_head; +static byte food[2]; +static unsigned int rng_state = 0xdeadbeef; + +static byte buttons[2]; + +static void gen_food(void) +{ + food[0] = (rng_state >> 28) & 7; + food[1] = (rng_state >> 20) & 7; + rng_state *= 0x3771cadb; +} + +static void snake_init(void) +{ + snake[0][0] = 0; + snake[0][1] = 0; + snake_dir = 3; + snake_tail = 0; + snake_head = 1; + gen_food(); +} + +static void snake_show(void) +{ + memset(display, 0, 8); + for (int i=snake_tail; i != snake_head; i = (i+1) % SNAKE_MAX) + display[snake[i][0]] |= 1 << snake[i][1]; + display[food[0]] |= 1 << food[1]; + refresh_display(); +} + +static void snake_step(void) +{ + if (buttons[0]) + snake_dir = (snake_dir+3) % 4; + else if (buttons[1]) + snake_dir = (snake_dir+1) % 4; + + int hi = (snake_head + SNAKE_MAX - 1) % SNAKE_MAX; + int x = snake[hi][0] + dirs[snake_dir][0]; + int y = snake[hi][1] + dirs[snake_dir][1]; + + if (x < 0 || x > 7 || y < 0 || y > 7) + return; + + snake[snake_head][0] = x; + snake[snake_head][1] = y; + snake_head = (snake_head + 1) % SNAKE_MAX; + + if (x == food[0] && y == food[1]) + gen_food(); + else + snake_tail = (snake_tail + 1) % SNAKE_MAX; + + snake_show(); +} + +int main(void) +{ + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_GPIOC); + + // PC13 = BluePill LED + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); + + // PB12 = display DIN + // PB13 = display CS* + // PB14 = display CLK + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12 | GPIO13 | GPIO14); + gpio_clear(GPIOB, GPIO12); + gpio_set(GPIOB, GPIO13); + gpio_clear(GPIOB, GPIO14); + + // PA0 = left button + // PA1 = right button + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0 | GPIO1); + gpio_set(GPIOA, GPIO0 | GPIO1); + + refresh_display(); + set_reg(9, 0); + set_reg(10, 0); // intensity + set_reg(11, 7); + set_reg(13, 0); // test + set_reg(12, 1); // shutdown + + snake_init(); + snake_show(); + + for (;;) { + buttons[0] = buttons[1] = 0; + for (int i=0; i<1000000; i++) { + if (!gpio_get(GPIOA, GPIO0)) + buttons[0] = 1; + if (!gpio_get(GPIOA, GPIO1)) + buttons[1] = 1; + asm volatile (""); + } + + gpio_toggle(GPIOC, GPIO13); + snake_step(); + } +} -- 2.39.2