X-Git-Url: http://pileus.org/git/?p=~andy%2Fcsm213a-hw;a=blobdiff_plain;f=hw2%2Fserial_irq.c;fp=hw2%2Fserial_irq.c;h=0f5106d8bda598b8bcbb0b91c55a443f6260a006;hp=e002ce94f49a07c96d7436612ab4cbaa014bc214;hb=af693a35ec651f1264e5332d30eca558e07a188f;hpb=a8fb9b5f585f2cd1d163e37269b6b44ad937c1b2 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) {