From bf2e8d0de9b3b5160220e3b9f6f49d61977eb553 Mon Sep 17 00:00:00 2001 From: Rom Embedded Forth Date: Thu, 14 Sep 2023 19:01:06 -0700 Subject: [PATCH] Enable serial input This change is, for the most part, a copy-paste of the serial output code. Here's sample usage where the input is attached to a file name "foo.inp" : ... simio add console serial ... simio config serial input foo.inp ... --- simio/simio_console.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/simio/simio_console.c b/simio/simio_console.c index 89a9b24b..8af0f88d 100644 --- a/simio/simio_console.c +++ b/simio/simio_console.c @@ -36,6 +36,9 @@ struct console { /* File output */ FILE *file; + + /* File input */ + FILE *infile; }; static struct simio_device *console_create(char **arg_text) @@ -65,6 +68,10 @@ static void console_destroy(struct simio_device *dev) fclose(c->file); } + if (c->infile != NULL) { + fclose(c->infile); + } + free(c); } @@ -76,6 +83,10 @@ static void console_reset(struct simio_device *dev) if (c->file != NULL) { rewind(c->file); } + + if (c->infile != NULL) { + rewind(c->infile); + } } static int config_addr(address_t *addr, char **arg_text) @@ -118,6 +129,29 @@ static int config_output(FILE **file, char **arg_text) return 0; } +static int config_input(FILE **file, char **arg_text) +{ + char *path = get_arg(arg_text); + + if (path == NULL) { + printc_err("console: config: expected path\n"); + return -1; + } + + // don't leak the descriptor if configured multiple times + if ((*file != NULL) && (*file != stdin)) { + fclose(*file); + } + + *file = fopen(path, "r"); + if (*file == NULL) { + printc_err("console: can't open %s for reading\n", path); + return -1; + } + + return 0; +} + static int console_config(struct simio_device *dev, const char *param, char **arg_text) { @@ -129,6 +163,9 @@ static int console_config(struct simio_device *dev, else if (!strcasecmp(param, "output")) { return config_output(&c->file, arg_text); } + else if (!strcasecmp(param, "input")) { + return config_input(&c->infile, arg_text); + } printc_err("console: config: unknown parameter: %s\n", param); return -1; @@ -177,6 +214,36 @@ static int console_write_b(struct simio_device *dev, return 1; } +static int console_read_b(struct simio_device *dev, + address_t addr, uint8_t *datap) +{ + struct console *c = (struct console *)dev; + + if (addr != c->base_addr) { + return 1; + } + + // read either from file or buffer + if (c->infile != NULL) + { + size_t nbytes = sizeof(*datap); + if (fread(datap, nbytes, 1, c->infile) != nbytes) { + printc_err("console: read error\n"); + return -1; + } + // printc_err("got %c\n", *datap); + } + else // buffer + { + *datap = c->buffer[c->buffer_offset++]; + if (*datap == '\n' || c->buffer_offset == sizeof c->buffer) + { + c->buffer_offset = 0; + } + } + + return 1; +} const struct simio_class simio_console = { .name = "console", @@ -188,6 +255,8 @@ const struct simio_class simio_console = { " Set the peripheral base address. Defaults to 0x00FF\n" " output \n" " Print to file instead of a buffer.\n" +" input \n" +" Read from file instead of a buffer.\n" "\n", .create = console_create, @@ -196,4 +265,5 @@ const struct simio_class simio_console = { .config = console_config, .info = console_info, .write_b = console_write_b, + .read_b = console_read_b, };