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