int serial_init(void) { u32 rdata; u32 baudRateDivisor, clock_step; u32 fcEnable = 0; u32 ahb_freq, ddr_freq, cpu_freq; ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq); /* GPIO Configuration */ ar7240_reg_wr(AR7240_GPIO_OE, 0xcff); rdata = ar7240_reg_rd(AR7240_GPIO_OUT); rdata |= 0x400; // GPIO 10 (UART_SOUT) must output 1 ar7240_reg_wr(AR7240_GPIO_OUT, rdata); rdata = ar7240_reg_rd(AR7240_GPIO_FUNC); /* GPIO_FUN, bit1/UART_EN, bit2/UART_RTS_CTS_EN, bit15(disable_s26_uart) */ rdata |= (0x3 << 1) | (0x1 << 15); ar7240_reg_wr(AR7240_GPIO_FUNC, rdata); /* Get reference clock rate, then set baud rate to 115200 */ // TODO: check the following code rdata = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS); rdata &= HORNET_BOOTSTRAP_SEL_25M_40M_MASK; if (rdata) { baudRateDivisor = (40000000 / (16 * 115200)) - 1; // 40 MHz clock is taken as UART clock } else { baudRateDivisor = (25000000 / (16 * 115200)) - 1; // 25 MHz clock is taken as UART clock } clock_step = 8192; rdata = UARTCLOCK_UARTCLOCKSCALE_SET(baudRateDivisor) | UARTCLOCK_UARTCLOCKSTEP_SET(clock_step); uart_reg_write(UARTCLOCK_ADDRESS, rdata); /* Config Uart Controller */ /* No interrupt */ rdata = UARTCS_UARTDMAEN_SET(0) | UARTCS_UARTHOSTINTEN_SET(0) | UARTCS_UARTHOSTINT_SET(0) | UARTCS_UARTSERIATXREADY_SET(0) | UARTCS_UARTTXREADYORIDE_SET(~fcEnable) | UARTCS_UARTRXREADYORIDE_SET(~fcEnable) | UARTCS_UARTHOSTINTEN_SET(0); /* is_dte == 1 */ rdata = rdata | UARTCS_UARTINTERFACEMODE_SET(2); if (fcEnable) { rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(2); } /* invert_fc ==0 (Inverted Flow Control) */ //rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(3); /* parityEnable == 0 */ //rdata = rdata | UARTCS_UARTPARITYMODE_SET(2); -->Parity Odd //rdata = rdata | UARTCS_UARTPARITYMODE_SET(3); -->Parity Even uart_reg_write(UARTCS_ADDRESS, rdata); return 0; }
static void uart_irq_handler_cons(__unused enum irq_nr irqnr) { const uint8_t uart = cons_get_uart(); uint8_t iir; //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_RHR: break; case IIR_INT_TYPE_THR: if (cons_rb_flush() == 1) { /* everything was flushed, disable THR IRQ */ uint8_t ier = uart_reg_read(uart, IER); ier &= ~(1 << 1); uart_reg_write(uart, IER, ier); } break; case IIR_INT_TYPE_MSR: break; case IIR_INT_TYPE_RX_STATUS_ERROR: break; case IIR_INT_TYPE_RX_TIMEOUT: break; case IIR_INT_TYPE_XOFF: break; } }
void uart_irq_enable(uint8_t uart, enum uart_irq irq, int on) { uint8_t ier = uart_reg_read(uart, IER); uint8_t mask = 0; switch (irq) { case UART_IRQ_TX_EMPTY: mask = (1 << 1); break; case UART_IRQ_RX_CHAR: mask = (1 << 0); break; } if (on) { ier |= mask; } else { ier &= ~mask; } uart_reg_write(uart, IER, ier); }
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); }
static void AthrUartPut(char __ch_data) { u32 rdata; do { rdata = uart_reg_read(UARTDATA_ADDRESS); } while (UARTDATA_UARTTXCSR_GET(rdata) == 0); rdata = UARTDATA_UARTTXRXDATA_SET((u32)__ch_data); rdata |= UARTDATA_UARTTXCSR_SET(1); uart_reg_write(UARTDATA_ADDRESS, rdata); }
static int AthrUartGet(char *__ch_data) { u32 rdata; rdata = uart_reg_read(UARTDATA_ADDRESS); if (UARTDATA_UARTRXCSR_GET(rdata)) { *__ch_data = (char) UARTDATA_UARTTXRXDATA_GET(rdata); rdata = UARTDATA_UARTRXCSR_SET(1); uart_reg_write(UARTDATA_ADDRESS, rdata); return 1; } else { return 0; } }
u8 UartGetPoll(void) { u8 ret_val; unsigned int rdata; do { rdata = uart_reg_read(UARTDATA_ADDRESS); } while (!UARTDATA_UARTRXCSR_GET(rdata)); ret_val = (u8) UARTDATA_UARTTXRXDATA_GET(rdata); rdata = UARTDATA_UARTRXCSR_SET(1); uart_reg_write(UARTDATA_ADDRESS, rdata); return ret_val; }
void UartPut(u8 byte) { unsigned int rdata; if (!serial_inited) { serial_inited = 1; UartInit(); } do { rdata = uart_reg_read(UARTDATA_ADDRESS); } while (UARTDATA_UARTTXCSR_GET(rdata) == 0); rdata = UARTDATA_UARTTXRXDATA_SET((unsigned int)byte); rdata |= UARTDATA_UARTTXCSR_SET(1); uart_reg_write(UARTDATA_ADDRESS, rdata); }
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); }
void UartInit(void) { unsigned int rdata; unsigned int baudRateDivisor, clock_step; unsigned int fcEnable = 0; ath_sys_frequency(); MY_WRITE(0xb8040000, 0xcff); MY_WRITE(0xb8040008, 0x3b); /* Enable UART , SPI and Disable S26 UART */ MY_WRITE(0xb8040028, (ath_reg_rd(0xb8040028) | 0x48002)); MY_WRITE(0xb8040008, 0x2f); #ifdef CONFIG_HORNET_EMULATION baudRateDivisor = (ath_ahb_freq / (16 * ATH_CONSOLE_BAUD)) - 1; // 24 MHz clock is taken as UART clock #else rdata = ath_reg_rd(HORNET_BOOTSTRAP_STATUS); rdata &= HORNET_BOOTSTRAP_SEL_25M_40M_MASK; if (rdata) baudRateDivisor = (40000000 / (16 * ATH_CONSOLE_BAUD)) - 1; // 40 MHz clock is taken as UART clock else baudRateDivisor = (25000000 / (16 * ATH_CONSOLE_BAUD)) - 1; // 25 MHz clock is taken as UART clock #endif clock_step = 8192; rdata = UARTCLOCK_UARTCLOCKSCALE_SET(baudRateDivisor) | UARTCLOCK_UARTCLOCKSTEP_SET(clock_step); uart_reg_write(UARTCLOCK_ADDRESS, rdata); /* Config Uart Controller */ #if 1 /* No interrupt */ rdata = UARTCS_UARTDMAEN_SET(0) | UARTCS_UARTHOSTINTEN_SET(0) | UARTCS_UARTHOSTINT_SET(0) | UARTCS_UARTSERIATXREADY_SET(0) | UARTCS_UARTTXREADYORIDE_SET(~fcEnable) | UARTCS_UARTRXREADYORIDE_SET(~fcEnable) | UARTCS_UARTHOSTINTEN_SET(0); #else rdata = UARTCS_UARTDMAEN_SET(0) | UARTCS_UARTHOSTINTEN_SET(0) | UARTCS_UARTHOSTINT_SET(0) | UARTCS_UARTSERIATXREADY_SET(0) | UARTCS_UARTTXREADYORIDE_SET(~fcEnable) | UARTCS_UARTRXREADYORIDE_SET(~fcEnable) | UARTCS_UARTHOSTINTEN_SET(1); #endif /* is_dte == 1 */ rdata = rdata | UARTCS_UARTINTERFACEMODE_SET(2); if (fcEnable) { rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(2); } /* invert_fc ==0 (Inverted Flow Control) */ //rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(3); /* parityEnable == 0 */ //rdata = rdata | UARTCS_UARTPARITYMODE_SET(2); -->Parity Odd //rdata = rdata | UARTCS_UARTPARITYMODE_SET(3); -->Parity Even uart_reg_write(UARTCS_ADDRESS, rdata); serial_inited = 1; }