esp_rom_sys.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdbool.h>
  9. #include <stdarg.h>
  10. #include <assert.h>
  11. #include <unistd.h>
  12. #include "esp_rom_sys.h"
  13. static void call_linux_putc(char c);
  14. static void (*s_esp_rom_putc)(char c) = call_linux_putc;
  15. static void call_linux_putc(char c) {
  16. putc(c, stdout);
  17. }
  18. #define is_digit(c) ((c >= '0') && (c <= '9'))
  19. static int _cvt(unsigned long long val, char *buf, long radix, const char *digits)
  20. {
  21. #ifdef SUPPORT_LITTLE_RADIX
  22. char temp[64];
  23. #else
  24. char temp[32];
  25. #endif
  26. char *cp = temp;
  27. int length = 0;
  28. if (val == 0) {
  29. /* Special case */
  30. *cp++ = '0';
  31. } else {
  32. while (val) {
  33. *cp++ = digits[val % radix];
  34. val /= radix;
  35. }
  36. }
  37. while (cp != temp) {
  38. *buf++ = *--cp;
  39. length++;
  40. }
  41. *buf = '\0';
  42. return (length);
  43. }
  44. static int esp_rom_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
  45. {
  46. #ifdef BINARY_SUPPORT
  47. char buf[sizeof(long long)*8];
  48. int i;
  49. #else
  50. char buf[32];
  51. #endif
  52. char c, sign;
  53. const char *cp = buf;
  54. int left_prec, right_prec, zero_fill, pad, pad_on_right,
  55. islong, islonglong;
  56. long long val = 0;
  57. int res = 0, length = 0;
  58. while ((c = *fmt++) != '\0') {
  59. if (c == '%') {
  60. c = *fmt++;
  61. left_prec = right_prec = pad_on_right = islong = islonglong = 0;
  62. if (c == '-') {
  63. c = *fmt++;
  64. pad_on_right++;
  65. }
  66. if (c == '0') {
  67. zero_fill = true;
  68. c = *fmt++;
  69. } else {
  70. zero_fill = false;
  71. }
  72. while (is_digit(c)) {
  73. left_prec = (left_prec * 10) + (c - '0');
  74. c = *fmt++;
  75. }
  76. if (c == '.') {
  77. c = *fmt++;
  78. zero_fill++;
  79. while (is_digit(c)) {
  80. right_prec = (right_prec * 10) + (c - '0');
  81. c = *fmt++;
  82. }
  83. } else {
  84. right_prec = left_prec;
  85. }
  86. sign = '\0';
  87. if (c == 'l') {
  88. c = *fmt++;
  89. islong = 1;
  90. if (c == 'l') {
  91. c = *fmt++;
  92. islonglong = 1;
  93. }
  94. }
  95. switch (c) {
  96. case 'p':
  97. islong = 1;
  98. case 'd':
  99. case 'D':
  100. case 'x':
  101. case 'X':
  102. case 'u':
  103. case 'U':
  104. #ifdef BINARY_SUPPORT
  105. case 'b':
  106. case 'B':
  107. #endif
  108. if (islonglong) {
  109. val = va_arg(ap, long long);
  110. } else if (islong) {
  111. val = (long long)va_arg(ap, long);
  112. } else{
  113. val = (long long)va_arg(ap, int);
  114. }
  115. if ((c == 'd') || (c == 'D')) {
  116. if (val < 0) {
  117. sign = '-';
  118. val = -val;
  119. }
  120. } else {
  121. if (islong) {
  122. val &= (((long long)1) << (sizeof(long) * 8)) - 1;
  123. } else{
  124. val &= (((long long)1) << (sizeof(int) * 8)) - 1;
  125. }
  126. }
  127. break;
  128. default:
  129. break;
  130. }
  131. switch (c) {
  132. case 'p':
  133. (*putc)('0');
  134. (*putc)('x');
  135. zero_fill = true;
  136. left_prec = sizeof(unsigned long)*2;
  137. case 'd':
  138. case 'D':
  139. case 'u':
  140. case 'U':
  141. case 'x':
  142. case 'X':
  143. switch (c) {
  144. case 'd':
  145. case 'D':
  146. case 'u':
  147. case 'U':
  148. length = _cvt(val, buf, 10, "0123456789");
  149. break;
  150. case 'p':
  151. case 'x':
  152. length = _cvt(val, buf, 16, "0123456789abcdef");
  153. break;
  154. case 'X':
  155. length = _cvt(val, buf, 16, "0123456789ABCDEF");
  156. break;
  157. }
  158. cp = buf;
  159. break;
  160. case 's':
  161. case 'S':
  162. cp = va_arg(ap, char *);
  163. if (cp == NULL) {
  164. cp = "<null>";
  165. }
  166. length = 0;
  167. while (cp[length] != '\0') length++;
  168. break;
  169. case 'c':
  170. case 'C':
  171. c = va_arg(ap, int /*char*/);
  172. (*putc)(c);
  173. res++;
  174. continue;
  175. #ifdef BINARY_SUPPORT
  176. case 'b':
  177. case 'B':
  178. length = left_prec;
  179. if (left_prec == 0) {
  180. if (islonglong)
  181. length = sizeof(long long)*8;
  182. else if (islong)
  183. length = sizeof(long)*8;
  184. else
  185. length = sizeof(int)*8;
  186. }
  187. for (i = 0; i < length-1; i++) {
  188. buf[i] = ((val & ((long long)1<<i)) ? '1' : '.');
  189. }
  190. cp = buf;
  191. break;
  192. #endif
  193. case '%':
  194. (*putc)('%');
  195. break;
  196. default:
  197. (*putc)('%');
  198. (*putc)(c);
  199. res += 2;
  200. }
  201. pad = left_prec - length;
  202. if (sign != '\0') {
  203. pad--;
  204. }
  205. if (zero_fill) {
  206. c = '0';
  207. if (sign != '\0') {
  208. (*putc)(sign);
  209. res++;
  210. sign = '\0';
  211. }
  212. } else {
  213. c = ' ';
  214. }
  215. if (!pad_on_right) {
  216. while (pad-- > 0) {
  217. (*putc)(c);
  218. res++;
  219. }
  220. }
  221. if (sign != '\0') {
  222. (*putc)(sign);
  223. res++;
  224. }
  225. while (length-- > 0) {
  226. c = *cp++;
  227. (*putc)(c);
  228. res++;
  229. }
  230. if (pad_on_right) {
  231. while (pad-- > 0) {
  232. (*putc)(' ');
  233. res++;
  234. }
  235. }
  236. } else {
  237. (*putc)(c);
  238. res++;
  239. }
  240. }
  241. return (res);
  242. }
  243. int esp_rom_printf(const char *fmt, ...)
  244. {
  245. va_list list;
  246. va_start(list, fmt);
  247. int result = esp_rom_vprintf(s_esp_rom_putc, fmt, list);
  248. va_end(list);
  249. return result;
  250. }
  251. void esp_rom_delay_us(uint32_t us)
  252. {
  253. int sleep_result = usleep(us);
  254. assert(sleep_result == 0);
  255. (void)sleep_result; // Prevents compiler from optimizing out usleep() due to unused result. Also prevents warning.
  256. }
  257. void esp_rom_install_channel_putc(int channel, void (*putc)(char c))
  258. {
  259. if (putc != NULL) {
  260. s_esp_rom_putc = putc;
  261. }
  262. }
  263. void esp_rom_install_uart_printf(void)
  264. {
  265. // Since this is the linux implementation, we don't set any "UART" putc function, but the one which delegates to
  266. // the Linux libc version of putc.
  267. s_esp_rom_putc = call_linux_putc;
  268. }
  269. soc_reset_reason_t esp_rom_get_reset_reason(int cpu_no)
  270. {
  271. return RESET_REASON_CHIP_POWER_ON;
  272. }