From eaf5d4799cc52e9dd1ebcaeafbf8f670658fea98 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 13 Jun 2017 21:10:37 +0100 Subject: inital commit --- app/vuart.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 app/vuart.c (limited to 'app/vuart.c') diff --git a/app/vuart.c b/app/vuart.c new file mode 100644 index 0000000..5aaf2d3 --- /dev/null +++ b/app/vuart.c @@ -0,0 +1,217 @@ +#include "project.h" + +#define RXR ((0)) +#define TXR ((0)) +#define DLLR ((0)) + +#define IER ((1)) +#define DLHR ((1)) + +#define IIR ((2)) +#define FCR ((2)) + +#define LCR ((3)) +#define LCR_WS0 (1<<0) +#define LCR_WS1 (1<<1) +#define LCR_NSTOP (1<<2) +#define LCR_PARITY_ENABLE (1<<3) +#define LCR_EVEN_PARITY (1<<4) +#define LCR_STUCK_PARITY (1<<5) +#define LCR_BREAK (1<<6) +#define LCR_DLAB (1<<7) + +#define MCR ((4)) +#define MCR_DTR (1<<0) +#define MCR_RTS (1<<1) +#define MCR_AUX1 (1<<2) +#define MCR_AUX2 (1<<3) +#define MCR_LOOP (1<<4) +#define MCR_AUTOFLOW (1<<5) + +#define LSR ((5)) +#define LSR_DA (1<<0) +#define LSR_OR (1<<1) +#define LSR_PE (1<<2) +#define LSR_FE (1<<3) +#define LSR_BRK (1<<4) +#define LSR_THRE (1<<5) +#define LSR_THREI (1<<6) +#define LSR_FIFOE (1<<7) + +#define MSR ((6)) +#define MSR_DCTS (1<<0) +#define MSR_DDSR (1<<1) +#define MSR_TERI (1<<2) +#define MSR_DDCD (1<<3) +#define MSR_CTS (1<<4) +#define MSR_DSR (1<<5) +#define MSR_RI (1<<6) +#define MSR_DCD (1<<7) + +#define SR ((7)) + + +/* 0 */ +static uint8_t dllr = 1; /* 115200 baud */ + +/* 1 */ +static uint8_t dlhr = 0; +static uint8_t ier = 0; + +/* 2 */ +static uint8_t iir = 0; + +/* 3 */ +static uint8_t lcr = LCR_WS0 | LCR_WS1; /* 8 bits, 1 stop, no parity */ + +/* 4 */ +static uint8_t mcr = MCR_RTS | MCR_DTR; /* RTS and DTR on */ + +/* 5 */ +static uint8_t lsr = LSR_THRE | LSR_THREI; + +/* 6 */ +static uint8_t msr = MSR_CTS | MSR_DSR | MSR_DCD; + +/* 7 */ +static uint8_t sr = 0; + + +static void vuart_xmit (uint8_t c) +{ + led1 = 100; + ring_write_byte (&usart_tx_ring, c); + usart_kick(); +#ifdef USB + ring_write_byte (&cdcacm_tx_ring, c); +#endif +} + + +static int vuart_recv_empty (void) +{ + if (!ring_empty (&usart_rx_ring)) { + return 0; + } + +#ifdef USB + + if (!ring_empty (&cdcacm_rx_ring)) { + return 0; + } + +#endif + return 1; +} + + +static int vuart_recv (uint8_t *c) +{ + *c = 0; + + if (!ring_read_byte (&usart_rx_ring, c)) { + led2 = 100; + return 0; + } + +#ifdef USB + + if (!ring_read_byte (&cdcacm_rx_ring, c)) { + led2 = 100; + return 0; + } + +#endif + return -1; +} + + +static void update_lsr (void) +{ + if (vuart_recv_empty()) { + lsr &= ~LSR_DA; + } else { + lsr |= LSR_DA; + } +} + +uint8_t vuart_read (unsigned reg) +{ + uint8_t val; + + switch (reg) { + case RXR: + + //case DLLR: + if (! (lcr & LCR_DLAB)) { + vuart_recv (&val); + update_lsr(); + return val; + } else { + return dllr; + } + + case IER: + //case DLLH: + return (lcr & LCR_DLAB) ? dlhr : ier; + case IIR: + return iir; + case LCR: + return lcr; + case MCR: + return mcr; + case LSR: + update_lsr(); + val = lsr; + lsr &= 0xe1; + return val; + case MSR: + val = msr; + msr &= 0xf0; + return val; + case SR: + return sr; + } + + return 0; +} + + +void vuart_write (unsigned reg, uint8_t val) +{ + switch (reg) { + case RXR: + + //case DLLR: + if (! (lcr & LCR_DLAB)) { + vuart_xmit (val); + } else { + dllr = val; + } + + break; + case IER: + + //case DLHR: + if (! (lcr & LCR_DLAB)) { + ier = val & 0xf; + } else { + dlhr = val; + } + + break; + case LCR: + lcr = val; + break; + case MCR: + mcr = val & 0x1f; + break; + case SR: + sr = val; + break; + } +} + + + + -- cgit v1.2.3