sbgInterfaceSerialWin.c
Go to the documentation of this file.
1 #include "sbgInterfaceSerial.h"
2 #include <windows.h>
3 
4 //----------------------------------------------------------------------//
5 //- Internal methods declarations -//
6 //----------------------------------------------------------------------//
7 
13 uint32 sbgGetWindowsErrorMsg(char outErrorMsg[256])
14 {
15  DWORD dw = GetLastError();
16  DWORD numCharWritten;
17  LPVOID lpMsgBuf = NULL;
18 
19  //
20  // Get the error message
21  //
22  numCharWritten = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
23  NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
24 
25  //
26  // Test if a message has been correctly written
27  //
28  if (numCharWritten > 0)
29  {
30  //
31  // Copy the error message
32  //
33  strcpy_s(outErrorMsg, 256, lpMsgBuf);
34  }
35  else
36  {
37  outErrorMsg[0] = '\0';
38  }
39 
40  //
41  // Release the buffer
42  //
43  LocalFree(lpMsgBuf);
44 
45  return dw;
46 }
47 
48 //----------------------------------------------------------------------//
49 //- Operations methods declarations -//
50 //----------------------------------------------------------------------//
51 
59 SbgErrorCode sbgInterfaceSerialCreate(SbgInterface *pHandle, const char *deviceName, uint32 baudRate)
60 {
61  char errorMsg[256];
62  char comPortPath[32];
63  COMMTIMEOUTS comTimeOut;
64  DCB comState;
65  uint32 deviceNum;
66  HANDLE hSerialDevice;
67 
68  //
69  // Test input argument
70  //
71  SBG_ASSERT(pHandle);
72 
73  //
74  // Extract device number
75  //
76  if (sscanf_s(deviceName, "COM%i", &deviceNum) == 1)
77  {
78  //
79  // Build the com port path
80  //
81  sprintf_s(comPortPath, 32, "\\\\.\\COM%i", deviceNum);
82 
83  //
84  // Init the com port
85  //
86  hSerialDevice = CreateFile(comPortPath, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
87 
88  //
89  // Test that the port has been initialized
90  //
91  if (hSerialDevice != INVALID_HANDLE_VALUE)
92  {
93  //
94  // Purge the com port
95  //
96  if (PurgeComm(hSerialDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
97  {
98  //
99  // Retreives current com state and com timeout
100  //
101  if ( (GetCommState(hSerialDevice, &comState)) && (GetCommTimeouts(hSerialDevice, &comTimeOut)) )
102  {
103  //
104  // Define common attributes
105  //
106  comState.BaudRate= baudRate;
107  comState.Parity= NOPARITY;
108  comState.ByteSize= 8;
109  comState.StopBits= ONESTOPBIT;
110 
111  //
112  // Disable flow control
113  //
114  comState.fDsrSensitivity = false;
115  comState.fOutxCtsFlow = false;
116  comState.fOutxDsrFlow = false;
117  comState.fOutX = false;
118  comState.fInX = false;
119 
120  //
121  // Define timeout attributes (0 ms read timeout)
122  //
123  comTimeOut.ReadIntervalTimeout = MAXDWORD;
124  comTimeOut.ReadTotalTimeoutMultiplier = 0;
125  comTimeOut.ReadTotalTimeoutConstant = 0;
126 
127  comTimeOut.WriteTotalTimeoutConstant = 0;
128  comTimeOut.WriteTotalTimeoutMultiplier = 0;
129 
130  //
131  // Configure the com port
132  //
133  if ( (SetCommState(hSerialDevice, &comState)) && (SetCommTimeouts(hSerialDevice, &comTimeOut)) )
134  {
135  //
136  // Wait until the com port has been configured by windows
137  //
138  sbgSleep(60);
139 
140  //
141  // Define the COM port buffer size
142  //
143  if (SetupComm(hSerialDevice, SBG_IF_SERIAL_RX_BUFFER_SIZE, SBG_IF_SERIAL_TX_BUFFER_SIZE))
144  {
145  //
146  // The serial port is ready so create a new serial interface
147  //
148  pHandle->handle = hSerialDevice;
149  pHandle->type = SBG_IF_TYPE_SERIAL;
152 
153  //
154  // Purge the communication
155  //
156  return sbgInterfaceSerialFlush(pHandle);
157  }
158  else
159  {
160  sbgGetWindowsErrorMsg(errorMsg);
161  SBG_LOG_ERROR(SBG_ERROR, "Unable to define buffer size: %s", errorMsg);
162  }
163  }
164  else
165  {
166  sbgGetWindowsErrorMsg(errorMsg);
167  SBG_LOG_ERROR(SBG_ERROR, "Unable to set com state and/or timeout: %s", errorMsg);
168  }
169  }
170  else
171  {
172  sbgGetWindowsErrorMsg(errorMsg);
173  SBG_LOG_ERROR(SBG_ERROR, "Unable to retreive com state and/or timeout: %s", errorMsg);
174  }
175  }
176  else
177  {
178  sbgGetWindowsErrorMsg(errorMsg);
179  SBG_LOG_ERROR(SBG_ERROR, "Unable to purge com port %i: %s", deviceNum, errorMsg);
180  }
181 
182  //
183  // Close the port com
184  // An error occurred while setting up the serial port, close it.
185  //
186  CloseHandle(hSerialDevice);
187  }
188 
189  return SBG_ERROR;
190  }
191  else
192  {
193  //
194  // Invalid device name
195  //
196  return SBG_INVALID_PARAMETER;
197  }
198 }
199 
206 {
207  HANDLE pSerialDevice;
208 
209  //
210  // Test input arguments
211  //
212  SBG_ASSERT(pHandle);
213 
214  //
215  // Get the internal serial handle
216  //
217  pSerialDevice = (HANDLE)(pHandle->handle);
218 
219  //
220  // Close the port com
221  //
222  CloseHandle(pSerialDevice);
223  pHandle->handle = NULL;
224 
225  return SBG_NO_ERROR;
226 }
227 
234 {
235  SbgErrorCode errorCode = SBG_NO_ERROR;
236  HANDLE pSerialDevice;
237  char errorMsg[256];
238  uint8 dummyBuffer[256];
239  size_t numBytesRead;
240 
241  //
242  // Test input arguments
243  //
244  SBG_ASSERT(pHandle);
245 
246  //
247  // Get the internal serial handle
248  //
249  pSerialDevice = (HANDLE)(pHandle->handle);
250 
251  //
252  // Flush both Rx and Tx buffers
253  //
254  if (PurgeComm(pSerialDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
255  {
256  //
257  // Wait because some hardware doesn't execute the flush directly
258  //
259  sbgSleep(5);
260 
261  //
262  // Try to read as much data as possible to avoid flush issues with some hardware
263  //
264  do
265  {
266  errorCode = sbgInterfaceSerialRead(pHandle, dummyBuffer, &numBytesRead, sizeof(dummyBuffer));
267  } while ( (errorCode == SBG_NO_ERROR) && (numBytesRead > 0) );
268 
269  //
270  // Serial port successfully purged
271  //
272  return SBG_NO_ERROR;
273  }
274  else
275  {
276  //
277  // Flush has failed
278  //
279  sbgGetWindowsErrorMsg(errorMsg);
280  errorCode = SBG_ERROR;
281  SBG_LOG_ERROR(SBG_ERROR, "PurgeComm failed: %s", errorMsg);
282  }
283 
284  return errorCode;
285 }
286 
294 {
295  SbgErrorCode errorCode = SBG_NO_ERROR;
296  HANDLE pSerialDevice;
297  DCB comState;
298  char errorMsg[256];
299 
300  //
301  // Test input arguments
302  //
303  SBG_ASSERT(pHandle);
304 
305  //
306  // Get the internal serial handle
307  //
308  pSerialDevice = (HANDLE)(pHandle->handle);
309 
310  //
311  // Try to retreive current com state
312  //
313  if (GetCommState(pSerialDevice, &comState))
314  {
315  //
316  // Change the baud rate
317  //
318  comState.BaudRate = baudRate;
319 
320  //
321  // Configure the com state
322  //
323  if (SetCommState(pSerialDevice, &comState))
324  {
325  //
326  // Wait until the com port has been configured by windows
327  //
328  sbgSleep(60);
329 
330  errorCode = SBG_NO_ERROR;
331  }
332  else
333  {
334  errorCode = SBG_ERROR;
335  sbgGetWindowsErrorMsg(errorMsg);
336  SBG_LOG_ERROR(errorCode, "Unable to set com state: %s", errorMsg);
337 
338  }
339  }
340  else
341  {
342  errorCode = SBG_ERROR;
343  sbgGetWindowsErrorMsg(errorMsg);
344  SBG_LOG_ERROR(errorCode, "Unable to retreive com state: %s", errorMsg);
345  }
346 
347  return errorCode;
348 }
349 
350 //----------------------------------------------------------------------//
351 //- Internal interfaces write/read implementations -//
352 //----------------------------------------------------------------------//
353 
361 SbgErrorCode sbgInterfaceSerialWrite(SbgInterface *pHandle, const void *pBuffer, size_t bytesToWrite)
362 {
363  DWORD numBytesLeftToWrite = (DWORD)bytesToWrite;
364  uint8 *pCurrentBuffer = (uint8*)pBuffer;
365  DWORD numBytesWritten;
366  HANDLE pSerialDevice;
367  char errorMsg[256];
368 
369  //
370  // Test input arguments
371  //
372  SBG_ASSERT(pHandle);
373  SBG_ASSERT(pBuffer);
374 
375  //
376  // Get the internal serial handle
377  //
378  pSerialDevice = (HANDLE)(pHandle->handle);
379 
380  //
381  // Write the whole buffer
382  //
383  while (numBytesLeftToWrite > 0)
384  {
385  //
386  // Write these bytes to the serial interface
387  //
388  if (!WriteFile(pSerialDevice, pCurrentBuffer, numBytesLeftToWrite, (LPDWORD)&numBytesWritten, NULL))
389  {
390  //
391  // An error has occured during the write
392  //
393  sbgGetWindowsErrorMsg(errorMsg);
394  SBG_LOG_ERROR(SBG_WRITE_ERROR, "Write failed error: %s", errorMsg);
395  return SBG_WRITE_ERROR;
396  }
397 
398  //
399  // Update the buffer pointer and the number of bytes to write
400  //
401  numBytesLeftToWrite -= (size_t)numBytesWritten;
402  pCurrentBuffer += numBytesWritten;
403  }
404 
405  return SBG_NO_ERROR;
406 }
407 
416 SbgErrorCode sbgInterfaceSerialRead(SbgInterface *pHandle, void *pBuffer, size_t *pReadBytes, size_t bytesToRead)
417 {
418  HANDLE pSerialDevice;
419  char errorMsg[256];
420  DWORD bytesRead;
421 
422  //
423  // Test input arguments
424  //
425  SBG_ASSERT(pHandle);
426  SBG_ASSERT(pBuffer);
427  SBG_ASSERT(pReadBytes);
428 
429  //
430  // Get the internal serial handle
431  //
432  pSerialDevice = (HANDLE)(pHandle->handle);
433 
434  //
435  // Read some bytes on the serial buffer
436  //
437  if (ReadFile(pSerialDevice, pBuffer, (DWORD)bytesToRead, (LPDWORD)&bytesRead, NULL))
438  {
439  //
440  // Update the number of bytes read
441  //
442  (*pReadBytes) = (size_t)bytesRead;
443 
444  return SBG_NO_ERROR;
445  }
446  else
447  {
448  *pReadBytes = (size_t)bytesRead;
449 
450  //
451  // Unable to read some bytes
452  //
453  sbgGetWindowsErrorMsg(errorMsg);
454  SBG_LOG_ERROR(SBG_READ_ERROR, "Read failed: %s", errorMsg);
455  return SBG_READ_ERROR;
456  }
457 }
unsigned int uint32
Definition: sbgTypes.h:58
SbgErrorCode sbgInterfaceSerialRead(SbgInterface *pHandle, void *pBuffer, size_t *pReadBytes, size_t bytesToRead)
SbgErrorCode sbgInterfaceSerialDestroy(SbgInterface *pHandle)
uint32 sbgGetWindowsErrorMsg(char outErrorMsg[256])
void sbgSleep(uint32 ms)
Definition: sbgPlatform.c:54
SbgErrorCode sbgInterfaceSerialChangeBaudrate(SbgInterface *pHandle, uint32 baudRate)
SbgErrorCode sbgInterfaceSerialWrite(SbgInterface *pHandle, const void *pBuffer, size_t bytesToWrite)
SbgInterfaceHandle handle
Definition: sbgInterface.h:105
#define SBG_IF_SERIAL_RX_BUFFER_SIZE
SbgInterfaceReadFunc pReadFunc
Definition: sbgInterface.h:109
This file implements a serial interface.
#define NULL
Definition: sbgDefines.h:43
unsigned char uint8
Definition: sbgTypes.h:56
#define SBG_ASSERT(expression)
Definition: sbgDebug.h:52
#define SBG_LOG_ERROR(errorCode, format,...)
Definition: sbgDebug.h:63
SbgInterfaceType type
Definition: sbgInterface.h:106
#define SBG_IF_SERIAL_TX_BUFFER_SIZE
SbgInterfaceWriteFunc pWriteFunc
Definition: sbgInterface.h:108
enum _SbgErrorCode SbgErrorCode
SbgErrorCode sbgInterfaceSerialCreate(SbgInterface *pHandle, const char *deviceName, uint32 baudRate)
SbgErrorCode sbgInterfaceSerialFlush(SbgInterface *pHandle)


sbg_driver
Author(s):
autogenerated on Sun Jan 27 2019 03:42:20