#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(); ring_write_byte (&cdcacm_tx_ring, c); } static int vuart_recv_empty (void) { if (!ring_empty (&usart_rx_ring)) return 0; if (!ring_empty (&cdcacm_rx_ring)) return 0; return 1; } static int vuart_recv (uint8_t *c) { *c = 0; if (!ring_read_byte (&usart_rx_ring, c)) { led2 = 100; return 0; } if (!ring_read_byte (&cdcacm_rx_ring, c)) { led2 = 100; return 0; } 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; } }