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  assert(pHandle);
69 
70  //
71  // Extract device number
72  //
73  if (sscanf_s(deviceName, "COM%i", &deviceNum) == 1)
74  {
75  //
76  // Build the com port path
77  //
78  sprintf_s(comPortPath, 32, "\\\\.\\COM%i", deviceNum);
79 
80  //
81  // Init the com port
82  //
83  hSerialDevice = CreateFile(comPortPath, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
84 
85  //
86  // Test that the port has been initialized
87  //
88  if (hSerialDevice != INVALID_HANDLE_VALUE)
89  {
90  //
91  // Purge the com port
92  //
93  if (PurgeComm(hSerialDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
94  {
95  //
96  // Retreives current com state and com timeout
97  //
98  if ( (GetCommState(hSerialDevice, &comState)) && (GetCommTimeouts(hSerialDevice, &comTimeOut)) )
99  {
100  //
101  // Define common attributes
102  //
103  comState.BaudRate= baudRate;
104  comState.Parity= NOPARITY;
105  comState.ByteSize= 8;
106  comState.StopBits= ONESTOPBIT;
107 
108  //
109  // Disable flow control
110  //
111  comState.fDsrSensitivity = false;
112  comState.fOutxCtsFlow = false;
113  comState.fOutxDsrFlow = false;
114  comState.fOutX = false;
115  comState.fInX = false;
116 
117  //
118  // Define timeout attributes (0 ms read timeout)
119  //
120  comTimeOut.ReadIntervalTimeout = MAXDWORD;
121  comTimeOut.ReadTotalTimeoutMultiplier = 0;
122  comTimeOut.ReadTotalTimeoutConstant = 0;
123 
124  comTimeOut.WriteTotalTimeoutConstant = 0;
125  comTimeOut.WriteTotalTimeoutMultiplier = 0;
126 
127  //
128  // Configure the com port
129  //
130  if ( (SetCommState(hSerialDevice, &comState)) && (SetCommTimeouts(hSerialDevice, &comTimeOut)) )
131  {
132  //
133  // Wait until the com port has been configured by windows
134  //
135  sbgSleep(60);
136 
137  //
138  // Define the COM port buffer size
139  //
140  if (SetupComm(hSerialDevice, SBG_IF_SERIAL_RX_BUFFER_SIZE, SBG_IF_SERIAL_TX_BUFFER_SIZE))
141  {
142  //
143  // The serial port is ready so create a new serial interface
144  //
145  pHandle->handle = hSerialDevice;
146  pHandle->type = SBG_IF_TYPE_SERIAL;
149 
150  //
151  // Purge the communication
152  //
153  return sbgInterfaceSerialFlush(pHandle);
154  }
155  else
156  {
157  sbgGetWindowsErrorMsg(errorMsg);
158  SBG_LOG_ERROR(SBG_ERROR, "Unable to define buffer size: %s", errorMsg);
159  }
160  }
161  else
162  {
163  sbgGetWindowsErrorMsg(errorMsg);
164  SBG_LOG_ERROR(SBG_ERROR, "Unable to set com state and/or timeout: %s", errorMsg);
165  }
166  }
167  else
168  {
169  sbgGetWindowsErrorMsg(errorMsg);
170  SBG_LOG_ERROR(SBG_ERROR, "Unable to retreive com state and/or timeout: %s", errorMsg);
171  }
172  }
173  else
174  {
175  sbgGetWindowsErrorMsg(errorMsg);
176  SBG_LOG_ERROR(SBG_ERROR, "Unable to purge com port %i: %s", deviceNum, errorMsg);
177  }
178 
179  //
180  // Close the port com
181  // An error occurred while setting up the serial port, close it.
182  //
183  CloseHandle(hSerialDevice);
184  }
185 
186  return SBG_ERROR;
187  }
188  else
189  {
190  //
191  // Invalid device name
192  //
193  return SBG_INVALID_PARAMETER;
194  }
195 }
196 
203 {
204  HANDLE pSerialDevice;
205 
206  assert(pHandle);
207 
208  //
209  // Get the internal serial handle
210  //
211  pSerialDevice = (HANDLE)(pHandle->handle);
212 
213  //
214  // Close the port com
215  //
216  CloseHandle(pSerialDevice);
217  pHandle->handle = NULL;
218 
219  return SBG_NO_ERROR;
220 }
221 
228 {
229  SbgErrorCode errorCode = SBG_NO_ERROR;
230  HANDLE pSerialDevice;
231  char errorMsg[256];
232  uint8 dummyBuffer[256];
233  size_t numBytesRead;
234 
235  assert(pHandle);
236 
237  //
238  // Get the internal serial handle
239  //
240  pSerialDevice = (HANDLE)(pHandle->handle);
241 
242  //
243  // Flush both Rx and Tx buffers
244  //
245  if (PurgeComm(pSerialDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
246  {
247  //
248  // Wait because some hardware doesn't execute the flush directly
249  //
250  sbgSleep(5);
251 
252  //
253  // Try to read as much data as possible to avoid flush issues with some hardware
254  //
255  do
256  {
257  errorCode = sbgInterfaceSerialRead(pHandle, dummyBuffer, &numBytesRead, sizeof(dummyBuffer));
258  } while ( (errorCode == SBG_NO_ERROR) && (numBytesRead > 0) );
259 
260  //
261  // Serial port successfully purged
262  //
263  return SBG_NO_ERROR;
264  }
265  else
266  {
267  //
268  // Flush has failed
269  //
270  sbgGetWindowsErrorMsg(errorMsg);
271  errorCode = SBG_ERROR;
272  SBG_LOG_ERROR(SBG_ERROR, "PurgeComm failed: %s", errorMsg);
273  }
274 
275  return errorCode;
276 }
277 
285 {
286  SbgErrorCode errorCode = SBG_NO_ERROR;
287  HANDLE pSerialDevice;
288  DCB comState;
289  char errorMsg[256];
290 
291  assert(pHandle);
292 
293  //
294  // Get the internal serial handle
295  //
296  pSerialDevice = (HANDLE)(pHandle->handle);
297 
298  //
299  // Try to retreive current com state
300  //
301  if (GetCommState(pSerialDevice, &comState))
302  {
303  //
304  // Change the baud rate
305  //
306  comState.BaudRate = baudRate;
307 
308  //
309  // Configure the com state
310  //
311  if (SetCommState(pSerialDevice, &comState))
312  {
313  //
314  // Wait until the com port has been configured by windows
315  //
316  sbgSleep(60);
317 
318  errorCode = SBG_NO_ERROR;
319  }
320  else
321  {
322  errorCode = SBG_ERROR;
323  sbgGetWindowsErrorMsg(errorMsg);
324  SBG_LOG_ERROR(errorCode, "Unable to set com state: %s", errorMsg);
325 
326  }
327  }
328  else
329  {
330  errorCode = SBG_ERROR;
331  sbgGetWindowsErrorMsg(errorMsg);
332  SBG_LOG_ERROR(errorCode, "Unable to retreive com state: %s", errorMsg);
333  }
334 
335  return errorCode;
336 }
337 
338 //----------------------------------------------------------------------//
339 //- Internal interfaces write/read implementations -//
340 //----------------------------------------------------------------------//
341 
349 SbgErrorCode sbgInterfaceSerialWrite(SbgInterface *pHandle, const void *pBuffer, size_t bytesToWrite)
350 {
351  DWORD numBytesLeftToWrite = (DWORD)bytesToWrite;
352  uint8 *pCurrentBuffer = (uint8*)pBuffer;
353  DWORD numBytesWritten;
354  HANDLE pSerialDevice;
355  char errorMsg[256];
356 
357  assert(pHandle);
358  assert(pBuffer);
359 
360  //
361  // Get the internal serial handle
362  //
363  pSerialDevice = (HANDLE)(pHandle->handle);
364 
365  //
366  // Write the whole buffer
367  //
368  while (numBytesLeftToWrite > 0)
369  {
370  //
371  // Write these bytes to the serial interface
372  //
373  if (!WriteFile(pSerialDevice, pCurrentBuffer, numBytesLeftToWrite, (LPDWORD)&numBytesWritten, NULL))
374  {
375  //
376  // An error has occured during the write
377  //
378  sbgGetWindowsErrorMsg(errorMsg);
379  SBG_LOG_ERROR(SBG_WRITE_ERROR, "Write failed error: %s", errorMsg);
380  return SBG_WRITE_ERROR;
381  }
382 
383  //
384  // Update the buffer pointer and the number of bytes to write
385  //
386  numBytesLeftToWrite -= (size_t)numBytesWritten;
387  pCurrentBuffer += numBytesWritten;
388  }
389 
390  return SBG_NO_ERROR;
391 }
392 
401 SbgErrorCode sbgInterfaceSerialRead(SbgInterface *pHandle, void *pBuffer, size_t *pReadBytes, size_t bytesToRead)
402 {
403  HANDLE pSerialDevice;
404  char errorMsg[256];
405  DWORD bytesRead;
406 
407  assert(pHandle);
408  assert(pBuffer);
409  assert(pReadBytes);
410 
411  //
412  // Get the internal serial handle
413  //
414  pSerialDevice = (HANDLE)(pHandle->handle);
415 
416  //
417  // Read some bytes on the serial buffer
418  //
419  if (ReadFile(pSerialDevice, pBuffer, (DWORD)bytesToRead, (LPDWORD)&bytesRead, NULL))
420  {
421  //
422  // Update the number of bytes read
423  //
424  (*pReadBytes) = (size_t)bytesRead;
425 
426  return SBG_NO_ERROR;
427  }
428  else
429  {
430  *pReadBytes = (size_t)bytesRead;
431 
432  //
433  // Unable to read some bytes
434  //
435  sbgGetWindowsErrorMsg(errorMsg);
436  SBG_LOG_ERROR(SBG_READ_ERROR, "Read failed: %s", errorMsg);
437  return SBG_READ_ERROR;
438  }
439 }
unsigned int uint32
Definition: sbgTypes.h:52
SbgErrorCode sbgInterfaceSerialRead(SbgInterface *pHandle, void *pBuffer, size_t *pReadBytes, size_t bytesToRead)
SbgErrorCode sbgInterfaceSerialDestroy(SbgInterface *pHandle)
uint32 sbgGetWindowsErrorMsg(char outErrorMsg[256])
SbgErrorCode sbgInterfaceSerialChangeBaudrate(SbgInterface *pHandle, uint32 baudRate)
SbgErrorCode sbgInterfaceSerialWrite(SbgInterface *pHandle, const void *pBuffer, size_t bytesToWrite)
SBG_COMMON_LIB_API void sbgSleep(uint32_t ms)
Definition: sbgPlatform.c:54
uint32_t type
Definition: sbgInterface.h:134
SbgInterfaceHandle handle
Definition: sbgInterface.h:133
#define SBG_IF_SERIAL_RX_BUFFER_SIZE
SbgInterfaceReadFunc pReadFunc
Definition: sbgInterface.h:138
This file implements a serial interface.
#define NULL
Definition: sbgDefines.h:81
#define SBG_IF_TYPE_SERIAL
Definition: sbgInterface.h:47
#define SBG_LOG_ERROR(format,...)
Definition: sbgDebug.h:62
unsigned char uint8
Definition: sbgTypes.h:50
#define SBG_IF_SERIAL_TX_BUFFER_SIZE
SbgInterfaceWriteFunc pWriteFunc
Definition: sbgInterface.h:137
enum _SbgErrorCode SbgErrorCode
SbgErrorCode sbgInterfaceSerialCreate(SbgInterface *pHandle, const char *deviceName, uint32 baudRate)
SbgErrorCode sbgInterfaceSerialFlush(SbgInterface *pHandle)


sbg_driver
Author(s): SBG Systems
autogenerated on Thu Oct 22 2020 03:47:22