]> Pileus Git - ~andy/csm213a-hw/commitdiff
Add serial transmit call
authorAndy Spencer <andy753421@gmail.com>
Sat, 15 Mar 2014 06:13:28 +0000 (06:13 +0000)
committerAndy Spencer <andy753421@gmail.com>
Sat, 15 Mar 2014 06:13:28 +0000 (06:13 +0000)
In event really mode, the mbed needs to queue up relayed event messages
until the time sync messages goes out, otherwise the timer will trigger
at the wrong time.

hw2/main.cpp
hw2/main_comm.c
hw2/makefile
hw2/serial_irq.c
hw2/serial_irq.h

index a31969dbda9de61f50e56a846a525cc3d42f0220..e794213546f0ff4a9d5d23e5b338614ebc778913 100644 (file)
@@ -178,9 +178,9 @@ void background(void)
 int main(int argc, char **argv)
 {
        // Open serial ports
-       sirq_dbg   = sirq_open(SIRQ_UART0, USBTX, USBRX, 115200); // to pc
-       sirq_bbb   = sirq_open(SIRQ_UART1, PTE0,  PTE1,  115200); // to bbb
-       sirq_mbed  = sirq_open(SIRQ_UART2, PTD3,  PTD2,  115200); // to mbed
+       sirq_dbg   = sirq_open(SIRQ_UART0, USBTX, USBRX, 115200, 0); // to pc
+       sirq_bbb   = sirq_open(SIRQ_UART1, PTE0,  PTE1,  115200, 0); // to bbb
+       sirq_mbed  = sirq_open(SIRQ_UART2, PTD3,  PTD2,  115200, 1); // to mbed
 
        // Setup timers
        tdma_evt   = tdma_open(TDMA_CHAN0, 3, PTC9,  PullDown); // async event
index 6afe80d27c1550dfffa208b78ea51355ee127161..380fc87f0535830935b5c5ae79a72d61179a90a2 100644 (file)
@@ -101,7 +101,6 @@ void comm_init(sirq_t *dbg, sirq_t *bbb, sirq_t *mbed,
        comm_tdma_xmt  = xmt;
 }
 
-
 /**
  * Output time sync message
  */
@@ -120,10 +119,13 @@ void comm_send_sync(uint64_t local)
        head.length = sizeof(body);
        head.cksum  = 0; // todo
 
+       sirq_write(comm_sirq_mbed, &head, sizeof(head));
+
+       // Capture transmit time
        tdma_stop(comm_tdma_rcv, 0);
        tdma_start(comm_tdma_xmt);
 
-       sirq_write(comm_sirq_mbed, &head, sizeof(head));
+       sirq_transmit(comm_sirq_mbed);
 
        tdma_stop(comm_tdma_xmt, 100);
        tdma_start(comm_tdma_rcv);
@@ -143,6 +145,8 @@ void comm_send_sync(uint64_t local)
 
        sirq_write(comm_sirq_mbed, &body, sizeof(body));
 
+       sirq_transmit(comm_sirq_mbed);
+
        // Queue next transmit time
        comm_sync_due  = 0;
 }
@@ -180,9 +184,11 @@ void comm_send_event(uint16_t event, uint64_t local)
        if (comm_device_id == 1) {
                sirq_write(comm_sirq_bbb,  &head, sizeof(head));
                sirq_write(comm_sirq_bbb,  &body, sizeof(body));
-       } else {
+       } else if (comm_device_id > 1) {
                sirq_write(comm_sirq_mbed, &head, sizeof(head));
                sirq_write(comm_sirq_mbed, &body, sizeof(body));
+       } else {
+               sirq_printf("no device id, skipping event\r\n");
        }
 }
 
index 8e8b2ee95b2bd38d2a8858dfd50ccd6938e881ab..54e987246accffe2a32c74d17a2d972e60f49192 100644 (file)
@@ -1,3 +1,5 @@
+-include config.mk
+
 # Common settings
 UART0    = /dev/ttyACM0
 UART1    = /dev/ttyACM1
@@ -7,8 +9,6 @@ CPPFLAGS =
 LDFLAGS  = -lm
 
 # Common rules
-default: all
-
 all: mbed.elf tester.elf control
 
 terms:
index e002ce94f49a07c96d7436612ab4cbaa014bc214..0f5106d8bda598b8bcbb0b91c55a443f6260a006 100644 (file)
@@ -21,6 +21,7 @@ struct sirq_t {
        queue_t  xmt;\r
        queue_t  rcv;\r
        int      irq;\r
+       int      buffered;\r
 };\r
 \r
 /* Port data */\r
@@ -32,13 +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
-               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
+       //   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
 \r
        // Handle receive\r
@@ -50,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
@@ -71,10 +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
-       if (!port->irq) {\r
-               port->irq = 1;\r
-               serial_irq_set(&port->uart, TxIrq, 1);\r
-       }\r
+       if (!port->buffered)\r
+               sirq_transmit(port);\r
 }\r
 \r
 /* Read byte from the port */\r
@@ -88,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
index e640a9e5a9d2f738190c48c3bfbd3d2b073f3fbd..c7ea568154e855eb8ed3052050366f5f6ea4f7c1 100644 (file)
@@ -23,13 +23,16 @@ typedef enum {
 typedef struct sirq_t sirq_t;
 
 /* Open */
-sirq_t *sirq_open(sirq_uart_t uart, PinName tx, PinName rx, int baud);
+sirq_t *sirq_open(sirq_uart_t uart, PinName tx, PinName rx, int baud, int buffered);
 
 /* Read/Write */
 void sirq_putc(sirq_t *port, int byte);
 int  sirq_getc(sirq_t *port);
 void sirq_write(sirq_t *port, void *data, int len);
 
+/* Transmit */
+void sirq_transmit(sirq_t *port);
+
 /* Read In */
 int  sirq_ready(sirq_t *port);