#include "lib.h" void lib_delay(volatile int count) { count *= 50000; while (count--); } int lib_putc(char ch) { while ((*UART_LSR & UART_LSR_EMPTY_MASK) == 0); return *UART_THR = ch; } void lib_puts(char *s) { while (*s) lib_putc(*s++); } int lib_vsnprintf(char * out, size_t n, const char* s, va_list vl) { int format = 0; int longarg = 0; size_t pos = 0; for( ; *s; s++) { if (format) { switch(*s) { case 'l': { longarg = 1; break; } case 'p': { longarg = 1; if (out && pos < n) { out[pos] = '0'; } pos++; if (out && pos < n) { out[pos] = 'x'; } pos++; } case 'x': { long num = longarg ? va_arg(vl, long) : va_arg(vl, int); int hexdigits = 2*(longarg ? sizeof(long) : sizeof(int))-1; for(int i = hexdigits; i >= 0; i--) { int d = (num >> (4*i)) & 0xF; if (out && pos < n) { out[pos] = (d < 10 ? '0'+d : 'a'+d-10); } pos++; } longarg = 0; format = 0; break; } case 'd': { long num = longarg ? va_arg(vl, long) : va_arg(vl, int); if (num < 0) { num = -num; if (out && pos < n) { out[pos] = '-'; } pos++; } long digits = 1; for (long nn = num; nn /= 10; digits++) ; for (int i = digits-1; i >= 0; i--) { if (out && pos + i < n) { out[pos + i] = '0' + (num % 10); } num /= 10; } pos += digits; longarg = 0; format = 0; break; } case 's': { const char* s2 = va_arg(vl, const char*); while (*s2) { if (out && pos < n) { out[pos] = *s2; } pos++; s2++; } longarg = 0; format = 0; break; } case 'c': { if (out && pos < n) { out[pos] = (char)va_arg(vl,int); } pos++; longarg = 0; format = 0; break; } default: break; } } else if(*s == '%') { format = 1; } else { if (out && pos < n) { out[pos] = *s; } pos++; } } if (out && pos < n) { out[pos] = 0; } else if (out && n) { out[n-1] = 0; } return pos; } static char out_buf[1000]; // buffer for lib_vprintf() int lib_vprintf(const char* s, va_list vl) { int res = lib_vsnprintf(NULL, -1, s, vl); if (res+1 >= sizeof(out_buf)) { lib_puts("error: lib_vprintf() output string size overflow\n"); while(1) {} } lib_vsnprintf(out_buf, res + 1, s, vl); lib_puts(out_buf); return res; } int lib_printf(const char* s, ...) { int res = 0; va_list vl; va_start(vl, s); res = lib_vprintf(s, vl); va_end(vl); return res; }