From 4f32bbc46a48276bba949364dc44d532c19dae78 Mon Sep 17 00:00:00 2001 From: taitep Date: Thu, 29 Jan 2026 21:27:36 +0100 Subject: i think i managed to make a working uart driver for the new interface?? --- CMakeLists.txt | 1 + include/uart.h | 53 ++++++++++++++++++++++++++--------------------------- src/crt0.S | 3 +++ src/syscalls.c | 16 +++++++++++----- src/uart.c | 24 ++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 src/uart.c 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 +#include + #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; +} -- cgit v1.2.3