30.11.2010 - initial commit
This commit is contained in:
245
piserial.cpp
Normal file
245
piserial.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
#include "piserial.h"
|
||||
|
||||
|
||||
PISerial::PISerial(string name, void * data_, SerialFunc slot): PIThread() {
|
||||
setPriority(piHigh);
|
||||
data = data_;
|
||||
devName = name;
|
||||
fd = -1;
|
||||
dataSize = headerSize = 0;
|
||||
headerPtr = 0;
|
||||
ret_func = slot;
|
||||
buffer = new char[BUFFER_SIZE];
|
||||
sbuffer = new char[BUFFER_SIZE];
|
||||
#ifdef WINDOWS
|
||||
hCom = 0;
|
||||
#endif
|
||||
ispeed = ospeed = B115200;
|
||||
}
|
||||
|
||||
|
||||
PISerial::~PISerial() {
|
||||
stop();
|
||||
pthread_cancel(thread);
|
||||
#ifdef WINDOWS
|
||||
if (fd != -1) {
|
||||
SetCommState(hCom, &sdesc);
|
||||
SetCommMask(hCom, mask);
|
||||
CloseHandle(hCom);
|
||||
}
|
||||
#else
|
||||
if (fd != -1) {
|
||||
tcsetattr(fd, TCSANOW, &sdesc);
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
delete buffer;
|
||||
delete sbuffer;
|
||||
}
|
||||
|
||||
|
||||
void PISerial::begin() {
|
||||
sbuffIndex = 0;
|
||||
startIndex = 0;
|
||||
backIndex = 0;
|
||||
tryagain = first = false;
|
||||
hbuffer = new char[headerSize];
|
||||
pbuffer = new char[dataSize];
|
||||
if (!init()) stop();
|
||||
}
|
||||
|
||||
|
||||
void PISerial::run() {
|
||||
if (dataSize == 0) return;
|
||||
char b;
|
||||
int i = 0, j;
|
||||
#ifdef WINDOWS
|
||||
WaitCommEvent(hCom, 0, 0);
|
||||
ReadFile(hCom, buffer, dataSize, &readed, 0);
|
||||
#else
|
||||
readed = read(fd, buffer, BUFFER_SIZE);
|
||||
#endif
|
||||
if (headerSize > 0)
|
||||
{
|
||||
while (i < readed)
|
||||
{
|
||||
//cout << sbuffIndex << ";" << startIndex << endl;
|
||||
if (!tryagain)
|
||||
{
|
||||
b = buffer[i];
|
||||
sbuffer[sbuffIndex] = b;
|
||||
} else {
|
||||
backIndex++;
|
||||
if (backIndex == headerSize + dataSize) tryagain = false;
|
||||
}
|
||||
if (first)
|
||||
{
|
||||
if (sbuffIndex-startIndex == headerSize + dataSize - 1)
|
||||
{
|
||||
//cout << "vsdfgvb" << endl;
|
||||
memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize);
|
||||
if (ret_func(data, pbuffer))
|
||||
{
|
||||
startIndex = 0;
|
||||
sbuffIndex = -1;
|
||||
} else {
|
||||
//startIndex++;
|
||||
memcpy(sbuffer, hbuffer, headerSize);
|
||||
memcpy(&sbuffer[headerSize], pbuffer, dataSize);
|
||||
backIndex = 0;
|
||||
tryagain = true;
|
||||
startIndex = 1;
|
||||
sbuffIndex = -1;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
if (sbuffIndex - startIndex == headerSize - 1)
|
||||
{
|
||||
memcpy(hbuffer, &sbuffer[startIndex], headerSize);
|
||||
for (j = 0; j < headerSize; ++j) {
|
||||
if (hbuffer[j] != ((char*)headerPtr)[j]) {
|
||||
startIndex++;
|
||||
//cout << "no" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == headerSize) {
|
||||
first = true;
|
||||
//cout << "yes" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuffIndex++;
|
||||
if (sbuffIndex >= BUFFER_SIZE)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
memcpy(pbuffer, &sbuffer[startIndex + headerSize], BUFFER_SIZE - startIndex - headerSize);
|
||||
memcpy(sbuffer, hbuffer, headerSize);
|
||||
memcpy(&sbuffer[headerSize], pbuffer, BUFFER_SIZE - startIndex - headerSize);
|
||||
sbuffIndex = BUFFER_SIZE - startIndex - 1;
|
||||
} else {
|
||||
memcpy(sbuffer, hbuffer, headerSize);
|
||||
sbuffIndex = headerSize - 1;
|
||||
startIndex = 0;
|
||||
}
|
||||
}
|
||||
if (!tryagain) i++;
|
||||
}
|
||||
} else {
|
||||
for (uint i = 0; i < readed; ++i) {
|
||||
b = buffer[i];
|
||||
sbuffer[sbuffIndex] = b;
|
||||
if (sbuffIndex == dataSize - 1) {
|
||||
if (ret_func != 0) ret_func(data, sbuffer);
|
||||
sbuffIndex = -1;
|
||||
}
|
||||
sbuffIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PISerial::end() {
|
||||
delete pbuffer;
|
||||
delete hbuffer;
|
||||
if (fd == -1) return;
|
||||
#ifdef WINDOWS
|
||||
SetCommState(hCom, &sdesc);
|
||||
CloseHandle(hCom);
|
||||
#else
|
||||
tcsetattr(fd, TCSANOW, &sdesc);
|
||||
close(fd);
|
||||
#endif
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::init() {
|
||||
#ifdef WINDOWS
|
||||
hCom = CreateFile(devName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if(hCom == INVALID_HANDLE_VALUE) {
|
||||
cout << "[PISerial] Unable to open " << devName << endl;
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
COMMTIMEOUTS times;
|
||||
times.ReadIntervalTimeout = 1;
|
||||
times.ReadTotalTimeoutConstant = 1;
|
||||
times.ReadTotalTimeoutMultiplier = 0;
|
||||
times.WriteTotalTimeoutConstant = 0;
|
||||
times.WriteTotalTimeoutMultiplier = 1;
|
||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||
cout << "[PISerial] Unable to set timeouts for " << devName << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
GetCommMask(hCom, &mask);
|
||||
SetCommMask(hCom, EV_RXCHAR);
|
||||
GetCommState(hCom, &sdesc);
|
||||
desc = sdesc;
|
||||
desc.DCBlength = sizeof(desc);
|
||||
desc.BaudRate = ispeed;
|
||||
desc.ByteSize = 8;
|
||||
desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1;
|
||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
if (SetCommState(hCom, &desc) == -1) {
|
||||
cout << "[PISerial] Unable to set comm state for " << devName << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
fd = open(devName.data(), O_NOCTTY | O_RDWR);
|
||||
if(fd == -1) {
|
||||
cout << "[PISerial] Unable to open " << devName << endl;
|
||||
return false;
|
||||
}
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
|
||||
tcgetattr(fd, &desc);
|
||||
sdesc = desc;
|
||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
||||
desc.c_cflag = CLOCAL | CREAD | CSIZE;
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag &= CSTOPB;
|
||||
if (params[PISerial::IgnoreParityControl]) desc.c_iflag &= IGNPAR ; // | INPCK | IGNBRK | IGNCR;
|
||||
desc.c_cc[VMIN] = 0;
|
||||
desc.c_cc[VTIME] = 1;
|
||||
|
||||
cfsetispeed(&desc, ispeed);
|
||||
cfsetospeed(&desc, ospeed);
|
||||
|
||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||
cout << "[PISerial] Can`t set attributes for " << devName << endl;
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
//cout << "[PISerial] Initialized " << devName << endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::send(char * data, int size) {
|
||||
//cout << "[PISerial] send size: " << sizeof(data) << endl;
|
||||
if (fd == -1) {
|
||||
//cout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
||||
return false;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
DWORD wrote;
|
||||
WriteFile(hCom, data, size, &wrote, 0);
|
||||
#else
|
||||
int wrote;
|
||||
wrote = write(fd, data, size);
|
||||
#endif
|
||||
if ((int)wrote != size) {
|
||||
//cout << "[PISerial] Error while sending" << endl;
|
||||
return false;
|
||||
}
|
||||
//cout << "[PISerial] Wrote " << wrote << " bytes in " << devName << endl;
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user