From 2f43145131a24ad504006d499893d46cbb3be8fb Mon Sep 17 00:00:00 2001 From: CTCaer Date: Mon, 16 Dec 2019 22:16:40 +0200 Subject: [PATCH] uart: Add invert, get/set IIR and fifo empty functions --- bootloader/soc/uart.c | 61 ++++++++++++++++++++++++++++++++++++++++++ bootloader/soc/uart.h | 4 +++ nyx/nyx_gui/soc/uart.c | 61 ++++++++++++++++++++++++++++++++++++++++++ nyx/nyx_gui/soc/uart.h | 4 +++ 4 files changed, 130 insertions(+) diff --git a/bootloader/soc/uart.c b/bootloader/soc/uart.c index 7b3657f..57694c4 100644 --- a/bootloader/soc/uart.c +++ b/bootloader/soc/uart.c @@ -104,3 +104,64 @@ u32 uart_recv(u32 idx, u8 *buf, u32 len) return i ? (len ? (i - 1) : i) : 0; } + +void uart_invert(u32 idx, bool enable, u32 invert_mask) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + if (enable) + uart->UART_IRDA_CSR |= invert_mask; + else + uart->UART_IRDA_CSR &= ~invert_mask; + (void)uart->UART_SPR; +} + +u32 uart_get_IIR(u32 idx) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + return uart->UART_IIR_FCR; +} + +void uart_set_IIR(u32 idx) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD; + (void)uart->UART_SPR; + uart->UART_IER_DLAB |= UART_IER_DLAB_IE_EORD; + (void)uart->UART_SPR; +} + +void uart_empty_fifo(u32 idx, u32 which) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + uart->UART_MCR = 0; + (void)uart->UART_SPR; + usleep(96); + + uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR; + (void)uart->UART_SPR; + usleep(18); + u32 tries = 0; + + if (UART_IIR_FCR_TX_CLR & which) + { + while (tries < 10 && uart->UART_LSR & UART_LSR_TMTY) + { + tries++; + usleep(100); + } + tries = 0; + } + + if (UART_IIR_FCR_RX_CLR & which) + { + while (tries < 10 && !uart->UART_LSR & UART_LSR_RDR) + { + tries++; + usleep(100); + } + } +} diff --git a/bootloader/soc/uart.h b/bootloader/soc/uart.h index 39a8f23..23dde13 100644 --- a/bootloader/soc/uart.h +++ b/bootloader/soc/uart.h @@ -78,5 +78,9 @@ void uart_init(u32 idx, u32 baud); void uart_wait_idle(u32 idx, u32 which); void uart_send(u32 idx, const u8 *buf, u32 len); u32 uart_recv(u32 idx, u8 *buf, u32 len); +void uart_invert(u32 idx, bool enable, u32 invert_mask); +u32 uart_get_IIR(u32 idx); +void uart_set_IIR(u32 idx); +void uart_empty_fifo(u32 idx, u32 which); #endif diff --git a/nyx/nyx_gui/soc/uart.c b/nyx/nyx_gui/soc/uart.c index 7b3657f..57694c4 100644 --- a/nyx/nyx_gui/soc/uart.c +++ b/nyx/nyx_gui/soc/uart.c @@ -104,3 +104,64 @@ u32 uart_recv(u32 idx, u8 *buf, u32 len) return i ? (len ? (i - 1) : i) : 0; } + +void uart_invert(u32 idx, bool enable, u32 invert_mask) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + if (enable) + uart->UART_IRDA_CSR |= invert_mask; + else + uart->UART_IRDA_CSR &= ~invert_mask; + (void)uart->UART_SPR; +} + +u32 uart_get_IIR(u32 idx) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + return uart->UART_IIR_FCR; +} + +void uart_set_IIR(u32 idx) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD; + (void)uart->UART_SPR; + uart->UART_IER_DLAB |= UART_IER_DLAB_IE_EORD; + (void)uart->UART_SPR; +} + +void uart_empty_fifo(u32 idx, u32 which) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + uart->UART_MCR = 0; + (void)uart->UART_SPR; + usleep(96); + + uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR; + (void)uart->UART_SPR; + usleep(18); + u32 tries = 0; + + if (UART_IIR_FCR_TX_CLR & which) + { + while (tries < 10 && uart->UART_LSR & UART_LSR_TMTY) + { + tries++; + usleep(100); + } + tries = 0; + } + + if (UART_IIR_FCR_RX_CLR & which) + { + while (tries < 10 && !uart->UART_LSR & UART_LSR_RDR) + { + tries++; + usleep(100); + } + } +} diff --git a/nyx/nyx_gui/soc/uart.h b/nyx/nyx_gui/soc/uart.h index 39a8f23..23dde13 100644 --- a/nyx/nyx_gui/soc/uart.h +++ b/nyx/nyx_gui/soc/uart.h @@ -78,5 +78,9 @@ void uart_init(u32 idx, u32 baud); void uart_wait_idle(u32 idx, u32 which); void uart_send(u32 idx, const u8 *buf, u32 len); u32 uart_recv(u32 idx, u8 *buf, u32 len); +void uart_invert(u32 idx, bool enable, u32 invert_mask); +u32 uart_get_IIR(u32 idx); +void uart_set_IIR(u32 idx); +void uart_empty_fifo(u32 idx, u32 which); #endif