Main MRPT website > C++ reference for MRPT 1.9.9
CInterfaceFTDI_WIN.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "comms-precomp.h" // Precompiled headers
11 
12 #ifdef MRPT_OS_WINDOWS
13 
14 /*===========================================================================
15  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16  START OF FTD2XX.H
17  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18  ===========================================================================*/
19 namespace comms
20 {
21 // The following ifdef block is the standard way of creating macros which make
22 // exporting
23 // from a DLL simpler. All files within this DLL are compiled with the
24 // FTD2XX_EXPORTS
25 // symbol defined on the command line. this symbol should not be defined on any
26 // project
27 // that uses this DLL. This way any other project whose source files include
28 // this file see
29 // FTD2XX_API functions as being imported from a DLL, wheras this DLL sees
30 // symbols
31 // defined with this macro as being exported.
32 #ifdef FTD2XX_EXPORTS
33 #define FTD2XX_API __declspec(dllexport)
34 #else
35 #define FTD2XX_API __declspec(dllimport)
36 #endif
37 
38 typedef unsigned long FT_HANDLE;
39 
40 //
41 // FT_OpenEx Flags
42 //
43 
44 #define FT_OPEN_BY_SERIAL_NUMBER 1
45 #define FT_OPEN_BY_DESCRIPTION 2
46 
47 //
48 // FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags
49 //
50 
51 #define FT_LIST_NUMBER_ONLY 0x80000000
52 #define FT_LIST_BY_INDEX 0x40000000
53 #define FT_LIST_ALL 0x20000000
54 
55 #define FT_LIST_MASK (FT_LIST_NUMBER_ONLY | FT_LIST_BY_INDEX | FT_LIST_ALL)
56 
57 //
58 // Baud Rates
59 //
60 
61 #define FT_BAUD_300 300
62 #define FT_BAUD_600 600
63 #define FT_BAUD_1200 1200
64 #define FT_BAUD_2400 2400
65 #define FT_BAUD_4800 4800
66 #define FT_BAUD_9600 9600
67 #define FT_BAUD_14400 14400
68 #define FT_BAUD_19200 19200
69 #define FT_BAUD_38400 38400
70 #define FT_BAUD_57600 57600
71 #define FT_BAUD_115200 115200
72 #define FT_BAUD_230400 230400
73 #define FT_BAUD_460800 460800
74 #define FT_BAUD_921600 921600
75 
76 //
77 // Word Lengths
78 //
79 
80 #define FT_BITS_8 (unsigned char)8
81 #define FT_BITS_7 (unsigned char)7
82 #define FT_BITS_6 (unsigned char)6
83 #define FT_BITS_5 (unsigned char)5
84 
85 //
86 // Stop Bits
87 //
88 
89 #define FT_STOP_BITS_1 (unsigned char)0
90 #define FT_STOP_BITS_1_5 (unsigned char)1
91 #define FT_STOP_BITS_2 (unsigned char)2
92 
93 //
94 // Parity
95 //
96 
97 #define FT_PARITY_NONE (unsigned char)0
98 #define FT_PARITY_ODD (unsigned char)1
99 #define FT_PARITY_EVEN (unsigned char)2
100 #define FT_PARITY_MARK (unsigned char)3
101 #define FT_PARITY_SPACE (unsigned char)4
102 
103 //
104 // Flow Control
105 //
106 
107 #define FT_FLOW_NONE 0x0000
108 #define FT_FLOW_RTS_CTS 0x0100
109 #define FT_FLOW_DTR_DSR 0x0200
110 #define FT_FLOW_XON_XOFF 0x0400
111 
112 //
113 // Purge rx and tx buffers
114 //
115 #define FT_PURGE_RX 1
116 #define FT_PURGE_TX 2
117 
118 //
119 // Events
120 //
121 
122 typedef void (*PFT_EVENT_HANDLER)(unsigned long, unsigned long);
123 
124 #define FT_EVENT_RXCHAR 1
125 #define FT_EVENT_MODEM_STATUS 2
126 
127 //
128 // Timeouts
129 //
130 
131 #define FT_DEFAULT_RX_TIMEOUT 300
132 #define FT_DEFAULT_TX_TIMEOUT 300
133 
134 } // end namespace comms
135 /*===========================================================================
136  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137  END OF FTD2XX.H
138  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139  ===========================================================================*/
140 
141 #include <windows.h>
142 
144 
145 using namespace mrpt;
146 using namespace mrpt::utils;
147 using namespace mrpt::comms;
148 using namespace std;
149 
150 /*-------------------------------------------------------------
151  CInterfaceFTDI
152 -------------------------------------------------------------*/
153 CInterfaceFTDI::CInterfaceFTDI() : m_readBuffer(4096)
154 {
155  MRPT_START
156 
157  m_ftHandle = 0;
158  loadDriver();
159 
160  MRPT_END
161 }
162 
163 /*-------------------------------------------------------------
164  ~CInterfaceFTDI
165 -------------------------------------------------------------*/
167 {
168  if (m_hmodule != nullptr)
169  {
170  // Close USB connection:
171  this->Close();
172 
173  // Unload FT2XX DLL:
174  FreeLibrary((HMODULE)m_hmodule);
175  m_hmodule = nullptr;
176  }
177 }
178 
179 /** This object cannot be copied */
180 CInterfaceFTDI::CInterfaceFTDI(const CInterfaceFTDI& o) : m_readBuffer(4096)
181 {
182  MRPT_START
183  THROW_EXCEPTION("This object cannot be copied");
184  MRPT_END
185 }
187 {
188  MRPT_START
189  THROW_EXCEPTION("This object cannot be copied");
190  MRPT_END
191 }
192 
193 /*-------------------------------------------------------------
194  isOpen
195 -------------------------------------------------------------*/
196 bool CInterfaceFTDI::isOpen() { return m_ftHandle != 0; }
197 /*-------------------------------------------------------------
198  loadDriver
199 -------------------------------------------------------------*/
200 void CInterfaceFTDI::loadDriver()
201 {
202  MRPT_START
203  // ------------------------------------------------------
204  // Windoze version
205  // ------------------------------------------------------
206  m_hmodule = ::LoadLibraryA("Ftd2xx.dll");
207  if (m_hmodule == nullptr) THROW_EXCEPTION("Error: Cannot load Ftd2xx.dll");
208 
209  m_pWrite = (PtrToWrite)GetProcAddress((HMODULE)m_hmodule, "FT_Write");
210  m_pRead = (PtrToRead)GetProcAddress((HMODULE)m_hmodule, "FT_Read");
211  m_pOpen = (PtrToOpen)GetProcAddress((HMODULE)m_hmodule, "FT_Open");
212  m_pOpenEx = (PtrToOpenEx)GetProcAddress((HMODULE)m_hmodule, "FT_OpenEx");
213  m_pListDevices =
214  (PtrToListDevices)GetProcAddress((HMODULE)m_hmodule, "FT_ListDevices");
215  m_pClose = (PtrToClose)GetProcAddress((HMODULE)m_hmodule, "FT_Close");
216  m_pResetDevice =
217  (PtrToResetDevice)GetProcAddress((HMODULE)m_hmodule, "FT_ResetDevice");
218  m_pPurge = (PtrToPurge)GetProcAddress((HMODULE)m_hmodule, "FT_Purge");
219  m_pSetTimeouts =
220  (PtrToSetTimeouts)GetProcAddress((HMODULE)m_hmodule, "FT_SetTimeouts");
221  m_pGetQueueStatus = (PtrToGetQueueStatus)GetProcAddress(
222  (HMODULE)m_hmodule, "FT_GetQueueStatus");
223  m_pSetLatencyTimer = (PtrToSetLatencyTimer)GetProcAddress(
224  (HMODULE)m_hmodule, "FT_SetLatencyTimer");
225 
226  if (!m_pWrite || !m_pRead || !m_pOpen || !m_pOpenEx || !m_pListDevices ||
227  !m_pClose || !m_pResetDevice || !m_pPurge || !m_pSetTimeouts ||
228  !m_pGetQueueStatus || !m_pSetLatencyTimer)
229  THROW_EXCEPTION("Error loading FTD2XX.DLL");
230 
231  MRPT_END
232 }
233 
234 /*-------------------------------------------------------------
235  FTD2XX.DLL INTERFACE FUNCTIONS
236 -------------------------------------------------------------*/
237 void CInterfaceFTDI::ftdi_open(void* pvDevice)
238 {
239  MRPT_START
240  if (isOpen()) Close();
241 
242  ASSERT_(m_pOpen);
243  checkErrorAndRaise((*m_pOpen)(pvDevice, &m_ftHandle));
244 
245  MRPT_END
246 }
247 
248 void CInterfaceFTDI::ftdi_openEx(void* pArg1, unsigned long dwFlags)
249 {
250  MRPT_START
251  if (isOpen()) Close();
252 
253  ASSERT_(m_pOpenEx);
254  checkErrorAndRaise((*m_pOpenEx)(pArg1, dwFlags, &m_ftHandle));
255 
256  MRPT_END
257 }
258 
259 /*-------------------------------------------------------------
260  ListAllDevices
261 -------------------------------------------------------------*/
263 {
264  MRPT_START
265 
266  outList.clear();
267 
268  unsigned long nConectedDevices;
269  char str[100];
270 
271  // Get the number of devices:
272  ftdi_listDevices(&nConectedDevices, nullptr, 0x80000000);
273 
274  for (size_t i = 0; i < nConectedDevices; i++)
275  {
276  TFTDIDevice newEntry;
277 
278  // Serial number:
279  ftdi_listDevices(
280  (void*)(i), (void*)str, (unsigned long)(0x40000000 | 1));
281  newEntry.ftdi_serial = str;
282 
283  // Description:
284  ftdi_listDevices(
285  (void*)(i), (void*)str, (unsigned long)(0x40000000 | 2));
286  newEntry.ftdi_description = str;
287 
288  outList.push_back(newEntry);
289  }
290 
291  MRPT_END
292 }
293 
294 void CInterfaceFTDI::ftdi_listDevices(
295  void* pArg1, void* pArg2, unsigned long dwFlags)
296 {
297  MRPT_START
298 
299  ASSERT_(m_pListDevices);
300  checkErrorAndRaise((*m_pListDevices)(pArg1, pArg2, dwFlags));
301 
302  MRPT_END
303 }
304 
306 {
307  MRPT_START
308 
309  if (m_ftHandle)
310  {
311  ASSERT_(m_pClose);
312  (*m_pClose)(m_ftHandle);
313  m_ftHandle = 0;
314  }
315 
317 
318  MRPT_END
319 }
320 
322  void* lpvBuffer, unsigned long dwBuffSize, unsigned long* lpdwBytesRead)
323 {
324  MRPT_START
325 
326  ASSERT_(m_pRead);
327  checkErrorAndRaise(
328  (*m_pRead)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytesRead));
329 
330  MRPT_END
331 }
332 
334  const void* lpvBuffer, unsigned long dwBuffSize, unsigned long* lpdwBytes)
335 {
336  MRPT_START
337 
338  ASSERT_(m_pWrite);
339  checkErrorAndRaise(
340  (*m_pWrite)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytes));
341 
342  MRPT_END
343 }
344 
346 {
347  MRPT_START
348 
349  ASSERT_(m_pResetDevice);
350  checkErrorAndRaise((*m_pResetDevice)(m_ftHandle));
351 
353 
354  MRPT_END
355 }
356 
358 {
359  MRPT_START
360 
361  ASSERT_(m_pPurge);
362  unsigned long dwMask = FT_PURGE_RX | FT_PURGE_TX;
363  checkErrorAndRaise((*m_pPurge)(m_ftHandle, dwMask));
364 
366  MRPT_END
367 }
368 
370  unsigned long dwReadTimeout_ms, unsigned long dwWriteTimeout_ms)
371 {
372  MRPT_START
373 
374  ASSERT_(m_pSetTimeouts);
375  checkErrorAndRaise(
376  (*m_pSetTimeouts)(m_ftHandle, dwReadTimeout_ms, dwWriteTimeout_ms));
377 
378  MRPT_END
379 }
380 
381 void CInterfaceFTDI::ftdi_getQueueStatus(unsigned long* lpdwAmountInRxQueue)
382 {
383  MRPT_START
384 
385  ASSERT_(m_pGetQueueStatus);
386  checkErrorAndRaise((*m_pGetQueueStatus)(m_ftHandle, lpdwAmountInRxQueue));
387 
388  MRPT_END
389 }
390 
391 void CInterfaceFTDI::SetLatencyTimer(unsigned char latency_ms)
392 {
393  MRPT_START
394 
395  ASSERT_(m_pSetLatencyTimer);
396  checkErrorAndRaise((*m_pSetLatencyTimer)(m_ftHandle, latency_ms));
397 
398  MRPT_END
399 }
400 
401 /*-------------------------------------------------------------
402  checkErrorAndRaise
403 -------------------------------------------------------------*/
404 void CInterfaceFTDI::checkErrorAndRaise(int errorCode)
405 {
406  /** Possible responses from the driver
407  enum FT_STATUS
408  {
409  FT_OK = 0,
410  FT_INVALID_HANDLE,
411  FT_DEVICE_NOT_FOUND,
412  FT_DEVICE_NOT_OPENED,
413  FT_IO_ERROR,
414  FT_INSUFFICIENT_RESOURCES,
415  FT_INVALID_PARAMETER
416  }; */
417  switch (errorCode)
418  {
419  case 0:
420  return;
421  case 1:
422  Close();
423  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INVALID_HANDLE");
424  case 2:
425  Close();
426  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_DEVICE_NOT_FOUND");
427  case 3:
428  Close();
429  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_DEVICE_NOT_OPENED");
430  case 4:
431  Close();
432  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_IO_ERROR");
433  case 5:
434  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INSUFFICIENT_RESOURCES");
435  case 6:
436  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INVALID_PARAMETER");
437  default:
438  THROW_EXCEPTION("*** FTD2XX ERROR ***: Invalid error code!?!?!?");
439  };
440 }
441 
442 /*-------------------------------------------------------------
443  OpenBySerialNumber
444 -------------------------------------------------------------*/
445 void CInterfaceFTDI::OpenBySerialNumber(const std::string& serialNumber)
446 {
447  MRPT_START
449 
450  ftdi_openEx((void*)serialNumber.c_str(), FT_OPEN_BY_SERIAL_NUMBER);
451  MRPT_END
452 }
453 
454 /*-------------------------------------------------------------
455  OpenByDescription
456 -------------------------------------------------------------*/
457 void CInterfaceFTDI::OpenByDescription(const std::string& description)
458 {
459  MRPT_START
461 
462  ftdi_openEx((void*)description.c_str(), FT_OPEN_BY_DESCRIPTION);
463  MRPT_END
464 }
465 
466 /*-------------------------------------------------------------
467  OpenByDescription
468 -------------------------------------------------------------*/
469 std::ostream& mrpt::comms::operator<<(std::ostream& o, const TFTDIDevice& d)
470 {
471  o << "Manufacturer : " << d.ftdi_manufacturer << endl
472  << "Description : " << d.ftdi_description << endl
473  << "FTDI serial : " << d.ftdi_serial << endl
474  << "USB ID (Vendor/Product) : "
475  << format("%04X / %04X", d.usb_idVendor, d.usb_idProduct) << endl
476  << "USB serial : " << d.usb_serialNumber << endl;
477 
478  return o;
479 }
480 
481 #endif
bool isOpen()
Checks whether the chip has been successfully open.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void ResetDevice()
Reset the USB device.
void clear()
Delete all the stored data, if any.
#define THROW_EXCEPTION(msg)
void OpenBySerialNumber(const std::string &serialNumber)
Open by device serial number.
STL namespace.
void Close()
Close the USB device.
void OpenByDescription(const std::string &description)
Open by device description.
mrpt::utils::circular_buffer< uint8_t > m_readBuffer
Used in Read.
void SetTimeouts(unsigned long dwReadTimeout_ms, unsigned long dwWriteTimeout_ms)
Change read & write timeouts, in milliseconds.
#define MRPT_END
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
void ListAllDevices(TFTDIDeviceList &outList)
Generates a list with all FTDI devices connected right now.
GLsizei const GLchar ** string
Definition: glext.h:4101
std::deque< TFTDIDevice > TFTDIDeviceList
Used in CInterfaceFTDI::ListAllDevices.
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
CInterfaceFTDI & operator=(const CInterfaceFTDI &o)
This object cannot be copied.
std::ostream & operator<<(std::ostream &o, const TFTDIDevice &d)
Print out all the information of a FTDI device in textual form.
A definition of a CStream actually representing a USB connection to a FTDI chip.
CInterfaceFTDI()
Constructor, which loads driver interface (the DLL under Windows).
#define ASSERT_(f)
void ftdi_read(void *lpvBuffer, unsigned long dwBuffSize, unsigned long *lpdwBytesRead)
void Purge()
Purge the I/O buffers.
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
void ftdi_write(const void *lpvBuffer, unsigned long dwBuffSize, unsigned long *lpdwBytes)
Serial and networking devices and utilities.
virtual ~CInterfaceFTDI()
Destructor, which closes the connection with the chip and unloads the driver interface.
void SetLatencyTimer(unsigned char latency_ms)
Change the latency timer (in milliseconds) implemented on the FTDI chip: for a few ms...
A list of FTDI devices and their descriptors.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019