my_printf.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #include "types.h"
  2. #include <stdarg.h>
  3. #include <string.h>
  4. #include "uart.h"
  5. #include "log.h"
  6. #define ZEROPAD 1 // Pad with zero
  7. #define SIGN 2 // Unsigned/signed long
  8. #define PLUS 4 // Show plus
  9. #define SPACE 8 // Space if plus
  10. #define LEFT 16 // Left justified
  11. #define SPECIAL 32 // 0x
  12. #define LARGE 64 // Use 'ABCDEF' instead of 'abcdef'
  13. #define is_digit(c) ((c) >= '0' && (c) <= '9')
  14. static const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
  15. static const char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  16. static size_t _strnlen(const char *s, size_t count)
  17. {
  18. const char *sc;
  19. for (sc = s; *sc != '\0' && count--; ++sc);
  20. return sc - s;
  21. }
  22. static int skip_atoi(const char **s)
  23. {
  24. int i = 0;
  25. while (is_digit(**s)) i = i * 10 + *((*s)++) - '0';
  26. return i;
  27. }
  28. static void number(std_putc putc, long num, int base, int size, int precision, int type)
  29. {
  30. char c, sign, tmp[66];
  31. const char *dig = digits;
  32. int i;
  33. char tmpch;
  34. if (type & LARGE) dig = upper_digits;
  35. if (type & LEFT) type &= ~ZEROPAD;
  36. if (base < 2 || base > 36) return;
  37. c = (type & ZEROPAD) ? '0' : ' ';
  38. sign = 0;
  39. if (type & SIGN)
  40. {
  41. if (num < 0)
  42. {
  43. sign = '-';
  44. num = -num;
  45. size--;
  46. }
  47. else if (type & PLUS)
  48. {
  49. sign = '+';
  50. size--;
  51. }
  52. else if (type & SPACE)
  53. {
  54. sign = ' ';
  55. size--;
  56. }
  57. }
  58. if (type & SPECIAL)
  59. {
  60. if (base == 16)
  61. size -= 2;
  62. else if (base == 8)
  63. size--;
  64. }
  65. i = 0;
  66. if (num == 0)
  67. tmp[i++] = '0';
  68. else
  69. {
  70. while (num != 0)
  71. {
  72. tmp[i++] = dig[((unsigned long)num) % (unsigned)base];
  73. num = ((unsigned long)num) / (unsigned)base;
  74. }
  75. }
  76. if (i > precision) precision = i;
  77. size -= precision;
  78. if (!(type & (ZEROPAD | LEFT))){
  79. while (size-- > 0){
  80. tmpch = ' ';
  81. putc(&tmpch, 1);
  82. }
  83. }
  84. if (sign){
  85. putc(&sign, 1);
  86. }
  87. if (type & SPECIAL)
  88. {
  89. if (base == 8){
  90. tmpch = '0';
  91. putc(&tmpch, 1);
  92. }
  93. else if (base == 16)
  94. {
  95. tmpch = '0';
  96. putc(&tmpch, 1);
  97. tmpch = digits[33];
  98. putc(&tmpch, 1);
  99. }
  100. }
  101. if (!(type & LEFT)){
  102. while (size-- > 0){
  103. putc(&c, 1);
  104. }
  105. }
  106. while (i < precision--){
  107. tmpch = '0';
  108. putc(&tmpch, 1);
  109. }
  110. while (i-- > 0){
  111. tmpch = tmp[i];
  112. putc(&tmpch, 1);
  113. }
  114. while (size-- > 0){
  115. tmpch = ' ';
  116. putc(&tmpch, 1);
  117. }
  118. }
  119. static void log_vsprintf(std_putc putc, const char *fmt, va_list args)
  120. {
  121. int len;
  122. unsigned long num;
  123. int base;
  124. char *s;
  125. int flags; // Flags to number()
  126. int field_width; // Width of output field
  127. int precision; // Min. # of digits for integers; max number of chars for from string
  128. int qualifier; // 'h', 'l', or 'L' for integer fields
  129. char* tmpstr = NULL;
  130. int tmpstr_size = 0;
  131. char tmpch;
  132. for (; *fmt; fmt++)
  133. {
  134. if (*fmt != '%')
  135. {
  136. if (tmpstr == NULL)
  137. {
  138. tmpstr = (char*)fmt;
  139. tmpstr_size = 0;
  140. }
  141. tmpstr_size ++;
  142. continue;
  143. }
  144. else if (tmpstr_size){
  145. putc(tmpstr, tmpstr_size);
  146. tmpstr = NULL;
  147. tmpstr_size = 0;
  148. }
  149. // Process flags
  150. flags = 0;
  151. repeat:
  152. fmt++; // This also skips first '%'
  153. switch (*fmt)
  154. {
  155. case '-': flags |= LEFT; goto repeat;
  156. case '+': flags |= PLUS; goto repeat;
  157. case ' ': flags |= SPACE; goto repeat;
  158. case '#': flags |= SPECIAL; goto repeat;
  159. case '0': flags |= ZEROPAD; goto repeat;
  160. }
  161. // Get field width
  162. field_width = -1;
  163. if (is_digit(*fmt))
  164. field_width = skip_atoi(&fmt);
  165. else if (*fmt == '*')
  166. {
  167. fmt++;
  168. field_width = va_arg(args, int);
  169. if (field_width < 0)
  170. {
  171. field_width = -field_width;
  172. flags |= LEFT;
  173. }
  174. }
  175. // Get the precision
  176. precision = -1;
  177. if (*fmt == '.')
  178. {
  179. ++fmt;
  180. if (is_digit(*fmt))
  181. precision = skip_atoi(&fmt);
  182. else if (*fmt == '*')
  183. {
  184. ++fmt;
  185. precision = va_arg(args, int);
  186. }
  187. if (precision < 0) precision = 0;
  188. }
  189. // Get the conversion qualifier
  190. qualifier = -1;
  191. if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
  192. {
  193. qualifier = *fmt;
  194. fmt++;
  195. }
  196. // Default base
  197. base = 10;
  198. switch (*fmt)
  199. {
  200. case 'c':
  201. if (!(flags & LEFT)){
  202. while (--field_width > 0)
  203. {
  204. tmpch = ' ';
  205. putc(&tmpch, 1);
  206. }
  207. }
  208. tmpch = (unsigned char)va_arg(args, int);
  209. putc(&tmpch, 1);
  210. while (--field_width > 0){
  211. tmpch = ' ';
  212. putc(&tmpch, 1);
  213. }
  214. continue;
  215. case 's':
  216. s = va_arg(args, char *);
  217. if (!s)
  218. s = "<NULL>";
  219. len = _strnlen(s, precision);
  220. if (!(flags & LEFT)){
  221. while (len < field_width--){
  222. tmpch = ' ';
  223. putc(&tmpch, 1);
  224. }
  225. }
  226. putc(s, len);
  227. while (len < field_width--){
  228. tmpch = ' ';
  229. putc(&tmpch, 1);
  230. }
  231. continue;
  232. case 'p':
  233. if (field_width == -1)
  234. {
  235. field_width = 2 * sizeof(void *);
  236. flags |= ZEROPAD;
  237. }
  238. number(putc,(unsigned long)va_arg(args, void *), 16, field_width, precision, flags);
  239. continue;
  240. case 'n':
  241. continue;
  242. case 'A':
  243. continue;
  244. // Integer number formats - set up the flags and "break"
  245. case 'o':
  246. base = 8;
  247. break;
  248. case 'X':
  249. flags |= LARGE;
  250. case 'x':
  251. base = 16;
  252. break;
  253. case 'd':
  254. case 'i':
  255. flags |= SIGN;
  256. case 'u':
  257. break;
  258. default:
  259. if (*fmt != '%'){
  260. tmpch = '%';
  261. putc(&tmpch, 1);
  262. }
  263. if (*fmt){
  264. tmpch = *fmt;
  265. putc(&tmpch, 1);
  266. }
  267. else
  268. {
  269. --fmt;
  270. }
  271. continue;
  272. }
  273. if (qualifier == 'l')
  274. num = va_arg(args, unsigned long);
  275. else if (qualifier == 'h')
  276. {
  277. if (flags & SIGN)
  278. num = va_arg(args, int);
  279. else
  280. num = va_arg(args, unsigned int);
  281. }
  282. else if (flags & SIGN)
  283. num = va_arg(args, int);
  284. else
  285. num = va_arg(args, unsigned int);
  286. number(putc, num, base, field_width, precision, flags);
  287. }
  288. if (tmpstr_size){
  289. putc(tmpstr, tmpstr_size);
  290. tmpstr = NULL;
  291. tmpstr_size = 0;
  292. }
  293. }
  294. void phy_printf(const char *format, ...)
  295. {
  296. va_list args;
  297. va_start(args, format);
  298. log_vsprintf((std_putc)hal_uart_send_buff, format, args);
  299. }
  300. void phy_printf_init(void)
  301. {
  302. uart_Cfg_t cfg = {
  303. .tx_pin = P9,
  304. .rx_pin = P10,
  305. .rts_pin = GPIO_DUMMY,
  306. .cts_pin = GPIO_DUMMY,
  307. .baudrate = 115200,
  308. .use_fifo = TRUE,
  309. .hw_fwctrl = FALSE,
  310. .use_tx_buf = FALSE,
  311. .parity = FALSE,
  312. .evt_handler = NULL,
  313. };
  314. hal_uart_init(cfg);//uart init
  315. }