diff --git a/litex/soc/software/include/base/console.h b/litex/soc/software/include/base/console.h
index 5a7a2ff7d..cd6c9c005 100644
--- a/litex/soc/software/include/base/console.h
+++ b/litex/soc/software/include/base/console.h
@@ -12,7 +12,6 @@ typedef int (*console_read_nonblock_hook)(void);
void console_set_write_hook(console_write_hook h);
void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn);
-char readchar(void);
int readchar_nonblock(void);
#ifdef __cplusplus
diff --git a/litex/soc/software/libbase/Makefile b/litex/soc/software/libbase/Makefile
index c93fa9078..f9370f71e 100755
--- a/litex/soc/software/libbase/Makefile
+++ b/litex/soc/software/libbase/Makefile
@@ -4,7 +4,6 @@ include $(SOC_DIRECTORY)/software/common.mak
OBJECTS = exception.o \
crc16.o \
crc32.o \
- console.o \
system.o \
id.o \
uart.o \
diff --git a/litex/soc/software/libc/iob.c b/litex/soc/software/libc/iob.c
index fe77e4017..9479c4e24 100644
--- a/litex/soc/software/libc/iob.c
+++ b/litex/soc/software/libc/iob.c
@@ -1,30 +1,84 @@
-#include
#include
-//#include
+#include
+#include
+#include
+
+static console_write_hook write_hook;
+static console_read_hook read_hook;
+static console_read_nonblock_hook read_nonblock_hook;
+
+void console_set_write_hook(console_write_hook h)
+{
+ write_hook = h;
+}
+
+void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
+{
+ read_hook = r;
+ read_nonblock_hook = rn;
+}
+
+#ifdef CSR_UART_BASE
static int
dummy_putc(char c, FILE *file)
{
(void) file;
- return base_putchar(c);
+ uart_write(c);
+ if(write_hook != NULL)
+ write_hook(c);
+ if (c == '\n')
+ dummy_putc('\r', NULL);
+ return c;
}
static int
dummy_getc(FILE *file)
{
(void) file;
- return readchar();
+ while(1) {
+ if(uart_read_nonblock())
+ return uart_read();
+ if((read_nonblock_hook != NULL) && read_nonblock_hook())
+ return read_hook();
+ }
+}
+
+int readchar_nonblock(void)
+{
+ return (uart_read_nonblock()
+ || ((read_nonblock_hook != NULL) && read_nonblock_hook()));
+}
+
+#else
+
+static int
+dummy_putc(char c, FILE *file)
+{
+ (void) file;
+ if(write_hook != NULL)
+ write_hook(c);
+ return c;
}
static int
-dummy_flush(FILE *file)
+dummy_getc(FILE *file)
{
(void) file;
- return 0;
+ while(1) {
+ if((read_nonblock_hook != NULL) && read_nonblock_hook())
+ return read_hook();
+ }
}
-static FILE __stdio = FDEV_SETUP_STREAM(dummy_putc, dummy_getc, dummy_flush, _FDEV_SETUP_RW);
+int readchar_nonblock(void)
+{
+ return ((read_nonblock_hook != NULL) && read_nonblock_hook());
+}
+#endif
+
+static FILE __stdio = FDEV_SETUP_STREAM(dummy_putc, dummy_getc, NULL, _FDEV_SETUP_RW);
FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio };