| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- // Copyright 2021 Espressif Systems (Shanghai) CO LTD
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <assert.h>
- #include <unistd.h>
- #include "esp_rom_sys.h"
- static void call_linux_putc(char c);
- static void (*s_esp_rom_putc)(char c) = call_linux_putc;
- static void call_linux_putc(char c) {
- putc(c, stdout);
- }
- #define is_digit(c) ((c >= '0') && (c <= '9'))
- static int _cvt(unsigned long long val, char *buf, long radix, char *digits)
- {
- #ifdef SUPPORT_LITTLE_RADIX
- char temp[64];
- #else
- char temp[32];
- #endif
- char *cp = temp;
- int length = 0;
- if (val == 0) {
- /* Special case */
- *cp++ = '0';
- } else {
- while (val) {
- *cp++ = digits[val % radix];
- val /= radix;
- }
- }
- while (cp != temp) {
- *buf++ = *--cp;
- length++;
- }
- *buf = '\0';
- return (length);
- }
- static int esp_rom_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
- {
- #ifdef BINARY_SUPPORT
- char buf[sizeof(long long)*8];
- int i;
- #else
- char buf[32];
- #endif
- char c, sign, *cp=buf;
- int left_prec, right_prec, zero_fill, pad, pad_on_right,
- islong, islonglong;
- long long val = 0;
- int res = 0, length = 0;
- while ((c = *fmt++) != '\0') {
- if (c == '%') {
- c = *fmt++;
- left_prec = right_prec = pad_on_right = islong = islonglong = 0;
- if (c == '-') {
- c = *fmt++;
- pad_on_right++;
- }
- if (c == '0') {
- zero_fill = true;
- c = *fmt++;
- } else {
- zero_fill = false;
- }
- while (is_digit(c)) {
- left_prec = (left_prec * 10) + (c - '0');
- c = *fmt++;
- }
- if (c == '.') {
- c = *fmt++;
- zero_fill++;
- while (is_digit(c)) {
- right_prec = (right_prec * 10) + (c - '0');
- c = *fmt++;
- }
- } else {
- right_prec = left_prec;
- }
- sign = '\0';
- if (c == 'l') {
- c = *fmt++;
- islong = 1;
- if (c == 'l') {
- c = *fmt++;
- islonglong = 1;
- }
- }
- switch (c) {
- case 'p':
- islong = 1;
- case 'd':
- case 'D':
- case 'x':
- case 'X':
- case 'u':
- case 'U':
- #ifdef BINARY_SUPPORT
- case 'b':
- case 'B':
- #endif
- if (islonglong) {
- val = va_arg(ap, long long);
- } else if (islong) {
- val = (long long)va_arg(ap, long);
- } else{
- val = (long long)va_arg(ap, int);
- }
- if ((c == 'd') || (c == 'D')) {
- if (val < 0) {
- sign = '-';
- val = -val;
- }
- } else {
- if (islong) {
- val &= (((long long)1) << (sizeof(long) * 8)) - 1;
- } else{
- val &= (((long long)1) << (sizeof(int) * 8)) - 1;
- }
- }
- break;
- default:
- break;
- }
- switch (c) {
- case 'p':
- (*putc)('0');
- (*putc)('x');
- zero_fill = true;
- left_prec = sizeof(unsigned long)*2;
- case 'd':
- case 'D':
- case 'u':
- case 'U':
- case 'x':
- case 'X':
- switch (c) {
- case 'd':
- case 'D':
- case 'u':
- case 'U':
- length = _cvt(val, buf, 10, "0123456789");
- break;
- case 'p':
- case 'x':
- length = _cvt(val, buf, 16, "0123456789abcdef");
- break;
- case 'X':
- length = _cvt(val, buf, 16, "0123456789ABCDEF");
- break;
- }
- cp = buf;
- break;
- case 's':
- case 'S':
- cp = va_arg(ap, char *);
- if (cp == NULL) {
- cp = "<null>";
- }
- length = 0;
- while (cp[length] != '\0') length++;
- break;
- case 'c':
- case 'C':
- c = va_arg(ap, int /*char*/);
- (*putc)(c);
- res++;
- continue;
- #ifdef BINARY_SUPPORT
- case 'b':
- case 'B':
- length = left_prec;
- if (left_prec == 0) {
- if (islonglong)
- length = sizeof(long long)*8;
- else if (islong)
- length = sizeof(long)*8;
- else
- length = sizeof(int)*8;
- }
- for (i = 0; i < length-1; i++) {
- buf[i] = ((val & ((long long)1<<i)) ? '1' : '.');
- }
- cp = buf;
- break;
- #endif
- case '%':
- (*putc)('%');
- break;
- default:
- (*putc)('%');
- (*putc)(c);
- res += 2;
- }
- pad = left_prec - length;
- if (sign != '\0') {
- pad--;
- }
- if (zero_fill) {
- c = '0';
- if (sign != '\0') {
- (*putc)(sign);
- res++;
- sign = '\0';
- }
- } else {
- c = ' ';
- }
- if (!pad_on_right) {
- while (pad-- > 0) {
- (*putc)(c);
- res++;
- }
- }
- if (sign != '\0') {
- (*putc)(sign);
- res++;
- }
- while (length-- > 0) {
- c = *cp++;
- (*putc)(c);
- res++;
- }
- if (pad_on_right) {
- while (pad-- > 0) {
- (*putc)(' ');
- res++;
- }
- }
- } else {
- (*putc)(c);
- res++;
- }
- }
- return (res);
- }
- int esp_rom_printf(const char *fmt, ...)
- {
- va_list list;
- va_start(list, fmt);
- int result = esp_rom_vprintf(s_esp_rom_putc, fmt, list);
- va_end(list);
- return result;
- }
- void esp_rom_delay_us(uint32_t us)
- {
- int sleep_result = usleep(us);
- assert(sleep_result == 0);
- (void)sleep_result; // Prevents compiler from optimizing out usleep() due to unused result. Also prevents warning.
- }
- void esp_rom_install_channel_putc(int channel, void (*putc)(char c))
- {
- if (putc != NULL) {
- s_esp_rom_putc = putc;
- }
- }
- void esp_rom_install_uart_printf(void)
- {
- // Since this is the linux implementation, we don't set any "UART" putc function, but the one which delegates to
- // the Linux libc version of putc.
- s_esp_rom_putc = call_linux_putc;
- }
- soc_reset_reason_t esp_rom_get_reset_reason(int cpu_no)
- {
- return RESET_REASON_CHIP_POWER_ON;
- }
|