5 #include <l4/arm_drivers_c/uart.h>
9 Base_ier_bits = 1 << 6,
23 MODE_8N1 = PAR_NONE | DAT_8 | STOP_1,
24 MODE_7E1 = PAR_EVEN | DAT_7 | STOP_1,
26 // these two values are to leave either mode
27 // or baud rate unchanged on a call to change_mode
33 TRB = 0, // Transmit/Receive Buffer (read/write)
34 BRD_LOW = 0, // Baud Rate Divisor LSB if bit 7 of LCR is set (read/write)
35 IER = 1, // Interrupt Enable Register (read/write)
36 BRD_HIGH = 1, // Baud Rate Divisor MSB if bit 7 of LCR is set (read/write)
37 IIR = 2, // Interrupt Identification Register (read only)
38 FCR = 2, // 16550 FIFO Control Register (write only)
39 LCR = 3, // Line Control Register (read/write)
40 MCR = 4, // Modem Control Register (read/write)
41 LSR = 5, // Line Status Register (read only)
42 MSR = 6, // Modem Status Register (read only)
43 SPR = 7, // Scratch Pad Register (read/write)
50 void outb(char b, enum Registers reg)
52 *(volatile char *)((port+reg)*4) = b;
56 char inb(enum Registers reg)
58 return *(volatile char *)((port+reg)*4);
137 static int uart_valid(void)
139 char scratch, scratch2, scratch3;
144 scratch2 = ier_get();
147 scratch3 = ier_get();
150 return (scratch2 == 0x00 && scratch3 == 0x0f);
154 int uart_startup(l4_addr_t _port, unsigned __irq)
162 proc_status o = proc_cli_save();
163 ier_set(Base_ier_bits);/* disable all rs-232 interrupts */
164 mcr_set(0x0b); /* out2, rts, and dtr enabled */
165 fcr_set(1); /* enable fifo */
166 fcr_set(0x07); /* clear rcv xmit fifo */
167 fcr_set(1); /* enable fifo */
168 lcr_set(0); /* clear line control register */
170 /* clearall interrupts */
171 /*read*/ msr_get(); /* IRQID 0*/
172 /*read*/ iir_get(); /* IRQID 1*/
173 /*read*/ trb_get(); /* IRQID 2*/
174 /*read*/ lsr_get(); /* IRQID 3*/
176 while(lsr_get() & 1/*DATA READY*/)
182 void uart_shutdown(void)
184 proc_status o = proc_cli_save();
192 int uart_change_mode(TransferMode m, BaudRate r)
194 proc_status o = proc_cli_save();
195 char old_lcr = lcr_get();
197 l4_uint16_t divisor = Base_rate / r;
198 lcr_set(old_lcr | 0x80/*DLAB*/);
199 trb_set(divisor & 0x0ff ); /* BRD_LOW */
200 ier_set((divisor >> 8) & 0x0ff ); /* BRD_HIGH */
211 int uart_getmode(void)
213 return lcr_get() & 0x7f;
217 int uart_get_mode(enum uart_mode_type type)
221 case UART_MODE_TYPE_8N1:
223 case UART_MODE_TYPE_NONE:
229 int uart_write(char const *s, unsigned count)
231 /* disable uart irqs */
235 ier_set(old_ier & ~0x0f);
238 for (i = 0; i < count; i++) {
239 while (!(lsr_get() & 0x20 /* THRE */))
246 while (!(lsr_get() & 0x20 /* THRE */))
252 /* wait till everything is transmitted */
253 while (!(lsr_get() & 0x40 /* TSRE */))
260 int uart_getchar(int blocking)
264 if (!blocking && !(lsr_get() & 1 /* DATA READY */))
268 ier_set(old_ier & ~0x0f);
269 while(!(lsr_get() & 1 /* DATA READY */))
276 int uart_char_avail(void)
278 if (lsr_get() & 1 /* DATA READY */)
284 l4_addr_t uart_base(void)
286 return 0x40100000 / 4;