blob: 2c8acecca245c1f5ad45b4ca42efa83c70b64864 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
//
// TTY support code
//
//-----------------------------------------------------------------
// Copyright (C) 2003, 2004 Gary Thomas <gary@mlbassoc.com>
//-----------------------------------------------------------------
struct uart {
unsigned char rbr;
#define thr rbr
#define dll rbr
unsigned char dlm;
#define ier dlm
unsigned char iir;
#define fcr iir
unsigned char lcr;
unsigned char mcr;
unsigned char lsr;
unsigned char msr;
unsigned char scr;
};
// Control register defines
// The interrupt enable register bits.
#define SIO_IER_ERDAI 0x01 // enable received data available irq
#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt
#define SIO_IER_ELSI 0x04 // enable receiver line status irq
#define SIO_IER_EMSI 0x08 // enable modem status interrupt
// The interrupt identification register bits.
#define SIO_IIR_IP 0x01 // 0 if interrupt pending
#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits
#define ISR_Tx 0x02
#define ISR_Rx 0x04
// The line status register bits.
#define SIO_LSR_DR 0x01 // data ready
#define SIO_LSR_OE 0x02 // overrun error
#define SIO_LSR_PE 0x04 // parity error
#define SIO_LSR_FE 0x08 // framing error
#define SIO_LSR_BI 0x10 // break interrupt
#define SIO_LSR_THRE 0x20 // transmitter holding register empty
#define SIO_LSR_TEMT 0x40 // transmitter register empty
#define SIO_LSR_ERR 0x80 // any error condition
// The modem status register bits.
#define SIO_MSR_DCTS 0x01 // delta clear to send
#define SIO_MSR_DDSR 0x02 // delta data set ready
#define SIO_MSR_TERI 0x04 // trailing edge ring indicator
#define SIO_MSR_DDCD 0x08 // delta data carrier detect
#define SIO_MSR_CTS 0x10 // clear to send
#define SIO_MSR_DSR 0x20 // data set ready
#define SIO_MSR_RI 0x40 // ring indicator
#define SIO_MSR_DCD 0x80 // data carrier detect
// The line control register bits.
#define SIO_LCR_WLS0 0x01 // word length select bit 0
#define SIO_LCR_WLS1 0x02 // word length select bit 1
#define SIO_LCR_STB 0x04 // number of stop bits
#define SIO_LCR_PEN 0x08 // parity enable
#define SIO_LCR_EPS 0x10 // even parity select
#define SIO_LCR_SP 0x20 // stick parity
#define SIO_LCR_SB 0x40 // set break
#define SIO_LCR_DLAB 0x80 // divisor latch access bit
// The FIFO control register
#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos
#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO
#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO
void
tty_init(void)
{
volatile struct uart *uart = (volatile struct uart *)0xEF600300;
unsigned char lcr;
// Reset/clear interrupts
uart->ier = 0;
// Disable and clear FIFOs (need to enable to clear).
uart->fcr = (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2);
uart->fcr = 0;
#if 0 // Assume that baud rate has been properly set
// Set speed to 38400.
uart->lcr = SIO_LCR_WLS0 | SIO_LCR_WLS1 | SIO_LCR_DLAB;
uart->dll = 0x12;
uart->dlm = 0;
#endif
// 8-1-no parity.
uart->lcr = SIO_LCR_WLS0 | SIO_LCR_WLS1;
// Enable FIFOs (and clear them).
uart->fcr = (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2);
}
void
tty_putc(char c)
{
volatile struct uart *uart = (volatile struct uart *)0xEF600300;
do {
} while ((uart->lsr & SIO_LSR_TEMT) == 0);
uart->thr = c;
}
void
tty_puts(char *s)
{
char c;
while ((c = *s++) != '\0') {
tty_putc(c);
if (c == '\n') {
tty_putc('\r');
}
}
}
char
tty_getc(void)
{
volatile struct uart *uart = (volatile struct uart *)0xEF600300;
while ((uart->lsr & SIO_LSR_DR) == 0) ;
return uart->rbr;
}
void
tty_puthex(unsigned long val)
{
char hex[] = "0123456789ABCDEF";
char str[11];
char *s = &str[10];
int i;
*--s = '\0';
for (i = 0; i < 8; i++) {
*--s = hex[(val & 0x0F)];
val >>= 4;
}
*--s = 'x';
*--s = '0';
tty_puts(s);
}
|