static uint8_t uart_reg_read(int uart, enum uart_reg reg) { uint8_t ret; if (reg & LCRBFBIT) { uart_set_lcr_bf(uart, 1); } else if (reg & LCR7BIT) { uart_set_lcr7bit(uart, 1); } else if (reg & MCR6BIT) { uart_set_mcr6bit(uart, 1); } ret = readb(UART_REG(uart, REG_OFFS(reg))); if (reg & LCRBFBIT) { uart_set_lcr_bf(uart, 0); } else if (reg & LCR7BIT) { uart_set_lcr7bit(uart, 0); } else if (reg & MCR6BIT) { uart_set_mcr6bit(uart, 0); } return ret; }
static void uart_reg_write(int uart, enum uart_reg reg, uint8_t val) { if (reg & LCRBFBIT) { uart_set_lcr_bf(uart, 1); } else if (reg & LCR7BIT) { uart_set_lcr7bit(uart, 1); } else if (reg & MCR6BIT) { uart_set_mcr6bit(uart, 1); } writeb(val, UART_REG(uart, REG_OFFS(reg))); if (reg & LCRBFBIT) { uart_set_lcr_bf(uart, 0); } else if (reg & LCR7BIT) { uart_set_lcr7bit(uart, 0); } else if (reg & MCR6BIT) { uart_set_mcr6bit(uart, 0); } }
int uart_baudrate(uint8_t uart, enum uart_baudrate bdrt) { uint16_t div; if (bdrt >= ARRAY_SIZE(divider)) return -1; div = divider[bdrt]; uart_set_lcr7bit(uart, 1); writeb(div & 0xff, UART_REG(uart, DLL)); writeb(div >> 8, UART_REG(uart, DLH)); uart_set_lcr7bit(uart, 0); return 0; }
void uart_init(uint8_t uart, __unused uint8_t interrupts) { /* no interrupts, only polling so far */ uart_reg_write(uart, IER, 0x00); if (uart == CONS_UART_NR) { cons_init(); } else { sercomm_init(); uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1); } uart_reg_write(uart, AUTOBAUD_EN, 0x00); /* disable AUTOBAUD */ uart_reg_write(uart, EFR, 0x10); /* Enhanced Features Register */ /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */ uart_reg_write(uart, EFR, (1 << 4)); /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */ //FIXME check those FIFO settings uart_reg_write(uart, IIR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR | (3 << TX_FIFO_TRIG_SHIFT) | (1 << RX_FIFO_TRIG_SHIFT)); /* RBR interrupt only when TX FIFO and TX shift register are empty */ uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); /* 8 bit, 1 stop bit, no parity, no break */ uart_reg_write(uart, LCR, 0x03); uart_set_lcr7bit(uart, 0); }
void uart_init(uint8_t uart, uint8_t interrupts) { uint8_t irq = uart2irq[uart]; uart_reg_write(uart, IER, 0x00); if (uart == cons_get_uart()) { cons_init(); if(interrupts) { irq_register_handler(irq, &uart_irq_handler_cons); irq_config(irq, 0, 0, 0xff); irq_enable(irq); } } else if (uart == sercomm_get_uart()) { sercomm_init(); if(interrupts) { irq_register_handler(irq, &uart_irq_handler_sercomm); irq_config(irq, 0, 0, 0xff); irq_enable(irq); } uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1); } else { return; } #if 0 if (uart == 1) { /* assign UART to MCU and unmask interrupts*/ writeb(UART_REG_UIR, 0x00); } #endif /* if we don't initialize these, we get strange corruptions in the received data... :-( */ uart_reg_write(uart, MDR1, 0x07); /* turn off UART */ uart_reg_write(uart, XON1, 0x00); /* Xon1/Addr Register */ uart_reg_write(uart, XON2, 0x00); /* Xon2/Addr Register */ uart_reg_write(uart, XOFF1, 0x00); /* Xoff1 Register */ uart_reg_write(uart, XOFF2, 0x00); /* Xoff2 Register */ uart_reg_write(uart, EFR, 0x00); /* Enhanced Features Register */ /* select UART mode */ uart_reg_write(uart, MDR1, 0); /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */ uart_reg_write(uart, EFR, (1 << 4)); /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */ uart_reg_write(uart, FCR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR | (3 << TX_FIFO_TRIG_SHIFT) | (3 << RX_FIFO_TRIG_SHIFT)); /* THR interrupt only when TX FIFO and TX shift register are empty */ uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); /* 8 bit, 1 stop bit, no parity, no break */ uart_reg_write(uart, LCR, 0x03); uart_set_lcr7bit(uart, 0); }