rmp_ftd2xx.cc
Go to the documentation of this file.
1 #include "segwayrmp/segwayrmp.h"
3 
4 #include <iostream>
5 #include <sstream>
6 
7 using namespace segwayrmp;
8 
9 static const bool ftd2xx_devices_debug = false;
10 
11 inline std::string
12 getErrorMessageByFT_STATUS(FT_STATUS result, std::string what)
13 {
14  std::stringstream msg;
15  msg << "FTD2XX error while " << what << ": ";
16  switch (result) {
17  case FT_INVALID_HANDLE:
18  msg << "FT_INVALID_HANDLE";
19  break;
21  msg << "FT_DEVICE_NOT_FOUND";
22  break;
24  msg << "FT_DEVICE_NOT_OPENED";
25  break;
26  case FT_IO_ERROR:
27  msg << "FT_IO_ERROR";
28  break;
30  msg << "FT_INSUFFICIENT_RESOURCES";
31  break;
33  msg << "FT_INVALID_PARAMETER";
34  break;
36  msg << "FT_INVALID_BAUD_RATE";
37  break;
39  msg << "FT_DEVICE_NOT_OPENED_FOR_ERASE";
40  break;
42  msg << "FT_DEVICE_NOT_OPENED_FOR_WRITE";
43  break;
45  msg << "FT_FAILED_TO_WRITE_DEVICE";
46  break;
48  msg << "FT_EEPROM_READ_FAILED";
49  break;
51  msg << "FT_EEPROM_WRITE_FAILED";
52  break;
54  msg << "FT_EEPROM_ERASE_FAILED";
55  break;
57  msg << "FT_EEPROM_NOT_PRESENT";
58  break;
60  msg << "FT_EEPROM_NOT_PROGRAMMED";
61  break;
62  case FT_INVALID_ARGS:
63  msg << "FT_INVALID_ARGS";
64  break;
65  case FT_NOT_SUPPORTED:
66  msg << "FT_NOT_SUPPORTED";
67  break;
68  case FT_OTHER_ERROR:
69  msg << "FT_OTHER_ERROR";
70  break;
71  default:
72  msg << "Unknown FTD2XX Error.";
73  break;
74  }
75  return msg.str();
76 }
77 
78 std::vector<FT_DEVICE_LIST_INFO_NODE> segwayrmp::enumerateUSBDevices() {
79  FT_STATUS result;
80  FT_DEVICE_LIST_INFO_NODE *device_info;
81  DWORD number_of_devices;
82 
83  // If mac or linux you must set VID/PID
84  #ifndef _WIN32
85  DWORD FTDI_VID = 0x403;
86  DWORD SEGWAY_PID = 0xe729;
87 
88  try {
89  result = FT_SetVIDPID(FTDI_VID, SEGWAY_PID);
90  } catch(std::exception &e) {
91  RMP_THROW_MSG(ReadFailedException, e.what());
92  }
93  if (result != FT_OK) {
94  RMP_THROW_MSG(ReadFailedException,
95  getErrorMessageByFT_STATUS(result, "setting vid and pid").c_str());
96  }
97  #endif
98 
99  try {
100  result = FT_CreateDeviceInfoList(&number_of_devices);
101  } catch(std::exception &e) {
102  RMP_THROW_MSG(ReadFailedException, e.what());
103  }
104  if (result != FT_OK) {
105  RMP_THROW_MSG(ReadFailedException,
106  getErrorMessageByFT_STATUS(result, "enumerating devices").c_str());
107  }
108 
110  std::cout << "Number of devices is: " << number_of_devices << std::endl;
111 
112  std::vector<FT_DEVICE_LIST_INFO_NODE> devices;
113  if (number_of_devices > 0) {
114  device_info = (FT_DEVICE_LIST_INFO_NODE*)malloc(
115  sizeof(FT_DEVICE_LIST_INFO_NODE)*number_of_devices
116  );
117  try {
118  result = FT_GetDeviceInfoList(device_info, &number_of_devices);
119  } catch(std::exception &e) {
120  RMP_THROW_MSG(ReadFailedException, e.what());
121  }
122  if (result != FT_OK) {
123  RMP_THROW_MSG(ReadFailedException,
124  getErrorMessageByFT_STATUS(result, "enumerating devices").c_str());
125  }
126  for (int i = 0; i < number_of_devices; i++) {
127  devices.push_back(device_info[i]);
128  if (ftd2xx_devices_debug) {
129  printf("Dev %d:\n", i);
130  printf(" Flags=0x%x\n", device_info[i].Flags);
131  printf(" Type=0x%x\n", device_info[i].Type);
132  printf(" ID=0x%x\n", device_info[i].ID);
133  printf(" LocId=0x%x\n", device_info[i].LocId);
134  printf(" SerialNumber=%s\n", device_info[i].SerialNumber);
135  printf(" Description=%s\n", device_info[i].Description);
136  }
137  }
138  }
139  return devices;
140 }
141 
143 // FTD2XXRMPIO
144 
146 : configured(false), config_type(by_none), baudrate(460800), is_open(false)
147 {
148  this->port_serial_number = "";
149  this->port_description = "";
150  this->port_index = 0;
151  this->connected = false;
152  this->usb_port_handle = NULL;
153 }
154 
156  this->disconnect();
157 }
158 
160  if(!this->configured) {
161  RMP_THROW_MSG(ConnectionFailedException, "The usb port must be "
162  "configured before connecting.");
163  }
164 
165  FT_STATUS result;
166 
167  this->enumerateUSBDevices_();
168 
169  // Select connection method and open
170  switch (this->config_type) {
171  case by_serial_number:
172  this->connectBySerial();
173  break;
174  case by_description:
175  this->connectByDescription();
176  break;
177  case by_index:
178  this->connectByIndex();
179  break;
180  case by_none:
181  default:
182  RMP_THROW_MSG(ConnectionFailedException, "The usb port must be "
183  "configured before connecting.");
184  break;
185  }
186 
187  this->is_open = true;
188 
189  // Configure the Baudrate
190  try {
191  result = FT_SetBaudRate(this->usb_port_handle, this->baudrate);
192  } catch(std::exception &e) {
193  RMP_THROW_MSG(ConnectionFailedException, e.what());
194  }
195  if (result != FT_OK) {
196  RMP_THROW_MSG(ConnectionFailedException,
197  getErrorMessageByFT_STATUS(result, "setting the baudrate").c_str());
198  }
199 
200  // Set default timeouts
201  try {
202  // 1 sec read and 1 sec write
203  result = FT_SetTimeouts(this->usb_port_handle, 1000, 1000);
204  } catch(std::exception &e) {
205  RMP_THROW_MSG(ConnectionFailedException, e.what());
206  }
207  if (result != FT_OK) {
208  RMP_THROW_MSG(ConnectionFailedException,
209  getErrorMessageByFT_STATUS(result, "setting timeouts").c_str());
210  }
211 
212  // Set Latency Timer
213  try {
214  result = FT_SetLatencyTimer(this->usb_port_handle, 1);
215  } catch(std::exception &e) {
216  RMP_THROW_MSG(ConnectionFailedException, e.what());
217  }
218  if (result != FT_OK) {
219  RMP_THROW_MSG(ConnectionFailedException,
220  getErrorMessageByFT_STATUS(result, "setting latency timer").c_str());
221  }
222 
223  // Set flowcontrol
224  try {
225  result = FT_SetFlowControl(this->usb_port_handle, FT_FLOW_NONE, 0, 0);
226  } catch(std::exception &e) {
227  RMP_THROW_MSG(ConnectionFailedException, e.what());
228  }
229  if (result != FT_OK) {
230  RMP_THROW_MSG(ConnectionFailedException,
231  getErrorMessageByFT_STATUS(result, "setting flowcontrol").c_str());
232  }
233 
234  // Purge the I/O buffers of the usb device
235  try {
236  result = FT_Purge(this->usb_port_handle, FT_PURGE_RX | FT_PURGE_TX);
237  } catch(std::exception &e) {
238  RMP_THROW_MSG(ConnectionFailedException, e.what());
239  }
240  if (result != FT_OK) {
241  RMP_THROW_MSG(ConnectionFailedException,
242  getErrorMessageByFT_STATUS(result, "purging the buffers").c_str());
243  }
244 
245  this->connected = true;
246 }
247 
249  if(this->connected) {
250  if (this->is_open) {
251  FT_Close(this->usb_port_handle);
252  }
253  this->connected = false;
254  }
255 }
256 
257 int FTD2XXRMPIO::read(unsigned char* buffer, int size) {
258  FT_STATUS result;
259  DWORD bytes_read;
260 
261  try {
262  result = FT_Read(this->usb_port_handle, buffer, size, &bytes_read);
263  } catch(std::exception &e) {
264  RMP_THROW_MSG(ReadFailedException, e.what());
265  }
266  if (result != FT_OK) {
267  RMP_THROW_MSG(ReadFailedException,
268  getErrorMessageByFT_STATUS(result, "reading").c_str());
269  }
270 
271  return bytes_read;
272 }
273 
274 int FTD2XXRMPIO::write(unsigned char* buffer, int size) {
275  FT_STATUS result;
276  DWORD bytes_written;
277 
278  try {
279  result = FT_Write(this->usb_port_handle, buffer, size, &bytes_written);
280  } catch(std::exception &e) {
281  RMP_THROW_MSG(ReadFailedException, e.what());
282  }
283  if (result != FT_OK) {
284  RMP_THROW_MSG(ReadFailedException,
285  getErrorMessageByFT_STATUS(result, "reading").c_str());
286  }
287 
288  return bytes_written;
289 }
290 
291 std::vector<FT_DEVICE_LIST_INFO_NODE> FTD2XXRMPIO::enumerateUSBDevices_() {
292  return enumerateUSBDevices();
293 }
294 
295 void
296 FTD2XXRMPIO::configureUSBBySerial(std::string serial_number, int baudrate)
297 {
299  this->port_serial_number = serial_number;
300  this->configured = true;
301  this->baudrate = baudrate;
302 }
303 
305  FT_STATUS result;
306  DWORD number_of_devices;
307 
308  try {
309  // Open the usb port
310  result = FT_OpenEx((PVOID)this->port_serial_number.c_str(),
312  &(this->usb_port_handle));
313  } catch(std::exception &e) {
314  RMP_THROW_MSG(ConnectionFailedException, e.what());
315  }
316  if (this->usb_port_handle == NULL) {
317  // Failed to open port
318  RMP_THROW_MSG(ConnectionFailedException,
319  getErrorMessageByFT_STATUS(result, "opening the usb port").c_str());
320  }
321 }
322 
323 void
325 {
326  this->config_type = by_description;
327  this->port_description = description;
328  this->configured = true;
329  this->baudrate = baudrate;
330 }
331 
333  FT_STATUS result;
334 
335  try {
336  // Open the usb port
337  result = FT_OpenEx(const_cast<char *>(this->port_description.c_str()),
339  &(this->usb_port_handle));
340  } catch(std::exception &e) {
341  RMP_THROW_MSG(ConnectionFailedException, e.what());
342  }
343  if (result != FT_OK) {
344  // Failed to open port
345  RMP_THROW_MSG(ConnectionFailedException,
346  getErrorMessageByFT_STATUS(result, "opening the usb port").c_str());
347  }
348 }
349 
350 void
351 FTD2XXRMPIO::configureUSBByIndex(unsigned int device_index, int baudrate)
352 {
353  this->config_type = by_index;
354  this->port_index = device_index;
355  this->configured = true;
356  this->baudrate = baudrate;
357 }
358 
360  FT_STATUS result;
361 
362  try {
363  // Open the usb port
364  result = FT_Open(this->port_index, &(this->usb_port_handle));
365  } catch(std::exception &e) {
366  RMP_THROW_MSG(ConnectionFailedException, e.what());
367  }
368  if (this->usb_port_handle == NULL) {
369  // Failed to open port
370  RMP_THROW_MSG(ConnectionFailedException,
371  getErrorMessageByFT_STATUS(result, "opening the usb port").c_str());
372  }
373 }
374 
int read(unsigned char *buffer, int size)
Definition: rmp_ftd2xx.cc:257
void configureUSBByDescription(std::string description, int baudrate)
Definition: rmp_ftd2xx.cc:324
#define FT_OPEN_BY_DESCRIPTION
Definition: ftd2xx.h:111
std::vector< FT_DEVICE_LIST_INFO_NODE > enumerateUSBDevices_()
Definition: rmp_ftd2xx.cc:291
ULONG FT_STATUS
Definition: ftd2xx.h:74
#define FT_OPEN_BY_SERIAL_NUMBER
Definition: ftd2xx.h:110
#define FT_PURGE_RX
Definition: ftd2xx.h:183
ConfigurationType config_type
Definition: rmp_ftd2xx.h:130
int write(unsigned char *buffer, int size)
Definition: rmp_ftd2xx.cc:274
FTD2XX_API FT_STATUS WINAPI FT_Open(int deviceNumber, FT_HANDLE *pHandle)
static const bool ftd2xx_devices_debug
Definition: rmp_ftd2xx.cc:9
void * PVOID
Definition: WinTypes.h:24
bool connected
Definition: rmp_io.h:129
FTD2XX_API FT_STATUS FT_SetVIDPID(DWORD dwVID, DWORD dwPID)
FTD2XX_API FT_STATUS WINAPI FT_SetBaudRate(FT_HANDLE ftHandle, ULONG BaudRate)
unsigned int port_index
Definition: rmp_ftd2xx.h:134
Definition: ftd2xx.h:80
FTD2XX_API FT_STATUS WINAPI FT_SetTimeouts(FT_HANDLE ftHandle, ULONG ReadTimeout, ULONG WriteTimeout)
FTD2XX_API FT_STATUS WINAPI FT_Purge(FT_HANDLE ftHandle, ULONG Mask)
FTD2XX_API FT_STATUS WINAPI FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs)
FT_HANDLE usb_port_handle
Definition: rmp_ftd2xx.h:138
FTD2XX_API FT_STATUS WINAPI FT_Close(FT_HANDLE ftHandle)
FTD2XX_API FT_STATUS WINAPI FT_SetFlowControl(FT_HANDLE ftHandle, USHORT FlowControl, UCHAR XonChar, UCHAR XoffChar)
#define FT_PURGE_TX
Definition: ftd2xx.h:184
FTD2XX_API FT_STATUS WINAPI FT_SetLatencyTimer(FT_HANDLE ftHandle, UCHAR ucLatency)
std::string port_serial_number
Definition: rmp_ftd2xx.h:132
FTD2XX_API FT_STATUS WINAPI FT_Read(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned)
#define FT_FLOW_NONE
Definition: ftd2xx.h:175
void configureUSBByIndex(unsigned int device_index, int baudrate)
Definition: rmp_ftd2xx.cc:351
FTD2XX_API FT_STATUS WINAPI FT_OpenEx(PVOID pArg1, DWORD Flags, FT_HANDLE *pHandle)
std::string getErrorMessageByFT_STATUS(FT_STATUS result, std::string what)
Definition: rmp_ftd2xx.cc:12
unsigned int DWORD
Definition: WinTypes.h:9
void configureUSBBySerial(std::string serial_number, int baudrate)
Definition: rmp_ftd2xx.cc:296
std::string port_description
Definition: rmp_ftd2xx.h:133
FTD2XX_API FT_STATUS WINAPI FT_Write(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten)
FTD2XX_API FT_STATUS WINAPI FT_GetDeviceInfoList(FT_DEVICE_LIST_INFO_NODE *pDest, LPDWORD lpdwNumDevs)
#define RMP_THROW_MSG(ExceptionClass, Message)
Definition: segwayrmp.h:83
std::vector< FT_DEVICE_LIST_INFO_NODE > enumerateUSBDevices()
Definition: rmp_ftd2xx.cc:78


libsegwayrmp
Author(s): William Woodall
autogenerated on Mon Jun 10 2019 13:46:49