1 #include "uart_s3c2410.h"
2 #include "poll_timeout_counter.h"
8 Type_24xx, Type_64xx, Type_s5pv210,
13 ULCON = 0x0, // line control register
14 UCON = 0x4, // control register
15 UFCON = 0x8, // FIFO control register
16 UMCON = 0xc, // modem control register
17 UTRSTAT = 0x10, // Tx/Rx status register
18 UERSTAT = 0x14, // Rx error status register
19 UFSTAT = 0x18, // FIFO status register
20 UMSTAT = 0x1c, // modem status register
21 UTXH = 0x20, // transmit buffer register (little endian, 0x23 for BE)
22 URXH = 0x24, // receive buffer register (little endian, 0x27 for BE)
23 UBRDIV = 0x28, // baud rate divisor register
25 UINTP = 0x30, // interrupt pending register
26 UINTSP = 0x34, // interrupt source pending register
27 UINTM = 0x38, // interrupt mask register
32 UCON_MODE_RECEIVE_IRQ_POLL = 1 << 0,
33 UCON_MODE_TRANSMIT_IRQ_POLL = 1 << 2,
34 UCON_SEND_BREAK_SIGNAL = 1 << 4,
35 UCON_LOOPBACK_MODE = 1 << 5,
36 UCON_RX_ERROR_STATUS_IRQ_EN = 1 << 6,
37 UCON_RX_TIME_OUT_EN = 1 << 7,
38 UCON_MODE = UCON_MODE_RECEIVE_IRQ_POLL
39 | UCON_MODE_TRANSMIT_IRQ_POLL
40 | UCON_RX_TIME_OUT_EN,
42 UFCON_ENABLE = 1 << 0, // enable fifo
43 UFCON_RX_FIFO_RESET = 1 << 1, // Rx Fifo reset
44 UFCON_TX_FIFO_RESET = 1 << 2, // Tx Fifo reset
48 UTRSTAT_Rx_RDY = 1 << 0,
49 UTRSTAT_Tx_RDY = 1 << 1,
57 UFSTAT_2410_Rx_COUNT_MASK = 0x00f,
58 UFSTAT_2410_Tx_COUNT_MASK = 0x0f0,
59 UFSTAT_2410_RxFULL = 0x100,
60 UFSTAT_2410_TxFULL = 0x200,
63 UFSTAT_64XX_Rx_COUNT_MASK = 0x003f,
64 UFSTAT_64XX_Tx_COUNT_MASK = 0x3f00,
65 UFSTAT_64XX_RxFULL = 0x0040,
66 UFSTAT_64XX_TxFULL = 0x4000,
69 UFSTAT_S5PV210_Rx_COUNT_MASK = 0x000000ff,
70 UFSTAT_S5PV210_Tx_COUNT_MASK = 0x00ff0000,
71 UFSTAT_S5PV210_RxFULL = 0x00000100,
72 UFSTAT_S5PV210_TxFULL = 0x01000000,
76 void Uart_s3c::fifo_reset()
78 _regs->write<unsigned int>(UFCON, UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET);
79 Poll_timeout_counter i(3000000);
80 while (i.test(_regs->read<unsigned int>(UFCON) & (UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET)))
85 bool Uart_s3c::startup(Io_register_block const *regs)
91 _regs->write<unsigned int>(UMCON, 0);
94 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
95 _regs->write<unsigned int>(UCON, UCON_MODE);
96 _regs->write<unsigned int>(UFCON, UFCON_ENABLE);
104 _regs->write<unsigned int>(UINTM, ~UINT_RXD); // mask all but receive irq
105 _regs->write<unsigned int>(UINTP, ~0); // clear all pending irqs
109 _regs->write<unsigned int>(UBRDIV, 0x23);
115 void Uart_s3c::shutdown()
120 bool Uart_s3c::change_mode(Transfer_mode, Baud_rate r)
126 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
127 _regs->write<unsigned int>(UCON, UCON_MODE);
128 _regs->write<unsigned int>(UFCON, 1);
130 _regs->write<unsigned int>(UBRDIV, 0x23);
136 int Uart_s3c::get_char(bool blocking) const
138 while (!char_avail())
142 _regs->read<unsigned int>(UFCON);
143 int c = _regs->read<unsigned int>(URXH) & 0xff;
148 int Uart_s3c::char_avail() const
150 return is_rx_fifo_non_empty();
153 void Uart_s3c::out_char(char c) const
155 wait_for_non_full_tx_fifo();
156 _regs->write<unsigned int>(UTXH, c);
159 int Uart_s3c::write(char const *s, unsigned long count) const
161 unsigned long c = count;
164 wait_for_empty_tx_fifo();
169 // -----------------------
171 void Uart_s3c2410::wait_for_empty_tx_fifo() const
173 Poll_timeout_counter i(3000000);
174 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Tx_COUNT_MASK | UFSTAT_2410_TxFULL)))
178 void Uart_s3c2410::wait_for_non_full_tx_fifo() const
180 Poll_timeout_counter i(3000000);
181 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_2410_TxFULL))
185 unsigned Uart_s3c2410::is_rx_fifo_non_empty() const
187 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Rx_COUNT_MASK | UFSTAT_2410_RxFULL);
190 void Uart_s3c2410::auto_flow_control(bool on)
192 _regs->write<unsigned int>(UMCON, (_regs->read<unsigned int>(UMCON) & ~UMCON_AFC) | (on ? UMCON_AFC : 0));
195 // -----------------------
197 void Uart_s3c64xx::wait_for_empty_tx_fifo() const
199 Poll_timeout_counter i(3000000);
200 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Tx_COUNT_MASK | UFSTAT_64XX_TxFULL)))
204 void Uart_s3c64xx::wait_for_non_full_tx_fifo() const
206 Poll_timeout_counter i(3000000);
207 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_64XX_TxFULL))
211 unsigned Uart_s3c64xx::is_rx_fifo_non_empty() const
213 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Rx_COUNT_MASK | UFSTAT_64XX_RxFULL);
216 void Uart_s3c64xx::ack_rx_irq() const
218 _regs->write<unsigned int>(UINTP, UINT_RXD);
221 // -----------------------
223 void Uart_s5pv210::wait_for_empty_tx_fifo() const
225 Poll_timeout_counter i(3000000);
226 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Tx_COUNT_MASK | UFSTAT_S5PV210_TxFULL)))
230 void Uart_s5pv210::wait_for_non_full_tx_fifo() const
232 Poll_timeout_counter i(3000000);
233 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_S5PV210_TxFULL))
237 unsigned Uart_s5pv210::is_rx_fifo_non_empty() const
239 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Rx_COUNT_MASK | UFSTAT_S5PV210_RxFULL);
242 void Uart_s5pv210::ack_rx_irq() const
244 _regs->write<unsigned int>(UINTP, UINT_RXD);