void uart_putc(char c) { if (c=='/n') uart_putc('/r'); wait_value(IP_UART2_CSR,4,0,100000); *(p32)IP_UART2_TDR = c; } void uart_puts(const char *s) { while(*s) uart_putc(*s++); } /* void uart_puts(void) { u32 cnt; cnt=0; while(prompt[cnt]) { wait_value(IP_UART2_CSR,4,0,10000); *(p32)IP_UART2_TDR = prompt[cnt++]; } } */ #define PAGE_SIZE 4096 #define is_digit(c) ((c) >= '0' && (c) <= '9') #define ZEROPAD 1 //pad with zero #define SIGN 2 //unsigned/signed long #define PLUS 4 //show plus #define SPACE 8 //space if plus #define LEFT 16 //left justified #define SPECIAL 32 //0x #define LARGE 64 //use 'ABCDEF' instead of 'abcdef' #define do_div(n,base) ({ int __res; __res = ((unsigned long) n) % (unsigned) base; n = ((unsigned long) n) / (unsigned) base; __res; }) int strnlen(char *pStr, unsigned long ulMaxLen) { unsigned long ulLength; if ((ulMaxLen <= 0) || (pStr==NULL)) { uart_puts("Wrong param!/n"); return -1; } ulLength = 0; while(*pStr++ && ulLength < ulMaxLen) ulLength++; return ulLength; } static int skip_atoi(const char **s) { int i=0; while (is_digit(**s)) i = i*10 + *((*s)++) - '0'; return i; } void number(long long num, int base, int size, int precision, int type) { char c,sign, tmp[66];; int i; const char *digits; static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; digits = (type & LARGE) ? large_digits : small_digits; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) return; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & PLUS) { sign = '+'; size--; } else if (type & SPACE) { sign = ' '; size--; } } if (type & SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) uart_putc(' '); if (sign) uart_putc(sign); if (type & SPECIAL) { if (base==8) uart_putc('0'); else if (base==16) { uart_putc('0'); uart_putc(digits[33]); } } if (!(type & LEFT)) while (size-- > 0) uart_putc(c); while (i < precision--) uart_putc('0'); while (i-- > 0) uart_putc(tmp[i]); while (size-- > 0) uart_putc(' '); } void xprintf( const char *fmt, ...) { va_list args; int flags, field_width, precision, qualifier, base; char *s; int len; unsigned long long num; va_start(args, fmt); for (; *fmt ; ++fmt) { if (*fmt != '%') { uart_putc(*fmt); continue; } flags = 0; repeat: ++fmt; switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; precision = va_arg(args, int); } if (precision < 0) precision = 0; } qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z' || *fmt == 'z') { qualifier = *fmt; ++fmt; if (qualifier == 'l' && *fmt == 'l') { qualifier = 'L'; ++fmt; } } base = 10; switch (*fmt) { case 'c': if (!(flags & LEFT)) while (--field_width > 0) uart_putc(' '); uart_putc((unsigned char)va_arg(args, int)); while (--field_width > 0) uart_putc(' '); continue; case 's': s = va_arg(args, char *); if ((unsigned long)s < PAGE_SIZE) s = "<NULL>"; len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) uart_putc(' '); uart_puts(s); while (len < field_width--) uart_putc(' '); continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } number((unsigned long) va_arg(args, void *),16, field_width, precision, flags); continue; case '%': uart_putc('%'); continue; case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: uart_putc('%'); if (*fmt) uart_putc(*fmt); else --fmt; continue; } if (qualifier == 'L') num = va_arg(args, long long); else if (qualifier == 'l') { num = va_arg(args, unsigned long); if (flags & SIGN) num = (signed long) num; } else if (qualifier == 'Z' || qualifier == 'z') { num = va_arg(args, size_t); } else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (signed short) num; } else { num = va_arg(args, unsigned int); if (flags & SIGN) num = (signed int) num; } number(num, base, field_width, precision, flags); } va_end(args); }