1 #include <lunaix/mm/valloc.h>
2 #include <lunaix/status.h>
4 #include <usr/lunaix/serial.h>
5 #include <usr/lunaix/term.h>
10 uart_alloc(ptr_t base_addr)
12 struct uart16550* uart = valloc(sizeof(struct uart16550));
14 // load registers default value
15 uart->cntl_save.rmc = UART_rMC_DTR | UART_rMC_RTS | UART_rMC_IEN;
16 uart->cntl_save.rie = 0;
18 uart->base_addr = base_addr;
19 uart->base_clk = 115200U;
24 uart_free(struct uart16550* uart)
30 uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len)
32 struct uart16550* uart = UART16550(sdev);
36 while (!uart_can_transmit(uart))
38 uart_write_byte(uart, data[i++]);
41 serial_end_xmit(sdev, len);
47 uart_set_control_mode(struct uart16550* uart, tcflag_t cflags)
49 uart->cntl_save.rie &= ~(UART_rIE_ERBFI | UART_rIE_EDSSI);
50 uart->cntl_save.rie |= (!(cflags & _CLOCAL)) * UART_rIE_EDSSI;
51 uart->cntl_save.rie |= (!!(cflags & _CREAD)) * UART_rIE_ERBFI;
54 uart->cntl_save.rlc &= ~UART_LCR_RESET;
55 uart->cntl_save.rlc |= (!!(cflags & _CSTOPB)) * UART_rLC_STOPB;
56 uart->cntl_save.rlc |= (!!(cflags & _CPARENB)) * UART_rLC_PAREN;
57 uart->cntl_save.rlc |= (!(cflags & _CPARODD)) * UART_rLC_PAREVN;
58 uart->cntl_save.rlc |= (cflags & _CSZ_MASK) >> 2;
63 uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args)
65 struct uart16550* uart = UART16550(sdev);
73 case SERIO_SETBRDRATE:
75 unsigned int div, rate;
77 rate = va_arg(args, speed_t);
82 div = uart->base_clk / va_arg(args, speed_t);
83 uart_baud_divisor(uart, div);
86 case SERIO_SETBRDBASE:
88 int clk = va_arg(args, unsigned int);
96 case SERIO_SETCNTRLMODE:
97 uart_set_control_mode(uart, va_arg(args, tcflag_t));
106 uart_handle_irq_overlap(int iv, struct llist_header* ports)
108 struct uart16550 *pos, *n;
109 llist_for_each(pos, n, ports, local_ports)
111 int is = uart_intr_identify(pos);
112 if (iv == pos->iv && (is == UART_CHR_TIMEOUT)) {
120 uart_handle_irq(iv, pos);
124 uart_handle_irq(int iv, struct uart16550 *uart)
129 while ((recv = uart_read_byte(uart))) {
131 if (likely(i < 32)) {
135 if (!serial_accept_buffer(uart->sdev, tmpbuf, i)) {
136 uart_clear_rxfifo(uart);
143 serial_accept_buffer(uart->sdev, tmpbuf, i);
144 serial_accept_one(uart->sdev, 0);
146 serial_end_recv(uart->sdev);