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