From: Andy Spencer Date: Sat, 15 Mar 2014 06:13:28 +0000 (+0000) Subject: Add serial transmit call X-Git-Url: http://pileus.org/git/?p=~andy%2Fcsm213a-hw;a=commitdiff_plain;h=af693a35ec651f1264e5332d30eca558e07a188f Add serial transmit call 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. --- diff --git a/hw2/main.cpp b/hw2/main.cpp index a31969d..e794213 100644 --- a/hw2/main.cpp +++ b/hw2/main.cpp @@ -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 diff --git a/hw2/main_comm.c b/hw2/main_comm.c index 6afe80d..380fc87 100644 --- a/hw2/main_comm.c +++ b/hw2/main_comm.c @@ -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"); } } diff --git a/hw2/makefile b/hw2/makefile index 8e8b2ee..54e9872 100644 --- a/hw2/makefile +++ b/hw2/makefile @@ -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: diff --git a/hw2/serial_irq.c b/hw2/serial_irq.c index e002ce9..0f5106d 100644 --- a/hw2/serial_irq.c +++ b/hw2/serial_irq.c @@ -21,6 +21,7 @@ struct sirq_t { queue_t xmt; queue_t rcv; int irq; + int buffered; }; /* Port data */ @@ -32,13 +33,18 @@ void sirq_handler(uint32_t _port, SerialIrq event) sirq_t *port = (sirq_t *)_port; // Handle transmit - if (event == TxIrq && port->xmt.rix != port->xmt.wix) { - int byte = port->xmt.buf[port->xmt.rix]; - serial_putc(&port->uart, byte); - port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN; - } else { - serial_irq_set(&port->uart, TxIrq, 0); - port->irq = 0; + // note: mbed seems to call TxIrq even it is not enabled, + // so we need to manually prevent transmitting when the + // port is set to buffered mode. + if (event == TxIrq && (port->irq || !port->buffered)) { + if (port->xmt.rix != port->xmt.wix) { + int byte = port->xmt.buf[port->xmt.rix]; + serial_putc(&port->uart, byte); + port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN; + } else { + serial_irq_set(&port->uart, TxIrq, 0); + port->irq = 0; + } } // Handle receive @@ -50,11 +56,14 @@ void sirq_handler(uint32_t _port, SerialIrq event) } /* Open port */ -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) { // Allocate port sirq_t *port = &sirq_ports[uart]; + // Buffered ports only transmit on demand + port->buffered = buffered; + // Configure port serial_init(&port->uart, tx, rx); serial_baud(&port->uart, baud); @@ -71,10 +80,8 @@ void sirq_putc(sirq_t *port, int byte) { port->xmt.buf[port->xmt.wix] = byte; port->xmt.wix = (port->xmt.wix+1) % SIRQ_LEN; - if (!port->irq) { - port->irq = 1; - serial_irq_set(&port->uart, TxIrq, 1); - } + if (!port->buffered) + sirq_transmit(port); } /* Read byte from the port */ @@ -88,6 +95,15 @@ int sirq_getc(sirq_t *port) return byte; } +/* Enable transmitter */ +void sirq_transmit(sirq_t *port) +{ + if (port->xmt.rix != port->xmt.wix && !port->irq) { + port->irq = 1; + serial_irq_set(&port->uart, TxIrq, 1); + } +} + /* Buffered write */ void sirq_write(sirq_t *port, void *data, int len) { diff --git a/hw2/serial_irq.h b/hw2/serial_irq.h index e640a9e..c7ea568 100644 --- a/hw2/serial_irq.h +++ b/hw2/serial_irq.h @@ -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);