33 static int debug_level = -10000;
34 static usb_dev_handle *xu1541_handle = NULL;
37 #define TIMEOUT_DELAY 25000 // 25ms
47 static void xu1541_dbg(
int level,
char *msg, ...)
52 if(debug_level == -10000)
54 char *val = getenv(
"XU1541_DEBUG");
56 debug_level = atoi(val);
59 if(level <= debug_level)
61 fprintf(stderr,
"[XU1541] ");
63 vfprintf(stderr, msg, argp);
65 fprintf(stderr,
"\n");
83 static int usbGetStringAscii(usb_dev_handle *dev,
int index,
int langid,
84 char *buf,
int buflen)
89 if((rval = usb.control_msg(dev, USB_ENDPOINT_IN,
90 USB_REQ_GET_DESCRIPTOR,
91 (USB_DT_STRING << 8) + index,
92 langid, buffer,
sizeof(buffer), 1000)) < 0)
95 if(buffer[1] != USB_DT_STRING)
98 if((
unsigned char)buffer[0] < rval)
99 rval = (
unsigned char)buffer[0];
106 buf[i-1] = buffer[2 * i];
107 if(buffer[2 * i + 1] != 0)
135 unsigned char ret[4];
138 xu1541_dbg(0,
"Scanning usb ...");
149 for(bus = usb.get_busses(); !xu1541_handle && bus; bus = bus->next) {
150 xu1541_dbg(1,
"Scanning bus %s", bus->dirname);
152 for(dev = bus->devices; !xu1541_handle && dev; dev = dev->next) {
153 xu1541_dbg(1,
"Device %04x:%04x at %s",
154 dev->descriptor.idVendor, dev->descriptor.idProduct,
157 if((dev->descriptor.idVendor == XU1541_VID) &&
158 (dev->descriptor.idProduct == XU1541_PID)) {
162 xu1541_dbg(0,
"Found xu1541 device on bus %s device %s.",
163 bus->dirname, dev->filename);
166 if(!(xu1541_handle = usb.open(dev)))
167 fprintf(stderr,
"Error: Cannot open USB device: %s\n",
172 len = usbGetStringAscii(xu1541_handle, dev->descriptor.iProduct,
173 0x0409,
string,
sizeof(
string));
175 fprintf(stderr,
"warning: cannot query product "
176 "name for device: %s\n", usb.strerror());
177 if(xu1541_handle) usb.close(xu1541_handle);
178 xu1541_handle = NULL;
182 if(strcmp(
string,
"xu1541") != 0) {
183 fprintf(stderr,
"Error: Found xu1541 in unexpected state,"
184 " please make sure device is _not_ in bootloader mode!\n");
186 if(xu1541_handle) usb.close(xu1541_handle);
187 xu1541_handle = NULL;
194 fprintf(stderr,
"ERROR: No xu1541 device found\n");
198 if (usb.set_configuration(xu1541_handle, 1) != 0) {
199 fprintf(stderr,
"USB error: %s\n", usb.strerror());
204 if (usb.claim_interface(xu1541_handle, 0) != 0) {
205 fprintf(stderr,
"USB error: %s\n", usb.strerror());
210 len = usb.control_msg(xu1541_handle,
211 USB_TYPE_CLASS | USB_ENDPOINT_IN,
212 XU1541_INFO, 0, 0, (
char*)ret,
sizeof(ret), 1000);
215 fprintf(stderr,
"USB request for XU1541 info failed: %s!\n",
220 if(len !=
sizeof(ret)) {
221 fprintf(stderr,
"Unexpected number of bytes (%d) returned\n", len);
225 xu1541_dbg(0,
"firmware version %x.%02x", ret[0], ret[1]);
228 fprintf(stderr,
"Device reports firmware version %x.%02x\n",
230 fprintf(stderr,
"but this version of opencbm requires at least "
245 xu1541_dbg(0,
"Closing USB link");
247 if(usb.release_interface(xu1541_handle, 0))
248 fprintf(stderr,
"USB error: %s\n", usb.strerror());
250 usb.close(xu1541_handle);
270 int xu1541_ioctl(
unsigned int cmd,
unsigned int addr,
unsigned int secaddr)
275 xu1541_dbg(1,
"ioctl %d for device %d, sub %d", cmd, addr, secaddr);
280 if((cmd == XU1541_TALK) || (cmd == XU1541_UNTALK) ||
281 (cmd == XU1541_LISTEN) || (cmd == XU1541_UNLISTEN) ||
282 (cmd == XU1541_OPEN) || (cmd == XU1541_CLOSE))
284 int link_ok = 0, err = 0;
287 if((nBytes = usb.control_msg(xu1541_handle,
288 USB_TYPE_CLASS | USB_ENDPOINT_IN,
289 cmd, (secaddr << 8) + addr, 0,
293 fprintf(stderr,
"USB error in xu1541_ioctl(async): %s\n",
305 if(usb.control_msg(xu1541_handle,
306 USB_TYPE_CLASS | USB_ENDPOINT_IN,
307 XU1541_GET_RESULT, 0, 0,
308 (
char*)rv,
sizeof(rv),
312 if(rv[0] == XU1541_IO_RESULT)
315 nBytes =
sizeof(rv)-1;
323 xu1541_dbg(3,
"unexpected result (%d/%d)", rv[0], rv[1]);
331 xu1541_dbg(3,
"usb timeout");
345 if((nBytes = usb.control_msg(xu1541_handle,
346 USB_TYPE_CLASS | USB_ENDPOINT_IN,
347 cmd, (secaddr << 8) + addr, 0,
351 fprintf(stderr,
"USB error in xu1541_ioctl(sync): %s\n",
358 xu1541_dbg(2,
"returned %d bytes", nBytes);
364 xu1541_dbg(2,
"return val = %x", ret[0]);
381 int bytesWritten = 0;
383 xu1541_dbg(1,
"write %d bytes from address %p", len, data);
387 int link_ok = 0, err = 0;
389 bytes2write = (len > XU1541_IO_BUFFER_SIZE)?XU1541_IO_BUFFER_SIZE:len;
393 if((wr = usb.control_msg(xu1541_handle,
394 USB_TYPE_CLASS | USB_ENDPOINT_OUT,
395 XU1541_WRITE, bytes2write, 0,
396 (
char*)data, bytes2write,
399 fprintf(stderr,
"USB error xu1541_write(): %s\n", usb.strerror());
408 xu1541_dbg(2,
"wrote chunk of %d bytes, total %d, left %d",
409 wr, bytesWritten, len);
417 if(usb.control_msg(xu1541_handle,
418 USB_TYPE_CLASS | USB_ENDPOINT_IN,
419 XU1541_GET_RESULT, 0, 0,
420 (
char*)rv,
sizeof(rv),
424 if(rv[0] == XU1541_IO_RESULT) {
434 xu1541_dbg(3,
"unexpected result (%d/%d)", rv[0], rv[1]);
440 xu1541_dbg(3,
"usb timeout");
465 xu1541_dbg(1,
"read %d bytes to address %p", len, data);
470 int link_ok = 0, err = 0;
474 bytes2read = (len > XU1541_IO_BUFFER_SIZE)?XU1541_IO_BUFFER_SIZE:len;
478 rd = usb.control_msg(xu1541_handle,
479 USB_TYPE_CLASS | USB_ENDPOINT_IN,
480 XU1541_REQUEST_READ, bytes2read, 0,
485 fprintf(stderr,
"USB error in xu1541_request_read(): %s\n",
499 xu1541_dbg(2,
"sent request for %d bytes, waiting for result",
506 if((rd = usb.control_msg(xu1541_handle,
507 USB_TYPE_CLASS | USB_ENDPOINT_IN,
508 XU1541_GET_RESULT, 0, 0,
509 (
char*)rv,
sizeof(rv),
510 1000)) ==
sizeof(rv))
512 xu1541_dbg(2,
"got result %d/%d", rv[0], rv[1]);
518 if(rv[0] != XU1541_IO_READ_DONE)
520 xu1541_dbg(3,
"unexpected result");
525 xu1541_dbg(3,
"link ok");
533 xu1541_dbg(3,
"usb timeout");
542 if((rd = usb.control_msg(xu1541_handle,
543 USB_TYPE_CLASS | USB_ENDPOINT_IN,
544 XU1541_READ, bytes2read, 0,
545 (
char*)data, bytes2read, 1000)) < 0)
547 fprintf(stderr,
"USB error in xu1541_read(): %s\n",
556 xu1541_dbg(2,
"received chunk of %d bytes, total %d, left %d",
590 int bytesWritten = 0;
592 xu1541_dbg(1,
"special write %d %d bytes from address %p",
597 int wr, bytes2write = (size>128)?128:size;
599 if((wr = usb.control_msg(xu1541_handle,
600 USB_TYPE_CLASS | USB_ENDPOINT_OUT,
601 mode, XU1541_WRITE, bytes2write,
602 (
char*)data, bytes2write, 1000)) < 0)
604 fprintf(stderr,
"USB error in xu1541_special_write(): %s\n",
609 xu1541_dbg(2,
"special wrote %d bytes", wr);
640 xu1541_dbg(1,
"special read %d %d bytes to address %p",
645 int rd, bytes2read = (size>128)?128:size;
647 if((rd = usb.control_msg(xu1541_handle,
648 USB_TYPE_CLASS | USB_ENDPOINT_IN,
649 mode, XU1541_READ, bytes2read,
650 (
char*)data, bytes2read,
653 fprintf(stderr,
"USB error in xu1541_special_read(): %s\n",
658 xu1541_dbg(2,
"special read %d bytes", rd);
int xu1541_special_read(int mode, unsigned char *data, size_t size)
"special" read data from the xu1541 device
#define TIMEOUT_DELAY
timeout value, used mainly after errors
void xu1541_close(void)
close the xu1541 device
Allow for libusb (0.1) to be loaded dynamically (Currently, this is used on Windows only) ...
Shared library / DLL for accessing the driver Functions for obtaining the addresses of plugin functio...
int xu1541_ioctl(unsigned int cmd, unsigned int addr, unsigned int secaddr)
perform an ioctl on the xu1541
int xu1541_special_write(int mode, const unsigned char *data, size_t size)
"special" write data to the xu1541 device
int xu1541_init(void)
initialise the xu1541 device
int xu1541_read(unsigned char *data, size_t len)
read data from the xu1541 device
DLL interface for accessing the driver.
Define makros and functions which account for differences between the different architectures.
int xu1541_write(const unsigned char *data, size_t len)
write data to the xu1541 device