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-2018, 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 _WIN32
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 using FT_HANDLE = unsigned long;
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 using PFT_EVENT_HANDLER = void (*)(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 #include <mrpt/core/exceptions.h>
145 
146 using namespace mrpt;
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 bool CInterfaceFTDI::isOpen() { return m_ftHandle != 0; }
181 {
182  MRPT_START
183  // ------------------------------------------------------
184  // Windoze version
185  // ------------------------------------------------------
186  m_hmodule = ::LoadLibraryA("Ftd2xx.dll");
187  if (m_hmodule == nullptr) THROW_EXCEPTION("Error: Cannot load Ftd2xx.dll");
188 
189  m_pWrite = (PtrToWrite)GetProcAddress((HMODULE)m_hmodule, "FT_Write");
190  m_pRead = (PtrToRead)GetProcAddress((HMODULE)m_hmodule, "FT_Read");
191  m_pOpen = (PtrToOpen)GetProcAddress((HMODULE)m_hmodule, "FT_Open");
192  m_pOpenEx = (PtrToOpenEx)GetProcAddress((HMODULE)m_hmodule, "FT_OpenEx");
194  (PtrToListDevices)GetProcAddress((HMODULE)m_hmodule, "FT_ListDevices");
195  m_pClose = (PtrToClose)GetProcAddress((HMODULE)m_hmodule, "FT_Close");
197  (PtrToResetDevice)GetProcAddress((HMODULE)m_hmodule, "FT_ResetDevice");
198  m_pPurge = (PtrToPurge)GetProcAddress((HMODULE)m_hmodule, "FT_Purge");
200  (PtrToSetTimeouts)GetProcAddress((HMODULE)m_hmodule, "FT_SetTimeouts");
201  m_pGetQueueStatus = (PtrToGetQueueStatus)GetProcAddress(
202  (HMODULE)m_hmodule, "FT_GetQueueStatus");
203  m_pSetLatencyTimer = (PtrToSetLatencyTimer)GetProcAddress(
204  (HMODULE)m_hmodule, "FT_SetLatencyTimer");
205 
206  if (!m_pWrite || !m_pRead || !m_pOpen || !m_pOpenEx || !m_pListDevices ||
209  THROW_EXCEPTION("Error loading FTD2XX.DLL");
210 
211  MRPT_END
212 }
213 
214 /*-------------------------------------------------------------
215  FTD2XX.DLL INTERFACE FUNCTIONS
216 -------------------------------------------------------------*/
217 void CInterfaceFTDI::ftdi_open(void* pvDevice)
218 {
219  MRPT_START
220  if (isOpen()) Close();
221 
222  ASSERT_(m_pOpen);
223  checkErrorAndRaise((*m_pOpen)(pvDevice, &m_ftHandle));
224 
225  MRPT_END
226 }
227 
228 void CInterfaceFTDI::ftdi_openEx(void* pArg1, unsigned long dwFlags)
229 {
230  MRPT_START
231  if (isOpen()) Close();
232 
234  checkErrorAndRaise((*m_pOpenEx)(pArg1, dwFlags, &m_ftHandle));
235 
236  MRPT_END
237 }
238 
239 /*-------------------------------------------------------------
240  ListAllDevices
241 -------------------------------------------------------------*/
243 {
244  MRPT_START
245 
246  outList.clear();
247 
248  unsigned long nConectedDevices;
249  char str[100];
250 
251  // Get the number of devices:
252  ftdi_listDevices(&nConectedDevices, nullptr, 0x80000000);
253 
254  for (size_t i = 0; i < nConectedDevices; i++)
255  {
256  TFTDIDevice newEntry;
257 
258  // Serial number:
260  (void*)(i), (void*)str, (unsigned long)(0x40000000 | 1));
261  newEntry.ftdi_serial = str;
262 
263  // Description:
265  (void*)(i), (void*)str, (unsigned long)(0x40000000 | 2));
266  newEntry.ftdi_description = str;
267 
268  outList.push_back(newEntry);
269  }
270 
271  MRPT_END
272 }
273 
275  void* pArg1, void* pArg2, unsigned long dwFlags)
276 {
277  MRPT_START
278 
280  checkErrorAndRaise((*m_pListDevices)(pArg1, pArg2, dwFlags));
281 
282  MRPT_END
283 }
284 
286 {
287  MRPT_START
288 
289  if (m_ftHandle)
290  {
291  ASSERT_(m_pClose);
292  (*m_pClose)(m_ftHandle);
293  m_ftHandle = 0;
294  }
295 
297 
298  MRPT_END
299 }
300 
302  void* lpvBuffer, unsigned long dwBuffSize, unsigned long* lpdwBytesRead)
303 {
304  MRPT_START
305 
306  ASSERT_(m_pRead);
308  (*m_pRead)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytesRead));
309 
310  MRPT_END
311 }
312 
314  const void* lpvBuffer, unsigned long dwBuffSize, unsigned long* lpdwBytes)
315 {
316  MRPT_START
317 
318  ASSERT_(m_pWrite);
320  (*m_pWrite)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytes));
321 
322  MRPT_END
323 }
324 
326 {
327  MRPT_START
328 
331 
333 
334  MRPT_END
335 }
336 
338 {
339  MRPT_START
340 
341  ASSERT_(m_pPurge);
342  unsigned long dwMask = FT_PURGE_RX | FT_PURGE_TX;
344 
346  MRPT_END
347 }
348 
350  unsigned long dwReadTimeout_ms, unsigned long dwWriteTimeout_ms)
351 {
352  MRPT_START
353 
356  (*m_pSetTimeouts)(m_ftHandle, dwReadTimeout_ms, dwWriteTimeout_ms));
357 
358  MRPT_END
359 }
360 
361 void CInterfaceFTDI::ftdi_getQueueStatus(unsigned long* lpdwAmountInRxQueue)
362 {
363  MRPT_START
364 
366  checkErrorAndRaise((*m_pGetQueueStatus)(m_ftHandle, lpdwAmountInRxQueue));
367 
368  MRPT_END
369 }
370 
371 void CInterfaceFTDI::SetLatencyTimer(unsigned char latency_ms)
372 {
373  MRPT_START
374 
377 
378  MRPT_END
379 }
380 
381 /*-------------------------------------------------------------
382  checkErrorAndRaise
383 -------------------------------------------------------------*/
385 {
386  /** Possible responses from the driver
387  enum FT_STATUS
388  {
389  FT_OK = 0,
390  FT_INVALID_HANDLE,
391  FT_DEVICE_NOT_FOUND,
392  FT_DEVICE_NOT_OPENED,
393  FT_IO_ERROR,
394  FT_INSUFFICIENT_RESOURCES,
395  FT_INVALID_PARAMETER
396  }; */
397  switch (errorCode)
398  {
399  case 0:
400  return;
401  case 1:
402  Close();
403  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INVALID_HANDLE");
404  case 2:
405  Close();
406  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_DEVICE_NOT_FOUND");
407  case 3:
408  Close();
409  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_DEVICE_NOT_OPENED");
410  case 4:
411  Close();
412  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_IO_ERROR");
413  case 5:
414  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INSUFFICIENT_RESOURCES");
415  case 6:
416  THROW_EXCEPTION("*** FTD2XX ERROR ***: FT_INVALID_PARAMETER");
417  default:
418  THROW_EXCEPTION("*** FTD2XX ERROR ***: Invalid error code!?!?!?");
419  };
420 }
421 
422 /*-------------------------------------------------------------
423  OpenBySerialNumber
424 -------------------------------------------------------------*/
426 {
427  MRPT_START
429 
430  ftdi_openEx((void*)serialNumber.c_str(), FT_OPEN_BY_SERIAL_NUMBER);
431  MRPT_END
432 }
433 
434 /*-------------------------------------------------------------
435  OpenByDescription
436 -------------------------------------------------------------*/
438 {
439  MRPT_START
441 
442  ftdi_openEx((void*)description.c_str(), FT_OPEN_BY_DESCRIPTION);
443  MRPT_END
444 }
445 
446 /*-------------------------------------------------------------
447  OpenByDescription
448 -------------------------------------------------------------*/
449 std::ostream& mrpt::comms::operator<<(std::ostream& o, const TFTDIDevice& d)
450 {
451  o << "Manufacturer : " << d.ftdi_manufacturer << endl
452  << "Description : " << d.ftdi_description << endl
453  << "FTDI serial : " << d.ftdi_serial << endl
454  << "USB ID (Vendor/Product) : "
455  << format("%04X / %04X", d.usb_idVendor, d.usb_idProduct) << endl
456  << "USB serial : " << d.usb_serialNumber << endl;
457 
458  return o;
459 }
460 
461 #endif
std::ostream & operator<<(std::ostream &o, const TFTDIDevice &d)
Print out all the information of a FTDI device in textual form.
PtrToResetDevice m_pResetDevice
FT_STATUS(__stdcall * PtrToPurge)(unsigned long, unsigned long)
bool isOpen()
Checks whether the chip has been successfully open.
#define MRPT_START
Definition: exceptions.h:262
void ftdi_getQueueStatus(unsigned long *lpdwAmountInRxQueue)
FT_STATUS(__stdcall * PtrToRead)(unsigned long, void *, unsigned long, unsigned long *)
void ftdi_write(const void *lpvBuffer, unsigned long dwBuffSize, unsigned long *lpdwBytes)
FT_STATUS(__stdcall * PtrToOpenEx)(void *, unsigned long, unsigned long *)
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
PtrToSetLatencyTimer m_pSetLatencyTimer
PtrToListDevices m_pListDevices
std::deque< TFTDIDevice > TFTDIDeviceList
Used in CInterfaceFTDI::ListAllDevices.
#define FT_PURGE_RX
FT_STATUS(__stdcall * PtrToClose)(unsigned long)
mrpt::containers::circular_buffer< uint8_t > m_readBuffer
Used in Read.
#define FT_PURGE_TX
STL namespace.
virtual ~CInterfaceFTDI()
Destructor, which closes the connection with the chip and unloads the driver interface.
FT_STATUS(__stdcall * PtrToSetLatencyTimer)(unsigned long, unsigned char)
CInterfaceFTDI()
Constructor, which loads driver interface (the DLL under Windows).
void ftdi_listDevices(void *pArg1, void *pArg2, unsigned long dwFlags)
void ListAllDevices(TFTDIDeviceList &outList)
Generates a list with all FTDI devices connected right now.
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
void ftdi_openEx(void *pArg1, unsigned long dwFlags)
void Close()
Close the USB device.
void SetTimeouts(unsigned long dwReadTimeout_ms, unsigned long dwWriteTimeout_ms)
Change read & write timeouts, in milliseconds.
void(*)(unsigned long, unsigned, long) PFT_EVENT_HANDLER
PtrToSetTimeouts m_pSetTimeouts
FT_STATUS(__stdcall * PtrToSetTimeouts)(unsigned long, unsigned long, unsigned long)
FT_STATUS(__stdcall * PtrToWrite)(unsigned long, const void *, unsigned long, unsigned long *)
void OpenBySerialNumber(const std::string &serialNumber)
Open by device serial number.
GLsizei const GLchar ** string
Definition: glext.h:4101
void ResetDevice()
Reset the USB device.
FT_STATUS(__stdcall * PtrToResetDevice)(unsigned long)
FT_STATUS(__stdcall * PtrToOpen)(void *, unsigned long *)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void ftdi_read(void *lpvBuffer, unsigned long dwBuffSize, unsigned long *lpdwBytesRead)
#define FT_OPEN_BY_SERIAL_NUMBER
FT_STATUS(__stdcall * PtrToListDevices)(void *, void *, unsigned long)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
void checkErrorAndRaise(int errorCode)
#define MRPT_END
Definition: exceptions.h:266
#define FT_OPEN_BY_DESCRIPTION
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
Serial and networking devices and utilities.
PtrToGetQueueStatus m_pGetQueueStatus
unsigned long FT_HANDLE
A list of FTDI devices and their descriptors.
void clear()
Delete all the stored data, if any.
void SetLatencyTimer(unsigned char latency_ms)
Change the latency timer (in milliseconds) implemented on the FTDI chip: for a few ms...
void OpenByDescription(const std::string &description)
Open by device description.
FT_STATUS(__stdcall * PtrToGetQueueStatus)(unsigned long, unsigned long *)
void Purge()
Purge the I/O buffers.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020