diff --git a/Kconfig b/Kconfig index d3804761d21dfc8a080d1116e313bd2a62ad61c3..0c86f1538fb3f856242448942ee15ca8ebb750d9 100644 --- a/Kconfig +++ b/Kconfig @@ -136,3 +136,14 @@ config CMD_CONFIG This options adds the "config" command to the shell, which reports the current configuration. This adds half a kilobyte to the binary size (100b for the code plus the .config file). + +config UART_SW + boolean "Use software uart (not the hardware one)" + help + The software uart is made up of two circular buffers. They + waste some RAM but allow to avoid the USB cable. Software + uarts can be accessed using tools/wrpc-uart-sw. + +config UART + boolean + default !UART_SW diff --git a/dev/dev.mk b/dev/dev.mk index 299d3fea68b5e0848c7936480b5ecf26a205c30e..56ec0be8cf7b779515e1059e1f596de403b81551 100644 --- a/dev/dev.mk +++ b/dev/dev.mk @@ -6,7 +6,9 @@ obj-y += \ dev/minic.o \ dev/pps_gen.o \ dev/syscon.o \ - dev/uart.o \ dev/sfp.o \ dev/onewire.o \ dev/sdb.o + +obj-$(CONFIG_UART) += dev/uart.o +obj-$(CONFIG_UART_SW) += dev/uart-sw.o diff --git a/dev/uart-sw.c b/dev/uart-sw.c new file mode 100644 index 0000000000000000000000000000000000000000..c8d6cc11f886e7e06f388417ca170f2b5dc27e5c --- /dev/null +++ b/dev/uart-sw.c @@ -0,0 +1,61 @@ +/* + * This work is part of the White Rabbit project + * + * Copyright (C) 2013 CERN (www.cern.ch) + * Author: Alessandro Rubini <rubini@gnudd.com> + * + * Released according to the GNU GPL, version 2 or any later version. + */ +#include <wrc.h> +#include <uart-sw.h> + +static struct wrc_uart_sw __attribute__((aligned(16))) uart_sw_dev = { + .magic = UART_SW_MAGIC, + .wsize = CONFIG_UART_SW_WSIZE, + .rsize = CONFIG_UART_SW_RSIZE, +}; + +static uint16_t nreturned; + +void uart_init(void) +{ + /* zero fields, as we may be reloaded */ + uart_sw_dev.nwritten = uart_sw_dev.nread = 0; +} + +void uart_write_byte(int b) +{ + int index; + + if (b == '\n') + uart_write_byte('\r'); + + index = uart_sw_dev.nwritten % CONFIG_UART_SW_WSIZE; + uart_sw_dev.wbuffer[index] = b; + uart_sw_dev.nwritten++; + + /* fake a real uart, so user-space can poll not-too-fast */ + usleep(1000 * 1000 / 11520); +} + +int uart_write_string(const char *s) +{ + const char *t = s; + while (*s) + uart_write_byte(*(s++)); + return s - t; +} + +int puts(const char *s) __attribute__((alias("uart_write_string"))); + + +int uart_read_byte() +{ + int index; + + if (nreturned == uart_sw_dev.nread) /* nread == written by host */ + return -1; + + index = (nreturned++) % CONFIG_UART_SW_RSIZE; + return uart_sw_dev.rbuffer[index]; +} diff --git a/include/uart-sw.h b/include/uart-sw.h new file mode 100644 index 0000000000000000000000000000000000000000..5555d3e61229b324984713d8a365f8b21f6674e0 --- /dev/null +++ b/include/uart-sw.h @@ -0,0 +1,30 @@ +/* + * This work is part of the White Rabbit project + * + * Copyright (C) 2013 CERN (www.cern.ch) + * Author: Alessandro Rubini <rubini@gnudd.com> + * + * Released according to the GNU GPL, version 2 or any later version. + */ +#ifndef __UART_SW_H +#define __UART_SW_H + +/* The host code (tools/wrpc-uart-sw) must include this too, for the struct */ +#ifdef __lm32__ +#include "uart.h" /* we need to offer the same prototypes */ +#endif + +/* These are currently static but can become Kconfig items */ +#define CONFIG_UART_SW_WSIZE 256 +#define CONFIG_UART_SW_RSIZE 32 + +#define UART_SW_MAGIC 0x752d7377 /* "u-sw" */ +struct wrc_uart_sw { + uint32_t magic; + uint16_t wsize, nwritten; + uint16_t rsize, nread; + unsigned char wbuffer[CONFIG_UART_SW_WSIZE]; + unsigned char rbuffer[CONFIG_UART_SW_RSIZE]; +}; + +#endif /* __UART_SW_H */