static void TXInterrupt(int uart_num) { volatile UART* reg = uart_reg[uart_num]; UART_STATE* uart = &uarts[uart_num]; BYTE_QUEUE* q = &uart->tx_queue; while (ByteQueueSize(q) && !(reg->uxsta & 0x0200)) { // TXIF == 1 iff the hardware FIFO is empty. We're just about to make it // non-empty, so we are safe to clear. AssignUxTXIF(uart_num, 0); reg->uxtxreg = ByteQueuePullByte(q); ++uart->num_tx_since_last_report; } // IE == 1 iff there is data in the software queue pending to be sent. AssignUxTXIE(uart_num, ByteQueueSize(q) != 0); }
void AppProtocolTasks(CHANNEL_HANDLE h) { if (state == STATE_CLOSED) return; if (state == STATE_CLOSING && ByteQueueSize(&tx_queue) == 0) { log_printf("Finished flushing, closing the channel."); ConnectionCloseChannel(h); state = STATE_CLOSED; return; } UARTTasks(); SPITasks(); I2CTasks(); ICSPTasks(); if (ConnectionCanSend(h)) { BYTE prev = SyncInterruptLevel(1); const BYTE* data; if (bytes_out) { ByteQueuePull(&tx_queue, bytes_out); bytes_out = 0; } ByteQueuePeek(&tx_queue, &data, &bytes_out); if (bytes_out > 0) { if (bytes_out > max_packet) bytes_out = max_packet; ConnectionSend(h, data, bytes_out); } SyncInterruptLevel(prev); } }