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

📄 winuart.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/* winuart.c

 Copyright 1991-1996 by NetPort Software
 Copyright 1997-2001 by InterNIche Technologies Inc.

   This implements a UART driver for PPP on Windows. The underlying
microsoft drivers are pretty bad, but hopefully good enough for a
demo.

*/


/* Microsoft Can't even get their sad-sack C code includes to compile 
 * cleanly, even with their own compiler. Disable the warnings here 
 * so that we can include windows.h without problems.
 */

#pragma warning(disable: 4244 4310 4115)
#include <windows.h>

#undef FAR
#include "ipport.h"

#ifdef USE_COMPORT

#include "winuart.h"
#include "nvparms.h"


int comport;   /* the "default" com port (for ..\modem\mdmport.c) */


/* table for mapping logical UART units to PC Com ports */
int comport_map[MAXUNITS]; /* map logical units to PC com ports */

struct com_win com_ports[MAXCOMMS];


/* uart_init() - PC UART init entry point. Fully installs & enables
the UART, including exit_hook() for closing.

Returns 0 if OK, else non-zero.
*/

char comfile[] = {"//./COM1" };     /* COM device name for CreateFile() */

int
uart_init(int unit)
{
int   comport;   /* com1, com2, etc. - get from NV parms */
int   err;
struct com_win * com;         /* our window comm manager struct */
COMMTIMEOUTS timeouts;        /* more crusty windows stuff */
DCB      dcb;                 /* ... */


   /* sanity check parameters */
   if(unit < 0 || unit > MAXUNITS)
      return -1;

   comport = comportcfg.comport+'0'; /* convert 0x01 to '1' */
   if(comport < '1' || comport > (MAXCOMMS+'0') )
   {
      dprintf("pcuart: bad comport: %c\n", comport);
      return ENP_LOGIC;
   }
   comfile[7] = (char)comport;  /* patch "COMX" device name */
   comport -= '1';      /* make comport into comport_map index */

   /* On windows the first unit to set up gets the comport from nvparms,
    * the next unit (if any) gets the other com port. We only use the
    * two standard ones on this port.
    */
   if(unit == 0)
      comport_map[unit] = comport;
   else     /* second unit, use other comport */
   {
      if(comport == 0)
         comport_map[unit] = comport = 1;
      else
         comport_map[unit] = comport = 0;
   }

   com = &com_ports[comport];

   if(com->uart_open == unit - 1)  /* it's open, nothing to do */
   {
      dtrap();    /* shouldn't happen anymore */
      return 0;   /* return "up" code */
   }

   /* Windozey UART API prentends it's a file (it seems they 
    * only borrow the stupid ideas from UNIX) - so call 
    * CreateFile() with no share, no security:
    */
   com->dev = CreateFile(comfile, GENERIC_READ|GENERIC_WRITE, 
      0, 0, OPEN_EXISTING, 0, NULL);

   if(com->dev == INVALID_HANDLE_VALUE)
   {
      err = GetLastError();
      dprintf("Error %d opening windows serial device\n", err);
      return ENP_LOGIC;
   }

   err = GetCommState(com->dev, &dcb);
   if(err == FALSE)  /* check boolean return */
   {
      dtrap();       /* Can this happen? */
      return ENP_LOGIC;
   }

   /* usually defaults to baud 1200, no parity, 8 data bits, 1 stop bit
    * DTR ENABLE. Set up what modems generally work well with:
    */
   dcb.BaudRate = CBR_57600;
   dcb.ByteSize = 8;
   dcb.fBinary = TRUE;
   dcb.Parity = NOPARITY;
   dcb.StopBits = ONESTOPBIT;

   err = SetCommState(com->dev, &dcb);
   if(err == FALSE)  /* check boolean return */
   {
      dtrap();       /* Comm port setup failed... */
      err = GetLastError();
      return ENP_LOGIC;
   }

   err = GetCommTimeouts(com->dev, &timeouts);
   if(err == FALSE)  /* check boolean return */
   {
      dtrap();       /* Can this happen? */
      return ENP_LOGIC;
   }

   com->baudrate = dcb.BaudRate;    /* record baud in local struct */

   timeouts.ReadIntervalTimeout = MAXDWORD;   /* immediate read return */

   err = SetCommTimeouts(com->dev, &timeouts);
   if(err == FALSE)  /* check boolean return */
   {
      dtrap();       /* Can this happen? */
      return ENP_LOGIC;
   }

   com->uart_open = unit - 1;
   exit_hook(uart_closehook);

   return 0;   /* OK return */
}


/*  void uart_putc(unit, char) - puts a byte out serial port.

    Returns 0 in AX if OK, else -1 if RDY timeout.
*/

int
uart_putc(int unit, u_char outchar)
{
struct com_win * com;
u_long   done;
int      err;

   if(unit < 0 || unit > MAXUNITS)
      return -1;

   com = &com_ports[comport_map[unit]];
   /* punt if the uart is not initialized. This means we have
    * to consider 0 an invalid handle value, although technically 
    * it seems to be legal. 
    */
   if((com->dev == INVALID_HANDLE_VALUE) ||
      (com->dev == 0))
   {
      return -1;
   }

   err = WriteFile(com->dev, &outchar, 1, &done, NULL);
   if((err == 0) || (done != 1))
   {
      dtrap()
      return -1;
   }

   com->uart_out++;

   return 0;
}


/*	uart_getc() - get the next character from the uart input buffer.
 Returns a 16 or 32 bit value. If a char is ready, the upper  bits are zero
 and the lower 8 bits have the byte value. If no char is ready, all bits
 are SET (ie, 16 bit value is 0xFFFF)
*/

int
uart_getc(int unit)
{
int      err;
int      retchar;
u_long   rlen;
struct com_win * com;

   if(unit < 0 || unit > MAXUNITS)
      return -1;

   com = &com_ports[comport_map[unit]];
   if(com->dev == INVALID_HANDLE_VALUE)
   {
      return -1;
   }

   rlen = 0;
   err = ReadFile(com->dev, &retchar, 1, &rlen, NULL);
   if(err == 0)      /* test boolean return */
   {
      err = GetLastError();
      if(rlen != 0)
      {
         dtrap();
      }

      switch (err)
      {
      case 0x03e4:   /* Overlapped I/O event is not in a signaled state */
      case 0x03e5:   /* Overlapped I/O operation is in progress. */
      case 0x0006:   /* Bad Handle */
         break;
      default:
         dprintf("UART ReadFile error %d\n", err);
         break;
      }
      return -1;
   }
   if(rlen != 1)
   {
      return -1;
   }
   com->uart_gets++;
   return (retchar & 0x000000FF);
}


/* uart_ready() - Returns true (0xFFFF) if UART is ready to send 
 a character, FALSE (0) if not. This allows a non-blocking UART send
 routine to be written in C.
*/

int
uart_ready(int unit)
{
struct com_win * com;

   if(unit < 0 || unit > MAXUNITS)
      return -1;

   com = &com_ports[comport_map[unit]];
   if(com->dev == INVALID_HANDLE_VALUE)
      return FALSE;
   else
      return TRUE;
}

/* void uart_close(void) - shut down UART
*/

void uart_close(int unit)
{
struct com_win * com;

   if(unit < 0 || unit > MAXUNITS)
   {
      dtrap();
      return;
   }

   com = &com_ports[comport_map[unit]];
   CloseHandle(com->dev);  /* best effort */

   /* clean up com_port struct */
   com->uart_open = unit;
   com->dev = INVALID_HANDLE_VALUE;
}



/* exit_hook to close all uarts. We close them all becasue we have no 
mechanism to pass a unit parameter through exit_hook 
*/

void
uart_closehook()
{
int unit;
struct com_win * com;

   dprintf("uart: closing com ports\n");
   for(unit = 0; unit < MAXUNITS; unit++)
   {
      com = &com_ports[comport_map[unit]];
      if(com->uart_open != unit - 1)
         continue;
      uart_close(unit);
      dprintf("uart: closed com%d\n", comport_map[unit] + 1);
   }
}

#ifdef NET_STATS

int
uart_stats(void * pio, int unit)
{
   int comport;
   int      err;
   struct com_win * com;
   DCB dcb;
   char * sbits;     /* stop bits string */
   char ptypes[5] = { 'N', 'O', 'E', 'M', 'S' };   /* parity types */

   comport = comport_map[unit];
   com = &com_ports[comport];
   if(com->uart_unit != unit)
   {
      dtrap();
   }

   ns_printf(pio, "   Win32 COM device status; handle:%x unit:%d:\n",
      com->dev, unit);
   ns_printf(pio,"Com port is Com%d\n", comport+1);
   ns_printf(pio, "uart_gets: %ld, uart_puts:%ld, set baud: %ld\n",
      com->uart_gets, com->uart_out, com->baudrate);
   ns_printf(pio,"send timeouts: %u\n", com->uart_tmo);

   err = GetCommState(com->dev, &dcb);

   switch(dcb.StopBits)    /* set string for stop bits */
   {
      case 0:
         sbits = "1";
         break;
      case 1:
         sbits = "1.5";
         break;
      case 2:
         sbits = "2";
         break;
      default:
         sbits = "foo";
   };
   ns_printf(pio, "actual Baudrate:%d, Parity %c, data bits %d, stop bits %s\n",
      dcb.BaudRate, ptypes[dcb.Parity], dcb.ByteSize, sbits);

   ns_printf(pio, "FLAGS: Binary Mode %d, parity enable %d, handshaking: CTS %d, DSR %d\n",
      dcb.fBinary, dcb.fParity, dcb.fOutxCtsFlow, dcb.fOutxDsrFlow);

   ns_printf(pio, "FLAGS: DTR Flow %d, DSR Sensitivity %d, TX when Xoff %d, Err Replacement %d\n",
      dcb.fDtrControl, dcb.fDsrSensitivity, dcb.fTXContinueOnXoff, dcb.fErrorChar);

   ns_printf(pio, "FLAGS: Null stripping %d, Rts Flow control %d, Abort on Error %d\n",
      dcb.fNull, dcb.fRtsControl, dcb.fAbortOnError);

   if(dcb.fOutX ||dcb.fInX)
   {
      ns_printf(pio, "fOutX:%d, fInX:%d\n",  dcb.fOutX, dcb.fInX);
      ns_printf(pio, "X-ON char:0x%x, X-OFF char:0x%x, Thresholds, XON %d, XOFF %d\n",
      dcb.XonLim, dcb.XoffLim, dcb.XonChar, dcb.XoffChar);
   }

   return 0;
}

#endif   /* NET_STATS */


#endif /* USE_COMPORT */



⌨️ 快捷键说明

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