]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/drivers/uart/src/uart_pl011.cc
update
[l4.git] / l4 / pkg / drivers / uart / src / uart_pl011.cc
1 /*
2  * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9 #include "uart_pl011.h"
10
11 namespace L4
12 {
13   enum {
14     UART011_RXIM = 1 << 4,
15     UART011_TXIM = 1 << 5,
16     UART011_RTIM = 1 << 6,
17     UART011_FEIM = 1 << 7,
18     UART011_PEIM = 1 << 8,
19     UART011_BEIM = 1 << 9,
20     UART011_OEIM = 1 << 10,
21
22     UART011_RXIS = 1 << 4,
23     UART011_RTIS = 1 << 6,
24
25     UART011_RXIC = 1 << 4,
26     UART011_RTIC = 1 << 6,
27
28     UART01x_CR_UARTEN = 1, // UART enable
29     UART011_CR_LBE    = 0x080, // loopback enable
30     UART011_CR_TXE    = 0x100, // transmit enable
31     UART011_CR_RXE    = 0x200, // receive enable
32
33     UART01x_FR_BUSY   = 0x008,
34     UART01x_FR_RXFE   = 0x010,
35     UART01x_FR_TXFF   = 0x020,
36
37     UART01x_LCRH_PEN    = 0x02, // parity enable
38     UART01x_LCRH_FEN    = 0x10, // FIFO enable
39     UART01x_LCRH_WLEN_8 = 0x60,
40
41     UART01x_DR   = 0x00,
42     UART011_ECR  = 0x04,
43     UART01x_FR   = 0x18,
44     UART011_IBRD = 0x24,
45     UART011_FBRD = 0x28,
46     UART011_LCRH = 0x2c,
47     UART011_CR   = 0x30,
48     UART011_IMSC = 0x38,
49     UART011_MIS  = 0x40,
50     UART011_ICR  = 0x44,
51   };
52
53
54   unsigned long Uart_pl011::rd(unsigned long reg) const
55   {
56     volatile unsigned long *r = (unsigned long*)(_base + reg);
57     return *r;
58   }
59
60   void Uart_pl011::wr(unsigned long reg, unsigned long val) const
61   {
62     volatile unsigned long *r = (unsigned long*)(_base + reg);
63     *r = val;
64   }
65
66   bool Uart_pl011::startup(unsigned long base)
67   {
68     _base = base;
69     wr(UART011_CR, UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE);
70     wr(UART011_FBRD, 2);
71     wr(UART011_IBRD, 13);
72     wr(UART011_LCRH, 0x60);
73     wr(UART011_IMSC, 0);
74     while (rd(UART01x_FR) & UART01x_FR_BUSY)
75       ;
76     return true;
77   }
78   
79   void Uart_pl011::shutdown()
80   {
81     wr(UART011_IMSC,0);
82     wr(UART011_ICR, 0xffff);
83     wr(UART011_CR, 0);
84   }
85
86   bool Uart_pl011::enable_rx_irq(bool enable) 
87   {
88     unsigned long mask = UART011_RXIM | UART011_RTIM;
89
90     wr(UART011_ICR, 0xffff);
91     wr(UART011_ECR, 0xff);
92     if (enable)
93       wr(UART011_IMSC, rd(UART011_IMSC) | mask);
94     else
95       wr(UART011_IMSC, rd(UART011_IMSC) & ~mask);
96     return true; 
97   }
98   bool Uart_pl011::enable_tx_irq(bool /*enable*/) { return false; }
99   bool Uart_pl011::change_mode(Transfer_mode, Baud_rate r)
100   {
101     if (r != 115200)
102       return false;
103
104     unsigned long old_cr = rd(UART011_CR);
105     wr(UART011_CR, 0);
106
107     wr(UART011_FBRD, 2);
108     wr(UART011_IBRD, 13);
109     wr(UART011_LCRH, UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN);
110
111     wr(UART011_CR, old_cr);
112
113     return true;
114   }
115
116   int Uart_pl011::get_char(bool blocking) const
117   { 
118     while (!char_avail()) 
119       if (!blocking) return -1;
120
121     //wr(UART011_ICR, UART011_RXIC | UART011_RTIC);
122
123     int c = rd(UART01x_DR);
124     wr(UART011_ECR, 0xff);
125     return c;
126   }
127
128   int Uart_pl011::char_avail() const 
129   { 
130     return !(rd(UART01x_FR) & UART01x_FR_RXFE); 
131   }
132
133   void Uart_pl011::out_char(char c) const
134   {
135     while (rd(UART01x_FR) & UART01x_FR_TXFF)
136       ;
137     wr(UART01x_DR,c);
138   }
139
140   int Uart_pl011::write(char const *s, unsigned long count) const
141   {
142     unsigned long c = count;
143     while (c)
144       {
145         if (*s == 10)
146           out_char(13);
147         out_char(*s++);
148         --c;
149       }
150     while (rd(UART01x_FR) & UART01x_FR_BUSY)
151       ;
152
153     return count;
154   }
155
156 };
157