strip the kernel version suffix from target directories, except for brcm-2.4 (the...
[15.05/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 }