Subversion Repositories HomeAutomation

Rev

Rev 270 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 270 Rev 800
1
#define STRICT
1
#define STRICT
2
#include "SerialConnection.h"
2
#include "SerialConnection.h"
3
 
3
 
4
 
4
 
5
 
5
 
6
void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length);
6
void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length);
7
 
7
 
8
bool queueEnqueue(CanProtoMessage cpm);
8
bool queueEnqueue(CanProtoMessage cpm);
9
bool queueDequeue(CanProtoMessage *cpm);
9
bool queueDequeue(CanProtoMessage *cpm);
10
 
10
 
11
CanProtoMessage *cpmQueue;
11
CanProtoMessage *cpmQueue;
12
int queueReadPointer=0;
12
int queueReadPointer=0;
13
int queueWritePointer=0;
13
int queueWritePointer=0;
14
int queueLength=0;
14
int queueLength=0;
15
 
15
 
16
 
16
 
17
static HANDLE hCom;
17
static HANDLE hCom;
18
static HANDLE  hRunMutex;  // "Keep Running" mutex 
18
static HANDLE  hRunMutex;  // "Keep Running" mutex 
19
 
19
 
20
static void SerRead(void *pMyID);
20
static void SerRead(void *pMyID);
21
 
21
 
22
SerialConnection::SerialConnection(LPCTSTR portName,EBaudrate baudRate,EDataBits byteSize,EParity parity, EStopBits stopBits)
22
SerialConnection::SerialConnection(LPCTSTR portName,EBaudrate baudRate,EDataBits byteSize,EParity parity, EStopBits stopBits)
23
{
23
{
24
    SerialConnection::uportName=portName;
24
    SerialConnection::uportName=portName;
25
    SerialConnection::ubaudRate=baudRate;
25
    SerialConnection::ubaudRate=baudRate;
26
    SerialConnection::ubyteSize=byteSize;
26
    SerialConnection::ubyteSize=byteSize;
27
    SerialConnection::uparity = parity;
27
    SerialConnection::uparity = parity;
28
    SerialConnection::ustopBits=stopBits;
28
    SerialConnection::ustopBits=stopBits;
29
 
29
 
30
    hCom = NULL;
30
    hCom = NULL;
31
}
31
}
32
 
32
 
33
SerialConnection::~SerialConnection() {  }
33
SerialConnection::~SerialConnection() {  }
34
 
34
 
35
bool SerialConnection::open()
35
bool SerialConnection::open()
36
{
36
{
37
    DCB dcb;
37
    DCB dcb;
38
 
38
 
39
    // Check if the port isn't already opened
39
    // Check if the port isn't already opened
40
    if (hCom)
40
    if (hCom)
41
    {
41
    {
42
        printf ("Open - Port already opened\n");
42
        printf ("Open - Port already opened\n");
43
        return false;
43
        return false;
44
    }
44
    }
45
 
45
 
46
    hCom = CreateFile( uportName,
46
    hCom = CreateFile( uportName,
47
                    GENERIC_READ | GENERIC_WRITE,
47
                    GENERIC_READ | GENERIC_WRITE,
48
                    0,    // must be opened with exclusive-access
48
                    0,    // must be opened with exclusive-access
49
                    NULL, // no security attributes
49
                    NULL, // no security attributes
50
                    OPEN_EXISTING, // must use OPEN_EXISTING
50
                    OPEN_EXISTING, // must use OPEN_EXISTING
51
                    FILE_FLAG_OVERLAPPED,    // not overlapped I/O
51
                    FILE_FLAG_OVERLAPPED,    // not overlapped I/O
52
                    NULL  // hTemplate must be NULL for comm devices
52
                    NULL  // hTemplate must be NULL for comm devices
53
                    );
53
                    );
54
 
54
 
55
    if (hCom == INVALID_HANDLE_VALUE)
55
    if (hCom == INVALID_HANDLE_VALUE)
56
    {
56
    {
57
       // Handle the error.
57
       // Handle the error.
58
       printf ("CreateFile failed with error %d.\n", GetLastError());
58
       printf ("CreateFile failed with error %d.\n", GetLastError());
59
       return false;
59
       return false;
60
    }
60
    }
61
 
61
 
62
    // Build on the current configuration, and skip setting the size
62
    // Build on the current configuration, and skip setting the size
63
    // of the input and output buffers with SetupComm.
63
    // of the input and output buffers with SetupComm.
64
 
64
 
65
 
65
 
66
    if (!GetCommState(hCom, &dcb))
66
    if (!GetCommState(hCom, &dcb))
67
    {
67
    {
68
      // Handle the error.
68
      // Handle the error.
69
      printf ("GetCommState failed with error %d.\n", GetLastError());
69
      printf ("GetCommState failed with error %d.\n", GetLastError());
70
      return false;
70
      return false;
71
    }
71
    }
72
 
72
 
73
    // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.
73
    // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.
74
 
74
 
75
    dcb.BaudRate = SerialConnection::ubaudRate;     // set the baud rate
75
    dcb.BaudRate = SerialConnection::ubaudRate;     // set the baud rate
76
    dcb.ByteSize = SerialConnection::ubyteSize;             // data size, xmit, and rcv
76
    dcb.ByteSize = SerialConnection::ubyteSize;             // data size, xmit, and rcv
77
    dcb.Parity = SerialConnection::uparity;        // no parity bit
77
    dcb.Parity = SerialConnection::uparity;        // no parity bit
78
    dcb.StopBits = SerialConnection::ustopBits;    // one stop bit
78
    dcb.StopBits = SerialConnection::ustopBits;    // one stop bit
79
 
79
 
80
    if (!SetCommState(hCom, &dcb))
80
    if (!SetCommState(hCom, &dcb))
81
    {
81
    {
82
      // Handle the error.
82
      // Handle the error.
83
      printf ("SetCommState failed with error %d.\n", GetLastError());
83
      printf ("SetCommState failed with error %d.\n", GetLastError());
84
      return false;
84
      return false;
85
    }
85
    }
86
 
86
 
87
    if (!SetCommMask(hCom, EV_RXCHAR))
87
    if (!SetCommMask(hCom, EV_RXCHAR))
88
    {
88
    {
89
        // Handle the error. 
89
        // Handle the error. 
90
        printf("SetCommMask failed with error %d.\n", GetLastError());
90
        printf("SetCommMask failed with error %d.\n", GetLastError());
91
        return false;
91
        return false;
92
    }
92
    }
93
 
93
 
94
    hRunMutex = CreateMutex( NULL, TRUE, NULL );      // Set 
94
    hRunMutex = CreateMutex( NULL, TRUE, NULL );      // Set 
95
    _beginthread( SerRead, 0, 0 );
95
    _beginthread( SerRead, 0, 0 );
96
 
96
 
97
    printf ("Serial port successfully reconfigured.\n");
97
    printf ("Serial port successfully reconfigured.\n");
98
    return true;
98
    return true;
99
}
99
}
100
 
100
 
101
HANDLE SerialConnection::getHandle()
101
HANDLE SerialConnection::getHandle()
102
{
102
{
103
 
103
 
104
    return hCom;
104
    return hCom;
105
}
105
}
106
 
106
 
107
 
107
 
108
bool SerialConnection::close()
108
bool SerialConnection::close()
109
{
109
{
110
    ReleaseMutex( hRunMutex );
110
    ReleaseMutex( hRunMutex );
111
    CloseHandle( hRunMutex );
111
    CloseHandle( hRunMutex );
112
 
112
 
113
    if (hCom==0)
113
    if (hCom==0)
114
    {
114
    {
115
        printf("Close - Method called when device is not open\n");
115
        printf("Close - Method called when device is not open\n");
116
        return false;
116
        return false;
117
    }
117
    }
118
 
118
 
119
    CloseHandle(hCom);
119
    CloseHandle(hCom);
120
 
120
 
121
    return true;
121
    return true;
122
}
122
}
123
 
123
 
124
bool SerialConnection::isOpen()
124
bool SerialConnection::isOpen()
125
{
125
{
126
    return (hCom != 0);
126
    return (hCom != 0);
127
}
127
}
128
 
128
 
129
bool SerialConnection::write(LPCVOID lpBuffer, unsigned int nNumberOfBytesToWrite)
129
bool SerialConnection::write(LPCVOID lpBuffer, unsigned int nNumberOfBytesToWrite)
130
{
130
{
131
    if (hCom==0)
131
    if (hCom==0)
132
    {
132
    {
133
        printf("Close - Method called when device is not open\n");
133
        printf("Close - Method called when device is not open\n");
134
        return false;
134
        return false;
135
    }
135
    }
136
 
136
 
137
    /*
137
    /*
138
    OVERLAPPED ol;
138
    OVERLAPPED ol;
139
    memset(&ol,0,sizeof(ol));
139
    memset(&ol,0,sizeof(ol));
140
 
140
 
141
    if (!WriteFileEx(hCom,lpBuffer,nNumberOfBytesToWrite,&ol,NULL))
141
    if (!WriteFileEx(hCom,lpBuffer,nNumberOfBytesToWrite,&ol,NULL))
142
    {
142
    {
143
        printf("Write - Unable to write the data\n");
143
        printf("Write - Unable to write the data\n");
144
    }
144
    }
145
*/
145
*/
146
 
146
 
147
    OVERLAPPED osWrite = {0};
147
    OVERLAPPED osWrite = {0};
148
   DWORD dwWritten;
148
   DWORD dwWritten;
149
   DWORD dwRes;
149
   DWORD dwRes;
150
   BOOL fRes;
150
   BOOL fRes;
151
 
151
 
152
 
152
 
153
    // Create this write operation's OVERLAPPED structure's hEvent.
153
    // Create this write operation's OVERLAPPED structure's hEvent.
154
   osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
154
   osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
155
   if (osWrite.hEvent == NULL)
155
   if (osWrite.hEvent == NULL)
156
   {
156
   {
157
      printf("error creating overlapped event handle\n");
157
      printf("error creating overlapped event handle\n");
158
      return FALSE;
158
      return FALSE;
159
   }
159
   }
160
 
160
 
161
 
161
 
162
    // Issue write.
162
    // Issue write.
163
   if (!WriteFile(hCom, lpBuffer, nNumberOfBytesToWrite, &dwWritten, &osWrite))
163
   if (!WriteFile(hCom, lpBuffer, nNumberOfBytesToWrite, &dwWritten, &osWrite))
164
   {
164
   {
165
      if (GetLastError() != ERROR_IO_PENDING)
165
      if (GetLastError() != ERROR_IO_PENDING)
166
      {
166
      {
167
         printf("WriteFile failed, but isn't delayed. Report error and abort.\n");
167
         printf("WriteFile failed, but isn't delayed. Report error and abort.\n");
168
         fRes = FALSE;
168
         fRes = FALSE;
169
      }
169
      }
170
      else
170
      else
171
      {
171
      {
172
         // Write is pending.
172
         // Write is pending.
173
         dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
173
         dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
174
         switch(dwRes)
174
         switch(dwRes)
175
         {
175
         {
176
            // OVERLAPPED structure's event has been signaled. 
176
            // OVERLAPPED structure's event has been signaled. 
177
            case WAIT_OBJECT_0:
177
            case WAIT_OBJECT_0:
178
                 if (!GetOverlappedResult(hCom, &osWrite, &dwWritten, FALSE))
178
                 if (!GetOverlappedResult(hCom, &osWrite, &dwWritten, FALSE))
179
                       fRes = FALSE;
179
                       fRes = FALSE;
180
                 else
180
                 else
181
                  // Write operation completed successfully.
181
                  // Write operation completed successfully.
182
                  fRes = TRUE;
182
                  fRes = TRUE;
183
                 break;
183
                 break;
184
           
184
           
185
            default:
185
            default:
186
                 // An error has occurred in WaitForSingleObject.
186
                 // An error has occurred in WaitForSingleObject.
187
                 // This usually indicates a problem with the
187
                 // This usually indicates a problem with the
188
                // OVERLAPPED structure's event handle.
188
                // OVERLAPPED structure's event handle.
189
                 fRes = FALSE;
189
                 fRes = FALSE;
190
                 break;
190
                 break;
191
         }
191
         }
192
      }
192
      }
193
   }
193
   }
194
   else fRes = TRUE;
194
   else fRes = TRUE;
195
      // WriteFile completed immediately.
195
      // WriteFile completed immediately.
196
     
196
     
197
 
197
 
198
   CloseHandle(osWrite.hEvent);
198
   CloseHandle(osWrite.hEvent);
199
   return fRes;
199
   return fRes;
200
 
200
 
201
 
201
 
202
 
202
 
203
 
203
 
204
    return false;
204
    return false;
205
}
205
}
206
 
206
 
207
 
207
 
208
void SerRead(void *pMyID)
208
void SerRead(void *pMyID)
209
{
209
{
210
    unsigned char iBuff[SERIAL_READ_BUFFER_SIZE];
210
    unsigned char iBuff[SERIAL_READ_BUFFER_SIZE];
211
    unsigned int iBuffPointer = 0;
211
    unsigned int iBuffPointer = 0;
212
 
212
 
213
    cpmQueue = (CanProtoMessage *)malloc(QUEUE_PLACES*sizeof(CanProtoMessage));
213
    cpmQueue = (CanProtoMessage *)malloc(QUEUE_PLACES*sizeof(CanProtoMessage));
214
 
214
 
215
    DWORD dwCommEvent;
215
    DWORD dwCommEvent;
216
    DWORD dwRead;
216
    DWORD dwRead;
217
    unsigned char chRead[128];
217
    unsigned char chRead[128];
218
 
218
 
219
    if (hCom ==0)
219
    if (hCom ==0)
220
    {
220
    {
221
        printf("Serial port closed.");
221
        printf("Serial port closed.");
222
        return;
222
        return;
223
    }
223
    }
224
 
224
 
225
    OVERLAPPED osReader = {0};
225
    OVERLAPPED osReader = {0};
226
 
226
 
227
    // Create the overlapped event. Must be closed before exiting
227
    // Create the overlapped event. Must be closed before exiting
228
    // to avoid a handle leak.
228
    // to avoid a handle leak.
229
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
229
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
230
 
230
 
231
 
231
 
232
 
232
 
233
    while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT )
233
    while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT )
234
    {
234
    {
235
 
235
 
236
        if (WaitCommEvent(hCom, &dwCommEvent, NULL))
236
        if (WaitCommEvent(hCom, &dwCommEvent, NULL))
237
        {
237
        {
238
            if (ReadFile(hCom, &chRead, 128, &dwRead, &osReader))
238
            if (ReadFile(hCom, &chRead, 128, &dwRead, &osReader))
239
            {
239
            {
240
 
240
 
241
                // Read data, until there is nothing left
241
                // Read data, until there is nothing left
242
                DWORD dwBytesRead = 0;
242
                DWORD dwBytesRead = 0;
243
                unsigned char szBuffer[SERIAL_INPUT_BUFFER_SIZE];
243
                unsigned char szBuffer[SERIAL_INPUT_BUFFER_SIZE];
244
                do
244
                do
245
                {
245
                {
246
 
246
 
247
                    if (dwRead > 0)
247
                    if (dwRead > 0)
248
                    {
248
                    {
249
                   
249
                   
250
                        // Spara i array, sist.
250
                        // Spara i array, sist.
251
                        arrayCopy(chRead, 0, iBuff, iBuffPointer, dwRead);
251
                        arrayCopy(chRead, 0, iBuff, iBuffPointer, dwRead);
252
                        iBuffPointer += dwRead;
252
                        iBuffPointer += dwRead;
253
 
253
 
254
                        // Följ parserutin.
254
                        // Följ parserutin.
255
                        // Köa.
255
                        // Köa.
256
                        // flytta.
256
                        // flytta.
257
 
257
 
258
                         // När array större eller lika med PACKET_LENGTH...
258
                         // När array större eller lika med PACKET_LENGTH...
259
                        while (iBuffPointer >= PACKET_LENGTH)
259
                        while (iBuffPointer >= PACKET_LENGTH)
260
                        {
260
                        {
261
                            int startIndex = 0;
261
                            int startIndex = 0;
262
 
262
 
263
                            // Sök igenom efter start byte från början.
263
                            // Sök igenom efter start byte från början.
264
                            for (unsigned int i = 0; i < iBuffPointer; i++)
264
                            for (unsigned int i = 0; i < iBuffPointer; i++)
265
                            {
265
                            {
266
                                // Poppa alla bytes som inte är startbyte.
266
                                // Poppa alla bytes som inte är startbyte.
267
                                if (iBuff[i] != UART_START_BYTE) startIndex++;
267
                                if (iBuff[i] != UART_START_BYTE) startIndex++;
268
                                else
268
                                else
269
                                {
269
                                {
270
                                    // När startbyte hittas, kolla om återstående längd är större eller lika med PACKET_LENGTH (inkl startbyte)
270
                                    // När startbyte hittas, kolla om återstående längd är större eller lika med PACKET_LENGTH (inkl startbyte)
271
                                    if ((iBuffPointer - startIndex) >= PACKET_LENGTH)
271
                                    if ((iBuffPointer - startIndex) >= PACKET_LENGTH)
272
                                    {
272
                                    {
273
                                        //om så, kolla PACKET_LENGTH-1 byte fram.
273
                                        //om så, kolla PACKET_LENGTH-1 byte fram.
274
                                        if (iBuff[startIndex + PACKET_LENGTH - 1] == UART_END_BYTE)
274
                                        if (iBuff[startIndex + PACKET_LENGTH - 1] == UART_END_BYTE)
275
                                        {
275
                                        {
276
                                            // Om byte PACKET_LENGTH-1 är slutbyte så extraktas startIndex till slutbyteindex.
276
                                            // Om byte PACKET_LENGTH-1 är slutbyte så extraktas startIndex till slutbyteindex.
277
                                            CanProtoMessage cmp(iBuff,startIndex + 1);
277
                                            CanProtoMessage cmp(iBuff,startIndex + 1);
278
                                            queueEnqueue(cmp);
278
                                            queueEnqueue(cmp);
279
                                           
279
                                           
280
 
280
 
281
                                            // Sätt ny startindex och avsluta loop.
281
                                            // Sätt ny startindex och avsluta loop.
282
                                            startIndex += PACKET_LENGTH;
282
                                            startIndex += PACKET_LENGTH;
283
                                            break;
283
                                            break;
284
                                        }
284
                                        }
285
                                    }
285
                                    }
286
                                }
286
                                }
287
                            }
287
                            }
288
                            // och i slutet göra en array copy.
288
                            // och i slutet göra en array copy.
289
                            // Flytta ner allt efter slutbyte till index 0 i array.
289
                            // Flytta ner allt efter slutbyte till index 0 i array.
290
                            arrayCopy(iBuff, startIndex, iBuff, 0, iBuffPointer - PACKET_LENGTH);
290
                            arrayCopy(iBuff, startIndex, iBuff, 0, iBuffPointer - PACKET_LENGTH);
291
                            iBuffPointer -= startIndex;
291
                            iBuffPointer -= startIndex;
292
                        }
292
                        }
293
                    }
293
                    }
294
 
294
 
295
 
295
 
296
                }while (dwBytesRead == sizeof(szBuffer)-1);
296
                }while (dwBytesRead == sizeof(szBuffer)-1);
297
       
297
       
298
                //printf("byte receiced\n");
298
                //printf("byte receiced\n");
299
 
299
 
300
 
300
 
301
            } else { printf("Error (1): %d\n",GetLastError()); break;}
301
            } else { printf("Error (1): %d\n",GetLastError()); break;}
302
        } else { printf("Error (2): %d\n",GetLastError()); break;}
302
        } else { printf("Error (2): %d\n",GetLastError()); break;}
303
    }
303
    }
304
 
304
 
305
 
305
 
306
}
306
}
307
 
307
 
308
bool SerialConnection::getMessage(CanProtoMessage *cpm)
308
bool SerialConnection::getMessage(CanProtoMessage *cpm)
309
{
309
{
310
    return queueDequeue(cpm);
310
    return queueDequeue(cpm);
311
}
311
}
312
 
312
 
313
void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length)
313
void arrayCopy(unsigned char *src,unsigned int srcIndex,unsigned char *dst,unsigned int dstIndex,unsigned int length)
314
{
314
{
315
    // Copy an aray to another array (of unsigned chars == bytes)
315
    // Copy an aray to another array (of unsigned chars == bytes)
316
    for(unsigned int i=0;i<length;i++) dst[dstIndex+i]=src[srcIndex+i];
316
    for(unsigned int i=0;i<length;i++) dst[dstIndex+i]=src[srcIndex+i];
317
}
317
}
318
 
318
 
319
 
319
 
320
bool queueEnqueue(CanProtoMessage cpm)
320
bool queueEnqueue(CanProtoMessage cpm)
321
{
321
{
322
    // Enqueue reveiced message to queue
322
    // Enqueue reveiced message to queue
323
    if (queueLength>=QUEUE_PLACES) return false;
323
    if (queueLength>=QUEUE_PLACES) return false;
324
 
324
 
325
    cpmQueue[queueWritePointer]=cpm;
325
    cpmQueue[queueWritePointer]=cpm;
326
 
326
 
327
    queueLength++;
327
    queueLength++;
328
    queueWritePointer++;
328
    queueWritePointer++;
329
    if (queueWritePointer>=QUEUE_PLACES) queueWritePointer=0;
329
    if (queueWritePointer>=QUEUE_PLACES) queueWritePointer=0;
330
 
330
 
331
    printf("[%ld] Queue message, length: %d\n",GetTickCount(),queueLength);
331
    printf("[%ld] Queue message, length: %d\n",GetTickCount(),queueLength);
332
 
332
 
333
    return true;
333
    return true;
334
}
334
}
335
bool queueDequeue(CanProtoMessage *cpm)
335
bool queueDequeue(CanProtoMessage *cpm)
336
{
336
{
337
    // Dequeue can message.
337
    // Dequeue can message.
338
    if (queueLength==0) return false;
338
    if (queueLength==0) return false;
339
 
339
 
340
    cpm = &cpmQueue[queueReadPointer];
340
    cpm = &cpmQueue[queueReadPointer];
341
 
341
 
342
    queueLength--;
342
    queueLength--;
343
    queueReadPointer++;
343
    queueReadPointer++;
344
    if (queueReadPointer>=QUEUE_PLACES) queueReadPointer=0;
344
    if (queueReadPointer>=QUEUE_PLACES) queueReadPointer=0;
345
 
345
 
346
    return true;
346
    return true;
347
}
347
}