Commit fd3f8864 authored by Alessandro Rubini's avatar Alessandro Rubini

dev: introduce uart-sw

This introduces dev/uart-sw as an alternative to dev/uart . The
software-only thing is a pair of circular buffers that can be driven
by tools/wrpc-uart-sw .

The software uart can be enabled by Kconfig (and is disabled by
default).  The code size is the same as the uart, but it "wastes" 306
bytes of data space.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent bccfebd2
......@@ -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
......@@ -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
/*
* 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];
}
/*
* 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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment