Mercurial > hg > Members > innparusu > xv6_rpi_port
comparison source/uart.c @ 0:c450faca55f4
Init
author | Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 22 Oct 2017 18:25:39 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c450faca55f4 |
---|---|
1 /***************************************************************** | |
2 * uart.c | |
3 * by Zhiyi Huang, hzy@cs.otago.ac.nz | |
4 * University of Otago | |
5 * | |
6 ********************************************************************/ | |
7 | |
8 | |
9 | |
10 #include "types.h" | |
11 #include "defs.h" | |
12 #include "memlayout.h" | |
13 #include "traps.h" | |
14 #include "arm.h" | |
15 | |
16 #define GPFSEL0 0xFE200000 | |
17 #define GPFSEL1 0xFE200004 | |
18 #define GPFSEL2 0xFE200008 | |
19 #define GPFSEL3 0xFE20000C | |
20 #define GPFSEL4 0xFE200010 | |
21 #define GPFSEL5 0xFE200014 | |
22 #define GPSET0 0xFE20001C | |
23 #define GPSET1 0xFE200020 | |
24 #define GPCLR0 0xFE200028 | |
25 #define GPCLR1 0xFE20002C | |
26 #define GPPUD 0xFE200094 | |
27 #define GPPUDCLK0 0xFE200098 | |
28 #define GPPUDCLK1 0xFE20009C | |
29 | |
30 #define AUX_IRQ 0xFE215000 | |
31 #define AUX_ENABLES 0xFE215004 | |
32 #define AUX_MU_IO_REG 0xFE215040 | |
33 #define AUX_MU_IER_REG 0xFE215044 | |
34 #define AUX_MU_IIR_REG 0xFE215048 | |
35 #define AUX_MU_LCR_REG 0xFE21504C | |
36 #define AUX_MU_MCR_REG 0xFE215050 | |
37 #define AUX_MU_LSR_REG 0xFE215054 | |
38 #define AUX_MU_MSR_REG 0xFE215058 | |
39 #define AUX_MU_SCRATCH 0xFE21505C | |
40 #define AUX_MU_CNTL_REG 0xFE215060 | |
41 #define AUX_MU_STAT_REG 0xFE215064 | |
42 #define AUX_MU_BAUD_REG 0xFE215068 | |
43 | |
44 void | |
45 setgpioval(uint func, uint val) | |
46 { | |
47 uint sel, ssel, rsel; | |
48 | |
49 if(func > 53) return; | |
50 sel = func >> 5; | |
51 ssel = GPSET0 + (sel << 2); | |
52 rsel = GPCLR0 + (sel << 2); | |
53 sel = func & 0x1f; | |
54 if(val == 0) outw(rsel, 1<<sel); | |
55 else outw(ssel, 1<<sel); | |
56 } | |
57 | |
58 | |
59 void | |
60 setgpiofunc(uint func, uint alt) | |
61 { | |
62 uint sel, data, shift; | |
63 | |
64 if(func > 53) return; | |
65 sel = 0; | |
66 while (func > 10) { | |
67 func = func - 10; | |
68 sel++; | |
69 } | |
70 sel = (sel << 2) + GPFSEL0; | |
71 data = inw(sel); | |
72 shift = func + (func << 1); | |
73 data &= ~(7 << shift); | |
74 data |= alt << shift; | |
75 outw(sel, data); | |
76 } | |
77 | |
78 | |
79 void | |
80 uartputc(uint c) | |
81 { | |
82 if(c=='\n') { | |
83 while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; | |
84 outw(AUX_MU_IO_REG, 0x0d); // add CR before LF | |
85 } | |
86 while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; | |
87 outw(AUX_MU_IO_REG, c); | |
88 } | |
89 | |
90 static int | |
91 uartgetc(void) | |
92 { | |
93 if(inw(AUX_MU_LSR_REG)&0x1) return inw(AUX_MU_IO_REG); | |
94 else return -1; | |
95 } | |
96 | |
97 void | |
98 enableirqminiuart(void) | |
99 { | |
100 intctrlregs *ip; | |
101 | |
102 ip = (intctrlregs *)INT_REGS_BASE; | |
103 ip->gpuenable[0] |= (1 << 29); // enable the miniuart through Aux | |
104 } | |
105 | |
106 | |
107 void | |
108 miniuartintr(void) | |
109 { | |
110 consoleintr(uartgetc); | |
111 } | |
112 | |
113 void | |
114 uartinit(void) | |
115 { | |
116 outw(AUX_ENABLES, 1); | |
117 outw(AUX_MU_CNTL_REG, 0); | |
118 outw(AUX_MU_LCR_REG, 0x3); | |
119 outw(AUX_MU_MCR_REG, 0); | |
120 outw(AUX_MU_IER_REG, 0x1); | |
121 outw(AUX_MU_IIR_REG, 0xC7); | |
122 outw(AUX_MU_BAUD_REG, 270); // (250,000,000/(115200*8))-1 = 270 | |
123 | |
124 setgpiofunc(14, 2); // gpio 14, alt 5 | |
125 setgpiofunc(15, 2); // gpio 15, alt 5 | |
126 | |
127 outw(GPPUD, 0); | |
128 delay(10); | |
129 outw(GPPUDCLK0, (1 << 14) | (1 << 15) ); | |
130 delay(10); | |
131 outw(GPPUDCLK0, 0); | |
132 | |
133 outw(AUX_MU_CNTL_REG, 3); | |
134 enableirqminiuart(); | |
135 } |