+#include <MKL46Z4.h>\r
+\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include "serial_api.h"\r
+#include "serial_irq.h"\r
+\r
+/* Defines */\r
+#define SIRQ_LEN 1024\r
+\r
+/* Port structure */\r
+typedef struct {\r
+ int rix;\r
+ int wix;\r
+ uint8_t buf[SIRQ_LEN];\r
+} queue_t;\r
+\r
+struct sirq_t {\r
+ serial_t uart;\r
+ queue_t xmt;\r
+ queue_t rcv;\r
+};\r
+\r
+/* Port data */\r
+static sirq_t sirq_ports[SIRQ_NUM_UART];\r
+\r
+/* Receive handler */\r
+void sirq_handler(uint32_t _port, SerialIrq event)\r
+{\r
+ 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
+ }\r
+\r
+ // Handle receive\r
+ if (event == RxIrq) {\r
+ int byte = serial_getc(&port->uart);\r
+ port->rcv.buf[port->rcv.wix] = byte;\r
+ port->rcv.wix = (port->rcv.wix+1) % SIRQ_LEN;\r
+ }\r
+}\r
+\r
+/* Open port */\r
+sirq_t *sirq_open(sirq_uart_t uart, PinName tx, PinName rx, int baud)\r
+{\r
+ // Allocate port\r
+ sirq_t *port = &sirq_ports[uart];\r
+\r
+ // Configure port\r
+ serial_init(&port->uart, tx, rx);\r
+ serial_baud(&port->uart, baud);\r
+\r
+ // Set IRQ handlers\r
+ serial_irq_handler(&port->uart, sirq_handler, (uint32_t)port);\r
+ serial_irq_set(&port->uart, RxIrq, 1);\r
+\r
+ return port;\r
+}\r
+\r
+/* Write byte to the port */\r
+void sirq_putc(sirq_t *port, int byte)\r
+{\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
+}\r
+\r
+/* Read byte from the port */\r
+int sirq_getc(sirq_t *port)\r
+{\r
+ int byte = 0;\r
+ if (port->rcv.rix < port->rcv.wix) {\r
+ byte = port->rcv.buf[port->rcv.rix];\r
+ port->rcv.rix = (port->rcv.rix+1) % SIRQ_LEN;\r
+ }\r
+ return byte;\r
+}\r
+\r
+/* Buffered write */\r
+void sirq_write(sirq_t *port, void *data, int len)\r
+{\r
+ uint8_t *bytes = (uint8_t*)data;\r
+ for (int i = 0; i < len; i++)\r
+ sirq_putc(port, bytes[i]);\r
+}\r
+\r
+/* Check if port is writable */\r
+int sirq_ready(sirq_t *port)\r
+{\r
+ return port->rcv.rix < port->rcv.wix;\r
+}\r
+\r
+/* Write ASCII data to the output queue */\r
+void sirq_vprintf(const char *fmt, va_list ap)\r
+{\r
+ static char buf[512];\r
+ int len = vsnprintf(buf, sizeof(buf), fmt, ap);\r
+ for (int i = 0; i < len; i++)\r
+ sirq_putc(&sirq_ports[0], buf[i]);\r
+}\r
+\r
+void sirq_printf(const char *fmt, ...)\r
+{\r
+ va_list ap;\r
+ va_start(ap, fmt);\r
+ sirq_vprintf(fmt, ap);\r
+ va_end(ap);\r
+}\r