OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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 | |||
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 | } |