The unified diff between revisions [cbddc8b3..] and [23a3e9a5..] is displayed below. It can also be downloaded as a raw diff.
This diff has been restricted to the following files: 'uart.c'
# # old_revision [cbddc8b347cfe68cf634efaf314c99652ed27527] # new_revision [23a3e9a50b4034343e3bd217d2c225dcaec064dd] # # patch "uart.c" # from [cd75769ab8ffb66cd0ff19a158def1fadbbbe56f] # to [37a2e0459886f7f9c4e4a5361e21d50902dbe3f7] # ============================================================ --- uart.c cd75769ab8ffb66cd0ff19a158def1fadbbbe56f +++ uart.c 37a2e0459886f7f9c4e4a5361e21d50902dbe3f7 @@ -1,11 +1,10 @@ #include "uart.h" #include "types.h" #include "interrupt.h" +#include "event.h" #define UARTBASE 0xE000C000 -#define FP0XVAL (*((volatile unsigned int *) 0x3FFFC014)) - #define RBR 0x00 #define THR 0x00 #define DLL 0x00 @@ -26,11 +25,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 +50,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 +71,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 +91,49 @@ 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; + event_set(EVENT_UART_INPUT); + 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(); } @@ -130,6 +155,31 @@ void putint(unsigned int n) { putstr(s+i); } +void putint_s(int n) { + char s[12]; + int i; + int neg; + + /* OK, technically, this might not work properly for the most + * negative possible number. Oh well. + */ + neg = (n < 0); + if (neg) + n = -n; + + i = 11; + s[i] = '\0'; + + do { + s[--i] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (neg) + s[--i] = '-'; + + putstr(s+i); +} + void puthex(unsigned int n) { char s[9]; int i; @@ -147,9 +197,11 @@ void puthex(unsigned int n) { putstr(s+i); } -char getch(void) { - while (!U0DR) { - FP0XVAL ^= 0x04000000; - } - return UREG(RBR); +bool getch(char *c) { + if (uart_rxread == uart_rxwrite) + return FALSE; + + *c = uart_rxbuf[uart_rxread]; + uart_rxread = (uart_rxread + 1) % UART_RXBUFSIZE; + return TRUE; }