]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/gps4020/v2_0/support/download/tty.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / gps4020 / v2_0 / support / download / tty.c
1 //
2 // TTY support code
3 //
4
5 struct uart {
6     unsigned char control;
7     unsigned char _fill0[3];
8     unsigned char mode;
9     unsigned char _fill1[3];
10     unsigned char baud;
11     unsigned char _fill2[3];
12     unsigned char status;
13     unsigned char _fill3[3];
14     unsigned char TxRx;
15     unsigned char _fill4[3];
16     unsigned char modem_control;
17     unsigned char _fill5[3+8];
18     unsigned char modem_status;
19     unsigned char _fill6[3];
20 };
21
22 // Serial control
23 #define SCR_MIE      0x80   // Modem interrupt enable
24 #define SCR_EIE      0x40   // Error interrupt enable
25 #define SCR_TIE      0x20   // Transmit interrupt enable
26 #define SCR_RIE      0x10   // Receive interrupt enable
27 #define SCR_FCT      0x08   // Flow type 0=>software, 1=>hardware
28 #define SCR_CLK      0x04   // Clock source 0=internal, 1=external
29 #define SCR_TEN      0x02   // Transmitter enabled
30 #define SCR_REN      0x01   // Receiver enabled
31 // Serial mode
32 #define SMR_DIV(x)   ((x)<<4) // Clock divisor
33 #define SMR_STOP     0x08   // Stop bits 0=>one, 1=>two
34 #define   SMR_STOP_1   0x00
35 #define   SMR_STOP_2   0x08
36 #define SMR_PARITY   0x04   // Parity mode 0=>even, 1=odd
37 #define   SMR_PARITY_EVEN 0x00
38 #define   SMR_PARITY_ODD  0x04
39 #define SMR_PARITY_ON 0x02  // Parity checked
40 #define   SMR_PARITY_OFF  0x00
41 #define SMR_LENGTH    0x01  // Character length
42 #define    SMR_LENGTH_8 0x00
43 #define    SMR_LENGTH_7 0x01
44 // Serial status
45 #define SSR_MSS      0x80   // Modem status has changed
46 #define SSR_OE       0x40   // Overrun error
47 #define SSR_FE       0x20   // Framing error
48 #define SSR_PE       0x10   // Parity error
49 #define SSR_TxActive 0x08   // Transmitter is active
50 #define SSR_RxActive 0x04   // Receiver is active
51 #define SSR_TxEmpty  0x02   // Tx buffer is empty
52 #define SSR_RxFull   0x01   // Rx buffer contains data
53 // Modem control
54 #define SMR_CFG      0x08   // Configuration 0=>normal, 1=>null
55 #define SMR_MSU      0x04   // Modem status update 1=>enable
56 #define SMR_DTR      0x02   // Assert DTR
57 #define SMR_RTS      0x01   // Assert RTS
58
59 #define GP4020_UART1 0xE0018000
60 #define GP4020_UART2 0xE0019000
61
62 //
63 // Initialize a TTY port
64 //
65 static void
66 _tty_init(volatile struct uart *uart)
67 {
68     uart->mode = SMR_STOP_1 | SMR_PARITY_OFF | SMR_LENGTH_8;
69     uart->baud = 0x15;  // Magic for 57600
70     uart->modem_control = SMR_DTR | SMR_RTS;
71     uart->control = SCR_TEN | SCR_REN;
72 }
73
74 //
75 // Output a character to a TTY port
76 //
77 static void
78 _tty_putc(volatile struct uart *uart, char c)
79 {
80     // Wait for space for character
81     do {
82     } while ((uart->status & SSR_TxEmpty) == 0);
83     uart->TxRx = c;
84 }
85
86 //
87 // Read a character from a TTY port
88 //
89 static char
90 _tty_getc(volatile struct uart *uart)
91 {
92     do {
93 #if 0
94         if ((uart->status & 0xF0) != 0) {
95             tty_puts("\nErr = ");
96             tty_puthex(uart->TxRx, 2);
97         }
98 #endif
99     } while ((uart->status & SSR_RxFull) == 0);
100     return uart->TxRx;
101 }
102
103 //
104 // Initialize the TTY ports
105 //
106 volatile struct uart *uarts[] = {
107     (volatile struct uart *)GP4020_UART1,
108     (volatile struct uart *)GP4020_UART2
109 };
110
111 void
112 tty_init(void)
113 {
114
115 #if 0
116     tty_puts("\nUart: ");
117     tty_puthex(uart->control, 2);
118     tty_puts(", ");
119     tty_puthex(uart->mode, 2);
120     tty_puts(", ");
121     tty_puthex(uart->baud, 2);
122     tty_puts(", ");
123     tty_puthex(uart->TxRx, 2);
124     tty_puts("\n");
125     tty_puts("\nStat at ");  tty_puthex(&uart->status, 8);  tty_puts("\n");
126 #endif
127     _tty_init(uarts[0]);
128     _tty_init(uarts[1]);
129 }
130
131 //
132 // Write a character to the selected TTY
133 //
134 void
135 tty_putc(int chan, char c)
136 {
137     _tty_putc(uarts[chan], c);
138 }
139
140 //
141 // Read a character from the selected TTY
142 //
143 char
144 tty_getc(int chan)
145 {
146     return _tty_getc(uarts[chan]);
147 }
148
149 //
150 // Display a string on the selected TTY
151 //
152 void
153 tty_puts(int chan, char *s)
154 {
155     char c;
156
157     while ((c = *s++) != '\0') {
158         if (c == '\n') {
159             tty_putc(chan, '\r');
160         }
161         tty_putc(chan, c);
162     }
163 }
164
165 //
166 // Read characters into a buffer, terminated by a '\n' character
167 // Note: the '\n' character is not stored
168 //
169 int
170 tty_getline(int chan, char *buf)
171 {
172     char c;
173     int len = 0;
174
175     while (((c = tty_getc(chan)) != '\n') && (c != '\r')) {
176         tty_putc(chan, c);
177         *buf++ = c;
178         len++;
179     }
180     *buf = '\0';
181     return len;
182 }
183
184 //
185 // Display a number in hex
186 //
187 void
188 tty_puthex(int chan, unsigned long val, int length)
189 {
190     char hex[] = "0123456789ABCDEF";
191     char str[16];
192     char *s = &str[length+3];
193     int i;
194
195     *--s = '\0';
196     for (i = 0;  i < length;  i++) {
197         *--s = hex[(val & 0x0F)];
198         val >>= 4;
199     }
200     *--s = 'x';
201     *--s = '0';
202     tty_puts(chan, s);
203 }
204