From ae6912650971b427776e80f42903c206728362f9 Mon Sep 17 00:00:00 2001 From: Resaec Date: Fri, 27 Apr 2018 23:57:20 +0200 Subject: [PATCH] adding UartVendorStatus, UartLineStatus and UartLineControl refactor defines edited uart_wait_idle() second parameter type to UartVendorStatus --- exosphere/src/uart.c | 14 +++++------ exosphere/src/uart.h | 55 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/exosphere/src/uart.c b/exosphere/src/uart.c index 733e66984..1b6da6578 100644 --- a/exosphere/src/uart.c +++ b/exosphere/src/uart.c @@ -17,7 +17,7 @@ void uart_init(UartDevice dev, uint32_t baud) { /* Set baud rate. */ uint32_t rate = (8 * baud + 408000000) / (16 * baud); - uart->UART_LCR = 0x80; /* Enable DLAB. */ + uart->UART_LCR = UART_LCR_DLAB; /* Enable DLAB. */ uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */ uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */ uart->UART_LCR = 0; /* Diable DLAB. */ @@ -27,17 +27,17 @@ void uart_init(UartDevice dev, uint32_t baud) { uart->UART_IIR_FCR = 7; /* Enable and clear TX and RX FIFOs. */ uart->UART_LSR; wait(3 * ((baud + 999999) / baud)); - uart->UART_LCR = 3; /* Set word length 8. */ + uart->UART_LCR = UART_LCR_WD_LENGTH_8; /* Set word length 8. */ uart->UART_MCR = 0; uart->UART_MSR = 0; uart->UART_IRDA_CSR = 0; - uart->UART_RX_FIFO_CFG = 1; + uart->UART_RX_FIFO_CFG = 1; /* Set RX_FIFO trigger level */ uart->UART_MIE = 0; uart->UART_ASR = 0; } -void uart_wait_idle(UartDevice dev, uint32_t which) { - while (!(get_uart_device(dev)->UART_VENDOR_STATUS & which)) { +void uart_wait_idle(UartDevice dev, UartVendorStatus status) { + while (!(get_uart_device(dev)->UART_VENDOR_STATUS & status)) { /* Wait */ } } @@ -47,7 +47,7 @@ void uart_send(UartDevice dev, const void *buf, size_t len) volatile uart_t *uart = get_uart_device(dev); for (size_t i = 0; i < len; i++) { - while (uart->UART_LSR & UART_TX_FIFO_FULL) { + while (uart->UART_LSR & UART_LSR_TX_FIFO_FULL) { /* Wait until the TX FIFO isn't full */ } uart->UART_THR_DLAB = *((const uint8_t *)buf + i); @@ -58,7 +58,7 @@ void uart_recv(UartDevice dev, void *buf, size_t len) { volatile uart_t *uart = get_uart_device(dev); for (size_t i = 0; i < len; i++) { - while (uart->UART_LSR & UART_RX_FIFO_EMPTY) { + while (uart->UART_LSR & UART_LSR_RX_FIFO_EMPTY) { /* Wait until the RX FIFO isn't empty */ } *((uint8_t *)buf + i) = uart->UART_THR_DLAB; diff --git a/exosphere/src/uart.h b/exosphere/src/uart.h index 247a79c64..54b42dac2 100644 --- a/exosphere/src/uart.h +++ b/exosphere/src/uart.h @@ -13,6 +13,8 @@ static inline uintptr_t get_uart_base(void) { #define UART_BASE (get_uart_base()) +#define BAUD_115200 115200 + /* Exosphère: add the clkreset values for UART C,D,E */ typedef enum { UART_A = 0, @@ -22,12 +24,53 @@ typedef enum { UART_E = 4, } UartDevice; -#define BAUD_115200 115200 +typedef enum { + UART_TX_IDLE = 1 << 0, + UART_RX_IDLE = 1 << 1, -#define UART_TX_IDLE 0x00000001 -#define UART_RX_IDLE 0x00000002 -#define UART_TX_FIFO_FULL 0x100 -#define UART_RX_FIFO_EMPTY 0x200 + /* This bit is set to 1 when a read is issued to an empty FIFO and gets cleared on register read (sticky bit until read) + 0 = NO_UNDERRUN + 1 = UNDERRUN */ + UART_UNDERRUN = 1 << 2, + + /* This bit is set to 1 when write data is issued to the TX FIFO when it is already full and gets cleared on register read (sticky bit until read) + 0 = NO_OVERRUN + 1 = OVERRUN */ + UART_OVERRUN = 1 << 3, + + RX_FIFO_COUNTER = 0b111111 << 16, /* reflects number of current entries in RX FIFO */ + TX_FIFO_COUNTER = 0b111111 << 24 /* reflects number of current entries in TX FIFO */ +} UartVendorStatus; + +typedef enum { + UART_LSR_RDR = 1 << 0, /* Receiver Data Ready */ + UART_LSR_OVRF = 1 << 1, /* Receiver Overrun Error */ + UART_LSR_PERR = 1 << 2, /* Parity Error */ + UART_LSR_FERR = 1 << 3, /* Framing Error */ + UART_LSR_BRK = 1 << 4, /* BREAK condition detected on line */ + UART_LSR_THRE = 1 << 5, /* Transmit Holding Register is Empty -- OK to write data */ + UART_LSR_TMTY = 1 << 6, /* Transmit Shift Register empty status */ + UART_LSR_FIFOE = 1 << 7, /* Receive FIFO Error */ + UART_LSR_TX_FIFO_FULL = 1 << 8, /* Transmitter FIFO full status */ + UART_LSR_RX_FIFO_EMPTY = 1 << 9, /* Receiver FIFO empty status */ +} UartLineStatus; + +typedef enum { + UART_LCR_WD_LENGTH_5 = 0, /* word length 5 */ + UART_LCR_WD_LENGTH_6 = 1, /* word length 6 */ + UART_LCR_WD_LENGTH_7 = 2, /* word length 7 */ + UART_LCR_WD_LENGTH_8 = 3, /* word length 8 */ + + /* STOP: + 0 = Transmit 1 stop bit + 1 = Transmit 2 stop bits (receiver always checks for 1 stop bit) */ + UART_LCR_STOP = 1 << 2, + UART_LCR_PAR = 1 << 3, /* Parity enabled */ + UART_LCR_EVEN = 1 << 4, /* Even parity format. There will always be an even number of 1s in the binary representation (PAR = 1) */ + UART_LCR_SET_P = 1 << 5, /* Set (force) parity to value in LCR[4] */ + UART_LCR_SET_B = 1 << 6, /* Set BREAK condition -- Transmitter sends all zeroes to indicate BREAK */ + UART_LCR_DLAB = 1 << 7, /* Divisor Latch Access Bit (set to allow programming of the DLH, DLM Divisors) */ +} UartLineControl; typedef struct { /* 0x00 */ uint32_t UART_THR_DLAB; @@ -48,7 +91,7 @@ typedef struct { void uart_select(UartDevice dev); void uart_init(UartDevice dev, uint32_t baud); -void uart_wait_idle(UartDevice dev, uint32_t which); +void uart_wait_idle(UartDevice dev, UartVendorStatus status); void uart_send(UartDevice dev, const void *buf, size_t len); void uart_recv(UartDevice dev, void *buf, size_t len);