Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed
#define STRICT#include "SerialConnection.h"void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length);bool queueEnqueue(CanProtoMessage cpm);bool queueDequeue(CanProtoMessage *cpm);CanProtoMessage *cpmQueue;int queueReadPointer=0;int queueWritePointer=0;int queueLength=0;static HANDLE hCom;static HANDLE hRunMutex; // "Keep Running" mutexstatic void SerRead(void *pMyID);SerialConnection::SerialConnection(LPCTSTR portName,EBaudrate baudRate,EDataBits byteSize,EParity parity, EStopBits stopBits){SerialConnection::uportName=portName;SerialConnection::ubaudRate=baudRate;SerialConnection::ubyteSize=byteSize;SerialConnection::uparity = parity;SerialConnection::ustopBits=stopBits;hCom = NULL;}SerialConnection::~SerialConnection() { }bool SerialConnection::open(){DCB dcb;// Check if the port isn't already openedif (hCom){printf ("Open - Port already opened\n");return false;}hCom = CreateFile( uportName,GENERIC_READ | GENERIC_WRITE,0, // must be opened with exclusive-accessNULL, // no security attributesOPEN_EXISTING, // must use OPEN_EXISTINGFILE_FLAG_OVERLAPPED, // not overlapped I/ONULL // hTemplate must be NULL for comm devices);if (hCom == INVALID_HANDLE_VALUE){// Handle the error.printf ("CreateFile failed with error %d.\n", GetLastError());return false;}// Build on the current configuration, and skip setting the size// of the input and output buffers with SetupComm.if (!GetCommState(hCom, &dcb)){// Handle the error.printf ("GetCommState failed with error %d.\n", GetLastError());return false;}// Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.dcb.BaudRate = SerialConnection::ubaudRate; // set the baud ratedcb.ByteSize = SerialConnection::ubyteSize; // data size, xmit, and rcvdcb.Parity = SerialConnection::uparity; // no parity bitdcb.StopBits = SerialConnection::ustopBits; // one stop bitif (!SetCommState(hCom, &dcb)){// Handle the error.printf ("SetCommState failed with error %d.\n", GetLastError());return false;}if (!SetCommMask(hCom, EV_RXCHAR)){// Handle the error.printf("SetCommMask failed with error %d.\n", GetLastError());return false;}hRunMutex = CreateMutex( NULL, TRUE, NULL ); // Set_beginthread( SerRead, 0, 0 );printf ("Serial port successfully reconfigured.\n");return true;}HANDLE SerialConnection::getHandle(){return hCom;}bool SerialConnection::close(){ReleaseMutex( hRunMutex );CloseHandle( hRunMutex );if (hCom==0){printf("Close - Method called when device is not open\n");return false;}CloseHandle(hCom);return true;}bool SerialConnection::isOpen(){return (hCom != 0);}bool SerialConnection::write(LPCVOID lpBuffer, unsigned int nNumberOfBytesToWrite){if (hCom==0){printf("Close - Method called when device is not open\n");return false;}/*OVERLAPPED ol;memset(&ol,0,sizeof(ol));if (!WriteFileEx(hCom,lpBuffer,nNumberOfBytesToWrite,&ol,NULL)){printf("Write - Unable to write the data\n");}*/OVERLAPPED osWrite = {0};DWORD dwWritten;DWORD dwRes;BOOL fRes;// Create this write operation's OVERLAPPED structure's hEvent.osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (osWrite.hEvent == NULL){printf("error creating overlapped event handle\n");return FALSE;}// Issue write.if (!WriteFile(hCom, lpBuffer, nNumberOfBytesToWrite, &dwWritten, &osWrite)){if (GetLastError() != ERROR_IO_PENDING){printf("WriteFile failed, but isn't delayed. Report error and abort.\n");fRes = FALSE;}else{// Write is pending.dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);switch(dwRes){// OVERLAPPED structure's event has been signaled.case WAIT_OBJECT_0:if (!GetOverlappedResult(hCom, &osWrite, &dwWritten, FALSE))fRes = FALSE;else// Write operation completed successfully.fRes = TRUE;break;default:// An error has occurred in WaitForSingleObject.// This usually indicates a problem with the// OVERLAPPED structure's event handle.fRes = FALSE;break;}}}else fRes = TRUE;// WriteFile completed immediately.CloseHandle(osWrite.hEvent);return fRes;return false;}void SerRead(void *pMyID){unsigned char iBuff[SERIAL_READ_BUFFER_SIZE];unsigned int iBuffPointer = 0;cpmQueue = (CanProtoMessage *)malloc(QUEUE_PLACES*sizeof(CanProtoMessage));DWORD dwCommEvent;DWORD dwRead;unsigned char chRead[128];if (hCom ==0){printf("Serial port closed.");return;}OVERLAPPED osReader = {0};// Create the overlapped event. Must be closed before exiting// to avoid a handle leak.osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT ){if (WaitCommEvent(hCom, &dwCommEvent, NULL)){if (ReadFile(hCom, &chRead, 128, &dwRead, &osReader)){// Read data, until there is nothing leftDWORD dwBytesRead = 0;unsigned char szBuffer[SERIAL_INPUT_BUFFER_SIZE];do{if (dwRead > 0){// Spara i array, sist.arrayCopy(chRead, 0, iBuff, iBuffPointer, dwRead);iBuffPointer += dwRead;// Följ parserutin.// Köa.// flytta.// När array större eller lika med PACKET_LENGTH...while (iBuffPointer >= PACKET_LENGTH){int startIndex = 0;// Sök igenom efter start byte från början.for (unsigned int i = 0; i < iBuffPointer; i++){// Poppa alla bytes som inte är startbyte.if (iBuff[i] != UART_START_BYTE) startIndex++;else{// När startbyte hittas, kolla om återstående längd är större eller lika med PACKET_LENGTH (inkl startbyte)if ((iBuffPointer - startIndex) >= PACKET_LENGTH){//om så, kolla PACKET_LENGTH-1 byte fram.if (iBuff[startIndex + PACKET_LENGTH - 1] == UART_END_BYTE){// Om byte PACKET_LENGTH-1 är slutbyte så extraktas startIndex till slutbyteindex.CanProtoMessage cmp(iBuff,startIndex + 1);queueEnqueue(cmp);// Sätt ny startindex och avsluta loop.startIndex += PACKET_LENGTH;break;}}}}// och i slutet göra en array copy.// Flytta ner allt efter slutbyte till index 0 i array.arrayCopy(iBuff, startIndex, iBuff, 0, iBuffPointer - PACKET_LENGTH);iBuffPointer -= startIndex;}}}while (dwBytesRead == sizeof(szBuffer)-1);//printf("byte receiced\n");} else { printf("Error (1): %d\n",GetLastError()); break;}} else { printf("Error (2): %d\n",GetLastError()); break;}}}bool SerialConnection::getMessage(CanProtoMessage *cpm){return queueDequeue(cpm);}void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length){// Copy an aray to another array (of unsigned chars == bytes)for(unsigned int i=0;i<length;i++) dst[dstIndex+i]=src[srcIndex+i];}bool queueEnqueue(CanProtoMessage cpm){// Enqueue reveiced message to queueif (queueLength>=QUEUE_PLACES) return false;cpmQueue[queueWritePointer]=cpm;queueLength++;queueWritePointer++;if (queueWritePointer>=QUEUE_PLACES) queueWritePointer=0;printf("[%ld] Queue message, length: %d\n",GetTickCount(),queueLength);return true;}bool queueDequeue(CanProtoMessage *cpm){// Dequeue can message.if (queueLength==0) return false;cpm = &cpmQueue[queueReadPointer];queueLength--;queueReadPointer++;if (queueReadPointer>=QUEUE_PLACES) queueReadPointer=0;return true;}