diff --git a/src/main.c b/src/main.c index c134d21..3fe1398 100644 --- a/src/main.c +++ b/src/main.c @@ -42,6 +42,7 @@ static struct sbuf *sbuf_free_head; static unsigned char passwd[20]; static unsigned char passwd_len; static char led; +static unsigned char leds; static char locked; static unsigned char disk[1000]; @@ -71,6 +72,17 @@ static void sbuf_free(struct sbuf *f) #define LED 13 /* port B, pin 5 */ +#define LED2 26 +#define LED3 27 +#define LED4 28 +#define LED5 29 +#define LED6 30 +#define LED7 31 + +#define SW1 8 +#define SW2 9 +#define SW3 19 + static unsigned char *rxframe; static void ssdisk_receive_buf(struct tty_struct *tty, const unsigned char *cp, @@ -82,6 +94,8 @@ static void ssdisk_receive_buf(struct tty_struct *tty, const unsigned char *cp, while (count-- > 0) { x = *cp++; + ACCESS_ONCE(leds) = x; + if (x == ':') { rxlen = 0; continue; @@ -242,6 +256,15 @@ static __init void init(void) unsigned int i; gpio_direction_output(LED, 1); + gpio_direction_output(LED2, 1); + gpio_direction_output(LED3, 1); + gpio_direction_output(LED4, 1); + gpio_direction_output(LED5, 1); + gpio_direction_output(LED6, 1); + gpio_direction_output(LED7, 1); + gpio_direction_input(SW1); + gpio_direction_input(SW2); + gpio_direction_input(SW3); for (i = 0; i < ARRAY_SIZE(sbuf); i++) sbuf_free(sbuf + i); @@ -249,24 +272,83 @@ static __init void init(void) rxframe = sbuf_alloc()->raw; } +struct key { + unsigned char c; + unsigned char pressed; +}; + +static void key_init(struct key *k) +{ + k->c = 0; + k->pressed = 0; +} + +static void key_handle(struct key *k, char x) +{ + unsigned char c = k->c; + + if (x) { + if (c < 255) { + c++; + if (c >= 128) { + c = 255; + k->pressed = 1; + } + } + } else { + if (c > 0) + c--; + if (c < 128) + c = 0; + } + k->c = c; +} + +static int key_get(struct key *k) +{ + int ret = k->pressed; + + k->pressed = 0; + return ret; +} + int main(void) { + static struct key keys[3]; struct tty_struct *tty0; struct queue_node *n; struct sbuf *txbuf = NULL; unsigned char txpos = 0; int ret; + unsigned char x; + unsigned char c; init(); + key_init(keys + 0); + key_init(keys + 1); + key_init(keys + 2); local_irq_disable(); tty0 = serial_init(0); tty_set_ldisc(tty0, &ssdisk_ldisc_ops, NULL); local_irq_enable(); + for (;;) { wdt_reset(); gpio_set_value(LED, ACCESS_ONCE(led)); + x = ACCESS_ONCE(leds); + gpio_set_value(LED2, x & 0x04); + gpio_set_value(LED3, x & 0x08); + gpio_set_value(LED4, x & 0x10); + gpio_set_value(LED5, x & 0x20); + gpio_set_value(LED6, x & 0x40); + gpio_set_value(LED7, x & 0x80); + + key_handle(keys + 0, !gpio_get_value(SW1)); + key_handle(keys + 1, !gpio_get_value(SW2)); + key_handle(keys + 2, !gpio_get_value(SW3)); + local_irq_disable(); n = queue_pop(&rxqueue); local_irq_enable(); @@ -278,26 +360,39 @@ int main(void) if (n) txbuf = queue_entry(n, struct sbuf, queue); } - if (txbuf && (tty0->ops->write_room(tty0) > 0)) { - unsigned char c; - - if (txpos == 0) { - c = ':'; - } else if (txpos - 1 < 2 * txbuf->len) { - unsigned char x = txbuf->raw[(txpos - 1) >> 1]; + if (tty0->ops->write_room(tty0) <= 0) + continue; - c = to_hex((txpos & 1) ? (x >> 4) : x); - } else { - c = '\n'; + if (!txbuf) { + if (key_get(keys + 0)) { + c = 'x'; + tty0->ops->write(tty0, &c, 1); + } else if (key_get(keys + 1)) { + c = 'y'; + tty0->ops->write(tty0, &c, 1); + } else if (key_get(keys + 2)) { + c = 'z'; + tty0->ops->write(tty0, &c, 1); } - ret = tty0->ops->write(tty0, &c, 1); - if (ret == 1) { - txpos++; - if (c == '\n') { - txpos = 0; - sbuf_free(txbuf); - txbuf = NULL; - } + continue; + } + + if (txpos == 0) { + c = ':'; + } else if (txpos - 1 < 2 * txbuf->len) { + unsigned char x = txbuf->raw[(txpos - 1) >> 1]; + + c = to_hex((txpos & 1) ? (x >> 4) : x); + } else { + c = '\n'; + } + ret = tty0->ops->write(tty0, &c, 1); + if (ret == 1) { + txpos++; + if (c == '\n') { + txpos = 0; + sbuf_free(txbuf); + txbuf = NULL; } } }