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



Page generated by Doxygen 1.8.14 for MRPT 1.5.6 Git: 4c65e8431 Tue Apr 24 08:18:17 2018 +0200 at lun oct 28 01:35:26 CET 2019