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