diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2017-09-27 19:24:08 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2017-09-27 19:24:08 +0900 |
commit | 5b7c5a9996333d882376cd45ebf4d590812ccecd (patch) | |
tree | 4e8330766db8b2c4efc9d08481cae10ed9f46baf | |
parent | bc39f0e58268e7f88e1c376c1a1fef17376ca44f (diff) |
Use flash routines in example-cdc-gnu-linux.
-rw-r--r-- | example-cdc-gnu-linux/Makefile | 15 | ||||
-rw-r--r-- | example-cdc-gnu-linux/README | 6 | ||||
-rw-r--r-- | example-cdc-gnu-linux/command.c | 579 | ||||
-rw-r--r-- | example-cdc-gnu-linux/command.h | 2 | ||||
-rw-r--r-- | example-cdc-gnu-linux/config.h | 2 | ||||
-rw-r--r-- | example-cdc-gnu-linux/sample.c | 80 |
6 files changed, 640 insertions, 44 deletions
diff --git a/example-cdc-gnu-linux/Makefile b/example-cdc-gnu-linux/Makefile index 9fbb2fe..28896aa 100644 --- a/example-cdc-gnu-linux/Makefile +++ b/example-cdc-gnu-linux/Makefile @@ -6,12 +6,12 @@ PROJECT = sample CHOPSTX = .. LDSCRIPT= -CSRC = sample.c usb-cdc.c +CSRC = sample.c usb-cdc.c command.c CHIP=gnu-linux -# USE_SYS = yes -USE_SYS = +USE_SYS = yes USE_USB = yes +USE_ADC = yes EMULATION=yes ################################### @@ -22,7 +22,7 @@ OBJCOPY = $(CROSS)objcopy MCU = none CWARN = -Wall -Wextra -Wstrict-prototypes -DEFS = -DGNU_LINUX_EMULATION +DEFS = -DGNU_LINUX_EMULATION -DUSE_SYS_BOARD_ID OPT = -g # -O3 -Os LIBS = -lpthread @@ -34,3 +34,10 @@ board.h: @exit 1 distclean: clean + +build/flash.data: Makefile + @echo 'Generating 8192-byte flash.data' + @/bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff' >$@ + @for i in $(shell seq 1023); do /bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff' >>$@; done + + diff --git a/example-cdc-gnu-linux/README b/example-cdc-gnu-linux/README index 34d21bc..d726009 100644 --- a/example-cdc-gnu-linux/README +++ b/example-cdc-gnu-linux/README @@ -1,3 +1,9 @@ +(0) Build and generate initial flash data + +$ make +$ make build/flash.data + + (1) preparation as root Don't run ModemManager diff --git a/example-cdc-gnu-linux/command.c b/example-cdc-gnu-linux/command.c new file mode 100644 index 0000000..9c14b08 --- /dev/null +++ b/example-cdc-gnu-linux/command.c @@ -0,0 +1,579 @@ +#include <string.h> +#include <stdint.h> +#include <chopstx.h> +#include "tty.h" +#include "config.h" +#ifdef ADC_SUPPORT +#include "adc.h" +static int adc_initialized = 0; +#endif +#include "board.h" +#include "sys.h" + +struct command_table +{ + const char *name; + void (*handler) (struct tty *tty, const char *line); +}; + +/* + * Put a line (or lines) to TTY. + * LINE should be terminated with newline. + */ +static void +put_line (struct tty *tty, const char *line) +{ + tty_send (tty, line, strlen (line)); +} + +static const char *help_string = + "mdb ADDR [COUNT]; memory display byte\r\n" + "mwh ADDR VALUE [COUNT]; memory write halfword\r\n" + "fes ADDR [COUNT]; flash erase sector\r\n" + "fwh ADDR VALUE [COUNT]; flash write halfword\r\n" +#ifdef CRC32_SUPPORT + "crc32 string; CRC32 calc string\r\n" +#endif +#ifdef ADC_SUPPORT + "adc; get 256-byte from ADC\r\n" +#endif + "sysinfo; system information\r\n" + "help\r\n"; + +static char hexchar (uint8_t x) +{ + x &= 0x0f; + if (x <= 0x09) + return '0' + x; + else if (x <= 0x0f) + return 'a' + x - 10; + else + return '?'; +} + +#ifdef TOUCH_SUPPORT +static char * +compose_decimal (char *s, int value) +{ + uint32_t v; + int col = 1000000000; + int d; + int digit_output = 0; + + if (value < 0) + { + *s++ = '-'; + v = 1 + ~((uint32_t)value); + } + else + v = (uint32_t)value; + + while (col >= 10) + { + if (v >= (uint32_t)col) + { + d = v / col; + v = v - d * col; + *s++ = d + '0'; + digit_output = 1; + } + else if (digit_output) + *s++ = '0'; + + col = col / 10; + } + + *s++ = v + '0'; + + return s; +} +#endif + + +char * +compose_hex_ptr (char *s, uintptr_t v) +{ + s[0] = hexchar (v >> 60); + s[1] = hexchar (v >> 56); + s[2] = hexchar (v >> 52); + s[3] = hexchar (v >> 48); + s[4] = hexchar (v >> 44); + s[5] = hexchar (v >> 40); + s[6] = hexchar (v >> 36); + s[7] = hexchar (v >> 32); + s[8] = hexchar (v >> 28); + s[9] = hexchar (v >> 24); + s[10] = hexchar (v >> 20); + s[11] = hexchar (v >> 16); + s[12] = hexchar (v >> 12); + s[13] = hexchar (v >> 8); + s[14] = hexchar (v >> 4); + s[15] = hexchar (v); + return s+16; +} + +static char * +compose_hex (char *s, uint32_t v) +{ + s[0] = hexchar (v >> 28); + s[1] = hexchar (v >> 24); + s[2] = hexchar (v >> 20); + s[3] = hexchar (v >> 16); + s[4] = hexchar (v >> 12); + s[5] = hexchar (v >> 8); + s[6] = hexchar (v >> 4); + s[7] = hexchar (v); + return s+8; +} + +static char * +compose_hex_byte (char *s, uint8_t v) +{ + s[0] = hexchar (v >> 4); + s[1] = hexchar (v); + return s+2; +} + +static const char * +get_hex (struct tty *tty, const char *s, uintptr_t *v_p) +{ + uintptr_t v = 0; + char c; + + if (s[0] == '0' && s[1] == 'x') + s = s + 2; + while (1) + { + c = *s++; + + if (c == 0) + { + s--; + break; + } + + if (c == ' ') + break; + + v = (v << 4); + if (c >= '0' && c <= '9') + v += (c - '0'); + else if (c >= 'a' && c <= 'f') + v += (c - 'a') + 10; + else if (c >= 'A' && c <= 'F') + v += (c - 'A') + 10; + else + { + put_line (tty, "hex error\r\n"); + return NULL; + } + } + + *v_p = v; + return s; +} + + +#ifdef TOUCH_SUPPORT +#define TOUCH_VALUE_HIGH 100 +#define TOUCH_VALUE_LOW 50 +static void +cmd_button (struct tty *tty, const char *line) +{ + int i = 0; + extern uint16_t touch_get (void); + uint16_t v0 = 0; + int touched = 0; + + (void)line; + put_line (tty, "Please touch the bear.\r\n"); + + while (i < 16) + { + uint16_t v = touch_get (); + v0 = (v0 * 2 + v)/3; + + if (touched == 0 && v0 > TOUCH_VALUE_HIGH) + { + tty_send (tty, "!", 1); + touched = 1; + } + else if (touched == 1 && v0 < TOUCH_VALUE_LOW) + { + tty_send (tty, ".", 1); + touched = 0; + i++; + } + + chopstx_usec_wait (10*1000); + } + + tty_send (tty, "\r\n", 2); +} + +static void +cmd_touch (struct tty *tty, const char *line) +{ + int i; + extern uint16_t touch_get (void); + + (void)line; + put_line (tty, "Please touch the bear.\r\n"); + + for (i = 0; i < 20; i++) + { + uint16_t v; + char output[8]; + char *s; + + chopstx_usec_wait (1000*1000); + v = touch_get (); + s = compose_decimal (output, v); + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); + } +} +#endif + + +static void +cmd_mdb (struct tty *tty, const char *line) +{ + int i; + uintptr_t addr = 0; + int count = 0; + char c; + const char *s = line; + + s = get_hex (tty, s, &addr); + addr &= ~3; + if (s == NULL) + return; + + if (*s == 0) + count = 1; + else + { + while (1) + { + c = *s++; + + if (c == 0 || c == ' ') + break; + + count = count * 10; + if (c >= '0' && c <= '9') + count += c - '0'; + else + { + put_line (tty, "mdb error\r\n"); + return; + } + } + } + + i = 0; + while (i < count) + { + uint8_t v; + char output[68]; + char *s; + + s = compose_hex_ptr (output, addr); + *s++ = ':'; + *s++ = ' '; + + while (1) + { + v = *(uint8_t *)addr; + s = compose_hex_byte (s, v); + i++; + addr += 1; + if (i >= count || (i % 16) == 0) + break; + *s++ = ' '; + } + + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); + } +} + +static void +cmd_mwh (struct tty *tty, const char *line) +{ + (void)tty; + (void)line; + put_line (tty, "mwh not yet supported\r\n"); +} + +static void +cmd_fes (struct tty *tty, const char *line) +{ + int i; + uintptr_t addr = 0; + int count = 0; + char c; + const char *s = line; + + s = get_hex (tty, s, &addr); + if (s == NULL) + return; + + if (*s == 0) + count = 1; + else + { + while (1) + { + c = *s++; + + if (c == 0 || c == ' ') + break; + + count = count * 10; + if (c >= '0' && c <= '9') + count += c - '0'; + else + { + put_line (tty, "fww error\r\n"); + return; + } + } + } + + for (i = 0; i < count; i++) + { + flash_erase_page (addr); + addr += 1024; + } +} + +static void +cmd_fwh (struct tty *tty, const char *line) +{ + int i; + uintptr_t addr = 0; + uintptr_t d; + uint16_t value = 0; + int count = 0; + char c; + const char *s = line; + + s = get_hex (tty, s, &addr); + if (s == NULL) + return; + + if (*s == 0) + return; + + s = get_hex (tty, s, &d); + value = (uint16_t)d; + if (s == NULL) + return; + + if (*s == 0) + count = 1; + else + { + while (1) + { + c = *s++; + + if (c == 0 || c == ' ') + break; + + count = count * 10; + if (c >= '0' && c <= '9') + count += c - '0'; + else + { + put_line (tty, "fww error\r\n"); + return; + } + } + } + + for (i = 0; i < count; i++) + { + flash_program_halfword (addr, value); + addr += 4; + } +} + + +#ifdef CRC32_SUPPORT +static unsigned int crc_value; + +static void +cmd_crc32 (struct tty *tty, const char *line) +{ + uint32_t v; + char string[10]; + char *s; + + crc32_init (&crc_value); + while (*line) + crc32_u8 (&crc_value, *line++); + v = crc_value ^ 0xffffffff; + + s = compose_hex (string, v); + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, string, sizeof (string)); +} +#endif + +#ifdef ADC_SUPPORT +static void +cmd_adc (struct tty *tty, const char *line) +{ + int i; + char output[73]; + char *s; + + (void)line; + + if (!adc_initialized) + { + if (adc_init ()) + { + put_line (tty, "adc_init error\r\n"); + return; + } + else + { + adc_start (); + adc_initialized = 1; + } + } + + adc_start_conversion (0, 64); + adc_wait_completion (); + + i = 0; + s = output; + while (1) + { + s = compose_hex (s, adc_buf[i]); + i++; + if ((i % 8)) + *s++ = ' '; + else + { + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); + s = output; + if (i >= 64) + break; + } + } +} +#endif + +static void +cmd_sysinfo (struct tty *tty, const char *line) +{ + char output[73]; + char *s; + int i; + + (void)line; + memcpy (output, "SYS version: ", 13); + s = output + 13; + *s++ = sys_version[2]; + *s++ = sys_version[4]; + *s++ = sys_version[6]; + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); + + memcpy (output, "Board ID: ", 10); + s = output + 10; + s = compose_hex (s, sys_board_id); + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); + + memcpy (output, "Board name: ", 12); + s = output + 12; + for (i = 0; i < (int)sizeof (output) - 2; i ++) + if ((*s = sys_board_name[i]) == 0) + break; + else + s++; + + *s++ = '\r'; + *s++ = '\n'; + tty_send (tty, output, s - output); +} + + +static void +cmd_help (struct tty *tty, const char *line) +{ + (void)line; + put_line (tty, help_string); +} + + +struct command_table command_table[] = { +#ifdef TOUCH_SUPPORT + { "button", cmd_button }, + { "touch", cmd_touch }, +#endif + { "mdb", cmd_mdb }, + { "mwh", cmd_mwh }, + { "fes", cmd_fes }, + { "fwh", cmd_fwh }, +#ifdef CRC32_SUPPORT + { "crc32", cmd_crc32 }, +#endif +#ifdef ADC_SUPPORT + { "adc", cmd_adc }, +#endif + { "sysinfo", cmd_sysinfo }, + { "help", cmd_help }, +}; + +#define N_CMDS (int)(sizeof (command_table) / sizeof (struct command_table)) + + +/* + * Dispatch a command parsing LINE. + * Line is NULL terminated with no newline. + */ +void +cmd_dispatch (struct tty *tty, const char *line) +{ + int i; + const char *p; + unsigned int n = 0; + + p = line; + while (*p) + { + if (*p++ == ' ') + break; + n++; + } + + for (i = 0; i < N_CMDS; i++) + if (n == strlen (command_table[i].name) + && strncmp ((const char *)line, command_table[i].name, n) == 0) + break; + + if (i != N_CMDS) + (*command_table[i].handler) (tty, p); + else + { + char crlf[] = { '\r', '\n' }; + + put_line (tty, "No such command: "); + tty_send (tty, line, n); + tty_send (tty, crlf, sizeof (crlf)); + } +} diff --git a/example-cdc-gnu-linux/command.h b/example-cdc-gnu-linux/command.h new file mode 100644 index 0000000..f4309b8 --- /dev/null +++ b/example-cdc-gnu-linux/command.h @@ -0,0 +1,2 @@ +void cmd_dispatch (struct tty *tty, const char *line); +char * compose_hex_ptr (char *s, uintptr_t v); diff --git a/example-cdc-gnu-linux/config.h b/example-cdc-gnu-linux/config.h new file mode 100644 index 0000000..3305d04 --- /dev/null +++ b/example-cdc-gnu-linux/config.h @@ -0,0 +1,2 @@ +#undef CRC32_SUPPORT +#define ADC_SUPPORT diff --git a/example-cdc-gnu-linux/sample.c b/example-cdc-gnu-linux/sample.c index fd80f78..e343f7d 100644 --- a/example-cdc-gnu-linux/sample.c +++ b/example-cdc-gnu-linux/sample.c @@ -5,33 +5,15 @@ #include <chopstx.h> +#include "sys.h" + #include "usb_lld.h" #include "tty.h" +#include "command.h" #include <unistd.h> #include <stdio.h> -static void -set_led (int on) -{ -#if 0 - /* For debugging, no output of LED. */ -#if 1 - if (on) - write (1, "********\x08\x08\x08\x08\x08\x08\x08\x08", 16); - else - write (1, " \x08\x08\x08\x08\x08\x08\x08\x08", 16); -#else - if (on) - puts ("!"); - else - puts (""); -#endif -#else - (void)on; -#endif -} - static chopstx_mutex_t mtx; static chopstx_cond_t cnd0; static chopstx_cond_t cnd1; @@ -114,6 +96,7 @@ main (int argc, const char *argv[]) { struct tty *tty; uint8_t count; + uintptr_t addr; (void)argc; (void)argv; @@ -134,6 +117,9 @@ main (int argc, const char *argv[]) chopstx_cond_signal (&cnd1); chopstx_mutex_unlock (&mtx); + addr = flash_init ("flash.data"); + flash_unlock (); + u = 1; tty = tty_open (); @@ -145,6 +131,7 @@ main (int argc, const char *argv[]) { char s[LINEBUFSIZE]; + connection_loop: u = 1; tty_wait_connection (tty); @@ -157,39 +144,52 @@ main (int argc, const char *argv[]) memcpy (s, "xx: Hello, World with Chopstx!\r\n", 32); s[0] = hexchar (count >> 4); s[1] = hexchar (count & 0x0f); - count++; puts("send hello"); if (tty_send (tty, s, 32) < 0) continue; + s[0] = hexchar (count >> 4); + s[1] = hexchar (count & 0x0f); + s[2] = ':'; + s[3] = ' '; + compose_hex_ptr (s+4, addr); + s[20] = '\r'; + s[21] = '\n'; + + count++; + + if (tty_send (tty, s, 22) < 0) + continue; + while (1) { - int size; uint32_t usec; - puts("recv msg"); - usec = 3000000; /* 3.0 seconds */ - size = tty_recv (tty, s + 4, &usec); - if (size < 0) + /* Prompt */ + if (tty_send (tty, "> ", 2) < 0) break; - if (size) + usec = 3000000; /* 3.0 seconds */ + while (1) { - size--; - - puts("send msg"); - s[0] = hexchar (size >> 4); - s[1] = hexchar (size & 0x0f); - s[2] = ':'; - s[3] = ' '; - s[size + 4] = '\r'; - s[size + 5] = '\n'; - if (tty_send (tty, s, size + 6) < 0) + int size = tty_recv (tty, s, &usec); + u ^= 1; + + if (size < 0) + goto connection_loop; + + if (size == 1) + /* Do nothing but prompt again. */ break; + else if (size) + { + /* Newline into NUL */ + s[size - 1] = 0; + cmd_dispatch (tty, (char *)s); + break; + } } - - u ^= 1; } } |