The unified diff between revisions [cbddc8b3..] and [a2621a92..] is displayed below. It can also be downloaded as a raw diff.
# # old_revision [cbddc8b347cfe68cf634efaf314c99652ed27527] # new_revision [a2621a92a8c03a907239e78df69f38370d023a70] # # patch "uart.c" # from [cd75769ab8ffb66cd0ff19a158def1fadbbbe56f] # to [07a014210246046a28c0b690de8dd6dd8af95e2d] # ============================================================ --- uart.c cd75769ab8ffb66cd0ff19a158def1fadbbbe56f +++ uart.c 07a014210246046a28c0b690de8dd6dd8af95e2d @@ -26,11 +26,15 @@ #define U0THRE ((UREG(LSR) & (1<<5))) /* UART0 transmitter holding register is empty */ #define U0DR ((UREG(LSR) & (1<<0))) /* UART0 data ready */ -#define UART_BUFSIZE 128 +#define UART_TXBUFSIZE 128 +#define UART_RXBUFSIZE 128 -char uart_txbuf[UART_BUFSIZE]; +char uart_txbuf[UART_TXBUFSIZE]; +char uart_rxbuf[UART_RXBUFSIZE]; volatile int uart_txread; volatile int uart_txwrite; +volatile int uart_rxread; +volatile int uart_rxwrite; volatile bool tx_running; void __attribute__((interrupt("IRQ"))) uart_interrupt_handler(void); @@ -47,15 +51,17 @@ void init_uart(void) uart_txread = 0; uart_txwrite = 0; + uart_rxread = 0; + uart_rxwrite = 0; tx_running = FALSE; interrupt_register(UART0, uart_interrupt_handler); - UREG(IER) = 0x02; /* THRE interrupt enable */ + UREG(IER) = 0x03; /* RBR and THRE interrupt enable */ } void putch(char c) { /* Wait for space in the buffer */ - while (uart_txread == ((uart_txwrite+1) % UART_BUFSIZE)); + while (uart_txread == ((uart_txwrite+1) % UART_TXBUFSIZE)); if (uart_txread == uart_txwrite) { if (U0THRE) { @@ -66,12 +72,12 @@ void putch(char c) { } uart_txbuf[uart_txwrite] = c; - uart_txwrite = (uart_txwrite + 1) % UART_BUFSIZE; + uart_txwrite = (uart_txwrite + 1) % UART_TXBUFSIZE; if (!tx_running) { if (uart_txread != uart_txwrite) { tx_running = TRUE; - uart_txread = (uart_txread + 1) % UART_BUFSIZE; + uart_txread = (uart_txread + 1) % UART_TXBUFSIZE; UREG(THR) = c; } } @@ -86,29 +92,48 @@ void __attribute__((interrupt("IRQ"))) u * to treat them as such in this handler, so let the compiler * have an easier time. */ - int local_txwrite = uart_txwrite; - int local_txread = uart_txread; + int local_txwrite; + int local_txread; + int local_rxwrite; + int local_rxread; source = UREG(IIR); - /* For now we assume that all interrupts are actually THR empty - * interrupts. Actually check this when we do more things with - * the UART - */ + switch (source & 0x0e) { + case 0x4: /* Receive Data Available */ + case 0xc: /* Character Time-out Indicator */ + local_rxwrite = uart_rxwrite; + local_rxread = uart_rxread; + while (U0DR) { + unsigned char c = UREG(RBR); + if (local_rxread != + ((local_rxwrite+1) % UART_RXBUFSIZE)) { + uart_rxbuf[local_rxwrite] = c; + local_rxwrite = (local_rxwrite + 1) % + UART_RXBUFSIZE; + } + } + uart_rxwrite = local_rxwrite; + break; - if (U0THRE) { + case 0x2: /* THRE interrupt */ + local_txwrite = uart_txwrite; + local_txread = uart_txread; for (i = 0; (i < 16) && (local_txwrite != local_txread); i++) { UREG(THR) = uart_txbuf[local_txread]; - local_txread = (local_txread + 1) % UART_BUFSIZE; + local_txread = (local_txread + 1) % UART_TXBUFSIZE; active = TRUE; } - } + uart_txread = local_txread; + if (!active) + tx_running = FALSE; + break; - uart_txread = local_txread; + case 0x6: /* Receive Line Status */ + default: /* Anything else */ + break; + } - if (!active) - tx_running = FALSE; - interrupt_clear(); } @@ -148,8 +173,13 @@ char getch(void) { } char getch(void) { - while (!U0DR) { + char c; + + while (uart_rxread == uart_rxwrite) { FP0XVAL ^= 0x04000000; } - return UREG(RBR); + + c = uart_rxbuf[uart_rxread]; + uart_rxread = (uart_rxread + 1) % UART_RXBUFSIZE; + return c; }