]> Pileus Git - ~andy/csm213a-hw/blobdiff - hw2/serial_irq.c
Add serial transmit call
[~andy/csm213a-hw] / hw2 / serial_irq.c
index 68945cfcbb759e8e46361046f7c40c7ce7734e0f..0f5106d8bda598b8bcbb0b91c55a443f6260a006 100644 (file)
@@ -20,16 +20,10 @@ struct sirq_t {
        serial_t uart;\r
        queue_t  xmt;\r
        queue_t  rcv;\r
+       int      irq;\r
+       int      buffered;\r
 };\r
 \r
-/* Test data */\r
-extern uint32_t test_xmt_enab;\r
-extern uint64_t test_xmt_time0;\r
-extern uint64_t test_xmt_time1;\r
-\r
-extern uint32_t test_rcv_enab;\r
-extern uint64_t test_rcv_time;\r
-\r
 /* Port data */\r
 static sirq_t sirq_ports[SIRQ_NUM_UART];\r
 \r
@@ -39,22 +33,18 @@ void sirq_handler(uint32_t _port, SerialIrq event)
        sirq_t *port = (sirq_t *)_port;\r
 \r
        // Handle transmit\r
-       if (event == TxIrq && port->xmt.rix != port->xmt.wix) {\r
-               int byte = port->xmt.buf[port->xmt.rix];\r
-\r
-               uint64_t time0 = tdma_time();\r
-               serial_putc(&port->uart, byte);\r
-               uint64_t time1 = tdma_time();\r
-\r
-               if (test_xmt_enab) {\r
-                       test_xmt_time0 = time0;\r
-                       test_xmt_time1 = time1;\r
-                       test_xmt_enab  = 0;\r
+       //   note: mbed seems to call TxIrq even it is not enabled,\r
+       //   so we need to manually prevent transmitting when the\r
+       //   port is set to buffered mode.\r
+       if (event == TxIrq && (port->irq || !port->buffered)) {\r
+               if (port->xmt.rix != port->xmt.wix) {\r
+                       int byte = port->xmt.buf[port->xmt.rix];\r
+                       serial_putc(&port->uart, byte);\r
+                       port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN;\r
+               } else {\r
+                       serial_irq_set(&port->uart, TxIrq, 0);\r
+                       port->irq = 0;\r
                }\r
-\r
-               port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN;\r
-       } else {\r
-               serial_irq_set(&port->uart, TxIrq, 0);\r
        }\r
 \r
        // Handle receive\r
@@ -66,11 +56,14 @@ void sirq_handler(uint32_t _port, SerialIrq event)
 }\r
 \r
 /* Open port */\r
-sirq_t *sirq_open(sirq_uart_t uart, PinName tx, PinName rx, int baud)\r
+sirq_t *sirq_open(sirq_uart_t uart, PinName tx, PinName rx, int baud, int buffered)\r
 {\r
        // Allocate port\r
        sirq_t *port = &sirq_ports[uart];\r
 \r
+       // Buffered ports only transmit on demand\r
+       port->buffered = buffered;\r
+\r
        // Configure port\r
        serial_init(&port->uart, tx, rx);\r
        serial_baud(&port->uart, baud);\r
@@ -87,7 +80,8 @@ void sirq_putc(sirq_t *port, int byte)
 {\r
        port->xmt.buf[port->xmt.wix] = byte;\r
        port->xmt.wix = (port->xmt.wix+1) % SIRQ_LEN;\r
-       serial_irq_set(&port->uart, TxIrq, 1);\r
+       if (!port->buffered)\r
+               sirq_transmit(port);\r
 }\r
 \r
 /* Read byte from the port */\r
@@ -101,6 +95,15 @@ int sirq_getc(sirq_t *port)
        return byte;\r
 }\r
 \r
+/* Enable transmitter */\r
+void sirq_transmit(sirq_t *port)\r
+{\r
+       if (port->xmt.rix != port->xmt.wix && !port->irq) {\r
+               port->irq = 1;\r
+               serial_irq_set(&port->uart, TxIrq, 1);\r
+       }\r
+}\r
+\r
 /* Buffered write */\r
 void sirq_write(sirq_t *port, void *data, int len)\r
 {\r