blob: f1dff53c8cc1397e1871052dab6612dd3d09ee2a [file] [log] [blame]
/****************************************************************************
* arch/arm/src/phy62xx/my_printf.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "rom_sym_def.h"
#include "types.h"
#include <stdarg.h>
#include <string.h>
#include "uart.h"
#include "log.h"
#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 is_digit(c) ((c) >= '0' && (c) <= '9')
static const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
static const char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/****************************************************************************
* Private Functions
****************************************************************************/
static size_t _strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; *sc != '\0' && count--; ++sc);
return sc - s;
}
static int skip_atoi(const char** s)
{
int i = 0;
while (is_digit(**s)) i = i * 10 + *((*s)++) - '0';
return i;
}
static void number(std_putc putc, long num, int base,
int size, int precision, int type)
{
char c;
char sign;
char tmp[66];
const char *dig = digits;
int i;
char tmpch;
if (type & LARGE) dig = upper_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++] = dig[((unsigned long)num) % (unsigned)base];
num = ((unsigned long)num) / (unsigned)base;
}
}
if (i > precision) precision = i;
size -= precision;
if (!(type & (ZEROPAD | LEFT)))
{
while (size-- > 0)
{
tmpch = ' ';
putc(&tmpch, 1);
}
}
if (sign)
{
putc(&sign, 1);
}
if (type & SPECIAL)
{
if (base == 8)
{
tmpch = '0';
putc(&tmpch, 1);
}
else if (base == 16)
{
tmpch = '0';
putc(&tmpch, 1);
tmpch = digits[33];
putc(&tmpch, 1);
}
}
if (!(type & LEFT))
{
while (size-- > 0)
{
putc(&c, 1);
}
}
while (i < precision--)
{
tmpch = '0';
putc(&tmpch, 1);
}
while (i-- > 0)
{
tmpch = tmp[i];
putc(&tmpch, 1);
}
while (size-- > 0)
{
tmpch = ' ';
putc(&tmpch, 1);
}
}
static void log_vsprintf(std_putc putc, const char *fmt, va_list args)
{
int len;
unsigned long num;
int base;
char *s;
int flags; /* Flags to number() */
int field_width; /* Width of output field */
int precision; /* Min. # of digits for integers; max number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
char *tmpstr = NULL;
int tmpstr_size = 0;
char tmpch;
for (; *fmt; fmt++)
{
if (*fmt != '%')
{
if (tmpstr == NULL)
{
tmpstr = (char *)fmt;
tmpstr_size = 0;
}
tmpstr_size++;
continue;
}
else if (tmpstr_size)
{
putc(tmpstr, tmpstr_size);
tmpstr = NULL;
tmpstr_size = 0;
}
/* Process flags */
flags = 0;
repeat:
fmt++; /* This also skips first '%' */
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;
}
/* Get field width */
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;
}
}
/* Get the precision */
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;
}
/* Get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
{
qualifier = *fmt;
fmt++;
}
/* Default base */
base = 10;
switch (*fmt)
{
case 'c':
if (!(flags & LEFT))
{
while (--field_width > 0)
{
tmpch = ' ';
putc(&tmpch, 1);
}
}
tmpch = (unsigned char)va_arg(args, int);
putc(&tmpch, 1);
while (--field_width > 0)
{
tmpch = ' ';
putc(&tmpch, 1);
}
continue;
case 's':
s = va_arg(args, char *);
if (!s)
s = "<NULL>";
len = _strnlen(s, precision);
if (!(flags & LEFT))
{
while (len < field_width--)
{
tmpch = ' ';
putc(&tmpch, 1);
}
}
putc(s, len);
while (len < field_width--)
{
tmpch = ' ';
putc(&tmpch, 1);
}
continue;
case 'p':
if (field_width == -1)
{
field_width = 2 * sizeof(void *);
flags |= ZEROPAD;
}
number(putc, (unsigned long)
va_arg(args, void *), 16, field_width, precision, flags);
continue;
case 'n':
continue;
case 'A':
continue;
/* Integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
if (*fmt != '%')
{
tmpch = '%';
putc(&tmpch, 1);
}
if (*fmt)
{
tmpch = *fmt;
putc(&tmpch, 1);
}
else
{
--fmt;
}
continue;
}
if (qualifier == 'l')
num = va_arg(args, unsigned long);
else if (qualifier == 'h')
{
if (flags & SIGN)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
}
else if (flags & SIGN)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
number(putc, num, base, field_width, precision, flags);
}
if (tmpstr_size)
{
putc(tmpstr, tmpstr_size);
tmpstr = NULL;
tmpstr_size = 0;
}
}
static void _uart_putc(char *data, uint16_t size)
{
hal_uart_send_buff(UART0, (uint8_t *)data, size);
}
/****************************************************************************
* Public Functions
****************************************************************************/
void dbg_printf_(const char *format, ...)
{
va_list args;
va_start(args, format);
log_vsprintf(_uart_putc, format, args);
va_end(args);
}
void dbg_printf_init(void)
{
uart_Cfg_t cfg =
{
.tx_pin = P9,
.rx_pin = P10,
.rts_pin = GPIO_DUMMY,
.cts_pin = GPIO_DUMMY,
.baudrate = 115200,
.use_fifo = TRUE,
.hw_fwctrl = FALSE,
.use_tx_buf = FALSE,
.parity = FALSE,
.evt_handler = NULL,
};
hal_uart_init(cfg, UART0); /* uart init */
}
void my_dump_byte(uint8_t *pData, int dlen)
{
for (int i = 0; i < dlen; i++)
{
dbg_printf_("%02x ", pData[i]);
}
dbg_printf_("\n");
}