/* * write data to serial port */ void uart_tx() { fd_set tx_fds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 500; FD_ZERO(&tx_fds); FD_SET(g_fd, &tx_fds); if (select(g_fd+1, NULL, &tx_fds, NULL, &tv) <= 0) return; if (FD_ISSET(g_fd, &tx_fds) && tx_qHead != NULL) { void * tx_ptr = uart_tx_dequeue(); if (tx_ptr) { int n = write(g_fd, UART_TX_DATA(tx_ptr), UART_TX_DATALEN(tx_ptr)); uart_tx_deallocate((uart_tx_t *)tx_ptr); #ifdef PRINT_UART_LOG printf("tx %d\n", n); #endif } } }
static void omahauart_int_tx(int irq, void *dev_id, struct pt_regs *regs) { struct uart_info *info = dev_id; volatile unsigned int status, pass_counter = OMAHA_ISR_PASS_LIMIT; status = UART_FIFO_STATUS(info->port); do { // TX if FIFO not full if (UART_TX_DATA(status)) omahauart_tx_chars(info); if (pass_counter-- == 0) break; status = UART_FIFO_STATUS(info->port); } while (UART_TX_DATA(status)); }
static void omahauart_tx_chars(struct uart_info *info) { struct uart_port *port = info->port; volatile unsigned int status; if (port->x_char) { UART_PUT_CHAR(port, port->x_char); port->icount.tx++; port->x_char = 0; return; } if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { omahauart_stop_tx(port, 0); return; } status = UART_FIFO_STATUS(info->port); // FIll FIFO as far as possible while(UART_TX_DATA(UART_FIFO_STATUS(info->port))) { UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]); info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (info->xmit.head == info->xmit.tail) break; } if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) uart_event(info, EVT_WRITE_WAKEUP); if (info->xmit.head == info->xmit.tail) omahauart_stop_tx(info->port, 0); }