text: /*
   * 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.
   * All rights reserved.
   *
   * 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 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.
   *
   * 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 <math.h>
  #include "fsl_debug_console.h"
  #include "fsl_device_registers.h"
  
  #if defined(K66F18_SERIES)
  #undef FSL_FEATURE_SOC_LPUART_COUNT
  #define FSL_FEATURE_SOC_LPUART_COUNT 0
  #endif
  
  #if defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT > 0)
  #include "fsl_uart.h"
  #endif /* FSL_FEATURE_SOC_UART_COUNT */
  
  #if defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT > 0)
  #include "fsl_lpsci.h"
  #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
  
  #if defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT > 0)
  #include "fsl_lpuart.h"
  #endif /* FSL_FEATURE_SOC_LPUART_COUNT */
  
  /*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
  #if defined(__CC_ARM)
  #pragma diag_suppress 1256
  #endif /* __CC_ARM */
  
  /*******************************************************************************
   * Definitions
   ******************************************************************************/
  
  /*! @brief This definition is maximum line that debugconsole can scanf each time.*/
  #define IO_MAXLINE 20U
  
  /*! @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 */
  
  /*! @brief Operation functions definitions for debug console. */
  typedef struct DebugConsoleOperationFunctions
  {
      union
      {
          void (*PutChar)(void *base, const uint8_t *buffer, size_t length);
  #if defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT > 0)
          void (*UART_PutChar)(UART_Type *base, const uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_UART_COUNT */
  #if defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT > 0)
          void (*LPSCI_PutChar)(UART0_Type *base, const uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
  #if defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT > 0)
          void (*LPUART_PutChar)(LPUART_Type *base, const uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_LPUART_COUNT */
      } tx_union;
      union
      {
          void (*GetChar)(void *base, const uint8_t *buffer, size_t length);
  #if defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT > 0)
          status_t (*UART_GetChar)(UART_Type *base, uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_UART_COUNT */
  #if defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT > 0)
          status_t (*LPSCI_GetChar)(UART0_Type *base, uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
  #if defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT > 0)
          status_t (*LPUART_GetChar)(LPUART_Type *base, uint8_t *buffer, size_t length);
  #endif /* FSL_FEATURE_SOC_LPUART_COUNT */
      } rx_union;
  } debug_console_ops_t;
  
  /*! @brief State structure storing debug console. */
  typedef struct DebugConsoleState
  {
      uint8_t type;            /*!< Indicator telling whether the debug console is initialized. */
      void *base;              /*!< Base of the IP register. */
      debug_console_ops_t ops; /*!< Operation function pointers for debug UART operations. */
  } debug_console_state_t;
  
  /*! @brief Type of KSDK printf function pointer. */
  typedef int (*PUTCHAR_FUNC)(int a);
  
  #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. */
  };
  
  /*******************************************************************************
   * Variables
   ******************************************************************************/
  /*! @brief Debug UART state information. */
  static debug_console_state_t s_debugConsole = {.type = DEBUG_CONSOLE_DEVICE_TYPE_NONE, .base = NULL, .ops = {{0}, {0}}};
  
  /*******************************************************************************
   * Prototypes
   ******************************************************************************/
  #if SDK_DEBUGCONSOLE
  static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, char *fmt, va_list ap);
  static int DbgConsole_ScanfFormattedData(const char *line_ptr, char *format, va_list args_ptr);
  double modf(double input_dbl, double *intpart_ptr);
  #endif /* SDK_DEBUGCONSOLE */
  
  /*******************************************************************************
   * 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)
  {
      if (s_debugConsole.type != DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return kStatus_Fail;
      }
  
      /* Set debug console to initialized to avoid duplicated initialized operation. */
      s_debugConsole.type = device;
  
      /* Switch between different device. */
      switch (device)
      {
  #if defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_UART:
          {
              uart_config_t uart_config;
              s_debugConsole.base = (UART_Type *)baseAddr;
              UART_GetDefaultConfig(&uart_config);
              uart_config.baudRate_Bps = baudRate;
              /* Enable clock and initial UART module follow user configure structure. */
              UART_Init(s_debugConsole.base, &uart_config, clkSrcFreq);
              UART_EnableTx(s_debugConsole.base, true);
              UART_EnableRx(s_debugConsole.base, true);
              /* Set the function pointer for send and receive for this kind of device. */
              s_debugConsole.ops.tx_union.UART_PutChar = UART_WriteBlocking;
              s_debugConsole.ops.rx_union.UART_GetChar = UART_ReadBlocking;
          }
          break;
  #endif /* FSL_FEATURE_SOC_UART_COUNT */
  #if defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
          {
              lpsci_config_t lpsci_config;
              s_debugConsole.base = (UART0_Type *)baseAddr;
              LPSCI_GetDefaultConfig(&lpsci_config);
              lpsci_config.baudRate_Bps = baudRate;
              /* Enable clock and initial UART module follow user configure structure. */
              LPSCI_Init(s_debugConsole.base, &lpsci_config, clkSrcFreq);
              LPSCI_EnableTx(s_debugConsole.base, true);
              LPSCI_EnableRx(s_debugConsole.base, true);
              /* Set the function pointer for send and receive for this kind of device. */
              s_debugConsole.ops.tx_union.LPSCI_PutChar = LPSCI_WriteBlocking;
              s_debugConsole.ops.rx_union.LPSCI_GetChar = LPSCI_ReadBlocking;
          }
          break;
  #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
  #if defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
          {
              lpuart_config_t lpuart_config;
              s_debugConsole.base = (LPUART_Type *)baseAddr;
              LPUART_GetDefaultConfig(&lpuart_config);
              lpuart_config.baudRate_Bps = baudRate;
              /* Enable clock and initial UART module follow user configure structure. */
              LPUART_Init(s_debugConsole.base, &lpuart_config, clkSrcFreq);
              LPUART_EnableTx(s_debugConsole.base, true);
              LPUART_EnableRx(s_debugConsole.base, true);
              /* Set the function pointer for send and receive for this kind of device. */
              s_debugConsole.ops.tx_union.LPUART_PutChar = LPUART_WriteBlocking;
              s_debugConsole.ops.rx_union.LPUART_GetChar = LPUART_ReadBlocking;
          }
          break;
  #endif  /* FSL_FEATURE_SOC_LPUART_COUNT */
          /* If new device is required as the low level device for debug console,
           * Add the case branch and add the preprocessor macro to judge whether
           * this kind of device exist in this SOC. */
          default:
              /* Device identified is invalid, return invalid device error code. */
              return kStatus_InvalidArgument;
      }
  
      return kStatus_Success;
  }
  
  /* See fsl_debug_console.h for documentation of this function. */
  status_t DbgConsole_Deinit(void)
  {
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return kStatus_Success;
      }
  
      switch (s_debugConsole.type)
      {
  #if defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_UART:
              /* Disable UART module. */
              UART_Deinit(s_debugConsole.base);
              break;
  #endif /* FSL_FEATURE_SOC_UART_COUNT */
  #if defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI:
              /* Disable LPSCI module. */
              LPSCI_Deinit(s_debugConsole.base);
              break;
  #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
  #if defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT > 0)
          case DEBUG_CONSOLE_DEVICE_TYPE_LPUART:
              /* Disable LPUART module. */
              LPUART_Deinit(s_debugConsole.base);
              break;
  #endif /* FSL_FEATURE_SOC_LPUART_COUNT */
          default:
              /* Device identified is invalid, return invalid device error code. */
              return kStatus_InvalidArgument;
      }
      s_debugConsole.type = DEBUG_CONSOLE_DEVICE_TYPE_NONE;
      return kStatus_Success;
  }
  
  #if SDK_DEBUGCONSOLE
  /* See fsl_debug_console.h for documentation of this function. */
  int DbgConsole_Printf(char *fmt_s, ...)
  {
      va_list ap;
      int result;
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
      va_start(ap, fmt_s);
      result = DbgConsole_PrintfFormattedData(DbgConsole_Putchar, fmt_s, ap);
      va_end(ap);
  
      return result;
  }
  
  /* See fsl_debug_console.h for documentation of this function. */
  int DbgConsole_Putchar(int ch)
  {
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
      s_debugConsole.ops.tx_union.PutChar(s_debugConsole.base, (uint8_t *)(&ch), 1);
  
      return 1;
  }
  
  /* See fsl_debug_console.h for documentation of this function. */
  int DbgConsole_Scanf(char *fmt_ptr, ...)
  {
      char temp_buf[IO_MAXLINE];
      va_list ap;
      uint32_t i;
      char result;
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
      va_start(ap, fmt_ptr);
      temp_buf[0] = '\0';
  
      for (i = 0; i < IO_MAXLINE; i++)
      {
          temp_buf[i] = result = DbgConsole_Getchar();
  
          if ((result == '\r') || (result == '\n'))
          {
              /* End of Line. */
              if (i == 0)
              {
                  i = (uint32_t)-1;
              }
              else
              {
                  break;
              }
          }
  
          temp_buf[i + 1] = '\0';
      }
  
      result = DbgConsole_ScanfFormattedData(temp_buf, fmt_ptr, ap);
      va_end(ap);
  
      return result;
  }
  
  /* See fsl_debug_console.h for documentation of this function. */
  int DbgConsole_Getchar(void)
  {
      char ch;
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
      s_debugConsole.ops.rx_union.GetChar(s_debugConsole.base, (uint8_t *)(&ch), 1);
  
      return ch;
  }
  
  /*************Code for process formatted data*******************************/
  /*!
   * @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 DbgConsole_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;
  }
  
  /*!
   * @brief This function puts padding character.
   *
   * @param[in] c         Padding character.
   * @param[in] curlen    Length of current formatted string .
   * @param[in] width     Width of expected formatted string.
   * @param[in] count     Number of characters.
   * @param[in] func_ptr  Function to put character out.
   */
  static void DbgConsole_PrintfPaddingCharacter(
      char c, int32_t curlen, int32_t width, int32_t *count, PUTCHAR_FUNC func_ptr)
  {
      int32_t i;
  
      for (i = curlen; i < width; i++)
      {
          func_ptr(c);
          (*count)++;
      }
  }
  
  /*!
   * @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 DbgConsole_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
  /*!
   * @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 DbgConsole_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 */
  
  /*!
   * @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] func_ptr  Function to put character out.
   * @param[in] fmt_ptr   Format string for printf.
   * @param[in] args_ptr  Arguments to printf.
   *
   * @return Number of characters
   */
  static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, char *fmt, va_list ap)
  {
      /* 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;
  #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 != '%')
          {
              func_ptr(c);
              count++;
              /* 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');
              }
              else
              {
                  /* We've gone one char too far. */
                  --p;
                  done = true;
              }
          }
          /* Next check for the width and precision field separator. */
          precision_width = 6;
          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');
                  }
                  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 = DbgConsole_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)
                          {
                              func_ptr(schar);
                              count++;
                          }
                          dschar = true;
  
                          DbgConsole_PrintfPaddingCharacter('0', vlen, field_width, &count, func_ptr);
                          vlen = field_width;
                      }
                      else
                      {
                          if (!(flags_used & kPRINTF_Minus))
                          {
                              DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                              if (schar)
                              {
                                  func_ptr(schar);
                                  count++;
                              }
                              dschar = true;
                          }
                      }
                      /* The string was built in reverse order, now display in correct order. */
                      if ((!dschar) && schar)
                      {
                          func_ptr(schar);
                          count++;
                      }
  #endif /* PRINTF_ADVANCED_ENABLE */
                  }
  
  #if PRINTF_FLOAT_ENABLE
                  if ((c == 'f') || (c == 'F'))
                  {
                      fval = (double)va_arg(ap, double);
                      vlen = DbgConsole_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)
                          {
                              func_ptr(schar);
                              count++;
                          }
                          dschar = true;
                          DbgConsole_PrintfPaddingCharacter('0', vlen, field_width, &count, func_ptr);
                          vlen = field_width;
                      }
                      else
                      {
                          if (!(flags_used & kPRINTF_Minus))
                          {
                              DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                              if (schar)
                              {
                                  func_ptr(schar);
                                  count++;
                              }
                              dschar = true;
                          }
                      }
                      if ((!dschar) && schar)
                      {
                          func_ptr(schar);
                          count++;
                      }
  #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 = DbgConsole_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)
                          {
                              func_ptr('0');
                              func_ptr((use_caps ? 'X' : 'x'));
                              count += 2;
                              /*vlen += 2;*/
                              dschar = true;
                          }
                          DbgConsole_PrintfPaddingCharacter('0', vlen, field_width, &count, func_ptr);
                          vlen = field_width;
                      }
                      else
                      {
                          if (!(flags_used & kPRINTF_Minus))
                          {
                              if (flags_used & kPRINTF_Pound)
                              {
                                  vlen += 2;
                              }
                              DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                              if (flags_used & kPRINTF_Pound)
                              {
                                  func_ptr('0');
                                  func_ptr(use_caps ? 'X' : 'x');
                                  count += 2;
  
                                  dschar = true;
                              }
                          }
                      }
  
                      if ((flags_used & kPRINTF_Pound) && (!dschar))
                      {
                          func_ptr('0');
                          func_ptr(use_caps ? 'X' : 'x');
                          count += 2;
                          vlen += 2;
                      }
  #endif /* PRINTF_ADVANCED_ENABLE */
                  }
                  if (c == 'o')
                  {
                      uval = (uint32_t)va_arg(ap, uint32_t);
                      radix = 8;
                  }
                  if (c == 'b')
                  {
                      uval = (uint32_t)va_arg(ap, uint32_t);
                      radix = 2;
                      vstrp = &vstr[vlen];
                  }
                  if (c == 'p')
                  {
                      uval = (uint32_t)va_arg(ap, void *);
                      radix = 16;
                      vstrp = &vstr[vlen];
                  }
                  if (c == 'u')
                  {
                      uval = (uint32_t)va_arg(ap, uint32_t);
                      radix = 10;
                      vstrp = &vstr[vlen];
                  }
                  if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
                  {
                      vlen = DbgConsole_ConvertRadixNumToString(vstr, &uval, false, radix, use_caps);
                      vstrp = &vstr[vlen];
  #if PRINTF_ADVANCED_ENABLE
                      if (flags_used & kPRINTF_Zero)
                      {
                          DbgConsole_PrintfPaddingCharacter('0', vlen, field_width, &count, func_ptr);
                          vlen = field_width;
                      }
                      else
                      {
                          if (!(flags_used & kPRINTF_Minus))
                          {
                              DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                          }
                      }
  #endif /* PRINTF_ADVANCED_ENABLE */
                  }
  #if !PRINTF_ADVANCED_ENABLE
                  DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
  #endif /* !PRINTF_ADVANCED_ENABLE */
                  while (*vstrp)
                  {
                      func_ptr(*vstrp--);
                      count++;
                  }
  #if PRINTF_ADVANCED_ENABLE
                  if (flags_used & kPRINTF_Minus)
                  {
                      DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                  }
  #endif /* PRINTF_ADVANCED_ENABLE */
              }
              else if (c == 'c')
              {
                  cval = (char)va_arg(ap, uint32_t);
                  func_ptr(cval);
                  count++;
              }
              else if (c == 's')
              {
                  sval = (char *)va_arg(ap, char *);
                  if (sval)
                  {
                      vlen = strlen(sval);
  #if PRINTF_ADVANCED_ENABLE
                      if (!(flags_used & kPRINTF_Minus))
  #endif /* PRINTF_ADVANCED_ENABLE */
                      {
                          DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                      }
                      while (*sval)
                      {
                          func_ptr(*sval++);
                          count++;
                      }
  #if PRINTF_ADVANCED_ENABLE
                      if (flags_used & kPRINTF_Minus)
                      {
                          DbgConsole_PrintfPaddingCharacter(' ', vlen, field_width, &count, func_ptr);
                      }
  #endif /* PRINTF_ADVANCED_ENABLE */
                  }
              }
              else
              {
                  func_ptr(c);
                  count++;
              }
          }
      }
      return count;
  }
  
  /*!
   * @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 "".
   */
  static int DbgConsole_ScanfFormattedData(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 (DbgConsole_ScanIgnoreWhiteSpace((const char **)&c))
          {
              n_decode += DbgConsole_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 += DbgConsole_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 += DbgConsole_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 += DbgConsole_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;
  }
  #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__))
  #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);
      }
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return ((size_t)-1);
      }
  
      /* Send data. */
      s_debugConsole.ops.tx_union.PutChar(s_debugConsole.base, buffer, 1);
      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);
      }
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return ((size_t)-1);
      }
  
      /* Receive data. */
      s_debugConsole.ops.rx_union.GetChar(s_debugConsole.base, buffer, size);
  
      return size;
  }
  /* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/
  #elif(defined(__GNUC__))
  int _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;
      }
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
  
      /* Send data. */
      s_debugConsole.ops.tx_union.PutChar(s_debugConsole.base, (uint8_t *)buffer, size);
      return size;
  }
  
  int _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;
      }
  
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
  
      /* Receive data. */
      s_debugConsole.ops.rx_union.GetChar(s_debugConsole.base, (uint8_t *)buffer, size);
      return size;
  }
  /* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/
  #elif defined(__CC_ARM)
  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
  FILE __stdout;
  FILE __stdin;
  
  #pragma weak fputc
  int fputc(int ch, FILE *f)
  {
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
  
      /* Send data. */
      s_debugConsole.ops.tx_union.PutChar(s_debugConsole.base, (uint8_t *)(&ch), 1);
      return 1;
  }
  
  #pragma weak fgetc
  int fgetc(FILE *f)
  {
      char ch;
      /* Do nothing if the debug UART is not initialized. */
      if (s_debugConsole.type == DEBUG_CONSOLE_DEVICE_TYPE_NONE)
      {
          return -1;
      }
  
      /* Receive data. */
      s_debugConsole.ops.rx_union.GetChar(s_debugConsole.base, (uint8_t *)(&ch), 1);
      return ch;
  }
  #endif /* __ICCARM__ */
  