summaryrefslogtreecommitdiffhomepage
path: root/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'utilities')
-rw-r--r--utilities/fsl_debug_console.c366
-rw-r--r--utilities/fsl_debug_console.h207
-rw-r--r--utilities/fsl_debug_console_conf.h160
-rw-r--r--utilities/fsl_io.c815
-rw-r--r--utilities/fsl_io.h140
-rw-r--r--utilities/fsl_log.c587
-rw-r--r--utilities/fsl_log.h146
-rw-r--r--utilities/fsl_str.c1327
-rw-r--r--utilities/fsl_str.h92
9 files changed, 3840 insertions, 0 deletions
diff --git a/utilities/fsl_debug_console.c b/utilities/fsl_debug_console.c
new file mode 100644
index 0000000..30c762f
--- /dev/null
+++ b/utilities/fsl_debug_console.c
@@ -0,0 +1,366 @@
+/*
+ * This is a modified version of the file printf.c, which was distributed
+ * by Motorola as part of the M5407C3BOOT.zip package used to initialize
+ * the M5407C3 evaluation board.
+ *
+ * Copyright:
+ * 1999-2000 MOTOROLA, INC. All Rights Reserved.
+ * You are hereby granted a copyright license to use, modify, and
+ * distribute the SOFTWARE so long as this entire notice is
+ * retained without alteration in any modified and/or redistributed
+ * versions, and that such modified versions are clearly identified
+ * as such. No licenses are granted by implication, estoppel or
+ * otherwise under any patents or trademarks of Motorola, Inc. This
+ * software is provided on an "AS IS" basis and without warranty.
+ *
+ * To the maximum extent permitted by applicable law, MOTOROLA
+ * DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ * PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE
+ * SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY
+ * ACCOMPANYING WRITTEN MATERIALS.
+ *
+ * To the maximum extent permitted by applicable law, IN NO EVENT
+ * SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING
+ * WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
+ * INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ * LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+ *
+ * Motorola assumes no responsibility for the maintenance and support
+ * of this software
+
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#if defined(__CC_ARM)
+#include <stdio.h>
+#endif
+
+#include "fsl_debug_console.h"
+#include "fsl_debug_console_conf.h"
+#include "fsl_log.h"
+#include "fsl_str.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief This is a printf call back function which is used to relocate the log to buffer
+ * or print the log immediately when the local buffer is full.
+ *
+ * @param[in] buf Buffer to store log.
+ * @param[in] indicator Buffer index.
+ * @param[in] val Target character to store.
+ * @param[in] len length of the character
+ *
+ */
+#if SDK_DEBUGCONSOLE
+static void DbgConsole_RelocateLog(char *buf, int32_t *indicator, char val, int len);
+#endif
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Init(uint32_t baseAddr, uint32_t baudRate, uint8_t device, uint32_t clkSrcFreq)
+{
+ assert(device != DEBUG_CONSOLE_DEVICE_TYPE_NONE);
+
+ return LOG_Init(baseAddr, device, baudRate, clkSrcFreq);
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+status_t DbgConsole_Deinit(void)
+{
+ /* LOG deinit */
+ LOG_Deinit();
+
+ return kStatus_Success;
+}
+
+status_t DbgConsole_Flush(void)
+{
+ /* wait log and io idle */
+ return LOG_WaitIdle();
+}
+
+#if SDK_DEBUGCONSOLE
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Printf(const char *fmt_s, ...)
+{
+ va_list ap;
+ int logLength = 0U, result = 0U;
+ char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {0U};
+
+ va_start(ap, fmt_s);
+ /* format print log first */
+ logLength = StrFormatPrintf(fmt_s, ap, printBuf, DbgConsole_RelocateLog);
+ /* print log */
+ result = LOG_Push((uint8_t *)printBuf, logLength);
+
+ va_end(ap);
+
+ return result;
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Putchar(int ch)
+{
+ /* print char */
+ return LOG_Push((uint8_t *)&ch, 1U);
+}
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Scanf(char *fmt_ptr, ...)
+{
+ va_list ap;
+ int result;
+ char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {0U};
+
+ /* scanf log */
+ LOG_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN);
+ /* get va_list */
+ va_start(ap, fmt_ptr);
+ /* format scanf log */
+ result = StrFormatScanf(scanfBuf, fmt_ptr, ap);
+
+ va_end(ap);
+
+ return result;
+}
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+status_t DbgConsole_TryGetchar(char *ch)
+{
+ if (NULL != ch)
+ {
+ return LOG_TryReadCharacter((uint8_t *)ch);
+ }
+
+ return kStatus_Fail;
+}
+#endif
+
+/* See fsl_debug_console.h for documentation of this function. */
+int DbgConsole_Getchar(void)
+{
+ uint8_t ch;
+
+ /* Get char */
+ LOG_ReadCharacter(&ch);
+
+ return ch;
+}
+
+static void DbgConsole_RelocateLog(char *buf, int32_t *indicator, char val, int len)
+{
+ int i = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ if ((*indicator + 1) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN)
+ {
+ LOG_Push((uint8_t *)buf, *indicator);
+ *indicator = 0U;
+ }
+
+ buf[*indicator] = val;
+ (*indicator)++;
+ }
+}
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*************Code to support toolchain's printf, scanf *******************************/
+/* These function __write and __read is used to support IAR toolchain to printf and scanf*/
+#if (defined(__ICCARM__))
+#if defined(SDK_DEBUGCONSOLE_UART)
+#pragma weak __write
+size_t __write(int handle, const unsigned char *buffer, size_t size)
+{
+ if (buffer == 0)
+ {
+ /*
+ * This means that we should flush internal buffers. Since we don't we just return.
+ * (Remember, "handle" == -1 means that all handles should be flushed.)
+ */
+ return 0;
+ }
+
+ /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+ if ((handle != 1) && (handle != 2))
+ {
+ return ((size_t)-1);
+ }
+
+ /* Send data. */
+ LOG_Push((uint8_t *)buffer, 1U);
+
+ return size;
+}
+
+#pragma weak __read
+size_t __read(int handle, unsigned char *buffer, size_t size)
+{
+ /* This function only reads from "standard in", for all other file handles it returns failure. */
+ if (handle != 0)
+ {
+ return ((size_t)-1);
+ }
+
+ /* Receive data.*/
+ LOG_ReadLine(buffer, size);
+
+ return size;
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+
+/* support LPC Xpresso with RedLib */
+#elif(defined(__REDLIB__))
+
+#if (!SDK_DEBUGCONSOLE) && (defined(SDK_DEBUGCONSOLE_UART))
+int __attribute__((weak)) __sys_write(int handle, char *buffer, int size)
+{
+ if (buffer == 0)
+ {
+ /* return -1 if error. */
+ return -1;
+ }
+
+ /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+ if ((handle != 1) && (handle != 2))
+ {
+ return -1;
+ }
+
+ /* Send data. */
+ LOG_Push((uint8_t *)buffer, size);
+
+ return 0;
+}
+
+int __attribute__((weak)) __sys_readc(void)
+{
+ char tmp;
+
+ /* Receive data. */
+ LOG_ReadCharacter((uint8_t *)&tmp);
+
+ return tmp;
+}
+#endif
+
+/* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/
+#elif(defined(__GNUC__))
+
+#if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \
+ (defined(__MCUXPRESSO) && (!SDK_DEBUGCONSOLE) && (defined(SDK_DEBUGCONSOLE_UART))))
+
+int __attribute__((weak)) _write(int handle, char *buffer, int size)
+{
+ if (buffer == 0)
+ {
+ /* return -1 if error. */
+ return -1;
+ }
+
+ /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
+ if ((handle != 1) && (handle != 2))
+ {
+ return -1;
+ }
+
+ /* Send data. */
+ LOG_Push((uint8_t *)buffer, size);
+
+ return size;
+}
+
+int __attribute__((weak)) _read(int handle, char *buffer, int size)
+{
+ /* This function only reads from "standard in", for all other file handles it returns failure. */
+ if (handle != 0)
+ {
+ return -1;
+ }
+
+ /* Receive data. */
+ return LOG_ReadLine((uint8_t *)buffer, size);
+}
+#endif
+
+/* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/
+#elif defined(__CC_ARM)
+#if defined(SDK_DEBUGCONSOLE_UART)
+struct __FILE
+{
+ int handle;
+ /*
+ * Whatever you require here. If the only file you are using is standard output using printf() for debugging,
+ * no file handling is required.
+ */
+};
+
+/* FILE is typedef in stdio.h. */
+#pragma weak __stdout
+#pragma weak __stdin
+FILE __stdout;
+FILE __stdin;
+
+#pragma weak fputc
+int fputc(int ch, FILE *f)
+{
+ /* Send data. */
+ return LOG_Push((uint8_t *)(&ch), 1);
+}
+
+#pragma weak fgetc
+int fgetc(FILE *f)
+{
+ char ch;
+
+ /* Receive data. */
+ LOG_ReadCharacter((uint8_t *)&ch);
+
+ return ch;
+}
+#endif /* SDK_DEBUGCONSOLE_UART */
+#endif /* __ICCARM__ */
diff --git a/utilities/fsl_debug_console.h b/utilities/fsl_debug_console.h
new file mode 100644
index 0000000..14dd3a0
--- /dev/null
+++ b/utilities/fsl_debug_console.h
@@ -0,0 +1,207 @@
+/*
+ * The Clear BSD License
+ * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Debug console shall provide input and output functions to scan and print formatted data.
+ * o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier"
+ * - [flags] :'-', '+', '#', ' ', '0'
+ * - [width]: number (0,1...)
+ * - [.precision]: number (0,1...)
+ * - [length]: do not support
+ * - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n'
+ * o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier"
+ * - [*]: is supported.
+ * - [width]: number (0,1...)
+ * - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t')
+ * - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's'
+ */
+
+#ifndef _FSL_DEBUGCONSOLE_H_
+#define _FSL_DEBUGCONSOLE_H_
+
+#include "fsl_common.h"
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Definition to select sdk or toolchain printf, scanf. */
+#ifndef SDK_DEBUGCONSOLE
+#define SDK_DEBUGCONSOLE 1U
+#endif
+
+/*! @brief Definition to select redirect toolchain printf, scanf to uart or not. */
+#ifndef SDK_DEBUGCONSOLE_UART
+/* mcux will handle this macro, not define it here */
+#if (!defined(__MCUXPRESSO))
+#define SDK_DEBUGCONSOLE_UART
+#endif
+#endif
+
+#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE)
+#include <stdio.h>
+#endif
+
+#if SDK_DEBUGCONSOLE /* Select printf, scanf, putchar, getchar of SDK version. */
+#define PRINTF DbgConsole_Printf
+#define SCANF DbgConsole_Scanf
+#define PUTCHAR DbgConsole_Putchar
+#define GETCHAR DbgConsole_Getchar
+#else /* Select printf, scanf, putchar, getchar of toolchain. */
+#define PRINTF printf
+#define SCANF scanf
+#define PUTCHAR putchar
+#define GETCHAR getchar
+#endif /* SDK_DEBUGCONSOLE */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*! @name Initialization*/
+/* @{ */
+
+/*!
+ * @brief Initializes the peripheral used for debug messages.
+ *
+ * Call this function to enable debug log messages to be output via the specified peripheral,
+ * frequency of peripheral source clock, and base address at the specified baud rate.
+ * After this function has returned, stdout and stdin are connected to the selected peripheral.
+ *
+ * @param baseAddr Indicates the address of the peripheral used to send debug messages.
+ * @param baudRate The desired baud rate in bits per second.
+ * @param device Low level device type for the debug console, can be one of the following.
+ * @arg DEBUG_CONSOLE_DEVICE_TYPE_UART,
+ * @arg DEBUG_CONSOLE_DEVICE_TYPE_LPUART,
+ * @arg DEBUG_CONSOLE_DEVICE_TYPE_LPSCI,
+ * @arg DEBUG_CONSOLE_DEVICE_TYPE_USBCDC.
+ * @param clkSrcFreq Frequency of peripheral source clock.
+ *
+ * @return Indicates whether initialization was successful or not.
+ * @retval kStatus_Success Execution successfully
+ * @retval kStatus_Fail Execution failure
+ * @retval kStatus_InvalidArgument Invalid argument existed
+ */
+status_t DbgConsole_Init(uint32_t baseAddr, uint32_t baudRate, uint8_t device, uint32_t clkSrcFreq);
+
+/*!
+ * @brief De-initializes the peripheral used for debug messages.
+ *
+ * Call this function to disable debug log messages to be output via the specified peripheral
+ * base address and at the specified baud rate.
+ *
+ * @return Indicates whether de-initialization was successful or not.
+ */
+status_t DbgConsole_Deinit(void);
+
+#if SDK_DEBUGCONSOLE
+/*!
+ * @brief Writes formatted output to the standard output stream.
+ *
+ * Call this function to write a formatted output to the standard output stream.
+ *
+ * @param fmt_s Format control string.
+ * @return Returns the number of characters printed or a negative value if an error occurs.
+ */
+int DbgConsole_Printf(const char *fmt_s, ...);
+
+/*!
+ * @brief Writes a character to stdout.
+ *
+ * Call this function to write a character to stdout.
+ *
+ * @param ch Character to be written.
+ * @return Returns the character written.
+ */
+int DbgConsole_Putchar(int ch);
+
+/*!
+ * @brief Reads formatted data from the standard input stream.
+ *
+ * Call this function to read formatted data from the standard input stream.
+ *
+ * @param fmt_ptr Format control string.
+ * @return Returns the number of fields successfully converted and assigned.
+ */
+int DbgConsole_Scanf(char *fmt_ptr, ...);
+
+/*!
+ * @brief Reads a character from standard input.
+ *
+ * Call this function to read a character from standard input.
+ *
+ * @return Returns the character read.
+ */
+int DbgConsole_Getchar(void);
+
+/*!
+ * @brief Debug console flush log.
+ *
+ * Call this function to wait the buffer empty and io idle before.
+ * If interrupt transfer is using, make sure the global IRQ is enable before call this function
+ * This function should be called when
+ * 1, before enter power down mode
+ * 2, log is required to print to terminal immediately
+ * @return Indicates whether wait idle was successful or not.
+ */
+status_t DbgConsole_Flush(void);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief Debug console try to get char
+ * This function provide a api which will not block current task, if character is
+ * avaliable return it , otherwise return fail.
+ * @param ch the address of char to receive
+ * @return Indicates get char was successful or not.
+ */
+status_t DbgConsole_TryGetchar(char *ch);
+#endif
+
+#endif /* SDK_DEBUGCONSOLE */
+
+/*! @} */
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_DEBUGCONSOLE_H_ */
diff --git a/utilities/fsl_debug_console_conf.h b/utilities/fsl_debug_console_conf.h
new file mode 100644
index 0000000..7dfad42
--- /dev/null
+++ b/utilities/fsl_debug_console_conf.h
@@ -0,0 +1,160 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _FSL_DEBUG_CONSOLE_CONF_H_
+#define _FSL_DEBUG_CONSOLE_CONF_H_
+
+/****************Debug console configuration********************/
+
+/*! @brief If Non-blocking mode is needed, please define it at project setting,
+* otherwise blocking mode is the default transfer mode.
+* Warning: If you want to use non-blocking transfer,please make sure the corresponding
+* IO interrupt is enable, otherwise there is no output.
+* And non-blocking is combine with buffer, no matter bare-metal or rtos.
+*/
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief define the transmit buffer length which is used to store the multi task log, buffer is enabled automatically
+* when
+* non-blocking transfer is using,
+* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+* If it is configured too small, log maybe missed , because the log will not be
+* buffered if the buffer is full, and the print will return immediately with -1.
+* And this value should be multiple of 4 to meet memory alignment.
+*
+*/
+#ifndef DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN
+#define DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN (512U)
+#endif /* DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN */
+
+/*! @brief define the receive buffer length which is used to store the user input, buffer is enabled automatically when
+* non-blocking transfer is using,
+* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
+* If it is configured too small, log maybe missed, because buffer will be overwrited if buffer is too small.
+* And this value should be multiple of 4 to meet memory alignment.
+*
+*/
+#ifndef DEBUG_CONSOLE_RECEIVE_BUFFER_LEN
+#define DEBUG_CONSOLE_RECEIVE_BUFFER_LEN (512U)
+#endif /* DEBUG_CONSOLE_RECEIVE_BUFFER_LEN */
+
+#else
+#define DEBUG_CONSOLE_TRANSFER_BLOCKING
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*!@ brief define the MAX log length debug console support , that is when you call printf("log", x);, the log
+* length can not bigger than this value.
+* This macro decide the local log buffer length, the buffer locate at stack, the stack maybe overflow if
+* the buffer is too big and current task stack size not big enough.
+*/
+#ifndef DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN (128U)
+#endif /* DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN */
+
+/*!@ brief define the buffer support buffer scanf log length, that is when you call scanf("log", &x);, the log
+* length can not bigger than this value.
+* As same as the DEBUG_CONSOLE_BUFFER_PRINTF_MAX_LOG_LEN.
+*/
+#ifndef DEBUG_CONSOLE_SCANF_MAX_LOG_LEN
+#define DEBUG_CONSOLE_SCANF_MAX_LOG_LEN (20U)
+#endif /* DEBUG_CONSOLE_SCANF_MAX_LOG_LEN */
+
+/*! @brief Debug console synchronization
+* User should not change these macro for synchronization mode, but add the
+* corresponding synchronization mechanism per different software environment.
+* Such as, if another RTOS is used,
+* add:
+* #define DEBUG_CONSOLE_SYNCHRONIZATION_XXXX 3
+* in this configuration file and implement the synchronization in fsl.log.c.
+*/
+/*! @brief synchronization for baremetal software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_BM 0
+/*! @brief synchronization for freertos software */
+#define DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS 1
+
+/*! @brief RTOS synchronization mechanism disable
+* If not defined, default is enable, to avoid multitask log print mess.
+* If other RTOS is used, you can implement the RTOS's specific synchronization mechanism in fsl.log.c
+* If synchronization is disabled, log maybe messed on terminal.
+*/
+#ifndef DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#ifdef FSL_RTOS_FREE_RTOS
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* FSL_RTOS_FREE_RTOS */
+#else
+#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION */
+
+/*! @brief echo function support
+* If you want to use the echo function,please define DEBUG_CONSOLE_ENABLE_ECHO
+* at your project setting.
+*/
+#ifndef DEBUG_CONSOLE_ENABLE_ECHO
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 0
+#else
+#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 1
+#endif /* DEBUG_CONSOLE_ENABLE_ECHO */
+
+/*********************************************************************/
+
+/***************Debug console other configuration*********************/
+/*! @brief Definition to printf the float number. */
+#ifndef PRINTF_FLOAT_ENABLE
+#define PRINTF_FLOAT_ENABLE 0U
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*! @brief Definition to scanf the float number. */
+#ifndef SCANF_FLOAT_ENABLE
+#define SCANF_FLOAT_ENABLE 0U
+#endif /* SCANF_FLOAT_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for printf. */
+#ifndef PRINTF_ADVANCED_ENABLE
+#define PRINTF_ADVANCED_ENABLE 0U
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Definition to support advanced format specifier for scanf. */
+#ifndef SCANF_ADVANCED_ENABLE
+#define SCANF_ADVANCED_ENABLE 0U
+#endif /* SCANF_ADVANCED_ENABLE */
+
+/*! @brief Definition to select virtual com(USB CDC) as the debug console. */
+#ifndef BOARD_USE_VIRTUALCOM
+#define BOARD_USE_VIRTUALCOM 0U
+#endif
+/*******************************************************************/
+
+#endif /* _FSL_DEBUG_CONSOLE_CONF_H_ */
diff --git a/utilities/fsl_io.c b/utilities/fsl_io.c
new file mode 100644
index 0000000..4345641
--- /dev/null
+++ b/utilities/fsl_io.c
@@ -0,0 +1,815 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "fsl_io.h"
+#include "fsl_debug_console_conf.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* check avaliable device */
+#if (defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT != 0))
+#define DEBUG_CONSOLE_IO_UART
+#endif
+
+#if (defined(FSL_FEATURE_SOC_IUART_COUNT) && (FSL_FEATURE_SOC_IUART_COUNT != 0))
+#define DEBUG_CONSOLE_IO_IUART
+#endif
+
+#if (defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT != 0))
+#define DEBUG_CONSOLE_IO_LPUART
+#endif
+
+#if (defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT != 0))
+#define DEBUG_CONSOLE_IO_LPSCI
+#endif
+
+#if ((defined(FSL_FEATURE_SOC_USB_COUNT) && (FSL_FEATURE_SOC_USB_COUNT != 0)) && \
+ (defined(BOARD_USE_VIRTUALCOM) && (BOARD_USE_VIRTUALCOM != 0)))
+#define DEBUG_CONSOLE_IO_USBCDC
+#endif
+
+#if (defined(FSL_FEATURE_SOC_FLEXCOMM_COUNT) && (FSL_FEATURE_SOC_FLEXCOMM_COUNT != 0))
+#define DEBUG_CONSOLE_IO_FLEXCOMM
+#endif
+
+#if (defined(FSL_FEATURE_SOC_VFIFO_COUNT) && (FSL_FEATURE_SOC_VFIFO_COUNT != 0))
+#define DEBUG_CONSOLE_IO_VUSART
+#endif
+
+/* If none of above io is supported, enable the swo for debug console, or swo can be enabled by define
+ * DEBUG_CONSOLE_IO_SWO directly */
+#if (!defined(DEBUG_CONSOLE_IO_SWO) && !defined(DEBUG_CONSOLE_IO_UART) && !defined(DEBUG_CONSOLE_IO_IUART) && \
+!defined(DEBUG_CONSOLE_IO_LPUART) && \
+ !defined(DEBUG_CONSOLE_IO_LPSCI) && !defined(DEBUG_CONSOLE_IO_USBCDC) && \
+!defined(DEBUG_CONSOLE_IO_FLEXCOMM) && \
+ !defined(DEBUG_CONSOLE_IO_VUSART))
+#define DEBUG_CONSOLE_IO_SWO
+#endif
+
+/* configuration for debug console device */
+/* If new device is required as the low level device for debug console,
+ * Add the #elif branch and add the preprocessor macro to judge whether
+ * this kind of device exist in this SOC. */
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+#include "fsl_uart.h"
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static uart_handle_t s_ioUartHandler;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART */
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+#include "fsl_lpuart.h"
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static lpuart_handle_t s_ioLpuartHandler;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* DEBUG_CONSOLE_IO_LPUART */
+
+#if defined DEBUG_CONSOLE_IO_LPSCI
+#include "fsl_lpsci.h"
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static lpsci_handle_t s_ioLpsciHandler;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* DEBUG_CONSOLE_IO_LPSCI */
+
+#if defined DEBUG_CONSOLE_IO_USBCDC
+#include "usb_device_config.h"
+#include "usb.h"
+#include "usb_device_cdc_acm.h"
+#include "usb_device_ch9.h"
+#include "virtual_com.h"
+#endif /* DEBUG_CONSOLE_IO_USBCDC */
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+#include "fsl_usart.h"
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static usart_handle_t s_ioUsartHandler;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+#endif /* defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART */
+
+#if defined DEBUG_CONSOLE_IO_SWO
+#include "fsl_swo.h"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Debug console IO state information. */
+static io_state_t s_debugConsoleIO = {
+ .ioBase = NULL,
+ .ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE,
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ .callBack = NULL,
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+};
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+static void UART_Callback(UART_Type *base, uart_handle_t *handle, status_t status, void *userData)
+{
+ bool tx = false, rx = false;
+ size_t size = 0U;
+
+ if (status == kStatus_UART_RxIdle)
+ {
+ rx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ if (status == kStatus_UART_TxIdle)
+ {
+ tx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ /* inform the buffer layer that transfer is complete */
+ if (s_debugConsoleIO.callBack != NULL)
+ {
+ /* call buffer callback function */
+ s_debugConsoleIO.callBack(&size, rx, tx);
+ }
+}
+#endif /* defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART */
+
+#if defined DEBUG_CONSOLE_IO_LPSCI
+static void LPSCI_Callback(UART0_Type *base, lpsci_handle_t *handle, status_t status, void *userData)
+{
+ bool tx = false, rx = false;
+ size_t size = 0U;
+
+ if (status == kStatus_LPSCI_RxIdle)
+ {
+ rx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ if (status == kStatus_LPSCI_TxIdle)
+ {
+ tx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ /* inform the buffer layer that transfer is complete */
+ if (s_debugConsoleIO.callBack != NULL)
+ {
+ /* call buffer callback function */
+ s_debugConsoleIO.callBack(&size, rx, tx);
+ }
+}
+#endif /* DEBUG_CONSOLE_IO_LPSCI */
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+static void LPUART_Callback(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData)
+{
+ bool tx = false, rx = false;
+ size_t size = 0U;
+
+ if (status == kStatus_LPUART_RxIdle)
+ {
+ rx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ if (status == kStatus_LPUART_TxIdle)
+ {
+ tx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ /* inform the buffer layer that transfer is complete */
+ if (s_debugConsoleIO.callBack != NULL)
+ {
+ /* call buffer callback function */
+ s_debugConsoleIO.callBack(&size, rx, tx);
+ }
+}
+#endif /* DEBUG_CONSOLE_IO_LPUART */
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+static void USART_Callback(USART_Type *base, usart_handle_t *handle, status_t status, void *userData)
+{
+ bool tx = false, rx = false;
+ size_t size = 0U;
+
+ if (status == kStatus_USART_RxIdle)
+ {
+ rx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ if (status == kStatus_USART_TxIdle)
+ {
+ tx = true;
+ size = handle->txDataSizeAll;
+ }
+
+ /* inform the buffer layer that transfer is complete */
+ if (s_debugConsoleIO.callBack != NULL)
+ {
+ /* call buffer callback function */
+ s_debugConsoleIO.callBack(&size, rx, tx);
+ }
+}
+#endif /* defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART */
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+void IO_Init(io_state_t *io, uint32_t baudRate, uint32_t clkSrcFreq, uint8_t *ringBuffer)
+{
+ assert(NULL != io);
+
+ /* record device type/base */
+ s_debugConsoleIO.ioType = io->ioType;
+ s_debugConsoleIO.ioBase = (void *)(io->ioBase);
+
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+ {
+ uart_config_t uart_config;
+ UART_GetDefaultConfig(&uart_config);
+ uart_config.baudRate_Bps = baudRate;
+ /* Enable clock and initial UART module follow user configure structure. */
+ UART_Init((UART_Type *)s_debugConsoleIO.ioBase, &uart_config, clkSrcFreq);
+ UART_EnableTx(s_debugConsoleIO.ioBase, true);
+ UART_EnableRx(s_debugConsoleIO.ioBase, true);
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ s_debugConsoleIO.callBack = io->callBack;
+ /* create handler for interrupt transfer */
+ UART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUartHandler, UART_Callback, NULL);
+ /* start ring buffer */
+ UART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUartHandler, ringBuffer,
+ DEBUG_CONSOLE_RECEIVE_BUFFER_LEN);
+#endif
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+ {
+ lpuart_config_t lpuart_config;
+ LPUART_GetDefaultConfig(&lpuart_config);
+ lpuart_config.baudRate_Bps = baudRate;
+ /* Enable clock and initial UART module follow user configure structure. */
+ LPUART_Init((LPUART_Type *)s_debugConsoleIO.ioBase, &lpuart_config, clkSrcFreq);
+ LPUART_EnableTx(s_debugConsoleIO.ioBase, true);
+ LPUART_EnableRx(s_debugConsoleIO.ioBase, true);
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ s_debugConsoleIO.callBack = io->callBack;
+ /* create handler for interrupt transfer */
+ LPUART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, LPUART_Callback, NULL);
+ /* start ring buffer */
+ LPUART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, ringBuffer,
+ DEBUG_CONSOLE_RECEIVE_BUFFER_LEN);
+#endif
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+ {
+ lpsci_config_t lpsci_config;
+ LPSCI_GetDefaultConfig(&lpsci_config);
+ lpsci_config.baudRate_Bps = baudRate;
+ /* Enable clock and initial UART module follow user configure structure. */
+ LPSCI_Init((UART0_Type *)s_debugConsoleIO.ioBase, &lpsci_config, clkSrcFreq);
+ LPSCI_EnableTx(s_debugConsoleIO.ioBase, true);
+ LPSCI_EnableRx(s_debugConsoleIO.ioBase, true);
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ s_debugConsoleIO.callBack = io->callBack;
+ /* create handler for interrupt transfer */
+ LPSCI_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, LPSCI_Callback, NULL);
+ /* start ring buffer */
+ LPSCI_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, ringBuffer,
+ DEBUG_CONSOLE_RECEIVE_BUFFER_LEN);
+#endif
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_USBCDC
+ case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC:
+ {
+ s_debugConsoleIO.ioBase = USB_VcomInit();
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_FLEXCOMM
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ {
+ usart_config_t usart_config;
+ USART_GetDefaultConfig(&usart_config);
+ usart_config.baudRate_Bps = baudRate;
+ /* Enable clock and initial UART module follow user configure structure. */
+ USART_Init((USART_Type *)s_debugConsoleIO.ioBase, &usart_config, clkSrcFreq);
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ s_debugConsoleIO.callBack = io->callBack;
+ /* create handler for interrupt transfer */
+ USART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUsartHandler, USART_Callback, NULL);
+ /* start ring buffer */
+ USART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler, ringBuffer,
+ DEBUG_CONSOLE_RECEIVE_BUFFER_LEN);
+#endif
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_VUSART
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+ {
+ usart_config_t usart_config;
+ USART_GetDefaultConfig(&usart_config);
+ usart_config.baudRate_Bps = baudRate;
+ usart_config.enableRx = true;
+ usart_config.enableTx = true;
+ /* Enable rx fifo for user's continously input */
+ usart_config.fifoConfig.enableRxFifo = true;
+ usart_config.fifoConfig.rxFifoSize = 8;
+ /* Enable clock and initial UART module follow user configure structure. */
+ USART_Init((USART_Type *)s_debugConsoleIO.ioBase, &usart_config, clkSrcFreq);
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ s_debugConsoleIO.callBack = io->callBack;
+ /* create handler for interrupt transfer */
+ USART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUsartHandler, USART_Callback, NULL);
+ /* start ring buffer */
+ USART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler, ringBuffer,
+ DEBUG_CONSOLE_RECEIVE_BUFFER_LEN);
+#endif
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_SWO
+ case DEBUG_CONSOLE_DEVICE_TYPE_SWO:
+ SWO_Init((uint32_t)s_debugConsoleIO.ioBase, baudRate, clkSrcFreq);
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+status_t IO_Deinit(void)
+{
+ if (s_debugConsoleIO.ioType == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
+ {
+ return kStatus_Success;
+ }
+
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* stop ring buffer */
+ UART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioUartHandler);
+#endif
+ /* Disable UART module. */
+ UART_Deinit((UART_Type *)s_debugConsoleIO.ioBase);
+
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* stop ring buffer */
+ LPSCI_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpsciHandler);
+#endif
+ /* Disable LPSCI module. */
+ LPSCI_Deinit((UART0_Type *)s_debugConsoleIO.ioBase);
+
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* stop ring buffer */
+ LPUART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpuartHandler);
+#endif
+ /* Disable LPUART module. */
+ LPUART_Deinit((LPUART_Type *)s_debugConsoleIO.ioBase);
+
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_USBCDC
+ case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC:
+ /* Disable USBCDC module. */
+ USB_VcomDeinit(s_debugConsoleIO.ioBase);
+ break;
+#endif
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* stop ring buffer */
+ USART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler);
+#endif
+ /* deinit IO */
+ USART_Deinit((USART_Type *)s_debugConsoleIO.ioBase);
+
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_SWO
+
+ case DEBUG_CONSOLE_DEVICE_TYPE_SWO:
+ SWO_Deinit((uint32_t)s_debugConsoleIO.ioBase);
+ break;
+#endif
+ default:
+ s_debugConsoleIO.ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE;
+ break;
+ }
+
+ s_debugConsoleIO.ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE;
+
+ return kStatus_Success;
+}
+
+status_t IO_WaitIdle(void)
+{
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ /* wait transfer complete flag */
+ while (!(UART_GetStatusFlags(s_debugConsoleIO.ioBase) & kUART_TransmissionCompleteFlag))
+ {
+ }
+
+ break;
+#endif
+
+#if (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+ /* wait transfer complete flag */
+ while (!(UART_GetStatusFlag(s_debugConsoleIO.ioBase, kUART_TxCompleteFlag)))
+ {
+ }
+
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+ /* wait transfer complete flag */
+ while (!(LPSCI_GetStatusFlags(s_debugConsoleIO.ioBase) & kLPSCI_TransmissionCompleteFlag))
+ {
+ }
+
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+ /* wait transfer complete flag */
+ while (!(LPUART_GetStatusFlags(s_debugConsoleIO.ioBase) & kLPUART_TransmissionCompleteFlag))
+ {
+ }
+ break;
+#endif
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+ /* wait transfer complete flag */
+ while (!(USART_GetStatusFlags(s_debugConsoleIO.ioBase) & kUSART_TxFifoEmptyFlag))
+ {
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return kStatus_Success;
+}
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+
+status_t IO_Transfer(uint8_t *ch, size_t size, bool tx)
+{
+ status_t status = kStatus_Fail;
+
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+ {
+ uart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ /* transfer data */
+ if (tx)
+ {
+ status = UART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer);
+ }
+ else
+ {
+ status = UART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+ {
+ lpsci_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ /* transfer data */
+ if (tx)
+ {
+ status = LPSCI_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer);
+ }
+ else
+ {
+ status = LPSCI_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+ {
+ lpuart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ /* transfer data */
+ if (tx)
+ {
+ status = LPUART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer);
+ }
+ else
+ {
+ status =
+ LPUART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_USBCDC
+ case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC:
+ {
+ if (tx)
+ {
+ USB_VcomWriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ USB_VcomReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+ {
+ usart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ /* transfer data */
+ if (tx)
+ {
+ status = USART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer);
+ }
+ else
+ {
+ status = USART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_SWO
+ case DEBUG_CONSOLE_DEVICE_TYPE_SWO:
+ status = SWO_SendBlocking((uint32_t)s_debugConsoleIO.ioBase, ch, size);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return status;
+}
+
+status_t IO_TryReceiveCharacter(uint8_t *ch)
+{
+ status_t status = kStatus_Fail;
+ uint32_t size = 1U;
+
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+ {
+ uart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ if (UART_TransferGetRxRingBufferLength(&s_ioUartHandler) >= size)
+ {
+ /* transfer data */
+ status = UART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+ {
+ lpsci_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ if (LPSCI_TransferGetRxRingBufferLength(&s_ioLpsciHandler) >= size)
+ {
+ /* transfer data */
+ status = LPSCI_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+ {
+ lpuart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ if (LPUART_TransferGetRxRingBufferLength(s_debugConsoleIO.ioBase, &s_ioLpuartHandler) >= size)
+ {
+ /* transfer data */
+ status =
+ LPUART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_USBCDC
+ case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC:
+ break;
+#endif
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+ {
+ usart_transfer_t transfer = {0U};
+ transfer.data = ch;
+ transfer.dataSize = size;
+ if (USART_TransferGetRxRingBufferLength(&s_ioUsartHandler) >= size)
+ {
+ /* transfer data */
+ status = USART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer, NULL);
+ }
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return status;
+}
+
+#else
+
+status_t IO_Transfer(uint8_t *ch, size_t size, bool tx)
+{
+ status_t status = kStatus_Success;
+ switch (s_debugConsoleIO.ioType)
+ {
+#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_UART:
+ case DEBUG_CONSOLE_DEVICE_TYPE_IUART:
+ {
+ if (tx)
+ {
+ UART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ status = UART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+#if defined DEBUG_CONSOLE_IO_LPSCI
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
+ {
+ if (tx)
+ {
+ LPSCI_WriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ status = LPSCI_ReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_LPUART
+ case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
+ {
+ if (tx)
+ {
+ LPUART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ status = LPUART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_USBCDC
+ case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC:
+ {
+ if (tx)
+ {
+ USB_VcomWriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ status = USB_VcomReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+
+#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART)
+ case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM:
+ case DEBUG_CONSOLE_DEVICE_TYPE_VUSART:
+ {
+ if (tx)
+ {
+ USART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ else
+ {
+ status = USART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size);
+ }
+ }
+ break;
+#endif
+
+#if defined DEBUG_CONSOLE_IO_SWO
+ case DEBUG_CONSOLE_DEVICE_TYPE_SWO:
+ status = SWO_SendBlocking((uint32_t)s_debugConsoleIO.ioBase, ch, size);
+ break;
+#endif
+ default:
+ status = kStatus_Fail;
+ break;
+ }
+
+ return status;
+}
+
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
diff --git a/utilities/fsl_io.h b/utilities/fsl_io.h
new file mode 100644
index 0000000..396f66c
--- /dev/null
+++ b/utilities/fsl_io.h
@@ -0,0 +1,140 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _FSL_IO_H
+#define _FSL_IO_H
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief define a notify callback for IO
+* @param size , transfer data size.
+* @param rx, indicate a rx transfer is success.
+* @param tx, indicate a tx transfer is success.
+*/
+typedef void (*notify)(size_t *size, bool rx, bool tx);
+
+/*! @brief State structure storing io. */
+typedef struct io_State
+{
+ void *ioBase; /*!< Base of the IP register. */
+ uint8_t ioType; /*!< device type */
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ notify callBack; /*!< define the callback function for buffer */
+#endif
+
+} io_state_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @brief io init function.
+ *
+ * Call this function to init IO.
+ *
+ * @param io configuration pointer
+ * @param baudRate baud rate
+ * @param clkSrcFreq clock freq
+ * @param ringbuffer used to receive character
+ */
+void IO_Init(io_state_t *io, uint32_t baudRate, uint32_t clkSrcFreq, uint8_t *ringBuffer);
+
+/*!
+ * @brief Deinit IO.
+ *
+ * Call this function to Deinit IO.
+ *
+ * @return deinit status
+ */
+status_t IO_Deinit(void);
+
+/*!
+ * @brief io transfer function.
+ *
+ * Call this function to transfer log.
+ * Print log:
+ * @code
+ * IO_Transfer(ch, size, true);
+ * @endcode
+ * Scanf log:
+ * @code
+ * IO_Transfer(ch, size, false);
+ * @endcode
+ *
+ * @param ch transfer buffer pointer
+ * @param size transfer size
+ * @param tx indicate the transfer is TX or RX
+ */
+status_t IO_Transfer(uint8_t *ch, size_t size, bool tx);
+
+/*!
+ * @brief io wait idle.
+ *
+ * Call this function to wait the io idle
+ *
+ * @return Indicates whether wait idle was successful or not.
+ */
+status_t IO_WaitIdle(void);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief io try to receive one character.
+ *
+ * Call this function try to receive character
+ * @param ch the address of char to receive
+ * @return Indicates try getchar was successful or not.
+ */
+status_t IO_TryReceiveCharacter(uint8_t *ch);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_IO_H */
diff --git a/utilities/fsl_log.c b/utilities/fsl_log.c
new file mode 100644
index 0000000..e36832d
--- /dev/null
+++ b/utilities/fsl_log.c
@@ -0,0 +1,587 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "fsl_log.h"
+#include "fsl_debug_console_conf.h"
+#include "fsl_io.h"
+#ifdef FSL_RTOS_FREE_RTOS
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+#endif
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#ifndef BACKSPACE
+/*! @brief character backspace ASCII value */
+#define BACKSPACE 127
+#endif
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief increase pop member */
+#define LOG_CHECK_BUFFER_INDEX_OVERFLOW(index) \
+ { \
+ if (index >= DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN) \
+ { \
+ index -= DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN; \
+ } \
+ \
+\
+}
+
+/*! @brief get current runing environment is ISR or not */
+#ifdef __CA7_REV
+#define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel()
+#else
+#define IS_RUNNING_IN_ISR() __get_IPSR()
+#endif /* __CA7_REV */
+
+#else
+#define IS_RUNNING_IN_ISR() (0U)
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/* define for rtos */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+/* metex semaphore */
+#define LOG_CREATE_MUTEX_SEMAPHORE(mutex) (mutex = xSemaphoreCreateMutex())
+
+#define LOG_GIVE_MUTEX_SEMAPHORE(mutex) \
+ \
+{ \
+ if (IS_RUNNING_IN_ISR() == 0U) \
+ { \
+ xSemaphoreGive(mutex); \
+ } \
+ \
+}
+
+#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \
+ \
+{ \
+ if (IS_RUNNING_IN_ISR() == 0U) \
+ { \
+ xSemaphoreTake(mutex, portMAX_DELAY); \
+ } \
+ \
+}
+
+#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \
+ \
+{ \
+ if (IS_RUNNING_IN_ISR() == 0U) \
+ { \
+ result = xSemaphoreTake(mutex, 0U); \
+ } \
+ else \
+ { \
+ result = 1U; \
+ } \
+ \
+}
+
+/* Binary semaphore */
+#define LOG_CREATE_BINARY_SEMAPHORE(binary) (binary = xSemaphoreCreateBinary())
+#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) (xSemaphoreTake(binary, portMAX_DELAY))
+#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (xSemaphoreGiveFromISR(binary, NULL))
+
+#elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM)
+
+#define LOG_CREATE_MUTEX_SEMAPHORE(mutex)
+#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex)
+#define LOG_GIVE_MUTEX_SEMAPHORE(mutex)
+#define LOG_CREATE_BINARY_SEMAPHORE(binary)
+#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U)
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \
+ \
+{ \
+ while (!binary) \
+ ; \
+ binary = false; \
+ \
+\
+}
+#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (binary = true)
+#else
+#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary)
+#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary)
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/* add other implementation here
+*such as :
+* #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_xxx)
+*/
+
+#else
+
+#define LOG_CREATE_MUTEX_SEMAPHORE(mutex)
+#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex)
+#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U)
+#define LOG_GIVE_MUTEX_SEMAPHORE(mutex)
+#define LOG_CREATE_BINARY_SEMAPHORE(binary)
+#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary)
+#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*! @brief Define the buffer
+* The total buffer size should be calucate as (BUFFER_SUPPORT_LOG_LENGTH + 1) * BUFFER_SUPPORT_LOG_NUM * 4
+*/
+typedef struct _log_buffer
+{
+ volatile uint16_t totalIndex; /*!< indicate the total usage of the buffer */
+ volatile uint16_t pushIndex; /*!< indicate the next push index */
+ volatile uint16_t popIndex; /*!< indicate the pop index */
+ uint8_t txBuf[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN]; /*!< buffer to store printf log */
+
+ uint8_t rxBuf[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN]; /*!< buffer to store scanf log */
+} log_buffer_t;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/* A global log buffer */
+static log_buffer_t s_log_buffer;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/* lock definition */
+#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS)
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static SemaphoreHandle_t s_logPushSemaphore = NULL;
+static SemaphoreHandle_t s_logReadSemaphore = NULL;
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+static SemaphoreHandle_t s_logPopSemaphore = NULL;
+static SemaphoreHandle_t s_logReadWaitSemaphore = NULL;
+
+#elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM)
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+
+static volatile bool s_logReadWaitSemaphore = false; /* transferred event from ISR for bare-metal + interrupt */
+
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+#else
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*******************************************************************************
+* Prototypes
+******************************************************************************/
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief callback function for IO layer to notify LOG
+ *
+ * @param size last transfer data size
+ * @param receive indicate a RX transfer
+ * @param transmit indicate a TX transfer
+ *
+ */
+static void LOG_Transferred(size_t *size, bool receive, bool transmit);
+
+/*!
+ * @brief log push function
+ *
+ * @param buf target buffer
+ * @param size log size
+ *
+ */
+static int LOG_BufPush(uint8_t *buf, size_t size);
+
+/*!
+ * @brief Get next avaliable log
+ *
+ * @param next avaliable size
+ * @return next avaliable address
+ */
+static uint8_t *LOG_BufGetNextAvaliableLog(size_t *size);
+
+/*!
+ * @brief buf pop
+ *
+ * @param size log size popped and next available log size
+ * @return next avaliable address
+ */
+static uint8_t *LOG_BufPop(size_t *size);
+
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+/*!
+ * @brief read one character
+ *
+ * @param ch character address
+ * @return indicate the read status
+ *
+ */
+static status_t LOG_ReadOneCharacter(uint8_t *ch);
+
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+/*!
+ * @brief echo one character
+ *
+ * @param ch character address
+ * @param isGetchar flag to distinguish getchar from scanf
+ * @param index special for scanf to support backspace
+ * @return indicate the read status
+ *
+ */
+static status_t LOG_EchoCharacter(uint8_t *ch, bool isGetChar, int *index);
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+status_t LOG_Init(uint32_t baseAddr, uint8_t device, uint32_t baudRate, uint32_t clkSrcFreq)
+{
+ io_state_t io;
+ /* init io */
+ io.ioBase = (void *)baseAddr;
+ io.ioType = device;
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* memset the global queue */
+ memset(&s_log_buffer, 0U, sizeof(s_log_buffer));
+ /* init callback for NON-BLOCKING */
+ io.callBack = LOG_Transferred;
+ /* io init function */
+ IO_Init(&io, baudRate, clkSrcFreq, s_log_buffer.rxBuf);
+ /* Debug console buffer push lock create */
+ LOG_CREATE_MUTEX_SEMAPHORE(s_logPushSemaphore);
+ /* Debug console get/scanf mutex lock create */
+ LOG_CREATE_MUTEX_SEMAPHORE(s_logReadSemaphore);
+#else
+ IO_Init(&io, baudRate, clkSrcFreq, NULL);
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+ /* Debug console lock create */
+ LOG_CREATE_MUTEX_SEMAPHORE(s_logPopSemaphore);
+ LOG_CREATE_BINARY_SEMAPHORE(s_logReadWaitSemaphore);
+
+ return kStatus_Success;
+}
+
+void LOG_Deinit(void)
+{
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* memset the global queue */
+ memset(&s_log_buffer, 0U, sizeof(s_log_buffer));
+#endif /*DEBUG_CONSOLE_TRANSFER_NON_BLOCKING*/
+ /* Deinit IO */
+ IO_Deinit();
+}
+
+status_t LOG_WaitIdle(void)
+{
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* wait buffer empty */
+ while (!(s_log_buffer.totalIndex == 0U))
+ ;
+#endif /*DEBUG_CONSOLE_TRANSFER_NON_BLOCKING*/
+ /* wait IO idle */
+ IO_WaitIdle();
+
+ return kStatus_Success;
+}
+
+int LOG_Push(uint8_t *buf, size_t size)
+{
+ assert(buf != NULL);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+ /* push to buffer */
+ LOG_BufPush(buf, size);
+ buf = LOG_BufGetNextAvaliableLog(&size);
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+ /* pop log */
+ return LOG_Pop(buf, size);
+}
+
+int LOG_Pop(uint8_t *buf, size_t size)
+{
+ uint8_t getLock = 0U;
+
+ if ((0 != size) && (NULL != buf))
+ {
+ /* take POP lock, should be non-blocking */
+ LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(s_logPopSemaphore, getLock);
+
+ if (getLock)
+ {
+ /* call IO transfer function */
+ if (IO_Transfer(buf, size, true) != kStatus_Success)
+ {
+ size = 0U;
+ }
+ /* release POP lock */
+ LOG_GIVE_MUTEX_SEMAPHORE(s_logPopSemaphore);
+ }
+ }
+
+ return size;
+}
+
+int LOG_ReadLine(uint8_t *buf, size_t size)
+{
+ assert(buf != NULL);
+
+ int i = 0;
+
+ /* take mutex lock function */
+ LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logReadSemaphore);
+
+ for (i = 0; i < size; i++)
+ {
+ /* recieve one char every time */
+ if (LOG_ReadOneCharacter(&buf[i]) != kStatus_Success)
+ {
+ return -1;
+ }
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+ LOG_EchoCharacter(&buf[i], false, &i);
+#endif
+ /* analysis data */
+ if ((buf[i] == '\r') || (buf[i] == '\n'))
+ {
+ /* End of Line. */
+ if (i == 0)
+ {
+ buf[i] = '\0';
+ i = -1;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ /* get char should not add '\0'*/
+ if (i == size)
+ {
+ buf[i] = '\0';
+ }
+ else
+ {
+ buf[i + 1] = '\0';
+ }
+
+ /* release mutex lock function */
+ LOG_GIVE_MUTEX_SEMAPHORE(s_logReadSemaphore);
+
+ return i;
+}
+
+int LOG_ReadCharacter(uint8_t *ch)
+{
+ assert(ch != NULL);
+ int ret = 0;
+
+ /* take mutex lock function */
+ LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logReadSemaphore);
+ /* read one character */
+ if (LOG_ReadOneCharacter(ch) == kStatus_Success)
+ {
+ ret = 1;
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+ LOG_EchoCharacter(ch, true, NULL);
+#endif
+ }
+ else
+ {
+ ret = -1;
+ }
+
+ /* release mutex lock function */
+ LOG_GIVE_MUTEX_SEMAPHORE(s_logReadSemaphore);
+
+ return ret;
+}
+
+static status_t LOG_ReadOneCharacter(uint8_t *ch)
+{
+ /* recieve one char every time */
+ if (IO_Transfer(ch, 1U, false) != kStatus_Success)
+ {
+ return kStatus_Fail;
+ }
+
+ /* wait release from ISR */
+ LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(s_logReadWaitSemaphore);
+
+ return kStatus_Success;
+}
+
+#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION
+static status_t LOG_EchoCharacter(uint8_t *ch, bool isGetChar, int *index)
+{
+ /* Due to scanf take \n and \r as end of string,should not echo */
+ if (((*ch != '\r') && (*ch != '\n')) || (isGetChar))
+ {
+ /* recieve one char every time */
+ if (IO_Transfer(ch, 1U, true) != kStatus_Success)
+ {
+ return kStatus_Fail;
+ }
+ }
+
+ if (!isGetChar)
+ {
+ if ((*index > 0) && (*ch == BACKSPACE))
+ {
+ *index -= 2;
+ }
+ }
+
+ return kStatus_Success;
+}
+#endif
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+static int LOG_BufPush(uint8_t *buf, size_t size)
+{
+ uint32_t pushIndex = 0U, i = 0U;
+ bool pushAvaliable = false;
+
+ /* take mutex lock function */
+ LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logPushSemaphore);
+ if (size <= (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - s_log_buffer.totalIndex))
+ {
+ /* get push index */
+ pushIndex = s_log_buffer.pushIndex;
+ s_log_buffer.pushIndex += size;
+ /* check index overflow */
+ LOG_CHECK_BUFFER_INDEX_OVERFLOW(s_log_buffer.pushIndex);
+ /* update push/total index value */
+ s_log_buffer.totalIndex += size;
+ pushAvaliable = true;
+ }
+ /* release mutex lock function */
+ LOG_GIVE_MUTEX_SEMAPHORE(s_logPushSemaphore);
+
+ /* check the buffer if have enough space to store the log */
+ if (pushAvaliable)
+ {
+ for (i = size; i > 0; i--)
+ {
+ /* copy log to buffer, the buffer only support a fixed length argument, if the log argument
+ is longer than the fixed length, the left argument will be losed */
+ s_log_buffer.txBuf[pushIndex] = *buf++;
+ /* increase index */
+ pushIndex++;
+ /* check index overflow */
+ LOG_CHECK_BUFFER_INDEX_OVERFLOW(pushIndex);
+ }
+ }
+ else
+ {
+ size = 0U;
+ }
+
+ return size;
+}
+
+static uint8_t *LOG_BufGetNextAvaliableLog(size_t *size)
+{
+ uint16_t popIndex = s_log_buffer.popIndex;
+
+ /* get avaliable size */
+ if (s_log_buffer.totalIndex > (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - popIndex))
+ {
+ *size = (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - popIndex);
+ }
+ else
+ {
+ *size = s_log_buffer.totalIndex;
+ }
+
+ /* return address */
+ return (&(s_log_buffer.txBuf[popIndex]));
+}
+
+static uint8_t *LOG_BufPop(size_t *size)
+{
+ if (s_log_buffer.totalIndex >= *size)
+ {
+ /* decrease the log total member */
+ s_log_buffer.totalIndex -= *size;
+ /* there is more log in the queue to be pushed */
+ if (s_log_buffer.totalIndex > 0U)
+ {
+ /* update the pop index */
+ s_log_buffer.popIndex += *size;
+ /* check index overflow */
+ LOG_CHECK_BUFFER_INDEX_OVERFLOW(s_log_buffer.popIndex);
+
+ return LOG_BufGetNextAvaliableLog(size);
+ }
+ else
+ {
+ /* reset push and pop */
+ s_log_buffer.popIndex = 0U;
+ s_log_buffer.pushIndex = 0U;
+ *size = 0U;
+ }
+ }
+
+ return NULL;
+}
+
+static void LOG_Transferred(size_t *size, bool receive, bool transmit)
+{
+ uint8_t *addr = NULL;
+
+ if (transmit)
+ {
+ addr = LOG_BufPop(size);
+ /* continue pop log from buffer */
+ LOG_Pop(addr, *size);
+ }
+
+ if (receive)
+ {
+ /* release from ISR */
+ LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_logReadWaitSemaphore);
+ }
+}
+#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+status_t LOG_TryReadCharacter(uint8_t *ch)
+{
+ if (NULL != ch)
+ {
+ return IO_TryReceiveCharacter(ch);
+ }
+ return kStatus_Fail;
+}
+#endif
diff --git a/utilities/fsl_log.h b/utilities/fsl_log.h
new file mode 100644
index 0000000..87f4c8a
--- /dev/null
+++ b/utilities/fsl_log.h
@@ -0,0 +1,146 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _FSL_LOG_H
+#define _FSL_LOG_H
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*************************************************************************************************
+ * Prototypes
+ ************************************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @brief Initializes
+ *
+ * Call this function to init the buffer
+ * @param baseAddr, device base address
+ * @param device, device type
+ * @param baudRate, device communicate baudrate
+ * @param clkSrcFreq, device source clock freq
+ *
+ * @return Indicates whether initialization was successful or not.
+ * @retval kStatus_Success Execution successfully
+ * @retval kStatus_Fail Execution failure
+ */
+status_t LOG_Init(uint32_t baseAddr, uint8_t device, uint32_t baudRate, uint32_t clkSrcFreq);
+
+/*!
+ * @brief De-Initializes
+ *
+ * Call this function to deinit the buffer
+ *
+ * @return Indicates whether Deinit was successful or not.
+ */
+void LOG_Deinit(void);
+
+/*!
+ * @brief log push interface
+ *
+ * Call this function to print log
+ * @param fmt, buffer pointer
+ * @param size, avaliable size
+ * @return indicate the push size
+ * @retval-1 indicate buffer is full or transfer fail.
+ * @retval size return the push log size.
+ */
+int LOG_Push(uint8_t *buf, size_t size);
+
+/*!
+ * @brief log read one line function
+ *
+ * Call this function to print log
+ * @param fmt, buffer pointer
+ * @param size, avaliable size
+ * @reutrn the number of the recieved character
+ */
+int LOG_ReadLine(uint8_t *buf, size_t size);
+
+/*!
+ * @brief log read one character function
+ *
+ * Call this function to GETCHAR
+ * @param ch receive address
+ * @reutrn the number of the recieved character
+ */
+int LOG_ReadCharacter(uint8_t *ch);
+
+/*!
+ * @brief wait log and io idle
+ *
+ * Call this function to wait log buffer empty and io idle before enter low power mode.
+ * @return Indicates whether wait idle was successful or not.
+ */
+status_t LOG_WaitIdle(void);
+
+#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
+/*!
+ * @brief log try read one character
+ * Call this function to check character avaliable or not, if not return fail, otherwise return it.
+ * @param ch the address of char to receive
+ * @return Indicates try getchar was successful or not.
+ */
+status_t LOG_TryReadCharacter(uint8_t *ch);
+#endif
+
+/*!
+ * @brief log pop function
+ *
+ * Call this function to pop log from buffer.
+ * @param buf buffer address to pop
+ * @param size log size to pop
+ * @return pop log size.
+ */
+int LOG_Pop(uint8_t *buf, size_t size);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif
diff --git a/utilities/fsl_str.c b/utilities/fsl_str.c
new file mode 100644
index 0000000..d34e41a
--- /dev/null
+++ b/utilities/fsl_str.c
@@ -0,0 +1,1327 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <math.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "fsl_str.h"
+#include "fsl_debug_console_conf.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief The overflow value.*/
+#ifndef HUGE_VAL
+#define HUGE_VAL (99.e99)
+#endif /* HUGE_VAL */
+
+#if SCANF_FLOAT_ENABLE
+static double fnum = 0.0;
+#endif /* SCANF_FLOAT_ENABLE */
+
+#if PRINTF_ADVANCED_ENABLE
+/*! @brief Specification modifier flags for printf. */
+enum _debugconsole_printf_flag
+{
+ kPRINTF_Minus = 0x01U, /*!< Minus FLag. */
+ kPRINTF_Plus = 0x02U, /*!< Plus Flag. */
+ kPRINTF_Space = 0x04U, /*!< Space Flag. */
+ kPRINTF_Zero = 0x08U, /*!< Zero Flag. */
+ kPRINTF_Pound = 0x10U, /*!< Pound Flag. */
+ kPRINTF_LengthChar = 0x20U, /*!< Length: Char Flag. */
+ kPRINTF_LengthShortInt = 0x40U, /*!< Length: Short Int Flag. */
+ kPRINTF_LengthLongInt = 0x80U, /*!< Length: Long Int Flag. */
+ kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */
+};
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+/*! @brief Specification modifier flags for scanf. */
+enum _debugconsole_scanf_flag
+{
+ kSCANF_Suppress = 0x2U, /*!< Suppress Flag. */
+ kSCANF_DestMask = 0x7cU, /*!< Destination Mask. */
+ kSCANF_DestChar = 0x4U, /*!< Destination Char Flag. */
+ kSCANF_DestString = 0x8U, /*!< Destination String FLag. */
+ kSCANF_DestSet = 0x10U, /*!< Destination Set Flag. */
+ kSCANF_DestInt = 0x20U, /*!< Destination Int Flag. */
+ kSCANF_DestFloat = 0x30U, /*!< Destination Float Flag. */
+ kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */
+#if SCANF_ADVANCED_ENABLE
+ kSCANF_LengthChar = 0x100U, /*!< Length Char Flag. */
+ kSCANF_LengthShortInt = 0x200U, /*!< Length ShortInt Flag. */
+ kSCANF_LengthLongInt = 0x400U, /*!< Length LongInt Flag. */
+ kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */
+#endif /* SCANF_ADVANCED_ENABLE */
+#if PRINTF_FLOAT_ENABLE
+ kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */
+#endif /*PRINTF_FLOAT_ENABLE */
+ kSCANF_TypeSinged = 0x2000U, /*!< TypeSinged Flag. */
+};
+
+/*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
+#if defined(__CC_ARM)
+#pragma diag_suppress 1256
+#endif /* __CC_ARM */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Scanline function which ignores white spaces.
+ *
+ * @param[in] s The address of the string pointer to update.
+ * @return String without white spaces.
+ */
+static uint32_t ScanIgnoreWhiteSpace(const char **s);
+
+/*!
+ * @brief Converts a radix number to a string and return its length.
+ *
+ * @param[in] numstr Converted string of the number.
+ * @param[in] nump Pointer to the number.
+ * @param[in] neg Polarity of the number.
+ * @param[in] radix The radix to be converted to.
+ * @param[in] use_caps Used to identify %x/X output format.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps);
+
+#if PRINTF_FLOAT_ENABLE
+/*!
+ * @brief Converts a floating radix number to a string and return its length.
+ *
+ * @param[in] numstr Converted string of the number.
+ * @param[in] nump Pointer to the number.
+ * @param[in] radix The radix to be converted to.
+ * @param[in] precision_width Specify the precision width.
+
+ * @return Length of the converted string.
+ */
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width);
+#endif /* PRINTF_FLOAT_ENABLE */
+
+/*!
+*
+ */
+double modf(double input_dbl, double *intpart_ptr);
+
+/*************Code for process formatted data*******************************/
+
+static uint32_t ScanIgnoreWhiteSpace(const char **s)
+{
+ uint8_t count = 0;
+ uint8_t c;
+
+ c = **s;
+ while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f'))
+ {
+ count++;
+ (*s)++;
+ c = **s;
+ }
+ return count;
+}
+
+static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
+{
+#if PRINTF_ADVANCED_ENABLE
+ int64_t a;
+ int64_t b;
+ int64_t c;
+
+ uint64_t ua;
+ uint64_t ub;
+ uint64_t uc;
+#else
+ int32_t a;
+ int32_t b;
+ int32_t c;
+
+ uint32_t ua;
+ uint32_t ub;
+ uint32_t uc;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+ int32_t nlen;
+ char *nstrp;
+
+ nlen = 0;
+ nstrp = numstr;
+ *nstrp++ = '\0';
+
+ if (neg)
+ {
+#if PRINTF_ADVANCED_ENABLE
+ a = *(int64_t *)nump;
+#else
+ a = *(int32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+ if (a == 0)
+ {
+ *nstrp = '0';
+ ++nlen;
+ return nlen;
+ }
+ while (a != 0)
+ {
+#if PRINTF_ADVANCED_ENABLE
+ b = (int64_t)a / (int64_t)radix;
+ c = (int64_t)a - ((int64_t)b * (int64_t)radix);
+ if (c < 0)
+ {
+ uc = (uint64_t)c;
+ c = (int64_t)(~uc) + 1 + '0';
+ }
+#else
+ b = a / radix;
+ c = a - (b * radix);
+ if (c < 0)
+ {
+ uc = (uint32_t)c;
+ c = (uint32_t)(~uc) + 1 + '0';
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ else
+ {
+ c = c + '0';
+ }
+ a = b;
+ *nstrp++ = (char)c;
+ ++nlen;
+ }
+ }
+ else
+ {
+#if PRINTF_ADVANCED_ENABLE
+ ua = *(uint64_t *)nump;
+#else
+ ua = *(uint32_t *)nump;
+#endif /* PRINTF_ADVANCED_ENABLE */
+ if (ua == 0)
+ {
+ *nstrp = '0';
+ ++nlen;
+ return nlen;
+ }
+ while (ua != 0)
+ {
+#if PRINTF_ADVANCED_ENABLE
+ ub = (uint64_t)ua / (uint64_t)radix;
+ uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix);
+#else
+ ub = ua / (uint32_t)radix;
+ uc = ua - (ub * (uint32_t)radix);
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+ if (uc < 10)
+ {
+ uc = uc + '0';
+ }
+ else
+ {
+ uc = uc - 10 + (use_caps ? 'A' : 'a');
+ }
+ ua = ub;
+ *nstrp++ = (char)uc;
+ ++nlen;
+ }
+ }
+ return nlen;
+}
+
+#if PRINTF_FLOAT_ENABLE
+static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width)
+{
+ int32_t a;
+ int32_t b;
+ int32_t c;
+ int32_t i;
+ uint32_t uc;
+ double fa;
+ double dc;
+ double fb;
+ double r;
+ double fractpart;
+ double intpart;
+
+ int32_t nlen;
+ char *nstrp;
+ nlen = 0;
+ nstrp = numstr;
+ *nstrp++ = '\0';
+ r = *(double *)nump;
+ if (!r)
+ {
+ *nstrp = '0';
+ ++nlen;
+ return nlen;
+ }
+ fractpart = modf((double)r, (double *)&intpart);
+ /* Process fractional part. */
+ for (i = 0; i < precision_width; i++)
+ {
+ fractpart *= radix;
+ }
+ if (r >= 0)
+ {
+ fa = fractpart + (double)0.5;
+ if (fa >= pow(10, precision_width))
+ {
+ intpart++;
+ }
+ }
+ else
+ {
+ fa = fractpart - (double)0.5;
+ if (fa <= -pow(10, precision_width))
+ {
+ intpart--;
+ }
+ }
+ for (i = 0; i < precision_width; i++)
+ {
+ fb = fa / (int32_t)radix;
+ dc = (fa - (int64_t)fb * (int32_t)radix);
+ c = (int32_t)dc;
+ if (c < 0)
+ {
+ uc = (uint32_t)c;
+ c = (int32_t)(~uc) + 1 + '0';
+ }
+ else
+ {
+ c = c + '0';
+ }
+ fa = fb;
+ *nstrp++ = (char)c;
+ ++nlen;
+ }
+ *nstrp++ = (char)'.';
+ ++nlen;
+ a = (int32_t)intpart;
+ if (a == 0)
+ {
+ *nstrp++ = '0';
+ ++nlen;
+ }
+ else
+ {
+ while (a != 0)
+ {
+ b = (int32_t)a / (int32_t)radix;
+ c = (int32_t)a - ((int32_t)b * (int32_t)radix);
+ if (c < 0)
+ {
+ uc = (uint32_t)c;
+ c = (int32_t)(~uc) + 1 + '0';
+ }
+ else
+ {
+ c = c + '0';
+ }
+ a = b;
+ *nstrp++ = (char)c;
+ ++nlen;
+ }
+ }
+ return nlen;
+}
+#endif /* PRINTF_FLOAT_ENABLE */
+
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
+{
+ /* va_list ap; */
+ char *p;
+ int32_t c;
+
+ char vstr[33];
+ char *vstrp = NULL;
+ int32_t vlen = 0;
+
+ int32_t done;
+ int32_t count = 0;
+
+ uint32_t field_width;
+ uint32_t precision_width;
+ char *sval;
+ int32_t cval;
+ bool use_caps;
+ uint8_t radix = 0;
+
+#if PRINTF_ADVANCED_ENABLE
+ uint32_t flags_used;
+ int32_t schar, dschar;
+ int64_t ival;
+ uint64_t uval = 0;
+ bool valid_precision_width;
+#else
+ int32_t ival;
+ uint32_t uval = 0;
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_FLOAT_ENABLE
+ double fval;
+#endif /* PRINTF_FLOAT_ENABLE */
+
+ /* Start parsing apart the format string and display appropriate formats and data. */
+ for (p = (char *)fmt; (c = *p) != 0; p++)
+ {
+ /*
+ * All formats begin with a '%' marker. Special chars like
+ * '\n' or '\t' are normally converted to the appropriate
+ * character by the __compiler__. Thus, no need for this
+ * routine to account for the '\' character.
+ */
+ if (c != '%')
+ {
+ cb(buf, &count, c, 1);
+ /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
+ continue;
+ }
+
+ use_caps = true;
+
+#if PRINTF_ADVANCED_ENABLE
+ /* First check for specification modifier flags. */
+ flags_used = 0;
+ done = false;
+ while (!done)
+ {
+ switch (*++p)
+ {
+ case '-':
+ flags_used |= kPRINTF_Minus;
+ break;
+ case '+':
+ flags_used |= kPRINTF_Plus;
+ break;
+ case ' ':
+ flags_used |= kPRINTF_Space;
+ break;
+ case '0':
+ flags_used |= kPRINTF_Zero;
+ break;
+ case '#':
+ flags_used |= kPRINTF_Pound;
+ break;
+ default:
+ /* We've gone one char too far. */
+ --p;
+ done = true;
+ break;
+ }
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+ /* Next check for minimum field width. */
+ field_width = 0;
+ done = false;
+ while (!done)
+ {
+ c = *++p;
+ if ((c >= '0') && (c <= '9'))
+ {
+ field_width = (field_width * 10) + (c - '0');
+ }
+#if PRINTF_ADVANCED_ENABLE
+ else if (c == '*')
+ {
+ field_width = (uint32_t)va_arg(ap, uint32_t);
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ else
+ {
+ /* We've gone one char too far. */
+ --p;
+ done = true;
+ }
+ }
+ /* Next check for the width and precision field separator. */
+ precision_width = 6;
+#if PRINTF_ADVANCED_ENABLE
+ valid_precision_width = false;
+#endif /* PRINTF_ADVANCED_ENABLE */
+ if (*++p == '.')
+ {
+ /* Must get precision field width, if present. */
+ precision_width = 0;
+ done = false;
+ while (!done)
+ {
+ c = *++p;
+ if ((c >= '0') && (c <= '9'))
+ {
+ precision_width = (precision_width * 10) + (c - '0');
+#if PRINTF_ADVANCED_ENABLE
+ valid_precision_width = true;
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+#if PRINTF_ADVANCED_ENABLE
+ else if (c == '*')
+ {
+ precision_width = (uint32_t)va_arg(ap, uint32_t);
+ valid_precision_width = true;
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ else
+ {
+ /* We've gone one char too far. */
+ --p;
+ done = true;
+ }
+ }
+ }
+ else
+ {
+ /* We've gone one char too far. */
+ --p;
+ }
+#if PRINTF_ADVANCED_ENABLE
+ /*
+ * Check for the length modifier.
+ */
+ switch (/* c = */ *++p)
+ {
+ case 'h':
+ if (*++p != 'h')
+ {
+ flags_used |= kPRINTF_LengthShortInt;
+ --p;
+ }
+ else
+ {
+ flags_used |= kPRINTF_LengthChar;
+ }
+ break;
+ case 'l':
+ if (*++p != 'l')
+ {
+ flags_used |= kPRINTF_LengthLongInt;
+ --p;
+ }
+ else
+ {
+ flags_used |= kPRINTF_LengthLongLongInt;
+ }
+ break;
+ default:
+ /* we've gone one char too far */
+ --p;
+ break;
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ /* Now we're ready to examine the format. */
+ c = *++p;
+ {
+ if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') ||
+ (c == 'b') || (c == 'p') || (c == 'u'))
+ {
+ if ((c == 'd') || (c == 'i'))
+ {
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_LengthLongLongInt)
+ {
+ ival = (int64_t)va_arg(ap, int64_t);
+ }
+ else
+#endif /* PRINTF_ADVANCED_ENABLE */
+ {
+ ival = (int32_t)va_arg(ap, int32_t);
+ }
+ vlen = ConvertRadixNumToString(vstr, &ival, true, 10, use_caps);
+ vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+ if (ival < 0)
+ {
+ schar = '-';
+ ++vlen;
+ }
+ else
+ {
+ if (flags_used & kPRINTF_Plus)
+ {
+ schar = '+';
+ ++vlen;
+ }
+ else
+ {
+ if (flags_used & kPRINTF_Space)
+ {
+ schar = ' ';
+ ++vlen;
+ }
+ else
+ {
+ schar = 0;
+ }
+ }
+ }
+ dschar = false;
+ /* Do the ZERO pad. */
+ if (flags_used & kPRINTF_Zero)
+ {
+ if (schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+ dschar = true;
+
+ cb(buf, &count, '0', field_width - vlen);
+ vlen = field_width;
+ }
+ else
+ {
+ if (!(flags_used & kPRINTF_Minus))
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ if (schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+ dschar = true;
+ }
+ }
+ /* The string was built in reverse order, now display in correct order. */
+ if ((!dschar) && schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+
+#if PRINTF_FLOAT_ENABLE
+ if ((c == 'f') || (c == 'F'))
+ {
+ fval = (double)va_arg(ap, double);
+ vlen = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
+ vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+ if (fval < 0)
+ {
+ schar = '-';
+ ++vlen;
+ }
+ else
+ {
+ if (flags_used & kPRINTF_Plus)
+ {
+ schar = '+';
+ ++vlen;
+ }
+ else
+ {
+ if (flags_used & kPRINTF_Space)
+ {
+ schar = ' ';
+ ++vlen;
+ }
+ else
+ {
+ schar = 0;
+ }
+ }
+ }
+ dschar = false;
+ if (flags_used & kPRINTF_Zero)
+ {
+ if (schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+ dschar = true;
+ cb(buf, &count, '0', field_width - vlen);
+ vlen = field_width;
+ }
+ else
+ {
+ if (!(flags_used & kPRINTF_Minus))
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ if (schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+ dschar = true;
+ }
+ }
+ if ((!dschar) && schar)
+ {
+ cb(buf, &count, schar, 1);
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+#endif /* PRINTF_FLOAT_ENABLE */
+ if ((c == 'X') || (c == 'x'))
+ {
+ if (c == 'x')
+ {
+ use_caps = false;
+ }
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_LengthLongLongInt)
+ {
+ uval = (uint64_t)va_arg(ap, uint64_t);
+ }
+ else
+#endif /* PRINTF_ADVANCED_ENABLE */
+ {
+ uval = (uint32_t)va_arg(ap, uint32_t);
+ }
+ vlen = ConvertRadixNumToString(vstr, &uval, false, 16, use_caps);
+ vstrp = &vstr[vlen];
+
+#if PRINTF_ADVANCED_ENABLE
+ dschar = false;
+ if (flags_used & kPRINTF_Zero)
+ {
+ if (flags_used & kPRINTF_Pound)
+ {
+ cb(buf, &count, '0', 1);
+ cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+ dschar = true;
+ }
+ cb(buf, &count, '0', field_width - vlen);
+ vlen = field_width;
+ }
+ else
+ {
+ if (!(flags_used & kPRINTF_Minus))
+ {
+ if (flags_used & kPRINTF_Pound)
+ {
+ vlen += 2;
+ }
+ cb(buf, &count, ' ', field_width - vlen);
+ if (flags_used & kPRINTF_Pound)
+ {
+ cb(buf, &count, '0', 1);
+ cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+ dschar = true;
+ }
+ }
+ }
+
+ if ((flags_used & kPRINTF_Pound) && (!dschar))
+ {
+ cb(buf, &count, '0', 1);
+ cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
+ vlen += 2;
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+ if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
+ {
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_LengthLongLongInt)
+ {
+ uval = (uint64_t)va_arg(ap, uint64_t);
+ }
+ else
+#endif /* PRINTF_ADVANCED_ENABLE */
+ {
+ uval = (uint32_t)va_arg(ap, uint32_t);
+ }
+
+ if (c == 'o')
+ {
+ radix = 8;
+ }
+ else if (c == 'b')
+ {
+ radix = 2;
+ }
+ else if (c == 'p')
+ {
+ radix = 16;
+ }
+ else
+ {
+ radix = 10;
+ }
+
+ vlen = ConvertRadixNumToString(vstr, &uval, false, radix, use_caps);
+ vstrp = &vstr[vlen];
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_Zero)
+ {
+ cb(buf, &count, '0', field_width - vlen);
+ vlen = field_width;
+ }
+ else
+ {
+ if (!(flags_used & kPRINTF_Minus))
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ }
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+#if !PRINTF_ADVANCED_ENABLE
+ cb(buf, &count, ' ', field_width - vlen);
+#endif /* !PRINTF_ADVANCED_ENABLE */
+ if (vstrp != NULL)
+ {
+ while (*vstrp)
+ {
+ cb(buf, &count, *vstrp--, 1);
+ }
+ }
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_Minus)
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+ else if (c == 'c')
+ {
+ cval = (char)va_arg(ap, uint32_t);
+ cb(buf, &count, cval, 1);
+ }
+ else if (c == 's')
+ {
+ sval = (char *)va_arg(ap, char *);
+ if (sval)
+ {
+#if PRINTF_ADVANCED_ENABLE
+ if (valid_precision_width)
+ {
+ vlen = precision_width;
+ }
+ else
+ {
+ vlen = strlen(sval);
+ }
+#else
+ vlen = strlen(sval);
+#endif /* PRINTF_ADVANCED_ENABLE */
+#if PRINTF_ADVANCED_ENABLE
+ if (!(flags_used & kPRINTF_Minus))
+#endif /* PRINTF_ADVANCED_ENABLE */
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ }
+
+#if PRINTF_ADVANCED_ENABLE
+ if (valid_precision_width)
+ {
+ while ((*sval) && (vlen > 0))
+ {
+ cb(buf, &count, *sval++, 1);
+ vlen--;
+ }
+ /* In case that vlen sval is shorter than vlen */
+ vlen = precision_width - vlen;
+ }
+ else
+ {
+#endif /* PRINTF_ADVANCED_ENABLE */
+ while (*sval)
+ {
+ cb(buf, &count, *sval++, 1);
+ }
+#if PRINTF_ADVANCED_ENABLE
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+
+#if PRINTF_ADVANCED_ENABLE
+ if (flags_used & kPRINTF_Minus)
+ {
+ cb(buf, &count, ' ', field_width - vlen);
+ }
+#endif /* PRINTF_ADVANCED_ENABLE */
+ }
+ }
+ else
+ {
+ cb(buf, &count, c, 1);
+ }
+ }
+ }
+
+ return count;
+}
+
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
+{
+ uint8_t base;
+ int8_t neg;
+ /* Identifier for the format string. */
+ char *c = format;
+ char temp;
+ char *buf;
+ /* Flag telling the conversion specification. */
+ uint32_t flag = 0;
+ /* Filed width for the matching input streams. */
+ uint32_t field_width;
+ /* How many arguments are assigned except the suppress. */
+ uint32_t nassigned = 0;
+ /* How many characters are read from the input streams. */
+ uint32_t n_decode = 0;
+
+ int32_t val;
+
+ const char *s;
+ /* Identifier for the input string. */
+ const char *p = line_ptr;
+
+ /* Return EOF error before any conversion. */
+ if (*p == '\0')
+ {
+ return -1;
+ }
+
+ /* Decode directives. */
+ while ((*c) && (*p))
+ {
+ /* Ignore all white-spaces in the format strings. */
+ if (ScanIgnoreWhiteSpace((const char **)&c))
+ {
+ n_decode += ScanIgnoreWhiteSpace(&p);
+ }
+ else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%')))
+ {
+ /* Ordinary characters. */
+ c++;
+ if (*p == *c)
+ {
+ n_decode++;
+ p++;
+ c++;
+ }
+ else
+ {
+ /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
+ * However, it is deserted now. */
+ break;
+ }
+ }
+ else
+ {
+ /* convernsion specification */
+ c++;
+ /* Reset. */
+ flag = 0;
+ field_width = 0;
+ base = 0;
+
+ /* Loop to get full conversion specification. */
+ while ((*c) && (!(flag & kSCANF_DestMask)))
+ {
+ switch (*c)
+ {
+#if SCANF_ADVANCED_ENABLE
+ case '*':
+ if (flag & kSCANF_Suppress)
+ {
+ /* Match failure. */
+ return nassigned;
+ }
+ flag |= kSCANF_Suppress;
+ c++;
+ break;
+ case 'h':
+ if (flag & kSCANF_LengthMask)
+ {
+ /* Match failure. */
+ return nassigned;
+ }
+
+ if (c[1] == 'h')
+ {
+ flag |= kSCANF_LengthChar;
+ c++;
+ }
+ else
+ {
+ flag |= kSCANF_LengthShortInt;
+ }
+ c++;
+ break;
+ case 'l':
+ if (flag & kSCANF_LengthMask)
+ {
+ /* Match failure. */
+ return nassigned;
+ }
+
+ if (c[1] == 'l')
+ {
+ flag |= kSCANF_LengthLongLongInt;
+ c++;
+ }
+ else
+ {
+ flag |= kSCANF_LengthLongInt;
+ }
+ c++;
+ break;
+#endif /* SCANF_ADVANCED_ENABLE */
+#if SCANF_FLOAT_ENABLE
+ case 'L':
+ if (flag & kSCANF_LengthMask)
+ {
+ /* Match failure. */
+ return nassigned;
+ }
+ flag |= kSCANF_LengthLongLongDouble;
+ c++;
+ break;
+#endif /* SCANF_FLOAT_ENABLE */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (field_width)
+ {
+ /* Match failure. */
+ return nassigned;
+ }
+ do
+ {
+ field_width = field_width * 10 + *c - '0';
+ c++;
+ } while ((*c >= '0') && (*c <= '9'));
+ break;
+ case 'd':
+ base = 10;
+ flag |= kSCANF_TypeSinged;
+ flag |= kSCANF_DestInt;
+ c++;
+ break;
+ case 'u':
+ base = 10;
+ flag |= kSCANF_DestInt;
+ c++;
+ break;
+ case 'o':
+ base = 8;
+ flag |= kSCANF_DestInt;
+ c++;
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ flag |= kSCANF_DestInt;
+ c++;
+ break;
+ case 'i':
+ base = 0;
+ flag |= kSCANF_DestInt;
+ c++;
+ break;
+#if SCANF_FLOAT_ENABLE
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ flag |= kSCANF_DestFloat;
+ c++;
+ break;
+#endif /* SCANF_FLOAT_ENABLE */
+ case 'c':
+ flag |= kSCANF_DestChar;
+ if (!field_width)
+ {
+ field_width = 1;
+ }
+ c++;
+ break;
+ case 's':
+ flag |= kSCANF_DestString;
+ c++;
+ break;
+ default:
+ return nassigned;
+ }
+ }
+
+ if (!(flag & kSCANF_DestMask))
+ {
+ /* Format strings are exhausted. */
+ return nassigned;
+ }
+
+ if (!field_width)
+ {
+ /* Large than length of a line. */
+ field_width = 99;
+ }
+
+ /* Matching strings in input streams and assign to argument. */
+ switch (flag & kSCANF_DestMask)
+ {
+ case kSCANF_DestChar:
+ s = (const char *)p;
+ buf = va_arg(args_ptr, char *);
+ while ((field_width--) && (*p))
+ {
+ if (!(flag & kSCANF_Suppress))
+ {
+ *buf++ = *p++;
+ }
+ else
+ {
+ p++;
+ }
+ n_decode++;
+ }
+
+ if ((!(flag & kSCANF_Suppress)) && (s != p))
+ {
+ nassigned++;
+ }
+ break;
+ case kSCANF_DestString:
+ n_decode += ScanIgnoreWhiteSpace(&p);
+ s = p;
+ buf = va_arg(args_ptr, char *);
+ while ((field_width--) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') &&
+ (*p != '\r') && (*p != '\v') && (*p != '\f'))
+ {
+ if (flag & kSCANF_Suppress)
+ {
+ p++;
+ }
+ else
+ {
+ *buf++ = *p++;
+ }
+ n_decode++;
+ }
+
+ if ((!(flag & kSCANF_Suppress)) && (s != p))
+ {
+ /* Add NULL to end of string. */
+ *buf = '\0';
+ nassigned++;
+ }
+ break;
+ case kSCANF_DestInt:
+ n_decode += ScanIgnoreWhiteSpace(&p);
+ s = p;
+ val = 0;
+ if ((base == 0) || (base == 16))
+ {
+ if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))
+ {
+ base = 16;
+ if (field_width >= 1)
+ {
+ p += 2;
+ n_decode += 2;
+ field_width -= 2;
+ }
+ }
+ }
+
+ if (base == 0)
+ {
+ if (s[0] == '0')
+ {
+ base = 8;
+ }
+ else
+ {
+ base = 10;
+ }
+ }
+
+ neg = 1;
+ switch (*p)
+ {
+ case '-':
+ neg = -1;
+ n_decode++;
+ p++;
+ field_width--;
+ break;
+ case '+':
+ neg = 1;
+ n_decode++;
+ p++;
+ field_width--;
+ break;
+ default:
+ break;
+ }
+
+ while ((*p) && (field_width--))
+ {
+ if ((*p <= '9') && (*p >= '0'))
+ {
+ temp = *p - '0';
+ }
+ else if ((*p <= 'f') && (*p >= 'a'))
+ {
+ temp = *p - 'a' + 10;
+ }
+ else if ((*p <= 'F') && (*p >= 'A'))
+ {
+ temp = *p - 'A' + 10;
+ }
+ else
+ {
+ temp = base;
+ }
+
+ if (temp >= base)
+ {
+ break;
+ }
+ else
+ {
+ val = base * val + temp;
+ }
+ p++;
+ n_decode++;
+ }
+ val *= neg;
+ if (!(flag & kSCANF_Suppress))
+ {
+#if SCANF_ADVANCED_ENABLE
+ switch (flag & kSCANF_LengthMask)
+ {
+ case kSCANF_LengthChar:
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed char *) = (signed char)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned char *) = (unsigned char)val;
+ }
+ break;
+ case kSCANF_LengthShortInt:
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed short *) = (signed short)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned short *) = (unsigned short)val;
+ }
+ break;
+ case kSCANF_LengthLongInt:
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed long int *) = (signed long int)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val;
+ }
+ break;
+ case kSCANF_LengthLongLongInt:
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed long long int *) = (signed long long int)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val;
+ }
+ break;
+ default:
+ /* The default type is the type int. */
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed int *) = (signed int)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+ }
+ break;
+ }
+#else
+ /* The default type is the type int. */
+ if (flag & kSCANF_TypeSinged)
+ {
+ *va_arg(args_ptr, signed int *) = (signed int)val;
+ }
+ else
+ {
+ *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
+ }
+#endif /* SCANF_ADVANCED_ENABLE */
+ nassigned++;
+ }
+ break;
+#if SCANF_FLOAT_ENABLE
+ case kSCANF_DestFloat:
+ n_decode += ScanIgnoreWhiteSpace(&p);
+ fnum = strtod(p, (char **)&s);
+
+ if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL))
+ {
+ break;
+ }
+
+ n_decode += (int)(s) - (int)(p);
+ p = s;
+ if (!(flag & kSCANF_Suppress))
+ {
+ if (flag & kSCANF_LengthLongLongDouble)
+ {
+ *va_arg(args_ptr, double *) = fnum;
+ }
+ else
+ {
+ *va_arg(args_ptr, float *) = (float)fnum;
+ }
+ nassigned++;
+ }
+ break;
+#endif /* SCANF_FLOAT_ENABLE */
+ default:
+ return nassigned;
+ }
+ }
+ }
+ return nassigned;
+}
diff --git a/utilities/fsl_str.h b/utilities/fsl_str.h
new file mode 100644
index 0000000..47d835e
--- /dev/null
+++ b/utilities/fsl_str.h
@@ -0,0 +1,92 @@
+/*
+ * The Clear BSD License
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _FSL_STR_H
+#define _FSL_STR_H
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup debugconsole
+ * @{
+ */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * @brief A function pointer which is used when format printf log.
+ */
+typedef void (*printfCb)(char *buf, int32_t *indicator, char val, int len);
+
+/*!
+ * @brief This function outputs its parameters according to a formatted string.
+ *
+ * @note I/O is performed by calling given function pointer using following
+ * (*func_ptr)(c);
+ *
+ * @param[in] fmt_ptr Format string for printf.
+ * @param[in] args_ptr Arguments to printf.
+ * @param[in] buf pointer to the buffer
+ * @param cb print callbck function pointer
+ *
+ * @return Number of characters to be print
+ */
+int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb);
+
+/*!
+ * @brief Converts an input line of ASCII characters based upon a provided
+ * string format.
+ *
+ * @param[in] line_ptr The input line of ASCII data.
+ * @param[in] format Format first points to the format string.
+ * @param[in] args_ptr The list of parameters.
+ *
+ * @return Number of input items converted and assigned.
+ * @retval IO_EOF When line_ptr is empty string "".
+ */
+int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_STR_H */