1 // usb2lpt.c V3.48.0
2 // THESE FUNCTIONS PERFORM THE IO TO THE USB2LPT 1.6 DEVICE
3 // based on V-USB driver by OBJECTIVE DEVELOPMENT Software GmbH
4 // see: http://www.obdev.at/products/vusb/index.html
5 // and http://vusb.wikidot.com/
6 // and the firmware usb2lpt6.c for USB2LPT 1.6 by Henrik Haftmann
7 // see http://www-user.tu-chemnitz.de/~heha/bastelecke/Rund%20um%20den%20PC/USB2LPT/index.html.en
8 // Pierre Vanhoucke / ON5GN
9
10 //UPDATE HISTORY
11 // 10 aug 2010 creation date
12 // 4 feb 2013 Ported from libusb-0.1 to libusb-1.0
13
14 #include "loadusb.h"
15 #include "options.h"
16
17 #include <sys/types.h>
18 #include <string.h>
19 #include "uidef.h"
20 #include "screendef.h"
21 #include "usbdefs.h"
22 #include "sdrdef.h"
23
24 #define USBDEV_SHARED_VENDOR_ID 0x16C0 // VOTI VID
25 #define USBDEV_SHARED_PRODUCT_ID 0x06B3 // USB2LPT PID
26 #define USB_ERROR_NOTFOUND 1
27 #define USB_ERROR_SYSTEM 2
28 #define USB_ERROR_ACCESS 2
29 #define USB_ERROR_IO 3
30 #define MAX_USB_ERR_CNT 6
31 #define DDR_OUT 0x00FF
32
33 usb_dev_handle *usb2lpt_handle0;
34 libusb_device_handle *usb2lpt_handle1;
35
out_firmware1(unsigned char port,unsigned char data)36 void out_firmware1 (unsigned char port, unsigned char data)
37 {
38 int nBytes;
39 unsigned char in_byte[1];
40 int err_cnt;
41 err_cnt =0;
42 out_again:;
43 nBytes = libusb_control_transfer
44 (
45 usb2lpt_handle1,
46 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, // request-type
47 0x92, // request_id parameter
48 port + data*256, // value parameter: first byte = portnumber, second byte = data
49 0, // index parameter
50 (unsigned char *)in_byte, // pointer to buffer
51 sizeof(in_byte),
52 5000); // timeoutInMilliseconds
53
54 if (nBytes != 0)
55 {
56 err_cnt ++;
57 if(err_cnt < MAX_USB_ERR_CNT)
58 {
59 lir_sleep(1000); // settling time
60 goto out_again;
61 }
62 else
63 {
64 printf("usb2lpt.c: Error during firmware setup \n");
65 }
66 }
67 }
68
usbOpenDevice1(void)69 int usbOpenDevice1(void)
70 {
71 libusb_context *ctx = NULL;
72 libusb_device **devs;
73 libusb_device *dev;
74 libusb_device_handle *dev_handle =NULL;
75 int errorCode = USB_ERROR_NOTFOUND;
76 unsigned char buffer[256];
77 int r,i;
78 int usb_open_flag;
79 ssize_t cnt;
80 r = libusb_init(&ctx);
81 if (r < 0)
82 {
83 printf("failed to init libusb rc=%i\n",r);
84 errorCode= USB_ERROR_SYSTEM;
85 return errorCode;
86 }
87 cnt = libusb_get_device_list(ctx, &devs);
88 if (cnt < 0)
89 {
90 printf("failed to get device list rc=%i\n",(int)cnt);
91 errorCode= USB_ERROR_SYSTEM;
92 return errorCode;
93 }
94 i=0;
95 while ((dev = devs[i++]) != NULL)
96 {
97 struct libusb_device_descriptor desc;
98 r = libusb_get_device_descriptor(dev, &desc);
99 if (r < 0)
100 {
101 printf("failed to get device descriptor rc=%i\n",r);
102 errorCode= USB_ERROR_SYSTEM;
103 return errorCode;
104 }
105
106 if (desc.idVendor == USBDEV_SHARED_VENDOR_ID &&
107 desc.idProduct == USBDEV_SHARED_PRODUCT_ID )
108 {
109 usb_open_flag =libusb_open(dev, &dev_handle);
110
111 if (usb_open_flag ==0)
112 {
113 libusb_get_string_descriptor_ascii
114 (dev_handle,
115 desc.iManufacturer,
116 buffer,
117 sizeof(buffer));
118 if(strcmp((const char *)buffer, "haftmann#software" ) == 0)
119 {
120 libusb_get_string_descriptor_ascii
121 (dev_handle,
122 desc.iProduct,
123 buffer,
124 sizeof(buffer));
125 if(strcmp((const char *)buffer, "USB2LPT low-speed adapter" ) == 0)
126 {
127 usb2lpt_handle1 = dev_handle;
128 errorCode = 0;
129 break;
130 }
131 }
132 }
133 else errorCode= USB_ERROR_IO;
134 }
135 }
136 return errorCode;
137 }
138
open_usb2lpt1(void)139 int open_usb2lpt1(void)
140 {
141 int retval, cnt;
142 char s[80];
143 if(usb2lpt_flag)return TRUE;
144 cnt=0;
145 clear_screen();
146 load_usb1_library(TRUE);
147 retry:;
148 retval=usbOpenDevice1();
149 if(retval != 0 )
150 {
151 sprintf(s,"Retcode:%d Could not find \"%s\" with VID=0x%x PID=0x%x",retval,
152 "USB2LPT low-speed adapter", USBDEV_SHARED_VENDOR_ID, USBDEV_SHARED_PRODUCT_ID);
153 lir_text(2,2,s);
154 if(retval == USB_ERROR_SYSTEM) lir_text(2,4,"USB-system failed");
155 if(retval == USB_ERROR_NOTFOUND) lir_text(2,4,"Is the USB2LPT device connected ?");
156 #if OSNUM == OSNUM_WINDOWS
157 if(retval == USB_ERROR_IO)lir_text(2,4,"USB permission denied");
158 #endif
159 #if OSNUM == OSNUM_LINUX
160 if(retval == USB_ERROR_IO)lir_text(2,4,"USB permission denied. Use sudo or run as root.");
161 #endif
162 lir_text(2,6,"Press R to retry. Any other key to skip.");
163 await_processed_keyboard();
164 if(lir_inkey == 'R')
165 {
166 cnt++;
167 sprintf(s,"Retry count %d",cnt);
168 lir_text(2,8,s);
169 goto retry;
170 }
171 clear_screen();
172 return FALSE;
173 }
174 clear_screen();
175 lir_refresh_screen();
176 out_firmware1(0x0F,0x00); // Normal operation: Pullups on
177 out_firmware1(0x0A,0x00); // SPP-Modus
178 out_firmware1(0x0D,(unsigned char)~DDR_OUT); // Statusport = Input
179 out_firmware1(0x0C,DDR_OUT); // Dataport = Output
180 out_firmware1(0x0E,DDR_OUT); // Controlport = Output
181 return TRUE;
182 }
183
out_usb2lpt1(unsigned char data,unsigned char port)184 void out_usb2lpt1(unsigned char data, unsigned char port)
185 {
186 int nBytes;
187 unsigned char in_byte[1];
188 int err_cnt;
189 char s[80];
190 err_cnt =0;
191 out_again:;
192 nBytes = libusb_control_transfer
193 (
194 usb2lpt_handle1,
195 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, // request-type
196 0x92, // request_id parameter
197 port + data*256, // value parameter: first byte = portnumber, second byte = data
198 0, // index parameter
199 (unsigned char *)in_byte, // pointer to buffer
200 sizeof(in_byte),
201 5000); // timeoutInMilliseconds
202 if (nBytes != 0)
203 {
204 err_cnt ++;
205 if(err_cnt < MAX_USB_ERR_CNT)
206 {
207 lir_sleep(1000); // settling time
208 goto out_again;
209 }
210 else
211 {
212 printf("usb2lpt.c: Error when writing to port=%i, data=%#4.2x, returncode=%i.\n",port,data,nBytes);
213 settextcolor(12);
214 sprintf(s,"Error when writing to USB2LPT device: unable to control WSE converters ");
215 lir_text(15,screen_last_line,s);
216 settextcolor(7);
217 lir_refresh_screen();
218 }
219 }
220 //printf(" OUT_USB port= %i data=%#4.2x \n",port,data);
221 //fflush(stdout);
222 return ;
223 }
224
in_usb2lpt1(unsigned char port)225 unsigned char in_usb2lpt1( unsigned char port)
226 {
227 int nBytes;
228 unsigned char in_byte[1] ;
229 int err_cnt;
230 char s[80];
231 err_cnt =0;
232 in_again:;
233 in_byte[0] = 0;
234 nBytes = 0;
235 nBytes = libusb_control_transfer
236 (
237 usb2lpt_handle1,
238 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, // request-type
239 0x01, // request_id parameter
240 port, // value parameter
241 0, // index parameter
242 (unsigned char *)in_byte, // pointer to buffer
243 sizeof(in_byte),
244 5000); // timeoutInMilliseconds
245 if (nBytes!= 1) // error recovery
246 {
247 err_cnt ++;
248 if(err_cnt < MAX_USB_ERR_CNT)
249 {
250 lir_sleep(1000); // settling time
251 goto in_again;
252 }
253 else
254 {
255 printf("usb2lpt.c: Error when reading from port=%i, data=%#4.2x, returncode=%i.\n",port,in_byte[0],nBytes);
256 in_byte[0] = 0;
257 settextcolor(12);
258 sprintf(s,"Error when reading from USB2LPT device: unable to control WSE converters ");
259 lir_text(15,screen_last_line,s);
260 settextcolor(7);
261 lir_refresh_screen();
262 }
263 }
264 //printf("IN_USB port= %i data=%#4.2x \n",port,in_byte[0] );
265 //fflush(stdout);
266 return in_byte[0] ;
267 }
268
out_firmware0(unsigned char port,unsigned char data)269 void out_firmware0 (unsigned char port, unsigned char data)
270 {
271 int nBytes;
272 unsigned char in_byte[1];
273 int err_cnt;
274 err_cnt =0;
275 out_again:;
276 nBytes = usb_control_msg
277 (
278 usb2lpt_handle0,
279 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, // request-type
280 0x92, // request_id parameter
281 port + data*256, // value parameter: first byte = portnumber, second byte = data
282 0, // index parameter
283 (char *)in_byte, // pointer to buffer
284 sizeof(in_byte),
285 5000); // timeoutInMilliseconds
286 if (nBytes != 0)
287 {
288 err_cnt ++;
289 if(err_cnt < MAX_USB_ERR_CNT)
290 {
291 lir_sleep(1000); // settling time
292 goto out_again;
293 }
294 else
295 {
296 printf("usb2lpt.c: Error during firmware setup \n");
297 printf("usb error message: %s\n", usb_strerror());
298 }
299 }
300 }
301
302
usbOpenDevice0(usb_dev_handle ** device,int vendor,char * vendorName,int product,char * productName)303 int usbOpenDevice0(usb_dev_handle **device, int vendor, char *vendorName,
304 int product, char *productName)
305 {
306 struct usb_bus *bus;
307 struct usb_device *dev;
308 int errorCode = USB_ERROR_NOTFOUND;
309 static int didUsbInit = 0;
310 char string[256];
311 int len;
312 if(!didUsbInit)
313 {
314 didUsbInit = 1;
315 usb_init();
316 }
317 usb_find_busses();
318 usb_find_devices();
319 for(bus=usb_get_busses(); bus; bus=bus->next)
320 {
321 for(dev=bus->devices; dev; dev=dev->next)
322 {
323 if(dev->descriptor.idVendor == vendor &&
324 dev->descriptor.idProduct == product)
325 {
326 // we need to open the device in order to query strings
327 usb2lpt_handle0 = usb_open(dev);
328 if(!usb2lpt_handle0)
329 {
330 errorCode = USB_ERROR_ACCESS;
331 printf("usb2lpt.c: Warning: cannot open USB device. \n");
332 printf("usb error message:%s\n", usb_strerror());
333 continue;
334 }
335 // name does not matter if strings are NULL
336 if(vendorName == NULL && productName == NULL) break;
337 // now check whether the names match:
338 len = usbGetStringAscii(usb2lpt_handle0,
339 dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
340 if(len < 0)
341 {
342 errorCode = USB_ERROR_IO;
343 printf("usb2lpt.c: Warning: cannot query manufacturer for device.\n");
344 printf("usb error message:%s\n", usb_strerror());
345 }
346 else
347 {
348 errorCode = USB_ERROR_NOTFOUND;
349 // printf("seen device from vendor ->%s<-\n", string);
350 if(strcmp(string, vendorName) == 0)
351 {
352 len = usbGetStringAscii(usb2lpt_handle0, dev->descriptor.iProduct,
353 0x0409, string, sizeof(string));
354 if(len < 0)
355 {
356 errorCode = USB_ERROR_IO;
357 printf("usb2lpt.c: Warning: cannot query product for device.\n");
358 printf("usb error message:%s\n", usb_strerror());
359 }
360 else
361 {
362 errorCode = USB_ERROR_NOTFOUND;
363 // printf("seen product ->%s<-\n", string);
364 if(strcmp(string, productName) == 0) break;
365 }
366 }
367 }
368 usb_close(usb2lpt_handle0);
369 usb2lpt_handle0 = NULL;
370 }
371 }
372 if(usb2lpt_handle0) break;
373 }
374 if(usb2lpt_handle0 != NULL)
375 {
376 errorCode = 0;
377 *device = usb2lpt_handle0;
378 }
379 return errorCode;
380 }
381
open_usb2lpt0(void)382 int open_usb2lpt0(void)
383 {
384 int retval, cnt;
385 char s[80];
386 char *usb2lpt_name_string="USB2LPT low-speed adapter";
387 if(usb2lpt_flag)return TRUE;
388 cnt=0;
389 clear_screen();
390 load_usb0_library(TRUE);
391 retry:;
392 retval=(usbOpenDevice0(&usb2lpt_handle0,
393 USBDEV_SHARED_VENDOR_ID,
394 "haftmann#software",
395 USBDEV_SHARED_PRODUCT_ID,
396 usb2lpt_name_string) );
397 if(retval != 0 )
398 {
399 sprintf(s,"%d Could not find \"%s\" with vid=0x%x pid=0x%x",retval,
400 usb2lpt_name_string, USBDEV_SHARED_VENDOR_ID, USBDEV_SHARED_PRODUCT_ID);
401 lir_text(2,2,s);
402 if(retval == USB_ERROR_NOTFOUND)
403 lir_text(2,4,"Is the USB2LPT device connected?");
404 #if OSNUM == OSNUM_WINDOWS
405 if(retval == USB_ERROR_IO)lir_text(2,4,"USB permission denied");
406 #endif
407 #if OSNUM == OSNUM_LINUX
408 if(retval == USB_ERROR_IO)lir_text(2,4,
409 "USB permission denied. Use sudo or run as root.");
410 #endif
411 lir_text(2,6,"Press R to retry. Any other key to skip.");
412 await_processed_keyboard();
413 if(lir_inkey == 'R')
414 {
415 cnt++;
416 sprintf(s,"Retry count %d",cnt);
417 lir_text(2,8,s);
418 goto retry;
419 }
420 clear_screen();
421 return FALSE;
422 }
423 clear_screen();
424 lir_refresh_screen();
425 out_firmware0(0x0F,0x00); // Normal operation: Pullups on
426 out_firmware0(0x0A,0x00); // SPP-Modus
427 out_firmware0(0x0D,(unsigned char)~DDR_OUT); // Statusport = Input
428 out_firmware0(0x0C,DDR_OUT); // Dataport = Output
429 out_firmware0(0x0E,DDR_OUT); // Controlport = Output
430 return TRUE;
431 }
432
out_usb2lpt0(unsigned char data,unsigned char port)433 void out_usb2lpt0 (unsigned char data, unsigned char port)
434 {
435 int nBytes;
436 unsigned char in_byte[1];
437 int err_cnt;
438 char s[80];
439 err_cnt =0;
440 out_again:;
441 nBytes = usb_control_msg
442 (
443 usb2lpt_handle0,
444 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, // request-type
445 0x92, // request_id parameter
446 port + data*256, // value parameter: first byte = portnumber, second byte = data
447 0, // index parameter
448 (char *)in_byte, // pointer to buffer
449 sizeof(in_byte),
450 5000); // timeoutInMilliseconds
451 if (nBytes != 0)
452 {
453 err_cnt ++;
454 if(err_cnt < MAX_USB_ERR_CNT)
455 {
456 lir_sleep(1000); // settling time
457 goto out_again;
458 }
459 else
460 {
461 printf("usb2lpt.c: Error when writing to port=%i, data=%#4.2x, returncode=%i.\n",port,data,nBytes);
462 printf("usb error message: %s\n", usb_strerror());
463 settextcolor(12);
464 sprintf(s,"Error when writing to USB2LPT device: unable to control WSE converters ");
465 lir_text(15,screen_last_line,s);
466 settextcolor(7);
467 lir_refresh_screen();
468 }
469 }
470 //printf(" OUT_USB port= %i data=%#4.2x \n",port,data);
471 //fflush(stdout);
472 return ;
473 }
474
in_usb2lpt0(unsigned char port)475 unsigned char in_usb2lpt0( unsigned char port)
476 {
477 int nBytes;
478 unsigned char in_byte[1] ;
479 int err_cnt;
480 char s[80];
481 err_cnt =0;
482 in_again:;
483 in_byte[0] = 0;
484 nBytes = 0;
485 nBytes = usb_control_msg
486 (
487 usb2lpt_handle0,
488 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, // request-type
489 0x01, // request_id parameter
490 port, // value parameter
491 0, // index parameter
492 (char *)in_byte, // pointer to buffer
493 sizeof(in_byte),
494 5000); // timeoutInMilliseconds
495 if (nBytes!= 1) // error recovery
496 {
497 err_cnt ++;
498 if(err_cnt < MAX_USB_ERR_CNT)
499 {
500 lir_sleep(1000); // settling time
501 goto in_again;
502 }
503 else
504 {
505 printf("usb2lpt.c: Error when reading from port=%i, data=%#4.2x, returncode=%i.\n",port,in_byte[0],nBytes);
506 printf("usb error message: %s\n", usb_strerror());
507 in_byte[0] = 0;
508 settextcolor(12);
509 sprintf(s,"Error when reading from USB2LPT device: unable to control WSE converters ");
510 lir_text(15,screen_last_line,s);
511 settextcolor(7);
512 lir_refresh_screen();
513 }
514 }
515 //printf("IN_USB port= %i data=%#4.2x \n",port,in_byte[0] );
516 //fflush(stdout);
517 return in_byte[0] ;
518 }
519
open_USB2LPT(void)520 int open_USB2LPT(void)
521 {
522 if(wse.libusb_version == 1)return open_usb2lpt1();
523 if(wse.libusb_version == 0)return open_usb2lpt0();
524 return FALSE;
525 }
526
out_USB2LPT(unsigned char data,unsigned char port)527 void out_USB2LPT(unsigned char data, unsigned char port)
528 {
529 if(wse.libusb_version == 1)out_usb2lpt1(data, port);
530 if(wse.libusb_version == 0)out_usb2lpt0(data, port);
531 }
532
in_USB2LPT(unsigned char port)533 unsigned char in_USB2LPT( unsigned char port)
534 {
535 if(wse.libusb_version == 1)return in_usb2lpt1(port);
536 if(wse.libusb_version == 0)return in_usb2lpt0(port);
537 return 0;
538 }
539