⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc550_usartdriver.c

📁 一款经典的数字电话设计资料
💻 C
字号:
/*****************************************************************************/
/*  CONFIDENTIAL                                                             */
/*  Sigpro Copyright 2003, All rights reserved                               */
/*****************************************************************************/
/*  CLIENT:  Telematrix                                                      */
/*  PROJECT: DC550 Digital Centrex Phone                                     */
/*  FILE:    dc550_usartdriver.c                                             */
/*****************************************************************************/
/*  The Debug USART Driver is used to generate debug messages during         */
/*  development.                                                             */
/*****************************************************************************/

/* IAR's version of printf wants these */
#include "stdio.h"
#include "stdarg.h"
#include "sysmac.h"

#include "dc550_usartdriver.h"

/******************************************************************************
 *  STATIC/LOCAL VARIABLES
 *****************************************************************************/
// Internally accessible variables
#define USARTDRIVER_BUFSIZE  64
static char *nextOut, *nextIn;
static int  numChars, charsLost;
static char workingBuffer[USARTDRIVER_BUFSIZE];
static BOOL bufferOverflow;


/******************************************************************************
 *  FUNCTION: void usartdriver_init(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called during the initialization phase to initialize all
 *  of the USART driver variables.
 *****************************************************************************/
void usartdriver_init(void)
{
    numChars = 0;
    nextOut = nextIn = &workingBuffer[0];
    bufferOverflow = FALSE;
    charsLost = 0;
}


/******************************************************************************
 *  FUNCTION: void usartdriver_exec(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to execute the USART driver task.
 *  The serial output is set up for 9600 baud, 1 start bit, and 2 stop bits.
 *  At these settings, a character should be transmitted approximately
 *  once every 1.15 ms.  Due to the real-time constraints of the main
 *  loop, this routine cannot afford to wait for the transmission to
 *  occur, so instead, it will load one character into the buffer (if
 *  it is currently empty) and return.
 *
 *  SPECIAL HANDLING:
 *  If a buffer overflow occurs, a warning message will be output
 *  to the serial line indicating that a message was dropped.
 *****************************************************************************/
void usartdriver_exec(void)
{
    // Any characters waiting for transmission?
    if (numChars == 0) {

        // No characters and no error conditions - return
        if (!bufferOverflow)
            return;

        // If a buffer overflow occurred, notify user
        if (bufferOverflow) {
            bufferOverflow = FALSE;
            dc550_printf("\r\n--USART BUFFER OVERFLOW."
                         " %d CHARACTERS WERE LOST!--\r\n",
                         charsLost);
            charsLost = 0;
        }
    }

    // Wait until the USART0 TX buffer is ready
    if ((IFG1 & UTXIFG0) == 0)
        return;

    // Load up the next character
    TXBUF0 = *nextOut;

    // Increment the outgoing buffer pointer
    nextOut++;
    if (nextOut >= (workingBuffer+USARTDRIVER_BUFSIZE))
        nextOut = &workingBuffer[0];

    // Only transmit one character at a time
    numChars--;

    return;
}



/*                      - INTWRI.C -

   Reduced version of the "printf" function.

   This module can be adopted to user-defined routines that needs formatters
   with special properties like different output channels or new format
   specifiers.

   This reduced version of formatter is suitable when program size is critical
   rather than formatting power.  This routine uses less than 20 bytes of
   stack space which makes it practical even in systems with less than 256
   bytes of user RAM.

   The only formatting specifiers supported are:

            %%  %o  %d  %c  %s  %x

   It means that "long" or real variables are not supported as well as field
   width and precision arguments.  Return value is always zero.

   $Name:  $

   Copyright 1986 - 1999 IAR Systems. All rights reserved.
*/


void dc550_putchar(char c)
{
    if ( (bufferOverflow == TRUE) ||
         ((numChars+1) >= USARTDRIVER_BUFSIZE) ) {
        bufferOverflow = TRUE;
        charsLost++;
        return;
    }

    *nextIn++ = (char)(c & 0xff);
    numChars++;
    if (nextIn >= (workingBuffer+USARTDRIVER_BUFSIZE))
      nextIn = workingBuffer;
}


int dc550_printf(const char *format, ...)
{
  static const char hex[] = "0123456789ABCDEF";
  char format_flag;
  unsigned int u_val, div_val, base;
  char *ptr;
  va_list ap;

  va_start(ap, format);
  
  for (;;)    /* Until full format string read */
  {
    while ((format_flag = *format++) != '%')      /* Until '%' or '\0' */
    {
      if (!format_flag)
      {
        va_end(ap);
        return 0;
      }
      dc550_putchar(format_flag);
    }

    switch (format_flag = *format++)
    {
    case 'c':
      format_flag = va_arg(ap, int);
    default:
      dc550_putchar(format_flag);
      continue;

    case 's':
      ptr = VAPTR(char);
      while (format_flag = *ptr++)
      {
        dc550_putchar(format_flag);
      }
      continue;

    case 'o':
      base = 8;
      if (sizeof(int) == 2)
        div_val = 0x8000;
      else
        div_val = 0x40000000;
      goto CONVERSION_LOOP;

    case 'd':
      base = 10;
      if (sizeof(int) == 2)
        div_val = 10000;
      else
        div_val = 1000000000;
      goto CONVERSION_LOOP;

    case 'x':
      base = 16;
      if (sizeof(int) == 2)
        div_val = 0x1000;
      else
        div_val = 0x10000000;

CONVERSION_LOOP:
      u_val = va_arg(ap,int);
      if (format_flag == 'd')
      {
        if (((int)u_val) < 0)
        {
          u_val = - u_val;
          dc550_putchar('-');
        }
        while (div_val > 1 && div_val > u_val)
        {
          div_val /= 10;
        }
      }

      do
      {
        dc550_putchar(hex[u_val / div_val]);
        u_val %= div_val;
        div_val /= base;
      }
      while (div_val);
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -