From 62c6e22ae6f91907f2df1292752d8f5952cd62d8 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Wed, 21 Oct 2009 20:28:33 +0200 Subject: [PATCH 1/7] Switched to getopt, fixed minor issues and some cleanups. --- tools/qdinc/Makefile | 2 +- tools/qdinc/qdinc.c | 198 ++++++++++++++++++++----------------------- tools/qdinc/qdinc.h | 5 +- 3 files changed, 92 insertions(+), 113 deletions(-) diff --git a/tools/qdinc/Makefile b/tools/qdinc/Makefile index ab60669..9ca6de2 100644 --- a/tools/qdinc/Makefile +++ b/tools/qdinc/Makefile @@ -27,7 +27,7 @@ NAME = qdinc OBJECTS = opendevice.o $(NAME).o CC = gcc -CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall +CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -D_GNU_SOURCE LIBS = $(USBLIBS) PROGRAM = $(NAME)$(EXE_SUFFIX) diff --git a/tools/qdinc/qdinc.c b/tools/qdinc/qdinc.c index 0332c63..01477e5 100644 --- a/tools/qdinc/qdinc.c +++ b/tools/qdinc/qdinc.c @@ -1,19 +1,31 @@ #include #include #include - #include +#include +#include #include "opendevice.h" - #include "qdinc.h" +#define _16MBIT 0x200000 +#define HIROM_BANK_SIZE_SHIFT 16 +#define LOROM_BANK_SIZE_SHIFT 15 +#define HIROM_BANK_COUNT_SHIFT 32 +#define LOROM_BANK_COUNT_SHIFT 64 + static const char * default_tempfile = "/tmp/quickdev"; void usage(void) { - fprintf(stderr, "usage: qdinc [-hsi] \n"); + fprintf(stderr, "Usage: qdinc [option] \n\n\ + Options:\n\ + -i\tInitial ROM upload\n\ + -s\tSkip ROM header\n\ + -q\tBe quiet\n\ + -h\tForce HiROM mode\n\n"); + exit(1); } @@ -24,81 +36,67 @@ int main(int argc, char * argv[]) int hirom = 0; int header = 0; int init = 0; - int i,j,j2; - for(i = 1; i < argc; i++) - { - if(argv[i][0] == '-') - { - if(strcmp(argv[i], "--") == 0) - { - if(i != argc - 2 || filename) - usage(); - else - { - filename = argv[i+1]; - break; - } - } - unsigned int len = strlen(argv[i]); - if(len == 1) + int quiet = 0; + int opt = 0; + + if (argc==1) + usage(); + + while ((opt = getopt(argc,argv,"qish")) != -1){ + switch (opt) { + case 'i': + init = 1; + break; + case 's': + header = 1; + break; + case 'h': + hirom = 1; + break; + case 'q': + quiet = 1; + break; + default: usage(); - for(j = 1; j < len; j++) - { - switch(argv[i][j]) - { - case 'h': - hirom = 1; - break; - case 's': - header = 1; - break; - case 'i': - init = 1; - break; - default: - usage(); - } - } - } - else - { - if(filename != 0) - usage(); - filename = argv[i]; } } + + + if (optind >= argc) { + usage(); + } + + filename = argv[optind]; + + int j,j2; + int ref_complete, upload_complete = 0; + const char * tempfile_name = getenv("QDINC_FILE"); - unsigned int pos = 0; - int ref_complete, upd_complete = 0; - - const char * tempfile = getenv("QDINC_FILE"); - - if(tempfile == 0) - tempfile = default_tempfile; + if(tempfile_name == 0) + tempfile_name = default_tempfile; - char * outfile = malloc(strlen(tempfile) + sizeof(".out")); - char * ext = stpcpy(outfile, tempfile); + char * outfile = malloc(strlen(tempfile_name) + sizeof(".out")); + char * ext = stpcpy(outfile, tempfile_name); strcpy(ext, ".out"); + FILE * temp_file = fopen(outfile, "wb"); - FILE * out = fopen(outfile, "wb"); - - if(out == 0) + if(temp_file == 0) { fprintf(stderr, "Could not open file %s for writing\n", outfile); exit(1); } - FILE * upd = fopen(filename, "rb"); + FILE * new_rom = fopen(filename, "rb"); - if(upd == 0) + if(new_rom == 0) { fprintf(stderr, "Could not open file %s\n", argv[3]); exit(1); } - fseek(upd, 0, SEEK_END); - unsigned int size = ftell(upd); + fseek(new_rom, 0, SEEK_END); + unsigned int size = ftell(new_rom); if(header) { @@ -106,12 +104,12 @@ int main(int argc, char * argv[]) size = 0; else size -= 512; - fseek(upd, 512, SEEK_SET); + fseek(new_rom, 512, SEEK_SET); } else - rewind(upd); + rewind(new_rom); - if(size > 0x200000) + if(size > _16MBIT) { fprintf(stderr, "Input file is larger than supported by Quickdev16\n"); exit(1); @@ -119,7 +117,7 @@ int main(int argc, char * argv[]) FILE * ref = 0; if(!init) - ref = fopen(tempfile, "rb"); + ref = fopen(tempfile_name, "rb"); ref_complete = (ref == 0); @@ -138,27 +136,23 @@ int main(int argc, char * argv[]) exit(1); } -#ifndef QDINC_OLD_FIRMWARE cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_ENDPOINT_OUT, USB_SET_LAODER, 0, 0, NULL, + USB_ENDPOINT_OUT, USB_SET_LOADER, 0, 0, NULL, 0, 5000); -#endif cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL, 0, 5000); -#ifdef QDINC_OLD_FIRMWARE - /* wait for the loader to depack */ - usleep(500000); -#else usleep(50000); -#endif cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, - USB_BULK_UPLOAD_INIT, (hirom ? 16 : 15) , (hirom ? 32 : 64) /* << this is wrong, but only used for progress display */, NULL, 0, 5000); + USB_BULK_UPLOAD_INIT, + (hirom ? HIROM_BANK_SIZE_SHIFT : LOROM_BANK_SIZE_SHIFT) , + (hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT) /* << this is wrong, but only used for progress display */, + NULL, 0, 5000); unsigned char diffblock[256]; unsigned int blocklen = 0; @@ -166,31 +160,31 @@ int main(int argc, char * argv[]) unsigned int position = 0; unsigned int last_position = (unsigned int)(-1); - unsigned char lastchar; + unsigned char lastchar = 0; unsigned int transmitted = 0; char progress[21]; - - for(i = 0; i < 20; i++) - progress[i] = ' '; + memset(progress,' ',19); progress[20] = 0; j = 0; j2 = 0; - while(!upd_complete) + while(!upload_complete) { int msg = 0; - unsigned char updchar = fgetc(upd); - unsigned char refchar; - if(feof(upd)) + unsigned char updchar = fgetc(new_rom); + unsigned char refchar=0; + + if(feof(new_rom)) { msg = 1; - upd_complete = 1; + upload_complete = 1; } else - fputc(updchar, out); - if(!ref_complete && !upd_complete) + fputc(updchar, temp_file); + + if(!ref_complete && !upload_complete) { refchar = fgetc(ref); if(feof(ref)) @@ -198,21 +192,11 @@ int main(int argc, char * argv[]) } int match = (ref_complete || updchar != refchar); -#ifdef QDINC_OLD_FIRMWARE - if(position < 64 * 1024) - match = 1; -#endif - if(upd_complete) + if(upload_complete) match = 0; + if(match) { -#ifdef QDINC_OLD_FIRMWARE - if(blocklen == 0 && (position & (hirom ? 0xFFFF : 0x7FFF)) == 0 && position != 0 && position != last_position) - { - diffblock[0] = lastchar; - blocklen++; - } -#endif diffblock[blocklen] = updchar; blocklen++; reallen = blocklen; @@ -224,7 +208,7 @@ int main(int argc, char * argv[]) } position++; - if((reallen > 0 && upd_complete) || ((!upd_complete) && (( (blocklen - reallen) >= QDINC_RANGE && !match) || blocklen == QDINC_SIZE)) ) + if((reallen > 0 && upload_complete) || ((!upload_complete) && (( (blocklen - reallen) >= QDINC_RANGE && !match) || blocklen == QDINC_SIZE)) ) { int consecutive = (last_position == position - blocklen); unsigned int begin = position - blocklen; @@ -243,7 +227,7 @@ int main(int argc, char * argv[]) msg = 1; } - if(msg) + if(!quiet && msg) { for(; j < (position - 1) * 20 / size; j++) progress[j] = '='; @@ -267,16 +251,17 @@ int main(int argc, char * argv[]) if(feof(ref)) ref_complete = 1; else - fputc(refchar, out); + fputc(refchar, temp_file); } - fclose(out); - fclose(upd); - fclose(ref); + fclose(temp_file); + fclose(new_rom); + if (!init) + fclose(ref); - if(rename(outfile, tempfile)) + if(rename(outfile, tempfile_name)) { - fprintf(stderr, "Could not replace tempfile %s\n", tempfile); + fprintf(stderr, "Could not replace tempfile %s\n", tempfile_name); exit(1); } @@ -285,18 +270,15 @@ int main(int argc, char * argv[]) USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL, 0, 5000); -#ifndef QDINC_OLD_FIRMWARE cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_ENDPOINT_OUT, USB_SET_LAODER, 1, 1, NULL, + USB_ENDPOINT_OUT, USB_SET_LOADER, 1, 1, NULL, 0, 5000); -#endif cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL, 0, 5000); + return 0; - - printf("Done"); } diff --git a/tools/qdinc/qdinc.h b/tools/qdinc/qdinc.h index 162ab53..5045c5a 100644 --- a/tools/qdinc/qdinc.h +++ b/tools/qdinc/qdinc.h @@ -4,9 +4,6 @@ #define QDINC_RANGE 96 #define QDINC_SIZE 254 -// makes this compatible with a bug in older quickdev firmware revisions -//#define QDINC_OLD_FIRMWARE - /* quickdev protocol defines */ #define USB_UPLOAD_INIT 0 @@ -25,7 +22,7 @@ #define USB_MODE_SNES 10 #define USB_MODE_AVR 11 #define USB_AVR_RESET 12 -#define USB_SET_LAODER 13 +#define USB_SET_LOADER 13 /* -------------------------- Device Description --------------------------- */ From d7c767dbc78398f5ddf863120fc384bcf7047e03 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Fri, 13 Nov 2009 16:01:27 +0100 Subject: [PATCH 2/7] - double write fix --- avr/usbload/sram.c | 1 - 1 file changed, 1 deletion(-) diff --git a/avr/usbload/sram.c b/avr/usbload/sram.c index 9e94fec..de514db 100644 --- a/avr/usbload/sram.c +++ b/avr/usbload/sram.c @@ -238,7 +238,6 @@ void sram_bulk_write_start(uint32_t addr) inline void sram_bulk_write_next(void) { - AVR_WR_PORT &= ~(1 << AVR_WR_PIN); addr_current++; counter_up(); } From 297b10ccf772926f5f461ad6855889b1b605a745 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Sat, 24 Oct 2009 22:44:23 +0200 Subject: [PATCH 3/7] o Added qdips - still nonworking so far --- tools/qdips/Makefile | 23 ++++ tools/qdips/opendevice.c | 286 +++++++++++++++++++++++++++++++++++++++ tools/qdips/opendevice.h | 77 +++++++++++ tools/qdips/qdips.c | 286 +++++++++++++++++++++++++++++++++++++++ tools/qdips/qdips.h | 59 ++++++++ 5 files changed, 731 insertions(+) create mode 100644 tools/qdips/Makefile create mode 100644 tools/qdips/opendevice.c create mode 100644 tools/qdips/opendevice.h create mode 100644 tools/qdips/qdips.c create mode 100644 tools/qdips/qdips.h diff --git a/tools/qdips/Makefile b/tools/qdips/Makefile new file mode 100644 index 0000000..49cca29 --- /dev/null +++ b/tools/qdips/Makefile @@ -0,0 +1,23 @@ +USBFLAGS = `libusb-config --cflags` +USBLIBS = `libusb-config --libs` + +CC = llvm-gcc +CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -D_GNU_SOURCE --std=c99 +LIBS = $(USBLIBS) + +NAME = qdips +OBJECTS = opendevice.o $(NAME).o + + +PROGRAM = $(NAME)$(EXE_SUFFIX) + + +all: $(PROGRAM) + +.c.o: + $(CC) $(CFLAGS) -c $< + +$(PROGRAM): $(OBJECTS) + $(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS) +clean: + rm -f *.o $(PROGRAM) diff --git a/tools/qdips/opendevice.c b/tools/qdips/opendevice.c new file mode 100644 index 0000000..7706310 --- /dev/null +++ b/tools/qdips/opendevice.c @@ -0,0 +1,286 @@ +/* + * Name: opendevice.c Project: V-USB host-side library Author: Christian + * Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c) 2008 by + * OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt), + * GNU GPL v3 or proprietary (CommercialLicense.txt) This Revision: $Id: + * opendevice.c 740 2009-04-13 18:23:31Z cs $ + */ + +/* + * General Description: The functions in this module can be used to find and + * open a device based on libusb or libusb-win32. + */ + + +#include +#include "opendevice.h" + +/* + * ------------------------------------------------------------------------- + */ + +#define MATCH_SUCCESS 1 +#define MATCH_FAILED 0 +#define MATCH_ABORT -1 + +/* + * private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or + * MATCH_ABORT. + */ +static int _shellStyleMatch(char *text, char *p) +{ + int last, + matched, + reverse; + + for (; *p; text++, p++) { + if (*text == 0 && *p != '*') + return MATCH_ABORT; + switch (*p) { + case '\\': + /* + * Literal match with following character. + */ + p++; + /* + * FALLTHROUGH + */ + default: + if (*text != *p) + return MATCH_FAILED; + continue; + case '?': + /* + * Match anything. + */ + continue; + case '*': + while (*++p == '*') + /* + * Consecutive stars act just like one. + */ + continue; + if (*p == 0) + /* + * Trailing star matches everything. + */ + return MATCH_SUCCESS; + while (*text) + if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) + return matched; + return MATCH_ABORT; + case '[': + reverse = p[1] == '^'; + if (reverse) /* Inverted character class. */ + p++; + matched = MATCH_FAILED; + if (p[1] == ']' || p[1] == '-') + if (*++p == *text) + matched = MATCH_SUCCESS; + for (last = *p; *++p && *p != ']'; last = *p) + if (*p == '-' && p[1] != ']' ? *text <= *++p + && *text >= last : *text == *p) + matched = MATCH_SUCCESS; + if (matched == reverse) + return MATCH_FAILED; + continue; + } + } + return *text == 0; +} + +/* + * public interface for shell style matching: returns 0 if fails, 1 if matches + */ +static int shellStyleMatch(char *text, char *pattern) +{ + if (pattern == NULL) /* NULL pattern is synonymous to "*" */ + return 1; + return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; +} + +/* + * ------------------------------------------------------------------------- + */ + +int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen) +{ + char buffer[256]; + int rval, + i; + + if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use + * libusb + * version + * if + * it + * works + */ + return rval; + if ((rval = + usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, + (USB_DT_STRING << 8) + index, 0x0409, buffer, + sizeof(buffer), 5000)) < 0) + return rval; + if (buffer[1] != USB_DT_STRING) { + *buf = 0; + return 0; + } + if ((unsigned char) buffer[0] < rval) + rval = (unsigned char) buffer[0]; + rval /= 2; + /* + * lossy conversion to ISO Latin1: + */ + for (i = 1; i < rval; i++) { + if (i > buflen) /* destination buffer overflow */ + break; + buf[i - 1] = buffer[2 * i]; + if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ + buf[i - 1] = '?'; + } + buf[i - 1] = 0; + return i - 1; +} + +/* + * ------------------------------------------------------------------------- + */ + +int usbOpenDevice(usb_dev_handle ** device, int vendorID, + char *vendorNamePattern, int productID, + char *productNamePattern, char *serialNamePattern, + FILE * printMatchingDevicesFp, FILE * warningsFp) +{ + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *handle = NULL; + int errorCode = USBOPEN_ERR_NOTFOUND; + + usb_find_busses(); + usb_find_devices(); + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { /* iterate over + * all devices + * on all + * busses */ + if ((vendorID == 0 || dev->descriptor.idVendor == vendorID) + && (productID == 0 || dev->descriptor.idProduct == productID)) { + char vendor[256], + product[256], + serial[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order + * to query strings */ + if (!handle) { + errorCode = USBOPEN_ERR_ACCESS; + if (warningsFp != NULL) + fprintf(warningsFp, + "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, usb_strerror()); + continue; + } + /* + * now check whether the names match: + */ + len = vendor[0] = 0; + if (dev->descriptor.iManufacturer > 0) { + len = + usbGetStringAscii(handle, dev->descriptor.iManufacturer, + vendor, sizeof(vendor)); + } + if (len < 0) { + errorCode = USBOPEN_ERR_ACCESS; + if (warningsFp != NULL) + fprintf(warningsFp, + "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, usb_strerror()); + } else { + errorCode = USBOPEN_ERR_NOTFOUND; + /* + * printf("seen device from vendor ->%s<-\n", vendor); + */ + if (shellStyleMatch(vendor, vendorNamePattern)) { + len = product[0] = 0; + if (dev->descriptor.iProduct > 0) { + len = + usbGetStringAscii(handle, + dev->descriptor.iProduct, + product, sizeof(product)); + } + if (len < 0) { + errorCode = USBOPEN_ERR_ACCESS; + if (warningsFp != NULL) + fprintf(warningsFp, + "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, + usb_strerror()); + } else { + errorCode = USBOPEN_ERR_NOTFOUND; + /* + * printf("seen product ->%s<-\n", product); + */ + if (shellStyleMatch(product, productNamePattern)) { + len = serial[0] = 0; + if (dev->descriptor.iSerialNumber > 0) { + len = + usbGetStringAscii(handle, + dev->descriptor. + iSerialNumber, serial, + sizeof(serial)); + } + if (len < 0) { + errorCode = USBOPEN_ERR_ACCESS; + if (warningsFp != NULL) + fprintf(warningsFp, + "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, + usb_strerror()); + } + if (shellStyleMatch(serial, serialNamePattern)) { + if (printMatchingDevicesFp != NULL) { + if (serial[0] == 0) { + fprintf(printMatchingDevicesFp, + "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, + vendor, product); + } else { + fprintf(printMatchingDevicesFp, + "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct, + vendor, product, serial); + } + } else { + break; + } + } + } + } + } + } + usb_close(handle); + handle = NULL; + } + } + if (handle) /* we have found a deice */ + break; + } + if (handle != NULL) { + errorCode = 0; + *device = handle; + } + if (printMatchingDevicesFp != NULL) /* never return an error for listing + * only */ + errorCode = 0; + return errorCode; +} + +/* + * ------------------------------------------------------------------------- + */ diff --git a/tools/qdips/opendevice.h b/tools/qdips/opendevice.h new file mode 100644 index 0000000..0e04f73 --- /dev/null +++ b/tools/qdips/opendevice.h @@ -0,0 +1,77 @@ +/* Name: opendevice.h + * Project: V-USB host-side library + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: opendevice.h 740 2009-04-13 18:23:31Z cs $ + */ + +/* +General Description: +This module offers additional functionality for host side drivers based on +libusb or libusb-win32. It includes a function to find and open a device +based on numeric IDs and textual description. It also includes a function to +obtain textual descriptions from a device. + +To use this functionality, simply copy opendevice.c and opendevice.h into your +project and add them to your Makefile. You may modify and redistribute these +files according to the GNU General Public License (GPL) version 2 or 3. +*/ + +#ifndef __OPENDEVICE_H_INCLUDED__ +#define __OPENDEVICE_H_INCLUDED__ + +#include /* this is libusb, see http://libusb.sourceforge.net/ */ +#include + +int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); +/* This function gets a string descriptor from the device. 'index' is the + * string descriptor index. The string is returned in ISO Latin 1 encoding in + * 'buf' and it is terminated with a 0-character. The buffer size must be + * passed in 'buflen' to prevent buffer overflows. A libusb device handle + * must be given in 'dev'. + * Returns: The length of the string (excluding the terminating 0) or + * a negative number in case of an error. If there was an error, use + * usb_strerror() to obtain the error message. + */ + +int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); +/* This function iterates over all devices on all USB busses and searches for + * a device. Matching is done first by means of Vendor- and Product-ID (passed + * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). + * When a device matches by its IDs, matching by names is performed. Name + * matching can be done on textual vendor name ('vendorNamePattern'), product + * name ('productNamePattern') and serial number ('serialNamePattern'). A + * device matches only if all non-null pattern match. If you don't care about + * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: + * '*' stands for 0 or more characters, '?' for one single character, a list + * of characters in square brackets for a single character from the list + * (dashes are allowed to specify a range) and if the lis of characters begins + * with a caret ('^'), it matches one character which is NOT in the list. + * Other parameters to the function: If 'warningsFp' is not NULL, warning + * messages are printed to this file descriptor with fprintf(). If + * 'printMatchingDevicesFp' is not NULL, no device is opened but matching + * devices are printed to the given file descriptor with fprintf(). + * If a device is opened, the resulting USB handle is stored in '*device'. A + * pointer to a "usb_dev_handle *" type variable must be passed here. + * Returns: 0 on success, an error code (see defines below) on failure. + */ + +/* usbOpenDevice() error codes: */ +#define USBOPEN_SUCCESS 0 /* no error */ +#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ +#define USBOPEN_ERR_IO 2 /* I/O error */ +#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ + + +/* Obdev's free USB IDs, see USBID-License.txt for details */ + +#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ +#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ +#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ +#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ +#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ + +#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/tools/qdips/qdips.c b/tools/qdips/qdips.c new file mode 100644 index 0000000..3ce3447 --- /dev/null +++ b/tools/qdips/qdips.c @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include +#include + +#include "opendevice.h" +#include "qdips.h" + + +#define _16MBIT 0x200000 + +#define HIROM_BANK_SIZE_SHIFT 16 +#define LOROM_BANK_SIZE_SHIFT 15 +#define HIROM_BANK_COUNT_SHIFT 32 +#define LOROM_BANK_COUNT_SHIFT 64 + +#define IPS_MAGIC "PATCH" +#define EOF_TAG 0x454f46 +#define PATCH_END 1 +#define PATCH_ERR 2 +#define PATCH_CHUNKS_MAX 512 + +#define QD16_MAX_TX_LEN 128 +#define QD16_CMD_TIMEOUT 5000 + + +#define QD16_SEND_DATA(__addr_hi,__addr_lo,__src,__len)\ + usb_control_msg(handle,\ + USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,\ + USB_BULK_UPLOAD_NEXT,\ + __addr_hi, __addr_lo,\ + (char*)__src, __len,\ + QD16_CMD_TIMEOUT); + +#define QD16_SEND_ADDR(__addr_hi,__addr_lo,__src,__len)\ + usb_control_msg(handle,\ + USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,\ + USB_BULK_UPLOAD_ADDR,\ + __addr_hi,__addr_lo,\ + (char*)__src,__len,\ + QD16_CMD_TIMEOUT); + + +typedef struct _ips_tag { + uint32_t ofs; /* offset in file to patch */ + uint16_t len; /* number of bytes in this chunk */ + uint8_t* data; /* chunk data */ +} ips_tag_t; + +int qd16_apply_ips_chunk(ips_tag_t* ips_tag); +int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag); +int qd16_init(void); +void qd16_finish(void); +void usage(void); + +usb_dev_handle *handle = NULL; +const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = { USB_CFG_DEVICE_ID}; +char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = { USB_CFG_DEVICE_NAME, 0}; +int cnt, vid, pid; + +int hirom = 0; +int header = 0; +int init = 0; +int quiet = 0; + +uint8_t dummy[128]; + +void usage(void) +{ + fprintf(stderr, "Usage: qdips [option] \n\n\ + Options:\n\ + -s\tSkip ROM header\n\ + -q\tBe quiet\n\ + -h\tForce HiROM mode\n\n"); + + exit(1); +} + +int main(int argc, char * argv[]) +{ + FILE* patch_file; + char * fname = 0; + int opt = 0; + + char magic[6]; + ips_tag_t ips_tags[PATCH_CHUNKS_MAX]; + int chunk_index = 0; + + if (argc==1) + usage(); + + while ((opt = getopt(argc,argv,"qish")) != -1){ + switch (opt) { + case 'i': + init = 1; + break; + case 's': + header = 1; + break; + case 'h': + hirom = 1; + break; + case 'q': + quiet = 1; + break; + default: + usage(); + } + } + + + if (optind >= argc) { + usage(); + } + + int ret = qd16_init(); + if (ret != 0){ + fprintf(stderr,"Error during init. Exiting!\n"); + exit(1); + } + qd16_finish(); + exit(0); + + fname = argv[optind]; + patch_file = fopen(fname,"rb"); + if (patch_file == 0) { + fprintf(stderr,"Failed to open file '%s'!\n",fname); + exit(1); + } + + if (fgets(magic,strlen(IPS_MAGIC)+1,patch_file) == NULL) { + fprintf(stderr,"Error reading from file %s\n",fname); + fclose(patch_file); + exit(1); + } + + if (strcmp(magic,IPS_MAGIC) != 0){ + fprintf(stderr,"Patch is not in ips format!\n"); + } + + int patch_error = 0; + + while (!feof(patch_file) && chunk_index < PATCH_CHUNKS_MAX) { + + printf("."); + + int ret = ips_read_next_tag(patch_file,&ips_tags[chunk_index]); + + if (ret == PATCH_END) + break; + else if (ret == PATCH_ERR) { + patch_error = 1; + break; + } + + chunk_index++; + } + + fclose(patch_file); + + for (int i=0; iofs)>>16; + int addr_lo = (ips_tag->ofs)&0xffff; + + printf("hi:%x lo:%x\n",addr_hi,addr_lo); + + int ret = QD16_SEND_ADDR(addr_hi,addr_lo,ips_tag->data,ips_tag->len); + /*int ret = QD16_SEND_ADDR(addr_hi,addr_lo,dummy,128);*/ + if (ret<0){ + printf("error executing command!:%s\n",usb_strerror()); + } + + ret = QD16_SEND_DATA(addr_hi,addr_lo,ips_tag->data,ips_tag->len); + /*int ret = QD16_SEND_ADDR(addr_hi,addr_lo,dummy,128);*/ + if (ret<0){ + printf("error executing command!:%s\n",usb_strerror()); + } + + return 0; +} + +void qd16_finish(void) +{ +#if 0 + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL, + 0, 5000); + + if (cnt<0) { + printf("USB_BULK_UPLOAD_END failed: %s\n",usb_strerror()); + } +#endif + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_ENDPOINT_OUT, USB_SET_LOADER, 0, 0, NULL, + 0, 5000); + + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL, + 0, 5000); + if (cnt<0) { + printf("USB_MODE_SNES failed: %s\n",usb_strerror()); + } + +} + +int qd16_init(void) +{ + usb_init(); + + vid = rawVid[1] * 256 + rawVid[0]; + pid = rawPid[1] * 256 + rawPid[0]; + + if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0) { + fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); + return 1; + } + + + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL, + 0, 5000); + + if (cnt<0) { + printf("USB_MODE_AVR failed: %s\n",usb_strerror()); + } + + usleep(500000); + +#if 0 + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, + USB_BULK_UPLOAD_INIT, + (hirom ? HIROM_BANK_SIZE_SHIFT : LOROM_BANK_SIZE_SHIFT) , + (hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT), + NULL, 0, 5000); + + if (cnt<0) { + printf("USB_BULK_UPLOAD_INIT failed: %s\n",usb_strerror()); + } +#endif + + return 0; +} + +int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag) +{ + + tag->ofs = getc(patch_file)<<16 | getc(patch_file)<<8 | getc(patch_file); + + if (tag->ofs == EOF_TAG) + return PATCH_END; + if (tag->ofs > _16MBIT) + return PATCH_ERR; + + tag->len = getc(patch_file)<<8 | getc(patch_file); + tag->data = malloc(tag->len); + + size_t ret = fread(tag->data,1,tag->len,patch_file); + if (ret != tag->len) + return PATCH_ERR; + + return 0; +} diff --git a/tools/qdips/qdips.h b/tools/qdips/qdips.h new file mode 100644 index 0000000..5045c5a --- /dev/null +++ b/tools/qdips/qdips.h @@ -0,0 +1,59 @@ +#ifndef __QDINC_H__ +#define __QDINC_H__ + +#define QDINC_RANGE 96 +#define QDINC_SIZE 254 + +/* quickdev protocol defines */ + +#define USB_UPLOAD_INIT 0 +#define USB_UPLOAD_ADDR 1 + +#define USB_DOWNLOAD_INIT 2 +#define USB_DOWNLOAD_ADDR 3 + +#define USB_CRC 4 +#define USB_CRC_ADDR 5 + +#define USB_BULK_UPLOAD_INIT 6 +#define USB_BULK_UPLOAD_ADDR 7 +#define USB_BULK_UPLOAD_NEXT 8 +#define USB_BULK_UPLOAD_END 9 +#define USB_MODE_SNES 10 +#define USB_MODE_AVR 11 +#define USB_AVR_RESET 12 +#define USB_SET_LOADER 13 + +/* -------------------------- Device Description --------------------------- */ + +#define USB_CFG_VENDOR_ID 0xc0, 0x16 +/* USB vendor ID for the device, low byte first. If you have registered your + * own Vendor ID, define it here. Otherwise you use one of obdev's free shared + * VID/PID pairs. Be sure to read USBID-License.txt for rules! + */ +#define USB_CFG_DEVICE_ID 0xdd, 0x05 +/* This is the ID of the product, low byte first. It is interpreted in the + * scope of the vendor ID. If you have registered your own VID with usb.org + * or if you have licensed a PID from somebody else, define it here. Otherwise + * you use obdev's free shared VID/PID pair. Be sure to read the rules in + * USBID-License.txt! + */ +#define USB_CFG_DEVICE_VERSION 0x00, 0x01 +/* Version number of the device: Minor number first, then major number. + */ +#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g' +#define USB_CFG_VENDOR_NAME_LEN 10 +/* These two values define the vendor name returned by the USB device. The name + * must be given as a list of characters under single quotes. The characters + * are interpreted as Unicode (UTF-16) entities. + * If you don't want a vendor name string, undefine these macros. + * ALWAYS define a vendor name containing your Internet domain name if you use + * obdev's free shared VID/PID pair. See the file USBID-License.txt for + * details. + */ +#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6' +#define USB_CFG_DEVICE_NAME_LEN 10 + +/* end of quickdev protocol defines */ + +#endif From b927fbf93b05b11032ba3594d1225c00d6c4172b Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Sun, 25 Oct 2009 01:34:03 +0200 Subject: [PATCH 4/7] - qdips: patch chunk upload working but fw transfer bug remains usb bulk transfers copy the last byte of the chunk to SRAM twice. --- avr/usbload/config.h | 2 +- avr/usbload/main.c | 2 +- tools/qdips/qdips.c | 36 +++++++++++++++--------------------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/avr/usbload/config.h b/avr/usbload/config.h index d51bf05..70516b4 100644 --- a/avr/usbload/config.h +++ b/avr/usbload/config.h @@ -50,7 +50,7 @@ #define DO_CRC_CHECK_LOADER 0 #define DO_CRC_CHECK 0 -#define DO_SHM_SCRATCHPAD 1 +#define DO_SHM_SCRATCHPAD 0 #define DO_SHM 0 #define DO_TIMER 0 #define DO_SHELL 1 diff --git a/avr/usbload/main.c b/avr/usbload/main.c index 50491cc..e60858f 100644 --- a/avr/usbload/main.c +++ b/avr/usbload/main.c @@ -305,7 +305,7 @@ int main(void) system_set_bus_avr(); system_send_snes_reset(); } - globals_init(); + /*globals_init();*/ } return 0; } diff --git a/tools/qdips/qdips.c b/tools/qdips/qdips.c index 3ce3447..7ba0aa2 100644 --- a/tools/qdips/qdips.c +++ b/tools/qdips/qdips.c @@ -44,9 +44,9 @@ typedef struct _ips_tag { - uint32_t ofs; /* offset in file to patch */ + uint32_t ofs; /* offset in file to patch */ uint16_t len; /* number of bytes in this chunk */ - uint8_t* data; /* chunk data */ + uint8_t* data; /* chunk data */ } ips_tag_t; int qd16_apply_ips_chunk(ips_tag_t* ips_tag); @@ -120,8 +120,6 @@ int main(int argc, char * argv[]) fprintf(stderr,"Error during init. Exiting!\n"); exit(1); } - qd16_finish(); - exit(0); fname = argv[optind]; patch_file = fopen(fname,"rb"); @@ -177,20 +175,11 @@ int main(int argc, char * argv[]) int qd16_apply_ips_chunk(ips_tag_t* ips_tag) { - return 0; int addr_hi = (ips_tag->ofs)>>16; int addr_lo = (ips_tag->ofs)&0xffff; - printf("hi:%x lo:%x\n",addr_hi,addr_lo); - + printf("hi:%x lo:%x len:%d\n",addr_hi,addr_lo,ips_tag->len); int ret = QD16_SEND_ADDR(addr_hi,addr_lo,ips_tag->data,ips_tag->len); - /*int ret = QD16_SEND_ADDR(addr_hi,addr_lo,dummy,128);*/ - if (ret<0){ - printf("error executing command!:%s\n",usb_strerror()); - } - - ret = QD16_SEND_DATA(addr_hi,addr_lo,ips_tag->data,ips_tag->len); - /*int ret = QD16_SEND_ADDR(addr_hi,addr_lo,dummy,128);*/ if (ret<0){ printf("error executing command!:%s\n",usb_strerror()); } @@ -200,7 +189,6 @@ int qd16_apply_ips_chunk(ips_tag_t* ips_tag) void qd16_finish(void) { -#if 0 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL, @@ -209,12 +197,12 @@ void qd16_finish(void) if (cnt<0) { printf("USB_BULK_UPLOAD_END failed: %s\n",usb_strerror()); } -#endif - cnt = usb_control_msg(handle, + + cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_ENDPOINT_OUT, USB_SET_LOADER, 0, 0, NULL, + USB_ENDPOINT_OUT, USB_SET_LOADER, 1, 1, NULL, 0, 5000); - + cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL, @@ -237,6 +225,14 @@ int qd16_init(void) return 1; } + cnt = usb_control_msg(handle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_ENDPOINT_OUT, USB_SET_LOADER, 0, 0, NULL, + 0, 5000); + + if (cnt<0) { + printf("USB_SET_LOADER failed: %s\n",usb_strerror()); + } cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | @@ -249,7 +245,6 @@ int qd16_init(void) usleep(500000); -#if 0 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_BULK_UPLOAD_INIT, @@ -260,7 +255,6 @@ int qd16_init(void) if (cnt<0) { printf("USB_BULK_UPLOAD_INIT failed: %s\n",usb_strerror()); } -#endif return 0; } From 0a9a87f3bd5512cce8d8769d9d733e860c4482e8 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Sun, 1 Nov 2009 11:54:35 +0100 Subject: [PATCH 5/7] changed bank count to 5 --- tools/qdips/Makefile | 2 +- tools/qdips/qdips.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/qdips/Makefile b/tools/qdips/Makefile index 49cca29..37e6fd2 100644 --- a/tools/qdips/Makefile +++ b/tools/qdips/Makefile @@ -1,7 +1,7 @@ USBFLAGS = `libusb-config --cflags` USBLIBS = `libusb-config --libs` -CC = llvm-gcc +CC = gcc CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -D_GNU_SOURCE --std=c99 LIBS = $(USBLIBS) diff --git a/tools/qdips/qdips.c b/tools/qdips/qdips.c index 7ba0aa2..a6b47a9 100644 --- a/tools/qdips/qdips.c +++ b/tools/qdips/qdips.c @@ -249,7 +249,8 @@ int qd16_init(void) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_BULK_UPLOAD_INIT, (hirom ? HIROM_BANK_SIZE_SHIFT : LOROM_BANK_SIZE_SHIFT) , - (hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT), + /*(hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT), */ + 5, NULL, 0, 5000); if (cnt<0) { From 72b0e1e6675dc55fb2720cb9449706332b57d0ca Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Thu, 5 Nov 2009 16:18:52 +0100 Subject: [PATCH 6/7] Added rle encoded ips chunk support --- tools/qdips/qdips.c | 62 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/tools/qdips/qdips.c b/tools/qdips/qdips.c index a6b47a9..4b5247b 100644 --- a/tools/qdips/qdips.c +++ b/tools/qdips/qdips.c @@ -22,6 +22,9 @@ #define PATCH_ERR 2 #define PATCH_CHUNKS_MAX 512 +#define RLE_LEN 0 +#define RLE_VAL 1 + #define QD16_MAX_TX_LEN 128 #define QD16_CMD_TIMEOUT 5000 @@ -44,8 +47,8 @@ typedef struct _ips_tag { - uint32_t ofs; /* offset in file to patch */ - uint16_t len; /* number of bytes in this chunk */ + uint32_t ofs; /* offset in file to patch (3 bytes (24bit address) in file!) */ + uint16_t len; /* number of bytes in this chunk (if len==0 : data[0] = counter / data[1] = fill byte*/ uint8_t* data; /* chunk data */ } ips_tag_t; @@ -142,8 +145,6 @@ int main(int argc, char * argv[]) while (!feof(patch_file) && chunk_index < PATCH_CHUNKS_MAX) { - printf("."); - int ret = ips_read_next_tag(patch_file,&ips_tags[chunk_index]); if (ret == PATCH_END) @@ -158,6 +159,10 @@ int main(int argc, char * argv[]) fclose(patch_file); + if (patch_error){ + printf("error at patch chunk #%d!\n",chunk_index); + } + for (int i=0; iofs)&0xffff; printf("hi:%x lo:%x len:%d\n",addr_hi,addr_lo,ips_tag->len); - int ret = QD16_SEND_ADDR(addr_hi,addr_lo,ips_tag->data,ips_tag->len); - if (ret<0){ - printf("error executing command!:%s\n",usb_strerror()); + + if (ips_tag->len > 0){ + + int ret = QD16_SEND_ADDR(addr_hi,addr_lo,ips_tag->data,ips_tag->len); + if (ret<0) + printf("error executing command: %s\n",usb_strerror()); + + } else { + + uint16_t len = (uint16_t)ips_tag->data[RLE_LEN]; + uint8_t val = ips_tag->data[RLE_VAL]; + printf("len:%d val:%x\n",len,val); + + // prepare patch buffer + uint8_t *buff = malloc(len); + memset(buff,val,len); + + // transfer + int ret = QD16_SEND_ADDR(addr_hi,addr_lo,buff,len); + if (ret<0) + printf("error executing command: %s\n",usb_strerror()); + } + return 0; } @@ -271,11 +296,26 @@ int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag) return PATCH_ERR; tag->len = getc(patch_file)<<8 | getc(patch_file); - tag->data = malloc(tag->len); - size_t ret = fread(tag->data,1,tag->len,patch_file); - if (ret != tag->len) - return PATCH_ERR; + // if the length field is > 0 then it is + // a standard replacement tag + // + if (tag->len>0) { + printf("normal tag\n"); + tag->data = malloc(tag->len); + + size_t ret = fread(tag->data,1,tag->len,patch_file); + if (ret != tag->len) + return PATCH_ERR; + + } else { + printf("rle tag\n"); + // if the length tag is 0 then it is + // a RLE tag: read 3 bytes from patch: 2bytes: count / 1 byte: value + tag->data = malloc(sizeof(3)); + tag->data[RLE_LEN] = (uint16_t)(getc(patch_file)<<8 | getc(patch_file)); + tag->data[RLE_VAL] = getc(patch_file); + } return 0; } From 7739b59bb88ed157578d6a9a0c677afb132ef884 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Fri, 13 Nov 2009 15:52:23 +0100 Subject: [PATCH 7/7] o Minor cleanup including command line argument fix --- tools/qdips/qdips.c | 78 ++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/tools/qdips/qdips.c b/tools/qdips/qdips.c index 4b5247b..256d700 100644 --- a/tools/qdips/qdips.c +++ b/tools/qdips/qdips.c @@ -20,7 +20,7 @@ #define EOF_TAG 0x454f46 #define PATCH_END 1 #define PATCH_ERR 2 -#define PATCH_CHUNKS_MAX 512 +#define PATCH_CHUNKS_MAX 2048 #define RLE_LEN 0 #define RLE_VAL 1 @@ -29,6 +29,7 @@ #define QD16_CMD_TIMEOUT 5000 + #define QD16_SEND_DATA(__addr_hi,__addr_lo,__src,__len)\ usb_control_msg(handle,\ USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,\ @@ -52,6 +53,7 @@ typedef struct _ips_tag { uint8_t* data; /* chunk data */ } ips_tag_t; +int qd16_transfer_data(int addr_hi, int addr_lo, uint8_t* data, int len); int qd16_apply_ips_chunk(ips_tag_t* ips_tag); int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag); int qd16_init(void); @@ -64,8 +66,6 @@ char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = { USB_CFG_DEVICE_NAME, 0 int cnt, vid, pid; int hirom = 0; -int header = 0; -int init = 0; int quiet = 0; uint8_t dummy[128]; @@ -74,7 +74,6 @@ void usage(void) { fprintf(stderr, "Usage: qdips [option] \n\n\ Options:\n\ - -s\tSkip ROM header\n\ -q\tBe quiet\n\ -h\tForce HiROM mode\n\n"); @@ -94,14 +93,8 @@ int main(int argc, char * argv[]) if (argc==1) usage(); - while ((opt = getopt(argc,argv,"qish")) != -1){ + while ((opt = getopt(argc,argv,"qh")) != -1){ switch (opt) { - case 'i': - init = 1; - break; - case 's': - header = 1; - break; case 'h': hirom = 1; break; @@ -163,39 +156,80 @@ int main(int argc, char * argv[]) printf("error at patch chunk #%d!\n",chunk_index); } - for (int i=0; i0) { + + txlen = (bytes_left>QD16_MAX_TX_LEN?QD16_MAX_TX_LEN:bytes_left); + ret = QD16_SEND_ADDR( ((addr>>16)&0xff), (addr&0xffff), data+pos, txlen); + if (ret<0) + break; + + addr += txlen; + pos += txlen; + bytes_left -= txlen; + } + + if (bytes_left){ + printf("%s\n",usb_strerror()); + return 1; + } + + return 0; + + + +} + int qd16_apply_ips_chunk(ips_tag_t* ips_tag) { int addr_hi = (ips_tag->ofs)>>16; int addr_lo = (ips_tag->ofs)&0xffff; - printf("hi:%x lo:%x len:%d\n",addr_hi,addr_lo,ips_tag->len); if (ips_tag->len > 0){ - int ret = QD16_SEND_ADDR(addr_hi,addr_lo,ips_tag->data,ips_tag->len); - if (ret<0) - printf("error executing command: %s\n",usb_strerror()); + int ret = qd16_transfer_data(addr_hi,addr_lo,ips_tag->data,ips_tag->len); + if (ret!=0) + printf("error transfering data to qd16\n"); } else { uint16_t len = (uint16_t)ips_tag->data[RLE_LEN]; uint8_t val = ips_tag->data[RLE_VAL]; - printf("len:%d val:%x\n",len,val); // prepare patch buffer uint8_t *buff = malloc(len); @@ -274,8 +308,8 @@ int qd16_init(void) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_BULK_UPLOAD_INIT, (hirom ? HIROM_BANK_SIZE_SHIFT : LOROM_BANK_SIZE_SHIFT) , - /*(hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT), */ - 5, + /*(hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT), */ // ??? + 5, NULL, 0, 5000); if (cnt<0) { @@ -301,7 +335,6 @@ int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag) // a standard replacement tag // if (tag->len>0) { - printf("normal tag\n"); tag->data = malloc(tag->len); size_t ret = fread(tag->data,1,tag->len,patch_file); @@ -309,7 +342,6 @@ int ips_read_next_tag(FILE* patch_file, ips_tag_t* tag) return PATCH_ERR; } else { - printf("rle tag\n"); // if the length tag is 0 then it is // a RLE tag: read 3 bytes from patch: 2bytes: count / 1 byte: value tag->data = malloc(sizeof(3));