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