comparison src/device/uart.c @ 0:83c23a36980d

Init
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Fri, 26 May 2017 23:11:05 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:83c23a36980d
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 }