get rid of $Id$ - it has never helped us and it has broken too many patches ;)
[openwrt.git] / target / linux / at91 / image / dfboot / src / com.c
1 /*----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support - ROUSSET -
3 *----------------------------------------------------------------------------
4 * The software is delivered "AS IS" without warranty or condition of any
5 * kind, either express, implied or statutory. This includes without
6 * limitation any warranty or condition with respect to merchantability or
7 * fitness for any particular purpose, or against the infringements of
8 * intellectual property rights of others.
9 *----------------------------------------------------------------------------
10 * File Name : com.c
11 * Object :
12 * Creation : HIi 03/27/2003
13 *
14 *----------------------------------------------------------------------------
15 */
16 #include "AT91RM9200.h"
17 #include "lib_AT91RM9200.h"
18 #include "config.h"
19 #include "com.h"
20 #include "stdio.h"
21
22 static char erase_seq[] = "\b \b"; /* erase sequence */
23
24 #define MAX_UARTS 1
25
26 //unsigned int usa[2] = {(unsigned int)AT91C_BASE_DBGU, (unsigned int)AT91C_ALTERNATE_USART};
27 unsigned int usa[1] = {(unsigned int)AT91C_BASE_DBGU};
28 unsigned int us;
29 int port_detected;
30
31 void at91_init_uarts(void)
32 {
33 int i;
34
35 port_detected = 0;
36 AT91F_DBGU_CfgPIO();
37 AT91F_US0_CfgPIO();
38 AT91F_US0_CfgPMC();
39
40 for(i=0; i<MAX_UARTS; i++) {
41 us = usa[i];
42 AT91F_US_ResetRx((AT91PS_USART)us);
43 AT91F_US_ResetTx((AT91PS_USART)us);
44
45 // Configure DBGU
46 AT91F_US_Configure(
47 (AT91PS_USART)us, // DBGU base address
48 AT91C_MASTER_CLOCK, // 60 MHz
49 AT91C_US_ASYNC_MODE, // mode Register to be programmed
50 115200, // baudrate to be programmed
51 0 // timeguard to be programmed
52 );
53
54 // Enable Transmitter
55 AT91F_US_EnableTx((AT91PS_USART)us);
56 // Enable Receiver
57 AT91F_US_EnableRx((AT91PS_USART)us);
58 }
59 us = usa[0];
60 }
61
62 int at91_serial_putc(int ch)
63 {
64 if (ch == '\n')
65 at91_serial_putc('\r');
66 while (!AT91F_US_TxReady((AT91PS_USART)us));
67 AT91F_US_PutChar((AT91PS_USART)us, (char)ch);
68 return ch;
69 }
70
71 /* This getc is modified to be able work on more than one port. On certain
72 * boards (i.e. Figment Designs VersaLink), the debug port is not available
73 * once the unit is in it's enclosure, so, if one needs to get into dfboot
74 * for any reason it is impossible. With this getc, it scans between the debug
75 * port and another port and once it receives a character, it sets that port
76 * as the debug port. */
77 int at91_serial_getc()
78 {
79 while(1) {
80 #if 0
81 if (!port_detected) {
82 if (us == usa[0]) {
83 us = usa[1];
84 }
85 else {
86 us = usa[0];
87 }
88 }
89 #endif
90 if(AT91F_US_RxReady((AT91PS_USART)us)) {
91 #if 0
92 port_detected = 1;
93 #endif
94 return((int)AT91F_US_GetChar((AT91PS_USART)us));
95 }
96 }
97 }
98
99 /*-----------------------------------------------------------------------------
100 * Function Name : AT91F_ReadLine()
101 * Object :
102 * Input Parameters :
103 * Return value :
104 *-----------------------------------------------------------------------------
105 */
106 int AT91F_ReadLine (const char *const prompt, char *console_buffer)
107 {
108 char *p = console_buffer;
109 int n = 0; /* buffer index */
110 int plen = strlen (prompt); /* prompt length */
111 int col; /* output column cnt */
112 char c;
113
114 /* print prompt */
115 if (prompt)
116 printf(prompt);
117 col = plen;
118
119 for (;;) {
120 c = getc();
121
122 switch (c) {
123 case '\r': /* Enter */
124 case '\n':
125 *p = '\0';
126 puts ("\n");
127 return (p - console_buffer);
128
129 case 0x03: /* ^C - break */
130 console_buffer[0] = '\0'; /* discard input */
131 return (-1);
132
133 case 0x08: /* ^H - backspace */
134 case 0x7F: /* DEL - backspace */
135 if (n) {
136 --p;
137 printf(erase_seq);
138 col--;
139 n--;
140 }
141 continue;
142
143 default:
144 /*
145 * Must be a normal character then
146 */
147 if (n < (AT91C_CB_SIZE -2))
148 {
149 ++col; /* echo input */
150 putc(c);
151 *p++ = c;
152 ++n;
153 }
154 else
155 { /* Buffer full */
156 putc('\a');
157 }
158 }
159 }
160 }
161
162
163 /*-----------------------------------------------------------------------------
164 * Function Name : AT91F_WaitKeyPressed()
165 * Object :
166 * Input Parameters :
167 * Return value :
168 *-----------------------------------------------------------------------------
169 */
170 void AT91F_WaitKeyPressed(void)
171 {
172 int c;
173 puts("KEY");
174 c = getc();
175 putc('\n');
176 }
177
178 int puts(const char *str)
179 {
180 while(*str != 0) {
181 at91_serial_putc(*str);
182 str++;
183 }
184 return 1;
185 }
186
187 int putc(int c)
188 {
189 return at91_serial_putc(c);
190 }
191
192 int putchar(c)
193 {
194 return putc(c);
195 }
196
197 int getc()
198 {
199 return at91_serial_getc();
200 }
201
202 int strlen(const char *str)
203 {
204 int len = 0;
205
206 if(str == (char *)0)
207 return 0;
208
209 while(*str++ != 0)
210 len++;
211
212 return len;
213 }
214
215 #define ZEROPAD 1 /* pad with zero */
216 #define SIGN 2 /* unsigned/signed long */
217 #define LEFT 4 /* left justified */
218 #define LARGE 8 /* use 'ABCDEF' instead of 'abcdef' */
219
220 #define do_div(n,base) ({ \
221 int __res; \
222 __res = ((unsigned) n) % (unsigned) base; \
223 n = ((unsigned) n) / (unsigned) base; \
224 __res; \
225 })
226
227 static int number(int num, int base, int size,
228 int precision, int type)
229 {
230 char c, sign, tmp[66];
231 const char *digits="0123456789ABCDEF";
232 int i;
233
234 if (type & LEFT)
235 type &= ~ZEROPAD;
236 if (base < 2 || base > 16)
237 return 0;
238 c = (type & ZEROPAD) ? '0' : ' ';
239 sign = 0;
240
241 if(type & SIGN && num < 0)
242 {
243 sign = '-';
244 num = -num;
245 size--;
246 }
247
248 i = 0;
249 if(num == 0)
250 tmp[i++] = digits[0];
251 else while(num != 0)
252 tmp[i++] = digits[do_div(num, base)];
253
254 if(i > precision)
255 precision = i;
256 size -= precision;
257
258 if(!(type&(ZEROPAD+LEFT)))
259 while(size-->0)
260 putc(' ');
261
262 if(sign)
263 putc(sign);
264
265 if (!(type & LEFT))
266 while (size-- > 0)
267 putc(c);
268
269 while (i < precision--)
270 putc('0');
271
272 while (i-- > 0)
273 putc(tmp[i]);
274
275 while (size-- > 0)
276 putc(' ');;
277
278 return 1;
279 }
280
281 int hvfprintf(const char *fmt, va_list va)
282 {
283 char *s;
284
285 do {
286 if(*fmt == '%') {
287 bool done = false;
288
289 int type = 0;
290 int precision = 0;
291
292 do {
293 fmt++;
294 switch(*fmt) {
295 case '0' :
296 if(!precision)
297 type |= ZEROPAD;
298 case '1' :
299 case '2' :
300 case '3' :
301 case '4' :
302 case '5' :
303 case '6' :
304 case '7' :
305 case '8' :
306 case '9' :
307 precision = precision * 10 + (*fmt - '0');
308 break;
309 case '.' :
310 break;
311 case 's' :
312 s = va_arg(va, char *);
313 if(!s)
314 puts("<NULL>");
315 else
316 puts(s);
317 done = true;
318 break;
319 case 'c' :
320 putc(va_arg(va, int));
321 done = true;
322 break;
323 case 'd' :
324 number(va_arg(va, int), 10, 0, precision, type);
325 done = true;
326 break;
327 case 'x' :
328 case 'X' :
329 number(va_arg(va, int), 16, 0, precision, type);
330 done = true;
331 break;
332 case '%' :
333 putc(*fmt);
334 done = true;
335 default:
336 putc('%');
337 putc(*fmt);
338 done = true;
339 break;
340 }
341 } while(!done);
342 } else if(*fmt == '\\') {
343 fmt++;
344 if(*fmt == 'r') {
345 putc('\r');
346 } else if(*fmt == 'n') {
347 putc('\n');
348 }
349 } else {
350 putc(*fmt);
351 }
352 fmt++;
353 } while(*fmt != 0);
354
355 return 0;
356 }
357
358 int printf(const char *fmt, ...)
359 {
360 va_list ap;
361 int i;
362
363 va_start(ap, fmt);
364 i = hvfprintf(fmt, ap);
365 va_end(ap);
366
367 return i;
368 }
This page took 0.064286 seconds and 5 git commands to generate.