0
|
1 // driver for ARM PrimeCell UART (PL011)
|
|
2 #include "types.h"
|
|
3 #include "defs.h"
|
|
4 #include "param.h"
|
|
5 #include "arm.h"
|
|
6 #include "memlayout.h"
|
|
7
|
|
8 static volatile uint *uart_base;
|
|
9 void isr_uart (struct trapframe *tf, int idx);
|
|
10
|
|
11 #define UART_DR 0 // data register
|
|
12 #define UART_RSR 1 // receive status register/error clear register
|
|
13 #define UART_FR 6 // flag register
|
|
14 #define UART_IBRD 9 // integer baud rate register
|
|
15 #define UART_FBRD 10 // Fractional baud rate register
|
|
16 #define UART_LCR 11 // line control register
|
|
17 #define UART_CR 12 // control register
|
|
18 #define UART_IMSC 14 // interrupt mask set/clear register
|
|
19 #define UART_MIS 16 // masked interrupt status register
|
|
20 #define UART_ICR 17 // interrupt clear register
|
|
21 // bits in registers
|
|
22 #define UARTFR_TXFF (1 << 5) // tramit FIFO full
|
|
23 #define UARTFR_RXFE (1 << 4) // receive FIFO empty
|
|
24 #define UARTCR_RXE (1 << 9) // enable receive
|
|
25 #define UARTCR_TXE (1 << 8) // enable transmit
|
|
26 #define UARTCR_EN (1 << 0) // enable UART
|
|
27 #define UARTLCR_FEN (1 << 4) // enable FIFO
|
|
28 #define UART_RXI (1 << 4) // receive interrupt
|
|
29 #define UART_TXI (1 << 5) // transmit interrupt
|
|
30 #define UART_BITRATE 19200
|
|
31
|
|
32 // enable uart
|
|
33 void uart_init (void *addr)
|
|
34 {
|
|
35 uint left;
|
|
36
|
|
37 uart_base = addr;
|
|
38
|
|
39 // set the bit rate: integer/fractional baud rate registers
|
|
40 uart_base[UART_IBRD] = UART_CLK / (16 * UART_BITRATE);
|
|
41
|
|
42 left = UART_CLK % (16 * UART_BITRATE);
|
|
43 uart_base[UART_FBRD] = (left * 4 + UART_BITRATE / 2) / UART_BITRATE;
|
|
44
|
|
45 // enable trasmit and receive
|
|
46 uart_base[UART_CR] |= (UARTCR_EN | UARTCR_RXE | UARTCR_TXE);
|
|
47
|
|
48 // enable FIFO
|
|
49 uart_base[UART_LCR] |= UARTLCR_FEN;
|
|
50 }
|
|
51
|
|
52 // enable the receive (interrupt) for uart (after PIC has initialized)
|
|
53 void uart_enable_rx ()
|
|
54 {
|
|
55 uart_base[UART_IMSC] = UART_RXI;
|
|
56 pic_enable(PIC_UART0, isr_uart);
|
|
57 }
|
|
58
|
|
59 void uartputc (int c)
|
|
60 {
|
|
61 // wait a short period if the transmit FIFO is full
|
|
62 while (uart_base[UART_FR] & UARTFR_TXFF) {
|
|
63 micro_delay(10);
|
|
64 }
|
|
65
|
|
66 uart_base[UART_DR] = c;
|
|
67 }
|
|
68
|
|
69 //poll the UART for data
|
|
70 int uartgetc (void)
|
|
71 {
|
|
72 if (uart_base[UART_FR] & UARTFR_RXFE) {
|
|
73 return -1;
|
|
74 }
|
|
75
|
|
76 return uart_base[UART_DR];
|
|
77 }
|
|
78
|
|
79 void isr_uart (struct trapframe *tf, int idx)
|
|
80 {
|
|
81 if (uart_base[UART_MIS] & UART_RXI) {
|
|
82 consoleintr(uartgetc);
|
|
83 }
|
|
84
|
|
85 // clear the interrupt
|
|
86 uart_base[UART_ICR] = UART_RXI | UART_TXI;
|
|
87 }
|