Root/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
22static 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};
27unsigned int usa[1] = {(unsigned int)AT91C_BASE_DBGU};
28unsigned int us;
29int port_detected;
30
31void 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
62int 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. */
77int 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 */
106int 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 */
170void AT91F_WaitKeyPressed(void)
171{
172    int c;
173        puts("KEY");
174        c = getc();
175    putc('\n');
176}
177
178int puts(const char *str)
179{
180  while(*str != 0) {
181        at91_serial_putc(*str);
182        str++;
183        }
184    return 1;
185}
186
187int putc(int c)
188{
189  return at91_serial_putc(c);
190}
191
192int putchar(c)
193{
194    return putc(c);
195}
196
197int getc()
198{
199  return at91_serial_getc();
200}
201
202int 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
227static 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
281int 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
358int 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}
369

Archive Download this file



interactive