first commit
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
#include "SerialPort.h"
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
Serial::Serial():
|
||||
portNo(0),
|
||||
connected(false),
|
||||
usbMode(MODE_USB_EXPRESS)
|
||||
{
|
||||
}
|
||||
|
||||
Serial::~Serial()
|
||||
{
|
||||
//Check if we are connected before trying to disconnect
|
||||
close();
|
||||
}
|
||||
|
||||
bool Serial::open(int portno, int baudrate)
|
||||
{
|
||||
if (isConnected())
|
||||
CloseHandle(this->hSerial);
|
||||
|
||||
//if (usbMode == MODE_USB_EXPRESS)
|
||||
// return open("0001");
|
||||
|
||||
portNo = portno;
|
||||
stringstream ss;
|
||||
ss << "\\\\.\\COM" << portNo;
|
||||
string portName = ss.str();
|
||||
//We're not yet connected
|
||||
this->connected = false;
|
||||
|
||||
//Try to connect to the given port throuh CreateFile
|
||||
this->hSerial = CreateFile(portName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
//Check if the connection was successfull
|
||||
if (this->hSerial == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("[Serial] ERROR: Invalid handle value\n");
|
||||
CloseHandle(this->hSerial);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
char mode_str[128];
|
||||
switch (baudrate)
|
||||
{
|
||||
case BAUDRATE_4800:
|
||||
strcpy(mode_str, "baud=4800");
|
||||
break;
|
||||
case BAUDRATE_9600:
|
||||
strcpy(mode_str, "baud=9600");
|
||||
break;
|
||||
case BAUDRATE_19200:
|
||||
strcpy(mode_str, "baud=19200");
|
||||
break;
|
||||
case BAUDRATE_38400:
|
||||
strcpy(mode_str, "baud=38400");
|
||||
break;
|
||||
case BAUDRATE_57600:
|
||||
strcpy(mode_str, "baud=57600");
|
||||
break;
|
||||
case BAUDRATE_115200:
|
||||
strcpy(mode_str, "baud=115200");
|
||||
break;
|
||||
case BAUDRATE_230400:
|
||||
strcpy(mode_str, "baud=230400");
|
||||
break;
|
||||
case BAUDRATE_256000:
|
||||
strcpy(mode_str, "baud=256000");
|
||||
break;
|
||||
case BAUDRATE_460800:
|
||||
strcpy(mode_str, "baud=460800");
|
||||
break;
|
||||
case BAUDRATE_921600:
|
||||
strcpy(mode_str, "baud=921600");
|
||||
break;
|
||||
}
|
||||
strcat(mode_str, " data=8");
|
||||
strcat(mode_str, " parity=n");
|
||||
strcat(mode_str, " stop=1");
|
||||
strcat(mode_str, " dtr=on rts=on");
|
||||
DCB port_settings;
|
||||
memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */
|
||||
port_settings.DCBlength = sizeof(port_settings);
|
||||
|
||||
if (!BuildCommDCBA(mode_str, &port_settings))
|
||||
{
|
||||
printf("unable to set comport dcb settings\n");
|
||||
CloseHandle(this->hSerial);
|
||||
return false;
|
||||
}
|
||||
if (!BuildCommDCBA(mode_str, &port_settings))
|
||||
{
|
||||
printf("unable to set comport dcb settings\n");
|
||||
CloseHandle(this->hSerial);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetCommState(this->hSerial, &port_settings))
|
||||
{
|
||||
printf("unable to set comport cfg settings\n");
|
||||
CloseHandle(this->hSerial);
|
||||
return false;
|
||||
}
|
||||
|
||||
COMMTIMEOUTS Cptimeouts;
|
||||
|
||||
Cptimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
Cptimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
Cptimeouts.ReadTotalTimeoutConstant = 0;
|
||||
Cptimeouts.WriteTotalTimeoutMultiplier = 100;
|
||||
Cptimeouts.WriteTotalTimeoutConstant = 100;
|
||||
|
||||
if (!SetCommTimeouts(this->hSerial, &Cptimeouts))
|
||||
{
|
||||
printf("unable to set comport time-out settings\n");
|
||||
CloseHandle(this->hSerial);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this->connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serial::open(std::string deviceId, int baudrate)
|
||||
{
|
||||
bool f;
|
||||
|
||||
transform(deviceId.begin(), deviceId.end(), deviceId.begin(), ::toupper);
|
||||
this->idNumber = deviceId;
|
||||
std::cout << "[LpmsU] Lpms::connect deviceID is : " << deviceId << std::endl;
|
||||
f = false;
|
||||
|
||||
SI_STATUS siStatus;
|
||||
DWORD devercNum = 0;
|
||||
SI_DEVICE_STRING DeviceString;
|
||||
|
||||
this->idNumber = deviceId;
|
||||
|
||||
DWORD numDevs;
|
||||
if (SI_GetNumDevices(&numDevs) != SI_SUCCESS)
|
||||
return false;
|
||||
devercNum = numDevs;
|
||||
for (DWORD d = 0; d < numDevs; d++)
|
||||
{
|
||||
siStatus = SI_GetProductString(d, DeviceString, SI_RETURN_SERIAL_NUMBER);
|
||||
if (siStatus == SI_SUCCESS)
|
||||
{
|
||||
string deviceString = string(DeviceString);
|
||||
|
||||
transform(deviceString.begin(), deviceString.end(), deviceString.begin(), ::toupper);
|
||||
if (deviceId == deviceString)
|
||||
{
|
||||
devercNum = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
siStatus = SI_Open(devercNum, &cyHandle);
|
||||
siStatus = SI_SetBaudRate(cyHandle, baudrate);
|
||||
siStatus = SI_SetFlowControl(cyHandle, SI_HANDSHAKE_LINE, SI_FIRMWARE_CONTROLLED, SI_HELD_INACTIVE, SI_STATUS_INPUT, SI_STATUS_INPUT, 0);
|
||||
if (siStatus == SI_SUCCESS) {
|
||||
std::cout << "[LpmsU] SI_Open device is successul : " << deviceId << std::endl;
|
||||
|
||||
this->connected = true;
|
||||
SI_FlushBuffers(cyHandle, TRUE, TRUE);
|
||||
}
|
||||
else {
|
||||
std::cout << "[LpmsU] SI_Open device is failed : " << deviceId << std::endl;
|
||||
|
||||
this->connected = false;
|
||||
}
|
||||
|
||||
return this->connected ;
|
||||
}
|
||||
|
||||
void Serial::setMode(int mode)
|
||||
{
|
||||
usbMode = mode;
|
||||
}
|
||||
|
||||
int Serial::getMode(void)
|
||||
{
|
||||
return usbMode;
|
||||
}
|
||||
|
||||
bool Serial::close()
|
||||
{
|
||||
if (this->connected)
|
||||
{
|
||||
//We're no longer connected
|
||||
this->connected = false;
|
||||
//Close the serial handler
|
||||
if (usbMode == MODE_USB_EXPRESS)
|
||||
{
|
||||
SI_Close(cyHandle);
|
||||
|
||||
cout << "[LpmsU] Connection to " << idNumber << " closed." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CloseHandle(this->hSerial);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Serial::readData(unsigned char *buffer, unsigned int nbChar)
|
||||
{
|
||||
if (!isConnected())
|
||||
return 0;
|
||||
|
||||
if (usbMode == MODE_USB_EXPRESS)
|
||||
{
|
||||
SI_STATUS siStatus;
|
||||
PBYTE ModemStatus;
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned long eventDWord;
|
||||
unsigned long txBytes;
|
||||
unsigned long rxBytes;
|
||||
unsigned long qStatus;
|
||||
#else
|
||||
unsigned int eventDWord;
|
||||
unsigned int txBytes;
|
||||
unsigned int rxBytes;
|
||||
#endif
|
||||
|
||||
bool f = true;
|
||||
|
||||
unsigned long bytesReceived = 0;
|
||||
|
||||
if (this->connected == false) return 0;
|
||||
|
||||
siStatus = SI_CheckRXQueue(cyHandle, &rxBytes, &qStatus);
|
||||
|
||||
if (siStatus != SI_SUCCESS)
|
||||
{
|
||||
std::cout << "USB read error\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
siStatus = SI_Read(cyHandle, buffer, rxBytes, &bytesReceived);
|
||||
#else
|
||||
siStatus = SI_Read(cyHandle, buffer, rxBytes, (unsigned int *)bytesReceived);
|
||||
#endif
|
||||
|
||||
|
||||
return bytesReceived;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Number of bytes we'll have read
|
||||
DWORD bytesRead;
|
||||
//Number of bytes we'll really ask to read
|
||||
unsigned int toRead;
|
||||
|
||||
//int n;
|
||||
//ReadFile(this->hSerial, buffer, nbChar, (LPDWORD)((void *)&n), NULL);
|
||||
//return n;
|
||||
//Use the ClearCommError function to get status info on the Serial port
|
||||
ClearCommError(this->hSerial, &this->errors, &this->status);
|
||||
|
||||
//Check if there is something to read
|
||||
if (this->status.cbInQue>0)
|
||||
{
|
||||
//If there is we check if there is enough data to read the required number
|
||||
//of characters, if not we'll read only the available characters to prevent
|
||||
//locking of the application.
|
||||
if (this->status.cbInQue>nbChar)
|
||||
{
|
||||
toRead = nbChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
toRead = this->status.cbInQue;
|
||||
}
|
||||
|
||||
//Try to read the require number of chars, and return the number of read bytes on success
|
||||
if (ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL))
|
||||
{
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//If nothing has been read, or that an error was detected return -1
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Serial::writeData(const char *buffer, unsigned int nbChar)
|
||||
{
|
||||
if (!isConnected())
|
||||
{
|
||||
if (usbMode == MODE_USB_EXPRESS)
|
||||
std::cout << "Sensor " << idNumber << " not connected\n";
|
||||
else
|
||||
std::cout << "COM "<< portNo << " not connected\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbMode == MODE_USB_EXPRESS)
|
||||
{
|
||||
SI_STATUS siStatus;
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned long bytesWritten;
|
||||
#else
|
||||
unsigned int bytesWritten;
|
||||
#endif
|
||||
|
||||
bool f = false;
|
||||
|
||||
if (this->connected == false) return false;
|
||||
|
||||
siStatus = SI_Write(cyHandle, (unsigned char *)buffer, nbChar, &bytesWritten);
|
||||
|
||||
if (siStatus == SI_SUCCESS) {
|
||||
f = true;
|
||||
}else{
|
||||
f = false;
|
||||
std::cout << "Write error\n";
|
||||
}
|
||||
return f;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD bytesSend;
|
||||
//Try to write the buffer on the Serial port
|
||||
if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
|
||||
{
|
||||
std::cout << "Write error\n";
|
||||
//In case it don't work get comm error and return false
|
||||
ClearCommError(this->hSerial, &this->errors, &this->status);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Serial::isConnected()
|
||||
{
|
||||
//Simply return the connection status
|
||||
return this->connected;
|
||||
}
|
||||
Reference in New Issue
Block a user