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); }
/* * @brief uart_setCallbacks register the callbacks * @param txCb uart tx call back function pointer * @param rxCb uart rx call back function pointer * * */ void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { /* Register Callbacks */ uart_vars.txCb = txCb; uart_vars.rxCb = rxCb; uart_irq_enable(); }
static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr) { const uint8_t uart = sercomm_get_uart(); uint8_t iir, ch; //uart_putchar_nb(uart, 'U'); iir = uart_reg_read(uart, IIR); if (iir & IIR_INT_PENDING) return; switch (iir & IIR_INT_TYPE) { case IIR_INT_TYPE_RX_TIMEOUT: case IIR_INT_TYPE_RHR: /* as long as we have rx data available */ while (uart_getchar_nb(uart, &ch)) { if (sercomm_drv_rx_char(ch) < 0) { /* sercomm cannot receive more data right now */ uart_irq_enable(uart, UART_IRQ_RX_CHAR, 0); } } break; case IIR_INT_TYPE_THR: /* as long as we have space in the FIFO */ while (!uart_tx_busy(uart)) { /* get a byte from sercomm */ if (!sercomm_drv_pull(&ch)) { /* no more bytes in sercomm, stop TX interrupts */ uart_irq_enable(uart, UART_IRQ_TX_EMPTY, 0); break; } /* write the byte into the TX FIFO */ uart_putchar_nb(uart, ch); } break; case IIR_INT_TYPE_MSR: printf("UART IRQ MSR\n"); break; case IIR_INT_TYPE_RX_STATUS_ERROR: printf("UART IRQ RX_SE\n"); break; case IIR_INT_TYPE_XOFF: printf("UART IRQXOFF\n"); break; } }
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); }