1 #include "uart_s3c2410.h"
7 Type_24xx, Type_64xx, Type_s5pv210,
12 ULCON = 0x0, // line control register
13 UCON = 0x4, // control register
14 UFCON = 0x8, // FIFO control register
15 UMCON = 0xc, // modem control register
16 UTRSTAT = 0x10, // Tx/Rx status register
17 UERSTAT = 0x14, // Rx error status register
18 UFSTAT = 0x18, // FIFO status register
19 UMSTAT = 0x1c, // modem status register
20 UTXH = 0x20, // transmit buffer register (little endian, 0x23 for BE)
21 URXH = 0x24, // receive buffer register (little endian, 0x27 for BE)
22 UBRDIV = 0x28, // baud rate divisor register
24 UINTP = 0x30, // interrupt pending register
25 UINTSP = 0x34, // interrupt source pending register
26 UINTM = 0x38, // interrupt mask register
31 UCON_MODE_RECEIVE_IRQ_POLL = 1 << 0,
32 UCON_MODE_TRANSMIT_IRQ_POLL = 1 << 2,
33 UCON_SEND_BREAK_SIGNAL = 1 << 4,
34 UCON_LOOPBACK_MODE = 1 << 5,
35 UCON_RX_ERROR_STATUS_IRQ_EN = 1 << 6,
36 UCON_RX_TIME_OUT_EN = 1 << 7,
37 UCON_MODE = UCON_MODE_RECEIVE_IRQ_POLL
38 | UCON_MODE_TRANSMIT_IRQ_POLL
39 | UCON_RX_TIME_OUT_EN,
41 UFCON_ENABLE = 1 << 0, // enable fifo
42 UFCON_RX_FIFO_RESET = 1 << 1, // Rx Fifo reset
43 UFCON_TX_FIFO_RESET = 1 << 2, // Tx Fifo reset
47 UTRSTAT_Rx_RDY = 1 << 0,
48 UTRSTAT_Tx_RDY = 1 << 1,
56 UFSTAT_2410_Rx_COUNT_MASK = 0x00f,
57 UFSTAT_2410_Tx_COUNT_MASK = 0x0f0,
58 UFSTAT_2410_RxFULL = 0x100,
59 UFSTAT_2410_TxFULL = 0x200,
62 UFSTAT_64XX_Rx_COUNT_MASK = 0x003f,
63 UFSTAT_64XX_Tx_COUNT_MASK = 0x3f00,
64 UFSTAT_64XX_RxFULL = 0x0040,
65 UFSTAT_64XX_TxFULL = 0x4000,
68 UFSTAT_S5PV210_Rx_COUNT_MASK = 0x000000ff,
69 UFSTAT_S5PV210_Tx_COUNT_MASK = 0x00ff0000,
70 UFSTAT_S5PV210_RxFULL = 0x00000100,
71 UFSTAT_S5PV210_TxFULL = 0x01000000,
75 void Uart_s3c::fifo_reset()
77 _regs->write<unsigned int>(UFCON, UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET);
78 while (_regs->read<unsigned int>(UFCON) & (UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET))
83 bool Uart_s3c::startup(Io_register_block const *regs)
89 _regs->write<unsigned int>(UMCON, 0);
92 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
93 _regs->write<unsigned int>(UCON, UCON_MODE);
94 _regs->write<unsigned int>(UFCON, UFCON_ENABLE);
102 _regs->write<unsigned int>(UINTM, ~UINT_RXD); // mask all but receive irq
103 _regs->write<unsigned int>(UINTP, ~0); // clear all pending irqs
107 _regs->write<unsigned int>(UBRDIV, 0x23);
113 void Uart_s3c::shutdown()
118 bool Uart_s3c::change_mode(Transfer_mode, Baud_rate r)
124 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
125 _regs->write<unsigned int>(UCON, UCON_MODE);
126 _regs->write<unsigned int>(UFCON, 1);
128 _regs->write<unsigned int>(UBRDIV, 0x23);
134 int Uart_s3c::get_char(bool blocking) const
136 while (!char_avail())
140 _regs->read<unsigned int>(UFCON);
141 int c = _regs->read<unsigned int>(URXH) & 0xff;
146 int Uart_s3c::char_avail() const
148 return is_rx_fifo_non_empty();
151 void Uart_s3c::out_char(char c) const
153 wait_for_non_full_tx_fifo();
154 _regs->write<unsigned int>(UTXH, c);
157 int Uart_s3c::write(char const *s, unsigned long count) const
159 unsigned long c = count;
162 wait_for_empty_tx_fifo();
167 // -----------------------
169 void Uart_s3c2410::wait_for_empty_tx_fifo() const
171 while (_regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Tx_COUNT_MASK | UFSTAT_2410_TxFULL))
175 void Uart_s3c2410::wait_for_non_full_tx_fifo() const
177 while (_regs->read<unsigned int>(UFSTAT) & UFSTAT_2410_TxFULL)
181 unsigned Uart_s3c2410::is_rx_fifo_non_empty() const
183 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Rx_COUNT_MASK | UFSTAT_2410_RxFULL);
186 void Uart_s3c2410::auto_flow_control(bool on)
188 _regs->write<unsigned int>(UMCON, (_regs->read<unsigned int>(UMCON) & ~UMCON_AFC) | (on ? UMCON_AFC : 0));
191 // -----------------------
193 void Uart_s3c64xx::wait_for_empty_tx_fifo() const
195 while (_regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Tx_COUNT_MASK | UFSTAT_64XX_TxFULL))
199 void Uart_s3c64xx::wait_for_non_full_tx_fifo() const
201 while (_regs->read<unsigned int>(UFSTAT) & UFSTAT_64XX_TxFULL)
205 unsigned Uart_s3c64xx::is_rx_fifo_non_empty() const
207 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Rx_COUNT_MASK | UFSTAT_64XX_RxFULL);
210 void Uart_s3c64xx::ack_rx_irq() const
212 _regs->write<unsigned int>(UINTP, UINT_RXD);
215 // -----------------------
217 void Uart_s5pv210::wait_for_empty_tx_fifo() const
219 while (_regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Tx_COUNT_MASK | UFSTAT_S5PV210_TxFULL))
223 void Uart_s5pv210::wait_for_non_full_tx_fifo() const
225 while (_regs->read<unsigned int>(UFSTAT) & UFSTAT_S5PV210_TxFULL)
229 unsigned Uart_s5pv210::is_rx_fifo_non_empty() const
231 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Rx_COUNT_MASK | UFSTAT_S5PV210_RxFULL);
234 void Uart_s5pv210::ack_rx_irq() const
236 _regs->write<unsigned int>(UINTP, UINT_RXD);