📄 win32lnk.c
字号:
//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//---------------------------------------------------------------------------
//
// Win32Lnk.C - COM functions using Win32 to be used as a test
// for DS2480 based Universal Serial Adapter 'U'
// functions.
//
// Version: 2.01
//
// History: 1.00 -> 1.01 Added function msDelay.
//
// 1.01 -> 1.02 Changed to generic OpenCOM/CloseCOM for easier
// use with other platforms.
//
// 1.02 -> 1.03 Add function msGettick()
//
// 1.03 -> 2.00 Support for multiple ports.
// 2.00 -> 2.01 Added error handling. Added circular-include check.
// 2.01 -> 2.10 Added raw memory error handling and SMALLINT
// 2.10 -> 3.00 Added memory bank functionality
// Added file I/O operations
//
#include "ownet.h"
#include "ds2480.h"
#include <windows.h>
#include <stdio.h>
// Win32 globals needed
static HANDLE ComID[MAX_PORTNUM];
static OVERLAPPED osRead[MAX_PORTNUM],osWrite[MAX_PORTNUM];
static SMALLINT ComID_init = 0;
//---------------------------------------------------------------------------
//-------- COM required functions for MLANU
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Attempt to open a com port. Keep the handle in ComID.
// Set the starting baud rate to 9600.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
// be used to indicate the port number desired when calling
// all other functions in this library.
//
//
// Returns: the port number if it was succesful otherwise -1
//
int OpenCOMEx(char *port_zstr)
{
int portnum;
if(!ComID_init)
{
int i;
for(i=0; i<MAX_PORTNUM; i++)
ComID[i] = 0;
ComID_init = 1;
}
// check to find first available handle slot
for(portnum = 0; portnum<MAX_PORTNUM; portnum++)
{
if(!ComID[portnum])
break;
}
OWASSERT( portnum<MAX_PORTNUM, OWERROR_PORTNUM_ERROR, -1 );
if(!OpenCOM(portnum, port_zstr))
{
return -1;
}
return portnum;
}
//---------------------------------------------------------------------------
// Attempt to open a com port. Keep the handle in ComID.
// Set the starting baud rate to 9600.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
// be used to indicate the port number desired when calling
// all other functions in this library.
//
// 'port_zstr' - zero terminate port name. For this platform
// use format COMX where X is the port number.
//
//
// Returns: TRUE(1) - success, COM port opened
// FALSE(0) - failure, could not open specified port
//
SMALLINT OpenCOM(int portnum, char *port_zstr)
{
char tempstr[80];
short fRetVal;
COMMTIMEOUTS CommTimeOuts;
DCB dcb;
if(!ComID_init)
{
int i;
for(i=0; i<MAX_PORTNUM; i++)
ComID[i] = 0;
ComID_init = 1;
}
OWASSERT( portnum<MAX_PORTNUM && portnum>=0 && !ComID[portnum],
OWERROR_PORTNUM_ERROR, FALSE );
// open COMM device
if ((ComID[portnum] =
CreateFile( port_zstr, GENERIC_READ | GENERIC_WRITE,
0,
NULL, // no security attrs
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
{
ComID[portnum] = 0;
OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED);
return (FALSE) ;
}
else
{
// create events for detection of reading and write to com port
sprintf(tempstr,"COMM_READ_OVERLAPPED_EVENT_FOR_%s",port_zstr);
osRead[portnum].hEvent = CreateEvent(NULL,TRUE,FALSE,tempstr);
sprintf(tempstr,"COMM_WRITE_OVERLAPPED_EVENT_FOR_%s",port_zstr);
osWrite[portnum].hEvent = CreateEvent(NULL,TRUE,FALSE,tempstr);
// get any early notifications
SetCommMask(ComID[portnum], EV_RXCHAR | EV_TXEMPTY | EV_ERR | EV_BREAK);
// setup device buffers
SetupComm(ComID[portnum], 2048, 2048);
// purge any information in the buffer
PurgeComm(ComID[portnum], PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
// set up for overlapped non-blocking I/O
CommTimeOuts.ReadIntervalTimeout = 0;
CommTimeOuts.ReadTotalTimeoutMultiplier = 20;
CommTimeOuts.ReadTotalTimeoutConstant = 40;
CommTimeOuts.WriteTotalTimeoutMultiplier = 20;
CommTimeOuts.WriteTotalTimeoutConstant = 40;
SetCommTimeouts(ComID[portnum], &CommTimeOuts);
// setup the com port
GetCommState(ComID[portnum], &dcb);
dcb.BaudRate = CBR_9600; // current baud rate
dcb.fBinary = TRUE; // binary mode, no EOF check
dcb.fParity = FALSE; // enable parity checking
dcb.fOutxCtsFlow = FALSE; // CTS output flow control
dcb.fOutxDsrFlow = FALSE; // DSR output flow control
dcb.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
dcb.fDsrSensitivity = FALSE; // DSR sensitivity
dcb.fTXContinueOnXoff = TRUE; // XOFF continues Tx
dcb.fOutX = FALSE; // XON/XOFF out flow control
dcb.fInX = FALSE; // XON/XOFF in flow control
dcb.fErrorChar = FALSE; // enable error replacement
dcb.fNull = FALSE; // enable null stripping
dcb.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
dcb.fAbortOnError = FALSE; // abort reads/writes on error
dcb.XonLim = 0; // transmit XON threshold
dcb.XoffLim = 0; // transmit XOFF threshold
dcb.ByteSize = 8; // number of bits/byte, 4-8
dcb.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
dcb.XonChar = 0; // Tx and Rx XON character
dcb.XoffChar = 1; // Tx and Rx XOFF character
dcb.ErrorChar = 0; // error replacement character
dcb.EofChar = 0; // end of input character
dcb.EvtChar = 0; // received event character
fRetVal = SetCommState(ComID[portnum], &dcb);
}
// check if successfull
if (!fRetVal)
{
CloseHandle(ComID[portnum]);
CloseHandle(osRead[portnum].hEvent);
CloseHandle(osWrite[portnum].hEvent);
ComID[portnum] = 0;
OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
}
return (fRetVal);
}
//---------------------------------------------------------------------------
// Closes the connection to the port.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
//
void CloseCOM(int portnum)
{
// disable event notification and wait for thread
// to halt
SetCommMask(ComID[portnum], 0);
// drop DTR
EscapeCommFunction(ComID[portnum], CLRDTR);
// purge any outstanding reads/writes and close device handle
PurgeComm(ComID[portnum], PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
CloseHandle(ComID[portnum]);
CloseHandle(osRead[portnum].hEvent);
CloseHandle(osWrite[portnum].hEvent);
ComID[portnum] = 0;
}
//---------------------------------------------------------------------------
// Flush the rx and tx buffers
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
//
void FlushCOM(int portnum)
{
// purge any information in the buffer
PurgeComm(ComID[portnum], PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
}
//--------------------------------------------------------------------------
// Write an array of bytes to the COM port, verify that it was
// sent out. Assume that baud rate has been set.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
// 'outlen' - number of bytes to write to COM port
// 'outbuf' - pointer ot an array of bytes to write
//
// Returns: TRUE(1) - success
// FALSE(0) - failure
//
SMALLINT WriteCOM(int portnum, int outlen, uchar *outbuf)
{
BOOL fWriteStat;
DWORD dwBytesWritten=0;
DWORD ler=0,to;
// calculate a timeout
to = 20 * outlen + 60;
// reset the write event
ResetEvent(osWrite[portnum].hEvent);
// write the byte
fWriteStat = WriteFile(ComID[portnum], (LPSTR) &outbuf[0],
outlen, &dwBytesWritten, &osWrite[portnum] );
// check for an error
if (!fWriteStat)
ler = GetLastError();
// if not done writting then wait
if (!fWriteStat && ler == ERROR_IO_PENDING)
{
WaitForSingleObject(osWrite[portnum].hEvent,to);
// verify all is written correctly
fWriteStat = GetOverlappedResult(ComID[portnum], &osWrite[portnum],
&dwBytesWritten, FALSE);
}
// check results of write
if (!fWriteStat || (dwBytesWritten != (DWORD)outlen))
return 0;
else
return 1;
}
//--------------------------------------------------------------------------
// Read an array of bytes to the COM port, verify that it was
// sent out. Assume that baud rate has been set.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
// 'inlen' - number of bytes to read from COM port
// 'inbuf' - pointer to a buffer to hold the incomming bytes
//
// Returns: number of characters read
//
int ReadCOM(int portnum, int inlen, uchar *inbuf)
{
DWORD dwLength=0;
BOOL fReadStat;
DWORD ler=0,to;
// calculate a timeout
to = 20 * inlen + 60;
// reset the read event
ResetEvent(osRead[portnum].hEvent);
// read
fReadStat = ReadFile(ComID[portnum], (LPSTR) &inbuf[0],
inlen, &dwLength, &osRead[portnum]) ;
// check for an error
if (!fReadStat)
ler = GetLastError();
// if not done writing then wait
if (!fReadStat && ler == ERROR_IO_PENDING)
{
// wait until everything is read
WaitForSingleObject(osRead[portnum].hEvent,to);
// verify all is read correctly
fReadStat = GetOverlappedResult(ComID[portnum], &osRead[portnum],
&dwLength, FALSE);
}
// check results
if (fReadStat)
return dwLength;
else
return 0;
}
//--------------------------------------------------------------------------
// Send a break on the com port for at least 2 ms
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
//
void BreakCOM(int portnum)
{
// start the reset pulse
SetCommBreak(ComID[portnum]);
// sleep
Sleep(2);
// clear the break
ClearCommBreak(ComID[portnum]);
}
//--------------------------------------------------------------------------
// Set the baud rate on the com port.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
// 'new_baud' - new baud rate defined as
// PARMSET_9600 0x00
// PARMSET_19200 0x02
// PARMSET_57600 0x04
// PARMSET_115200 0x06
//
void SetBaudCOM(int portnum, uchar new_baud)
{
DCB dcb;
// get the current com port state
GetCommState(ComID[portnum], &dcb);
// change just the baud rate
switch (new_baud)
{
case PARMSET_115200:
dcb.BaudRate = CBR_115200;
break;
case PARMSET_57600:
dcb.BaudRate = CBR_57600;
break;
case PARMSET_19200:
dcb.BaudRate = CBR_19200;
break;
case PARMSET_9600:
default:
dcb.BaudRate = CBR_9600;
break;
}
// restore to set the new baud rate
SetCommState(ComID[portnum], &dcb);
}
//--------------------------------------------------------------------------
// Description:
// Delay for at least 'len' ms
//
void msDelay(int len)
{
Sleep(len);
}
//--------------------------------------------------------------------------
// Get the current millisecond tick count. Does not have to represent
// an actual time, it just needs to be an incrementing timer.
//
long msGettick(void)
{
return GetTickCount();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -