Commit 992dc8d7 authored by Alessandro Rubini's avatar Alessandro Rubini

general: improve sw-uart support (only for expert config).

This commits affect several files, to be able to support both uart and
uart_sw at the same time. My aim is sending verbose ppsi diagnostics
to the uart_sw while retaining the real uart (or vuart) for the
interactive user and wrpc status gui.

To this aim, I use weak functions to avoid hairy ifdef around the code.
Now both hw and sw uarts are initialized, and the missing init just
does nothing. Also, uart_sw_write_string is always defined, and
it is an alias of uart_write_string if no uart_sw is built.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 0bcbe429
......@@ -25,7 +25,7 @@ config PTP_NOPOSIX
config UART
boolean
default !UART_SW
default y
config SOCKITOWM
boolean
......@@ -186,17 +186,25 @@ config DETERMINISTIC_BINARY
If in doubt, say No.
config UART_SW
config UART
boolean "Use hardware uart (and/or vuart if available)"
depends on DEVELOPER
boolean "Use software uart (not the hardware one)"
default y
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.
This option selects the serial driver, connected to either
the USB socket, or "vuart" (software fifo) or both, according
to how the gateware is built.
config UART
boolean
default !UART_SW
config UART_SW
depends on DEVELOPER
default !UART
boolean "Use software uart"
help
The software uart is made up of two circular buffers. It can
be used either as an alternative to the harwdare UART or as
an addition. If the option is turned on, ppsi log messages
are routed to the software uart. The interactive wrpc shell
and diagnostics run on the hardware UART if available.
config W1
depends on DEVELOPER
......
......@@ -17,13 +17,17 @@ static struct wrc_uart_sw __attribute__((aligned(16))) uart_sw_dev = {
static uint16_t nreturned;
void uart_init(void)
void uart_init_sw(void)
{
/* zero fields, as we may be reloaded */
uart_sw_dev.nwritten = uart_sw_dev.nread = 0;
}
void uart_write_byte(int b)
void __attribute__((weak)) uart_init_hw(void)
{}
void uart_sw_write_byte(int b)
{
int index;
......@@ -38,7 +42,7 @@ void uart_write_byte(int b)
usleep(1000 * 1000 / 11520);
}
int uart_write_string(const char *s)
int uart_sw_write_string(const char *s)
{
const char *t = s;
while (*s)
......@@ -46,10 +50,7 @@ int uart_write_string(const char *s)
return s - t;
}
int puts(const char *s) __attribute__((alias("uart_write_string")));
int uart_read_byte()
int uart_sw_read_byte()
{
int index;
......@@ -59,3 +60,14 @@ int uart_read_byte()
index = (nreturned++) % CONFIG_UART_SW_RSIZE;
return uart_sw_dev.rbuffer[index];
}
/* alias the "hw" names to these, so this applies if !CONFIG_UART */
int puts(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
void uart_write_byte(int b)
__attribute__((alias("uart_sw_write_byte"), weak));
int uart_write_string(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
int uart_read_byte()
__attribute__((alias("uart_sw_read_byte"), weak));
......@@ -19,12 +19,16 @@
volatile struct UART_WB *uart;
void uart_init()
void uart_init_hw()
{
uart = (volatile struct UART_WB *)BASE_UART;
uart->BCR = CALC_BAUD(UART_BAUDRATE);
}
void __attribute__((weak)) uart_init_sw(void)
{}
void uart_write_byte(int b)
{
if (b == '\n')
......@@ -42,8 +46,6 @@ int uart_write_string(const char *s)
return s - t;
}
int puts(const char *s) __attribute__((alias("uart_write_string")));
static int uart_poll()
{
return uart->SR & UART_SR_RX_RDY;
......@@ -56,3 +58,10 @@ int uart_read_byte()
return uart->RDR & 0xff;
}
int puts(const char *s)
__attribute__((alias("uart_write_string")));
/* The next alias is for ppsi log messages, that go to sw_uart if built */
int uart_sw_write_string(const char *s)
__attribute__((alias("uart_write_string"), weak));
#ifndef __UART_H
#define __UART_H
void uart_init(void);
void uart_init_sw(void);
void uart_init_hw(void);
void uart_write_byte(int b);
int uart_write_string(const char *s);
int puts(const char *s);
int uart_read_byte(void);
/* uart-sw is used by ppsi (but may be wrapped to normal uart) */
int uart_sw_write_string(const char *s);
#endif
......@@ -47,7 +47,8 @@ static void wrc_initialize()
uint8_t mac_addr[6];
sdb_find_devices();
uart_init();
uart_init_sw();
uart_init_hw();
mprintf("WR Core: starting up...\n");
......@@ -195,7 +196,8 @@ static void check_reset(void)
/* Ok, now init the devices so we can printf and delay */
sdb_find_devices();
uart_init();
uart_init_sw();
uart_init_hw();
timer_init(1);
pp_printf("\nWarning: the CPU was reset\nStack trace:\n");
......
......@@ -52,7 +52,8 @@ int wrc_ptp_init()
{
struct pp_instance *ppi = &ppi_static; /* no malloc, one instance */
sdb_find_devices();
uart_init();
uart_init_sw();
uart_init_hw();
pp_printf("Spec: starting. Compiled on " __DATE__ "\n");
......
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