/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : rs232.cpp
* Author : MCD Application Team
* Version : v2.2.0
* Date : 05/03/2010
* Description : Implements the RS232 class for COM communication
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "rs232.h"
/// set serial communication over COM1 with 115200 Bauds, 8 bitand no parity.
CRS232::CRS232()
{
hcom = NULL;
bufferSize = 2048;
numPort = 1;
speedInBaud = 115200;
nbBit = 8;
parity = 2;
nbStopBit = 1;
isConnected = FALSE;
bEcho =0;
FlowControl = FALSE;
}
CRS232::~CRS232()
{
if(hcom != NULL)
closeCom();
}
void CRS232::SetComSettings(int _numPort, long _speedInBaud, int _nbBit, int _parity, float _nbStopBit)
{
numPort = _numPort;
speedInBaud = _speedInBaud;
nbBit = _nbBit;
parity = _parity;
nbStopBit = _nbStopBit;
}
bool CRS232::open()
{
char buf[] = "\\\\.\\COM1";
if(numPort<1 || numPort>999)
return false;
if(speedInBaud<1)
return false;
if(nbBit<5 || nbBit > 9)
return false;
if(parity<0 || parity > 2)
return false;
if(nbStopBit<1 || nbStopBit > 2)
return false;
itoa(numPort, &buf[7], 10);
hcom=CreateFile(buf, GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING , 0, NULL);
if (hcom==0 || hcom==INVALID_HANDLE_VALUE)
return false;
isConnected = TRUE;
setTimeOut(5000);
if ( !SetupComm(hcom, bufferSize, bufferSize) )
return false;
if ( !GetCommState(hcom, &dcb))
return false;
dcb.BaudRate = speedInBaud;
dcb.ByteSize = nbBit;
if(nbStopBit == 1)
dcb.StopBits = ONESTOPBIT;
if(nbStopBit == 1.5)
dcb.StopBits = ONE5STOPBITS;
if(nbStopBit == 2)
dcb.StopBits = TWOSTOPBITS;
if(parity == 0)
dcb.Parity = NOPARITY;
if(parity == 1)
dcb.Parity = ODDPARITY;
if(parity == 2)
dcb.Parity = EVENPARITY;
if ( FlowControl == true)
{
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
}
else
{
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
}
if (!SetCommState(hcom, &dcb))
return false;
else
return true;
}
void CRS232::closeCom()
{
CloseHandle(hcom);
hcom = NULL;
isConnected = FALSE;
}
bool CRS232::setTimeOut(DWORD ms)
{
if( ms<0)
return false;
ct.ReadIntervalTimeout = ms;
ct.ReadTotalTimeoutMultiplier = ms;
ct.ReadTotalTimeoutConstant = ms;
ct.WriteTotalTimeoutMultiplier = ms;
ct.WriteTotalTimeoutConstant = ms;
if ( !SetCommTimeouts(hcom, &ct) )
return false;
return false;
//MSDN: The SetCommTimeouts function sets the time-out parameters for all read and write operations on a specified communications device.
}
bool CRS232::setSpeed(DWORD baudrate)
{
if( baudrate<1)
return false;
if (!GetCommState(hcom, &dcb))
return FALSE;
dcb.BaudRate = baudrate;
if (!SetCommState(hcom, &dcb))
return FALSE;
else
return TRUE;
//MSDN: The SetCommState function configures a communications device according to the specifications in a device-control block (a DCB structure). The function reinitializes all hardware and control settings, but it does not empty output or input queues.
}
int CRS232::sendData(string* data)
{
if( data == NULL )
return false;
return sendData((DWORD)data->size(), (LPBYTE)data->data());
}
int CRS232::sendData(DWORD lg, LPBYTE data)
{
DWORD result=0;
DWORD result1=0;
DWORD counter =0;
if( lg<0 || data==NULL)
return false;
if ( bEcho == 2)
{
for ( counter =0 ; counter < lg ; counter ++)
{
if ( !WriteFile(hcom, data+counter, 1, &result1, 0) )
return -1;
if( lg<0 || data==NULL)
return false;
if (!ReadFile(hcom, data+counter, 1, &result, 0))
return -1;
}
return (counter);
}
else
{
if ( !WriteFile(hcom, data, lg, &result, 0) )
return -1;
else
return (int)result;
}
//MSDN: The WriteFile function writes data to a file and is designed for both synchronous
// and asynchronous operation. The function starts writing data to the file at the
// position indicated by the file pointer. After the write operation has been completed
// , the file pointer is adjusted by the number of bytes actually written, except when
// the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for
// overlapped input and output (I/O), the application must adjust the position of the
// file pointer after the write operation is finished.
// This function is designed for both synchronous and asynchronous operation.
// The WriteFileEx function is designed solely for asynchronous operation.
// It lets an application perform other processing during a file write operation.
}
int CRS232::receiveData(string* data)
{ char buffer[1025];
int nbChar=0;
if( data==NULL)
return false;
nbChar = receiveData(1024, (LPBYTE)buffer);
buffer[nbChar] = 0;
data->assign(buffer);
return nbChar;
}
int CRS232::receiveData(DWORD lg, LPBYTE data)
{
DWORD result=0;
DWORD result1=0;
DWORD counter =0;
if( lg<0 || data==NULL)
return false;
if ( bEcho == 0)
{
if (!ReadFile(hcom, data, lg, &result, 0))
return -1;
else
return (int)result;
}
else if ( bEcho == 1)
{
for ( counter =0 ; counter < lg ; counter ++)
{
if (!ReadFile(hcom, data+counter, 1, &result, 0))
return -1;
if( lg<0 || data==NULL)
return false;
if ( !WriteFile(hcom, data+counter, 1, &result1, 0) )
return -1;
}
return (counter);
}
else if ( bEcho == 2)
{
if (!ReadFile(hcom, data, lg, &result, 0))
return -1;
else
return (int)result;
}
else
{
/* TODO */
return -1;
}
//MSDN: The ReadFile function reads data from a file, starting at the position indicated
// by the file pointer. After the read operation has been completed, the file pointer
// is adjusted by the number of bytes actually read, unless the file handle is
// created with the overlapped attribute. If the file handle is created for
// overlapped input and output (I/O), the application must adjust the position of
// the file pointer after the read operation.
// This function is designed for both synchronous and asynchronous operation.
// The ReadFileEx function is designed solely for asynchronous operation. It lets
// an application perform other processing during a file read operation.
}
/**************************** SetRts(val) **************************************************/
bool CRS232::setRts(bool val)
{
if(val)
{
if(EscapeCommFunction(hcom, SETRTS) == TRUE )
return true;
}
else
{
if(EscapeCommFunction(hcom, CLRRTS) == TRUE )
return true;
}
return false;
}
/**************************** SetTxd(val) ***************************************************/
bool CRS232::setTxd(bool val)
{
if(val)
{
if( EscapeCommFunction(hcom, SETBREAK) == TRUE )
return true;
}
else
{
if( EscapeCommFunction(hcom, CLRBREAK) == TRUE )
return true;
}
return false;
}
/**************************** SetDtr(val) ************************************************** */
bool CRS232::setDtr(bool val)
{
if(val)
{
if( EscapeCommFunction(hcom, SETDTR) == TRUE )
return true;
}
else
{
if( EscapeCommFunction(hcom, CLRDTR) == TRUE )
return false;
}
return false;
}
/********************** GetCts() ***********************/
bool CRS232::getCts()
{
DWORD result;
GetCommModemStatus(hcom, &result);
if(result & MS_CTS_ON)
return true;
else
return false;
}
/********************** GetDtr() ***********************/
bool CRS232::getDtr()
{
DWORD result;
GetCommModemStatus(hcom, &result);
if(result & MS_DSR_ON)
return true;
else
return false;
}
/********************** GetRi() ***********************/
bool CRS232::getRi()
{
DWORD result;
GetCommModemStatus(hcom, &result);
if(result & MS_RING_ON)
return true;
else
return false;
}
/********************** GetCd() ***********************/
bool CRS232::getCd()
{ int err=0;
DWORD result;
err = GetCommModemStatus(hcom, &result);
if(result & MS_RLSD_ON)
return true;
else
return false;
}
string CRS232::getErrorMsg()
{
LPVOID lpMsgBuf;
string sErreur = "";
if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL ))
{
sErreur.assign((LPCTSTR)lpMsgBuf);
}
return sErreur;
}
void CRS232::SetParity(int _parity)
{
if(_parity == 0)
dcb.Parity = NOPARITY;
if(_parity == 1)
dcb.Parity = ODDPARITY;
if(_parity == 2)
dcb.Parity = EVENPARITY;
SetCommState(hcom, &dcb);
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE******/