+
+/**
+ * Serial 0 TX interrupt handler
+ */
+static void uart0_irq_tx(void)
+{
+ SER_STROBE_ON;
+
+ struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+
+ if (fifo_isempty(txfifo))
+ {
+ SER_UART0_BUS_TXEND;
+ UARTDescs[SER_UART0].sending = false;
+ }
+ else
+ {
+ char c = fifo_pop(txfifo);
+ SER_UART0_BUS_TXCHAR(c);
+ }
+
+ SER_STROBE_OFF;
+}
+
+/**
+ * Serial 0 RX complete interrupt handler.
+ */
+static void uart0_irq_rx(void)
+{
+ SER_STROBE_ON;
+
+ /* Should be read before US_CRS */
+ ser_uart0->status |= US0_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+
+ char c = US0_RHR;
+ struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
+
+ if (fifo_isfull(rxfifo))
+ ser_uart0->status |= SERRF_RXFIFOOVERRUN;
+ else
+ fifo_push(rxfifo, c);
+
+ SER_STROBE_OFF;
+}
+
+/**
+ * Serial IRQ dispatcher for USART0.
+ */
+static void uart0_irq_dispatcher(void) __attribute__ ((naked));
+static void uart0_irq_dispatcher(void)
+{
+ IRQ_ENTRY();
+
+ if (US0_IMR & BV(US_RXRDY))
+ uart0_irq_rx();
+
+ if (US0_IMR & BV(US_TXRDY))
+ uart0_irq_tx();
+
+ IRQ_EXIT();
+}
+
+/**
+ * Serial 1 TX interrupt handler
+ */
+static void uart1_irq_tx(void)
+{
+ SER_STROBE_ON;
+
+ struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+
+ if (fifo_isempty(txfifo))
+ {
+ SER_UART1_BUS_TXEND;
+ UARTDescs[SER_UART1].sending = false;
+ }
+ else
+ {
+ char c = fifo_pop(txfifo);
+ SER_UART1_BUS_TXCHAR(c);
+ }
+
+ SER_STROBE_OFF;
+}
+
+/**
+ * Serial 1 RX complete interrupt handler.
+ */
+static void uart1_irq_rx(void)
+{
+ SER_STROBE_ON;
+
+ /* Should be read before US_CRS */
+ ser_uart1->status |= US1_CSR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+
+ char c = US1_RHR;
+ struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
+
+ if (fifo_isfull(rxfifo))
+ ser_uart1->status |= SERRF_RXFIFOOVERRUN;
+ else
+ fifo_push(rxfifo, c);
+
+ SER_STROBE_OFF;
+}
+
+/**
+ * Serial IRQ dispatcher for USART1.
+ */
+static void uart1_irq_dispatcher(void) __attribute__ ((naked));
+static void uart1_irq_dispatcher(void)
+{
+ IRQ_ENTRY();
+
+ if (US1_IMR & BV(US_RXRDY))
+ uart1_irq_rx();
+
+ if (US1_IMR & BV(US_TXRDY))
+ uart1_irq_tx();
+
+ IRQ_EXIT();
+}