62 lines
1.7 KiB
C
62 lines
1.7 KiB
C
#ifndef _TB_UART_IO_H
|
|
#define _TB_UART_IO_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
// Testbench UART-over-TCP MMIO (see tb_common/include/tb_constants.h).
|
|
//
|
|
// Each UART is exposed as a raw TCP byte stream (one client at a time).
|
|
// Software should poll STATUS.RX_AVAIL before reading DATA.
|
|
|
|
#ifndef TB_IO_BASE
|
|
#define TB_IO_BASE 0xC0000000u
|
|
#endif
|
|
|
|
#define TB_UART_BASE 0x200u
|
|
#define TB_UART_STRIDE 0x20u
|
|
|
|
#define TB_UART_DATA 0x00u
|
|
#define TB_UART_STATUS 0x04u
|
|
#define TB_UART_CTRL 0x08u
|
|
|
|
#define TB_UART_STATUS_RX_AVAIL (1u << 0)
|
|
#define TB_UART_STATUS_TX_READY (1u << 1)
|
|
#define TB_UART_STATUS_CONNECTED (1u << 2)
|
|
#define TB_UART_STATUS_OVERRUN (1u << 3)
|
|
|
|
#define TB_UART_CTRL_CLR_OVERRUN (1u << 0)
|
|
|
|
static inline volatile uint32_t *tb_uart_reg(unsigned uart_idx, unsigned reg_off) {
|
|
return (volatile uint32_t *)(TB_IO_BASE + TB_UART_BASE + (uart_idx * TB_UART_STRIDE) + reg_off);
|
|
}
|
|
|
|
static inline uint32_t tb_uart_status(unsigned uart_idx) {
|
|
return *tb_uart_reg(uart_idx, TB_UART_STATUS);
|
|
}
|
|
|
|
static inline bool tb_uart_connected(unsigned uart_idx) {
|
|
return (tb_uart_status(uart_idx) & TB_UART_STATUS_CONNECTED) != 0;
|
|
}
|
|
|
|
static inline bool tb_uart_can_read(unsigned uart_idx) {
|
|
return (tb_uart_status(uart_idx) & TB_UART_STATUS_RX_AVAIL) != 0;
|
|
}
|
|
|
|
static inline int tb_uart_try_read(unsigned uart_idx) {
|
|
if (!tb_uart_can_read(uart_idx))
|
|
return -1;
|
|
return (int)(*tb_uart_reg(uart_idx, TB_UART_DATA) & 0xffu);
|
|
}
|
|
|
|
static inline void tb_uart_write(unsigned uart_idx, uint8_t byte) {
|
|
*tb_uart_reg(uart_idx, TB_UART_DATA) = (uint32_t)byte;
|
|
}
|
|
|
|
static inline void tb_uart_clear_overrun(unsigned uart_idx) {
|
|
*tb_uart_reg(uart_idx, TB_UART_CTRL) = TB_UART_CTRL_CLR_OVERRUN;
|
|
}
|
|
|
|
#endif
|
|
|