aboutsummaryrefslogtreecommitdiffstats
path: root/app/vuart.c
diff options
context:
space:
mode:
authorroot <root@no.no.james.local>2017-06-13 21:10:37 +0100
committerroot <root@no.no.james.local>2017-06-13 21:10:37 +0100
commiteaf5d4799cc52e9dd1ebcaeafbf8f670658fea98 (patch)
treebbeb1993818c5fc8cbcf5a001080f246facc8de6 /app/vuart.c
downloadserial_over_dp-eaf5d4799cc52e9dd1ebcaeafbf8f670658fea98.tar.gz
serial_over_dp-eaf5d4799cc52e9dd1ebcaeafbf8f670658fea98.tar.bz2
serial_over_dp-eaf5d4799cc52e9dd1ebcaeafbf8f670658fea98.zip
inital commit
Diffstat (limited to 'app/vuart.c')
-rw-r--r--app/vuart.c217
1 files changed, 217 insertions, 0 deletions
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;
+ }
+}
+
+
+
+