summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaitep <taitep@taitep.se>2026-01-29 21:27:36 +0100
committertaitep <taitep@taitep.se>2026-01-29 21:27:36 +0100
commit4f32bbc46a48276bba949364dc44d532c19dae78 (patch)
tree8f54108788735efff25a4a9549bedbe7967d3c7b
parent25bec21f20208a9369656a337cf5325e7b3a5a8d (diff)
i think i managed to make a working uart driver for the new interface??HEADmain
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/uart.h53
-rw-r--r--src/crt0.S3
-rw-r--r--src/syscalls.c16
-rw-r--r--src/uart.c24
5 files changed, 65 insertions, 32 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f00d15f..85cc3f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcmodel=medany -march=rv64im -mabi=lp64")
set(SRC_FILES
src/syscalls.c
src/crt0.S
+ src/uart.c
)
include_directories(include)
diff --git a/include/uart.h b/include/uart.h
index 76f4b34..7b414ca 100644
--- a/include/uart.h
+++ b/include/uart.h
@@ -1,30 +1,29 @@
#pragma once
+#include <stdbool.h>
+#include <stdint.h>
+
#define UART_BASE 0x10000
-#define UART_DATA *(volatile char *)(UART_BASE + 0)
-#define UART_STATUS *(volatile char *)(UART_BASE + 1)
-#define UART_TX_READY 0b01
-#define UART_RX_READY 0b10
-
-static inline int uart_rx_ready() { return (UART_STATUS & UART_RX_READY) != 0; }
-static inline int uart_tx_ready() { return (UART_STATUS & UART_TX_READY) != 0; }
-
-static inline void uart_putc(char c) {
- while (!uart_tx_ready())
- ;
- UART_DATA = c;
-}
-
-static inline void uart_puts(const char *s) {
- while (*s) {
- uart_putc(*s++);
- }
-}
-
-static inline char uart_getc_nonblocking() { return UART_DATA; }
-
-static inline char uart_getc() {
- while (!uart_rx_ready())
- ;
- return UART_DATA;
-}
+#define UART_REG(offset) *(volatile uint32_t *)(UART_BASE + offset)
+#define UART_TXDATA UART_REG(0x00)
+#define UART_RXDATA UART_REG(0x04)
+#define UART_TXCTRL UART_REG(0x08)
+#define UART_RXCTRL UART_REG(0x0c)
+#define UART_IE UART_REG(0x10)
+#define UART_IP UART_REG(0x14)
+#define UART_DIV UART_REG(0x18)
+
+#define UART_TXDATA_FULL 0x80000000
+#define UART_RXDATA_EMPTY 0x80000000
+
+#define UART_TXCTRL_TXEN 1
+#define UART_RXCTRL_RXEN 1
+
+void uart_init(void);
+
+bool uart_tx_ready(void);
+
+void uart_putc(char c);
+void uart_puts(const char *s);
+
+char uart_getc(void);
diff --git a/src/crt0.S b/src/crt0.S
index 97228c1..49d8493 100644
--- a/src/crt0.S
+++ b/src/crt0.S
@@ -62,6 +62,9 @@ _start:
#endif
call __libc_init_array # Run global initialization functions
+ # initialize UART
+ call uart_init
+
call main
call exit
_exit: j _exit
diff --git a/src/syscalls.c b/src/syscalls.c
index 443c9cd..5c5d577 100644
--- a/src/syscalls.c
+++ b/src/syscalls.c
@@ -44,17 +44,21 @@ int _lseek(int file, int ptr, int dir) { return 0; }
int _open(const char *name, int flags, int mode) { return -1; }
int _read(int file, char *buf, int len) {
- while (!uart_rx_ready())
- ;
+ uint32_t uart_data;
+ do {
+ uart_data = UART_RXDATA;
+ } while (uart_data & UART_RXDATA_EMPTY);
int i;
for (i = 0; i < len; i++) {
- if (!uart_rx_ready()) {
+ buf[i] = (char)uart_data;
+ uart_data = UART_RXDATA;
+ if (uart_data & UART_RXDATA_EMPTY) {
break;
}
- buf[i] = uart_getc_nonblocking();
}
- return i;
+ // *(volatile int *)1 = i;
+ return i + 1;
}
void *_sbrk(int incr) {
@@ -91,9 +95,11 @@ int _wait(int *status) {
}
int _write(int file, char *buf, int len) {
+ // uart_puts("_write called\n");
for (int i = 0; i < len; i++) {
uart_putc(buf[i]);
}
+ // *(volatile int *)0 = len;
return len;
}
diff --git a/src/uart.c b/src/uart.c
new file mode 100644
index 0000000..86bc01f
--- /dev/null
+++ b/src/uart.c
@@ -0,0 +1,24 @@
+#include "uart.h"
+
+void uart_init(void) {
+ UART_TXCTRL = UART_TXCTRL_TXEN;
+ UART_RXCTRL = UART_RXCTRL_RXEN;
+}
+
+void uart_putc(char c) {
+ while (UART_TXDATA & UART_TXDATA_FULL) {}
+ UART_TXDATA = (uint32_t)c;
+}
+
+void uart_puts(const char* s) {
+ while (*s)
+ uart_putc(*s++);
+}
+
+char uart_getc(void) {
+ uint32_t data;
+ do {
+ data = UART_RXDATA;
+ } while (data & UART_RXDATA_EMPTY);
+ return (char)data;
+}