2 * (c) 2008-2011 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
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.
14 URXD = 0x00, // Receiver
15 UTXD = 0x40, // Transmitter
16 UCR1 = 0x80, // Control 1
17 UCR2 = 0x84, // Control 2
18 UCR3 = 0x88, // Control 3
19 UCR4 = 0x8c, // Control 4
20 UFCR = 0x90, // FIFO Control
21 USR1 = 0x94, // Status 1
22 USR2 = 0x98, // Status 2
23 UESC = 0x9c, // Escape Charater
24 UTIM = 0xa0, // Escape Timer
25 UBIR = 0xa4, // BRM Incremental Registers
26 UBMR = 0xa8, // BRM Modulator Registers
27 UBRC = 0xac, // Baud Rate Count
28 ONEMS = 0xb0, // One millisecond
32 UCR1_EN = 1 << 0, // Enable UART
34 UCR2_SRST = 1 << 0, // Software Reset
35 UCR2_RXEN = 1 << 1, // Receiver Enable
36 UCR2_TXEN = 1 << 2, // Transmitter Enable
37 UCR2_WS = 1 << 5, // 8-bit character length
38 UCR2_STPB = 1 << 6, // 0 = 1 Stop bit, 1 = 2 stop bits
39 UCR2_PROE = 1 << 7, // 0 = even parity, 1 = odd parity
40 UCR2_PREN = 1 << 8, // Parity enable
41 UCR2_RTEC_MASK = 3 << 9, // Request to Send Edge Control mask
42 UCR2_RTEC_RISI = 0 << 9, // Trigger IRQ on rising edge
43 UCR2_RTEC_FALL = 1 << 9, // Trigger IRQ on falling edge
44 UCR2_RTEC_ANY = 2 << 9, // Trigger IRQ on any edge
45 UCR2_ESCEN = 1 << 11, // Escape enable
46 UCR2_CTS = 1 << 12, // Clear to Send: 0 = pin is high (inactive), 1 = pin is low (active)
47 UCR2_CTSC = 1 << 13, // CTS Pin Control: 0 = pin controlled by CTS bit, 1 = pin controlled by the receiver
48 UCR2_IRTS = 1 << 14, // Ignore RTS pin
49 UCR2_ESCI = 1 << 15, // Escape Sequence Interrupt Enable
51 UCR3_ACIEN = 1 << 0, // Autobaud Counter Interrupt enable
52 UCR3_INVT = 1 << 1, // Inverted Infrared Transmission
53 UCR3_RXDMUXSEL = 1 << 2, // RXD Muxed Input Selected: 0 = serial ist IPP_UART_RXD, IR is IPP_UART_RXD_IR, 1 = IPP_UART_RXD_MUX for both
56 UCR4_DREN = 1 << 0, // Receive Data Ready Interrupt Enable
57 UCR4_OREN = 1 << 1, // Receiver Overrun Interrupt enable
58 UCR4_BKEN = 1 << 2, // BREAK Condition Dected Interrupt enable
59 UCR4_TCEN = 1 << 3, // Transmit Complete Interrupt Enable
60 UCR4_LPBYP = 1 << 4, // Low Power Bypass
61 UCR4_IRSC = 1 << 5, // IR Special Case
62 // Bit 6 is reserve, should be written as 0
63 UCR4_WKEN = 1 << 7, // WAKE Interrupt Enable
64 UCR4_ENIRI = 1 << 8, // Serial Infrared Interrupt Enable
65 UCR4_INVR = 1 << 9, // Inverted Infrared Reception
66 UCR4_CTSTL_32 = 32 << 10, // CTS Trigger Level
68 UFCR_RXTL_MASK = 63 << 0, // Receiver Trigger Level Mask
69 UFCR_RXTL_1 = 1 << 0, // Receiver Trigger Level: 1 char
70 UFCR_RFDIV_2 = 4 << 7, // Reference Frequency Divier: by 2
71 UFCR_TXTL_MASK = 63 << 10, // Trasmitter Trigger Level: 8 chars
72 UFCR_TXTL_8 = 8 << 10, // Trasmitter Trigger Level: 8 chars
73 UFCR_TXTL_32 = 32 << 10, // Trasmitter Trigger Level: 32 chars
75 USR1_TRDY = 1 << 13, // Transmitter Ready
77 USR2_RDR = 1 << 0, // Receive Data Ready
78 USR2_ORE = 1 << 1, // Overrun Error
79 USR2_BRCD = 1 << 2, // Break Condition Detected
80 USR2_TXDC = 1 << 3, // Transmitter Complete
81 USR2_TXFE = 1 << 14, // Transmit Buffer FIFO Empty
85 unsigned long Uart_imx::rd(unsigned long reg) const
86 { return *(volatile unsigned long *)(_base + reg); }
87 void Uart_imx::wr(unsigned long reg, unsigned long val) const
88 { *(volatile unsigned long *)(_base + reg) = val; }
90 bool Uart_imx::startup(unsigned long base)
112 wr(UCR2, UCR2_SRST | UCR2_RXEN | UCR2_TXEN | UCR2_WS | UCR2_IRTS); // note: no IRQs enabled
113 wr(UCR3, UCR3_RXDMUXSEL);
114 wr(UCR4, UCR4_CTSTL_32);
115 wr(UFCR, UFCR_TXTL_8 | UFCR_RFDIV_2 | UFCR_RXTL_1);
120 void Uart_imx::shutdown()
122 wr(UCR1, 0); // Disable UART
125 bool Uart_imx::enable_rx_irq(bool enable)
129 wr(UCR2, rd(UCR2) | UCR2_RTEC_ANY);
130 wr(UCR4, rd(UCR4) | UCR4_DREN);
133 wr(UCR4, rd(UCR4) & ~UCR4_DREN);
137 bool Uart_imx::enable_tx_irq(bool /*enable*/) { return false; }
138 bool Uart_imx::change_mode(Transfer_mode, Baud_rate)
141 int Uart_imx::get_char(bool blocking) const
143 while (!char_avail())
144 if (!blocking) return -1;
146 return rd(URXD) & 0xff;
149 int Uart_imx::char_avail() const
151 return rd(USR2) & USR2_RDR;
154 void Uart_imx::out_char(char c) const
156 while (!(rd(USR1) & USR1_TRDY))
161 int Uart_imx::write(char const *s, unsigned long count) const
163 unsigned long c = count;
171 while (!(rd(USR2) & USR2_TXDC))