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.
10 #include "poll_timeout_counter.h"
15 URXD = 0x00, // Receiver
16 UTXD = 0x40, // Transmitter
17 UCR1 = 0x80, // Control 1
18 UCR2 = 0x84, // Control 2
19 UCR3 = 0x88, // Control 3
20 UCR4 = 0x8c, // Control 4
21 UFCR = 0x90, // FIFO Control
22 USR1 = 0x94, // Status 1
23 USR2 = 0x98, // Status 2
24 UESC = 0x9c, // Escape Charater
25 UTIM = 0xa0, // Escape Timer
26 UBIR = 0xa4, // BRM Incremental Registers
27 UBMR = 0xa8, // BRM Modulator Registers
28 UBRC = 0xac, // Baud Rate Count
29 ONEMS = 0xb0, // One millisecond
33 UCR1_EN = 1 << 0, // Enable UART
35 UCR2_SRST = 1 << 0, // Software Reset
36 UCR2_RXEN = 1 << 1, // Receiver Enable
37 UCR2_TXEN = 1 << 2, // Transmitter Enable
38 UCR2_WS = 1 << 5, // 8-bit character length
39 UCR2_STPB = 1 << 6, // 0 = 1 Stop bit, 1 = 2 stop bits
40 UCR2_PROE = 1 << 7, // 0 = even parity, 1 = odd parity
41 UCR2_PREN = 1 << 8, // Parity enable
42 UCR2_RTEC_MASK = 3 << 9, // Request to Send Edge Control mask
43 UCR2_RTEC_RISI = 0 << 9, // Trigger IRQ on rising edge
44 UCR2_RTEC_FALL = 1 << 9, // Trigger IRQ on falling edge
45 UCR2_RTEC_ANY = 2 << 9, // Trigger IRQ on any edge
46 UCR2_ESCEN = 1 << 11, // Escape enable
47 UCR2_CTS = 1 << 12, // Clear to Send: 0 = pin is high (inactive), 1 = pin is low (active)
48 UCR2_CTSC = 1 << 13, // CTS Pin Control: 0 = pin controlled by CTS bit, 1 = pin controlled by the receiver
49 UCR2_IRTS = 1 << 14, // Ignore RTS pin
50 UCR2_ESCI = 1 << 15, // Escape Sequence Interrupt Enable
52 UCR3_ACIEN = 1 << 0, // Autobaud Counter Interrupt enable
53 UCR3_INVT = 1 << 1, // Inverted Infrared Transmission
54 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
57 UCR4_DREN = 1 << 0, // Receive Data Ready Interrupt Enable
58 UCR4_OREN = 1 << 1, // Receiver Overrun Interrupt enable
59 UCR4_BKEN = 1 << 2, // BREAK Condition Dected Interrupt enable
60 UCR4_TCEN = 1 << 3, // Transmit Complete Interrupt Enable
61 UCR4_LPBYP = 1 << 4, // Low Power Bypass
62 UCR4_IRSC = 1 << 5, // IR Special Case
63 // Bit 6 is reserve, should be written as 0
64 UCR4_WKEN = 1 << 7, // WAKE Interrupt Enable
65 UCR4_ENIRI = 1 << 8, // Serial Infrared Interrupt Enable
66 UCR4_INVR = 1 << 9, // Inverted Infrared Reception
67 UCR4_CTSTL_32 = 32 << 10, // CTS Trigger Level
69 UFCR_RXTL_MASK = 63 << 0, // Receiver Trigger Level Mask
70 UFCR_RXTL_1 = 1 << 0, // Receiver Trigger Level: 1 char
71 UFCR_RFDIV_2 = 4 << 7, // Reference Frequency Divier: by 2
72 UFCR_TXTL_MASK = 63 << 10, // Trasmitter Trigger Level: 8 chars
73 UFCR_TXTL_8 = 8 << 10, // Trasmitter Trigger Level: 8 chars
74 UFCR_TXTL_32 = 32 << 10, // Trasmitter Trigger Level: 32 chars
76 USR1_TRDY = 1 << 13, // Transmitter Ready
78 USR2_RDR = 1 << 0, // Receive Data Ready
79 USR2_ORE = 1 << 1, // Overrun Error
80 USR2_BRCD = 1 << 2, // Break Condition Detected
81 USR2_TXDC = 1 << 3, // Transmitter Complete
82 USR2_TXFE = 1 << 14, // Transmit Buffer FIFO Empty
86 bool Uart_imx::startup(Io_register_block const *regs)
94 _regs->write<unsigned int>(UBIR, 0x0344);
95 _regs->write<unsigned int>(UBMR, 0x270f);
98 _regs->write<unsigned int>(UBIR, 0xf);
99 _regs->write<unsigned int>(UBMR, 0x1b2);
102 _regs->write<unsigned int>(UBIR, 0xf);
103 _regs->write<unsigned int>(UBMR, 0x120);
106 _regs->write<unsigned int>(UBIR, 0xf);
107 _regs->write<unsigned int>(UBMR, 0x15b);
111 _regs->write<unsigned int>(UCR1, UCR1_EN);
112 _regs->write<unsigned int>(UCR2, UCR2_SRST | UCR2_RXEN | UCR2_TXEN | UCR2_WS | UCR2_IRTS); // note: no IRQs enabled
113 _regs->write<unsigned int>(UCR3, UCR3_RXDMUXSEL);
114 _regs->write<unsigned int>(UCR4, UCR4_CTSTL_32);
115 _regs->write<unsigned int>(UFCR, UFCR_TXTL_8 | UFCR_RFDIV_2 | UFCR_RXTL_1);
120 void Uart_imx::shutdown()
122 _regs->write<unsigned int>(UCR1, 0); // Disable UART
125 bool Uart_imx::enable_rx_irq(bool enable)
129 _regs->write<unsigned int>(UCR2, _regs->read<unsigned int>(UCR2) | UCR2_RTEC_ANY);
130 _regs->write<unsigned int>(UCR4, _regs->read<unsigned int>(UCR4) | UCR4_DREN);
133 _regs->write<unsigned int>(UCR4, _regs->read<unsigned int>(UCR4) & ~UCR4_DREN);
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 _regs->read<unsigned int>(URXD) & 0xff;
149 int Uart_imx::char_avail() const
151 return _regs->read<unsigned int>(USR2) & USR2_RDR;
154 void Uart_imx::out_char(char c) const
156 Poll_timeout_counter i(3000000);
157 while (i.test(!(_regs->read<unsigned int>(USR1) & USR1_TRDY)))
159 _regs->write<unsigned int>(UTXD, c);
162 int Uart_imx::write(char const *s, unsigned long count) const
164 unsigned long c = count;
168 Poll_timeout_counter i(3000000);
169 while (i.test(!(_regs->read<unsigned int>(USR2) & USR2_TXDC)))