writer.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Yujin Robot.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Yujin Robot nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * RACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
37 /*****************************************************************************
38  ** Includes
39  *****************************************************************************/
40 
41 #include <cstring>
42 #include <ftdi.h>
43 
44 /*****************************************************************************
45  ** Definition
46  *****************************************************************************/
47 
49 
52 class FTDI_Writer {
53 public:
58  log_level(0),
59  serial_only(false),
60  use_first_device(false),
61  vendor_id(0x0403),
62  product_id(0x6001)
63  {
64  (void) log_level;
65  }
66 
71  void reset_flags() {
72  serial_only = false;
73  use_first_device = false;
74  return;
75  }
76 
83  int write(const std::string &new_id_) {
84  serial_only = true;
85  use_first_device = true;
86  int ret_val = write("", new_id_, "", "");
87  reset_flags();
88 
89  return ret_val;
90  }
91 
99  int write(const std::string &old_id_, const std::string &new_id_)
100  {
101  serial_only = true;
102  int ret_val = write(old_id_, new_id_, "", "");
103  reset_flags();
104 
105  return ret_val;
106  }
107 
117  int write(const std::string &old_id_, const std::string &new_id_, const std::string &manufacturer_, const std::string &product_)
118  {
119 // int ret;
120 // int i, no_devices;
121  struct ftdi_context ftdic;
122 // struct ftdi_device_list *devlist, *curdev;
123 /*
124  char manufacturer[128], description[128];
125  char serial[128];
126 */
127 
128  /* Initialization */
129  if (ftdi_init(&ftdic) < 0)
130  {
131  std::cerr << "ftdi_init failed" << std::endl;
132  return -1;
133  }
134 
135 // if ((no_devices = ftdi_usb_find_all(&ftdic, &devlist, vendor_id, product_id)) < 0)
136 // {
137 // std::cerr << "ftdi_usb_find_all failed: " << ftdi_get_error_string(&ftdic) << std::endl;
138 // return -1;
139 // }
140 // std::cout << "Number of FTDI devices found: " << no_devices << std::endl;
141 // std::cout << std::endl;
142 //
143 //
144 // i = 0;
145 // for (curdev = devlist; curdev != NULL; i++)
146 // {
147 // if( i > no_devices ) break; // Exceptional cases
148 //
149 // std::cout << "Target Device #" << i << std::endl;
150 #if 0
151  if ((ret = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128)) < 0)
152  {
153  std::cerr << "ftdi_usb_get_strings failed: " << ftdi_get_error_string(&ftdic) << "." << std::endl;
154  return -1;
155  /*
156  if( std::string(ftdi_get_error_string(&ftdic)).find("Operation not permitted") == -1 ) {
157  continue;
158  }
159  else
160  return EXIT_FAILURE;
161  */
162  }
163  std::cout << " Manufacturer: " << manufacturer << std::endl;
164  std::cout << " Description : " << description << std::endl;
165  std::cout << " Serial Id : " << serial << std::endl;
166  std::cout << std::endl;
167 
168  if ((!use_first_device) && (serial != old_id_)) {
169  std::cout << "It is not intedend target." << std::endl;
170  std::cout << "target: " << old_id_ << ", current: " << serial << std::endl;
171  curdev = curdev->next;
172  continue;
173  }
174 #endif
175  // Open the ftdi device
176  if (use_first_device) {
177  if (ftdi_usb_open(&ftdic, vendor_id, product_id) < 0)
178  {
179  std::cerr << "Couldn't find/open a ftdi device." << std::endl;
180  return -1;
181  }
182  } else {
183  if (ftdi_usb_open_desc(&ftdic, vendor_id, product_id, NULL, old_id_.c_str()) < 0)
184  {
185  std::cerr << "Couldn't open the device with serial id string " << old_id_ << std::endl;
186  return -1;
187  }
188  }
189 
190  // Open an Eeprom
191  //std::cout << "Eeprom Binary" << std::endl;
192  ftdi_eeprom eeprom;
193  unsigned char eeprom_binary[512];
194  int result = ftdi_read_eeprom(&ftdic, eeprom_binary);
195  int size = FTDI_DEFAULT_EEPROM_SIZE;
196  // this never works for me
197  // int size = ftdi_read_eeprom_getsize(&ftdi, eeprom_binary, 512);
198  if (size < 0)
199  {
200  std::cerr << "Error: Could not read the eeprom from the requested device." << std::endl;
201  return -1;
202  }
203  std::cout << "Read eeprom binary [" << size << " bytes]." << std::endl;
204 
205  std::cout << "Decoding into eeprom structure." << std::endl;
206  // put the binary into an eeprom structure
207  if ( ftdi_eeprom_decode(&eeprom, eeprom_binary, size) != 0 ) {
208  std::cerr << "Error: Could not write raw binary eeprom into the eeprom structure." << std::endl;
209  return -1;//EXIT_FAILURE;
210  }
211 
212  std::string new_manufacturer = manufacturer_;
213  std::string new_product = product_;
214  std::string new_id = new_id_;
215 
216  //Preparnig eeprom data to write
217  eeprom.chip_type = TYPE_R;
218  eeprom.size = size;
219  free(eeprom.serial);
220  eeprom.serial = (char*)malloc(new_id.size() + 1);
221  std::strcpy(eeprom.serial, new_id.c_str());
222  if (!serial_only) {
223  free(eeprom.manufacturer);
224  eeprom.manufacturer = (char*)malloc(new_manufacturer.size() + 1);
225  std::strcpy(eeprom.manufacturer, new_manufacturer.c_str());
226  free(eeprom.product);
227  eeprom.product = (char*)malloc(new_product.size() + 1);
228  std::strcpy(eeprom.product, new_product.c_str());
229  }
230 
231  /* Build new eeprom in binary */
232  std::cout << "Building new eeprom binary." << std::endl;
233  int eeprom_binary_length = ftdi_eeprom_build(&eeprom, eeprom_binary);
234  if (eeprom_binary_length == -1)
235  {
236  std::cerr << "Eeprom binary exceeded 128 bytes, reduce the size of your strings." << std::endl;
237  return -1;
238  //continue;
239  //return EXIT_FAILURE;
240  }
241  else if (eeprom_binary_length == -2)
242  {
243  std::cerr << "Eeprom structure not valid." << std::endl;
244  return -1; //continue;
245  //return EXIT_FAILURE;
246  }
247 
248  /* Flashing eeprom on ftdi chip */
249  std::cout << "Flashing eeprom binary." << std::endl;
250  result = ftdi_write_eeprom(&ftdic, eeprom_binary);
251  if (result < 0)
252  {
253  std::cerr << " Could not rewrite the eeprom." << std::endl;
254  return -1; //continue;
255  //return EXIT_FAILURE;
256  }
257  std::cout << " Flashed " << ftdic.eeprom_size << " bytes" << std::endl;
258 
259 #if 0
260  // Verification
261  if ((ret = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128)) < 0)
262  {
263  std::cerr << "ftdi_usb_get_strings failed: " << ftdi_get_error_string(&ftdic) << "." << std::endl;
264  return -1;
265  }
266  std::cout << "Verify Device #" << i << std::endl;
267  std::cout << " Manufacturer: " << manufacturer << std::endl;
268  std::cout << " Description : " << description << std::endl;
269  std::cout << " Serial Id : " << serial << std::endl;
270  std::cout << std::endl;
271 #endif
272  std::cout << "Done." << std::endl;
273 //
274 // curdev = curdev->next;
275 // }
276 //
277 // ftdi_list_free(&devlist);
278  ftdi_deinit(&ftdic);
279  return 0;
280  }
281 
282 private:
283  int log_level;
284  bool serial_only;
290  const unsigned short vendor_id;
291 
295  const unsigned short product_id;
296 };
int log_level
Definition: writer.hpp:283
const unsigned short product_id
Definition: writer.hpp:295
bool use_first_device
Definition: writer.hpp:285
int write(const std::string &new_id_)
Definition: writer.hpp:83
int write(const std::string &old_id_, const std::string &new_id_)
Definition: writer.hpp:99
const unsigned short vendor_id
Definition: writer.hpp:290
FTDI_Writer()
Definition: writer.hpp:57
A Writer class.
Definition: writer.hpp:52
bool serial_only
Definition: writer.hpp:284
void reset_flags()
Definition: writer.hpp:71
int write(const std::string &old_id_, const std::string &new_id_, const std::string &manufacturer_, const std::string &product_)
Definition: writer.hpp:117


kobuki_ftdi
Author(s): Younghun Ju
autogenerated on Mon Feb 28 2022 22:37:20