Make Jz4740 USB tools a bit more configurable by letting you choose what file you want to upload when doing usbtool 10


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20415 a1c6a512-1295-4272-9138-f99709370657
diff --git a/utils/jz4740_tools/Makefile b/utils/jz4740_tools/Makefile
index 3b1061b..f40adaa 100644
--- a/utils/jz4740_tools/Makefile
+++ b/utils/jz4740_tools/Makefile
@@ -3,42 +3,52 @@
 WIN_LIBUSB_LIB_DIR = "$(WIN_DRIVERS_LIBUSB_DIR)\lib\gcc"
 
 CFLAGS=-Wall
+CC=gcc
 
 linux: usbtool HXFmerge HXFreplace HXFsplit IHFSsplit HXF2IHFS DLanalyser
 win: usbtool_win HXFmerge_win HXFsplit_win HXFreplace_win IHFSsplit_win HXF2IHFS_win DLanalyser_win
 
-usbtool:
-	$(CC) $(CFLAGS) -o usbtool jz4740_usbtool.c -lusb
-usbtool_win:
-	$(CC) $(CFLAGS) -o usbtool.exe jz4740_usbtool.c -lusb -I $(WIN_LIBUSB_INCLUDE_DIR) -L $(WIN_LIBUSB_LIB_DIR)
+bin2c: ../../rbutil/sansapatcher/bin2c.c
+	$(CC) $(CFLAGS) -o bin2c ../../rbutil/sansapatcher/bin2c.c
 
-HXFmerge:
+bin2c.exe: ../../rbutil/sansapatcher/bin2c.c
+	$(CC) $(CFLAGS) -o bin2c.exe ../../rbutil/sansapatcher/bin2c.c
+
+jz_xloader.c: jz_xloader.bin
+	./bin2c jz_xloader.bin jz_xloader
+
+usbtool: jz4740_usbtool.c bin2c jz_xloader.c
+	$(CC) $(CFLAGS) -o usbtool jz4740_usbtool.c jz_xloader.c -lusb
+usbtool_win: jz4740_usbtool.c bin2c.exe jz_xloader.c
+	$(CC) $(CFLAGS) -o usbtool.exe jz4740_usbtool.c jz_xloader.c -lusb -I $(WIN_LIBUSB_INCLUDE_DIR) -L $(WIN_LIBUSB_LIB_DIR)
+
+HXFmerge: HXFmerge.c
 	$(CC) $(CFLAGS) -o HXFmerge HXFmerge.c
-HXFreplace:
+HXFreplace: HXFreplace.c
 	$(CC) $(CFLAGS) -o HXFreplace HXFreplace.c
-HXFsplit:
+HXFsplit: HXFsplit.c
 	$(CC) $(CFLAGS) -o HXFsplit HXFsplit.c
-IHFSsplit:
+IHFSsplit: IHFSsplit.c
 	$(CC) $(CFLAGS) -o IHFSsplit IHFSsplit.c
-HXF2IHFS:
+HXF2IHFS: HXF2IHFS.c
 	$(CC) $(CFLAGS) -o HXF2IHFS HXF2IHFS.c
-DLanalyser:
+DLanalyser: DLanalyser.c
 	$(CC) $(CFLAGS) -o DLanalyser DLanalyser.c
 
-HXFmerge_win:
+HXFmerge_win: HXFmerge.c
 	$(CC) $(CFLAGS) -o HXFmerge.exe HXFmerge.c
-HXFreplace_win:
+HXFreplace_win: HXFreplace.c
 	$(CC) $(CFLAGS) -o HXFreplace.exe HXFreplace.c
-HXFsplit_win:
+HXFsplit_win: HXFsplit.c
 	$(CC) $(CFLAGS) -o HXFsplit.exe HXFsplit.c
-IHFSsplit_win:
+IHFSsplit_win: IHFSsplit.c
 	$(CC) $(CFLAGS) -o IHFSsplit.exe IHFSsplit.c
-HXF2IHFS_win:
+HXF2IHFS_win: HXF2IHFS.c
 	$(CC) $(CFLAGS) -o HXF2IHFS.exe HXF2IHFS.c
- DLanalyser_win:
+DLanalyser_win: DLanalyser.c
 	$(CC) $(CFLAGS) -o DLanalyser.exe DLanalyser.c
 
 clean-linux:
-	rm HXFmerge HXFreplace HXFsplit usbtool IHFSsplit HXF2IHFS DLanalyser
+	rm HXFmerge HXFreplace HXFsplit usbtool IHFSsplit HXF2IHFS DLanalyser bin2c
 clean-win:
-	del HXFmerge.exe HXFreplace.exe HXFsplit.exe usbtool.exe IHFSsplit.exe HXF2IHFS.exe DLanalyser.exe
+	del HXFmerge.exe HXFreplace.exe HXFsplit.exe usbtool.exe IHFSsplit.exe HXF2IHFS.exe DLanalyser.exe bin2c.exe
diff --git a/utils/jz4740_tools/README b/utils/jz4740_tools/README
index d6a64d8..75c0dc1 100644
--- a/utils/jz4740_tools/README
+++ b/utils/jz4740_tools/README
@@ -5,6 +5,9 @@
   Copyright (C) 2008
 *******************************************************************************
 
+To compile usbtools, you'll need jz_xloader (which can be get at
+http://repo.or.cz/w/jz_xloader.git).
+
 When you're on Linux, just type "make linux" to compile all the utilities (make
 sure you have libusb-dev installed).
 For cleaning: "make clean-linux"
diff --git a/utils/jz4740_tools/jz4740_usbtool.c b/utils/jz4740_tools/jz4740_usbtool.c
index 1fdb8f4..904d647 100644
--- a/utils/jz4740_tools/jz4740_usbtool.c
+++ b/utils/jz4740_tools/jz4740_usbtool.c
@@ -35,9 +35,10 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include "jz4740.h"
 #include <stdbool.h>
 #include <unistd.h>
+#include "jz4740.h"
+#include "jz_xloader.h"
 
 #define VERSION "0.4"
 
@@ -120,12 +121,28 @@
 int filesize(FILE* fd)
 {
     int ret;
+    
     fseek(fd, 0, SEEK_END);
     ret = ftell(fd);
     fseek(fd, 0, SEEK_SET);
+    
     return ret;
 }
 
+bool file_exists(const char* filename)
+{
+    FILE* fp = fopen(filename, "r");
+    
+    if(fp)
+    {
+        fclose(fp);
+        return true;
+    }
+    else
+        return false;
+}
+
+
 #define SEND_COMMAND(cmd, arg) err = usb_control_msg(dh, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, (cmd), (arg)>>16, (arg)&0xFFFF, NULL, 0, TOUT);\
                                if (err < 0) \
                                { \
@@ -155,8 +172,7 @@
                                    fprintf(stderr,"[ERR]  Bulk write error (%d, %s)\n", err, strerror(-err)); \
                                    return -1; \
                                }
-
-int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len, bool stage2)
+int upload_data(usb_dev_handle* dh, int address, unsigned char* p, int len)
 {
     int err;
     char buf[9];
@@ -166,11 +182,6 @@
     GET_CPU_INFO(buf);
     buf[8] = 0;
     fprintf(stderr, "%s\n", buf);
-#if 0
-    fprintf(stderr, "[INFO] Flushing cache...");
-    SEND_COMMAND(VR_FLUSH_CACHES, 0);
-    fprintf(stderr, " Done!\n");
-#endif
 
     fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address);
     SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
@@ -196,12 +207,32 @@
     else
         fprintf(stderr, " Done!\n");
     free(tmp_buf);
+    
+    return 0;
+}
 
-    fprintf(stderr, "[INFO] Booting device [STAGE%d]...", (stage2 ? 2 : 1));
+int boot(usb_dev_handle* dh, int address, bool stage2)
+{
+    int err;
+    
+    fprintf(stderr, "[INFO] Booting device STAGE%d...", (stage2 ? 2 : 1));
     SEND_COMMAND((stage2 ? VR_PROGRAM_START2 : VR_PROGRAM_START1), address );
     fprintf(stderr, " Done!\n");
     
-    return 0;
+    return err;
+}
+
+int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len, bool stage2)
+{
+    int err = upload_data(dh, address, p, len);
+    if(err == 0)
+    {
+        err = boot(dh, address, stage2);
+        if(err == 0)
+            fprintf(stderr, "[INFO] Done!\n");
+    }
+    
+    return err;
 }
 
 int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len)
@@ -313,46 +344,6 @@
     return 0;
 }
 
-#define VOL_DOWN (1 << 27)
-#define VOL_UP (1 << 0)
-#define MENU (1 << 1)
-#define HOLD (1 << 16)
-#define OFF (1 << 29)
-#define MASK (VOL_DOWN|VOL_UP|MENU|HOLD|OFF)
-#define TS_MASK (SADC_STATE_PEND|SADC_STATE_PENU|SADC_STATE_TSRDY)
-int probe_device(usb_dev_handle* dh)
-{
-    int tmp;
-    
-    while(1)
-    {
-        if(read_reg(dh, SADC_STATE, 1) & SADC_STATE_TSRDY)
-        {
-            printf("%x\n", read_reg(dh, SADC_TSDAT, 4));
-            or_reg(dh, SADC_CTRL, read_reg(dh, SADC_STATE, 1) & TS_MASK, 1);
-        }
-        
-        tmp = read_reg(dh, GPIO_PXPIN(3), 4);
-        if(tmp < 0)
-            return tmp;
-        if(tmp ^ MASK)
-        {
-            if(!(tmp & VOL_DOWN))
-                printf("VOL_DOWN\t");
-            if(!(tmp & VOL_UP))
-                printf("VOL_UP\t");
-            if(!(tmp & MENU))
-                printf("MENU\t");
-            if(!(tmp & OFF))
-                printf("OFF\t");
-            if(!(tmp & HOLD))
-                printf("HOLD\t");
-            printf("\n");
-        }
-    }    
-    return 0;
-}
-
 unsigned int read_file(const char *name, unsigned char **buffer)
 {
     FILE *fd;
@@ -508,30 +499,33 @@
     return 0;
 }
 
-int send_rockbox(usb_dev_handle *dh)
+int send_rockbox(usb_dev_handle *dh, const char* filename)
 {
-    int err, fsize;
-    unsigned char *buffer, *buffer2;
-    char cpu[8];
+    int fsize;
+    unsigned char *buffer;
     
     fprintf(stderr, "[INFO] Start!\n");
-    _GET_CPU;
-    _SET_ADDR(0x8000 << 16);
-    _SEND_FILE("1.bin");
-    _GET_CPU;
-    _VERIFY_DATA("1.bin", 0x8000 << 16);
-    _STAGE1(0x8000 << 16);
-    _SLEEP(3);
-    _GET_CPU;
-    _SET_ADDR(0x080004000);
-    _SEND_FILE("onda.bin");
-    _GET_CPU;
-    _VERIFY_DATA("onda.bin", 0x080004000);
-    _GET_CPU;
-    _FLUSH;
-    _GET_CPU;
-    _STAGE2(0x080004008);
+    if(file_exists("jz_xloader.bin"))
+    {
+        fprintf(stderr, "[INFO] Using jz_xloader.bin\n");
+        fsize = read_file("jz_xloader.bin", &buffer);
+        upload_data(dh, 0x080000000, buffer, fsize);
+        free(buffer);
+    }
+    else
+    {
+        fprintf(stderr, "[INFO] Using built-in jz_xloader.bin\n");
+        upload_data(dh, 0x080000000, jz_xloader, LEN_jz_xloader);
+    }
+    boot(dh, 0x080000000, false);
+    
+    fsize = read_file(filename, &buffer);
+    upload_data(dh, 0x080004000, buffer, fsize);
+    free(buffer);
+    boot(dh, 0x080004000, true);
+    
     fprintf(stderr, "[INFO] Done!\n");
+    
     return 0;
 }
 
@@ -558,7 +552,6 @@
         fclose(fd);
         return 0;
     }
-    memset(buffer, 0, LENGTH);
     
     SEND_NAND_COMMAND(0, NAND_INIT, 0);
     /*
@@ -595,9 +588,8 @@
     
     return n;
 }
-#undef LENGTH
 
-#define LENGTH 0x1000*16
+#define ROM_LENGTH 0x1000*16
 int rom_dump(usb_dev_handle *dh)
 {
     int err;
@@ -612,21 +604,20 @@
         return 0;
     }
     
-    buffer = (unsigned char*)malloc(LENGTH);
+    buffer = (unsigned char*)malloc(ROM_LENGTH);
     if (buffer == NULL)
     {
         fprintf(stderr, "[ERR]  Could not allocate memory.\n");
         fclose(fd);
         return 0;
     }
-    memset(buffer, 0, LENGTH);
     
     SEND_COMMAND(VR_SET_DATA_ADDRESS, 0x1FC00000);
-    SEND_COMMAND(VR_SET_DATA_LENGTH, LENGTH);
+    SEND_COMMAND(VR_SET_DATA_LENGTH, ROM_LENGTH);
     
     fprintf(stderr, "[INFO] Reading data...\n");
-    err = usb_bulk_read(dh, USB_ENDPOINT_IN | EP_BULK_TO, (char*)buffer, LENGTH, TOUT);
-    if (err != LENGTH) 
+    err = usb_bulk_read(dh, USB_ENDPOINT_IN | EP_BULK_TO, (char*)buffer, ROM_LENGTH, TOUT);
+    if (err != ROM_LENGTH) 
     {
         fprintf(stderr,"\n[ERR]  Error writing data\n");
         fprintf(stderr,"[ERR]  Bulk write error (%d, %s)\n", err, strerror(-err));
@@ -635,8 +626,8 @@
         return -1;
     }
     
-    n = fwrite(buffer, 1, LENGTH, fd);
-    if (n != LENGTH)
+    n = fwrite(buffer, 1, ROM_LENGTH, fd);
+    if (n != ROM_LENGTH)
     {
         fprintf(stderr, "[ERR]  Short write.\n");
         fclose(fd);
@@ -736,9 +727,6 @@
         case 3:
             err = test_device(dh);
         break;
-        case 4:
-            err = probe_device(dh);
-        break;
         case 6:
         case 7:
             err = mimic_of(dh, (func == 7));
@@ -750,7 +738,7 @@
             err = rom_dump(dh);
         break;
         case 10:
-            err = send_rockbox(dh);
+            err = send_rockbox(dh, buf);
         break;
     }
     
@@ -775,13 +763,12 @@
     fprintf(stderr, "\t\t 1 -> upload file to specified address and boot from it\n");
     fprintf(stderr, "\t\t 2 -> read data from [ADDRESS] with length [LEN] to [FILE]\n");
     fprintf(stderr, "\t\t 3 -> read device status\n");
-    fprintf(stderr, "\t\t 4 -> probe keys (only Onda VX747)\n");
     fprintf(stderr, "\t\t 5 -> same as 1 but do a stage 2 boot\n");
     fprintf(stderr, "\t\t 6 -> mimic VX747 OF fw recovery\n");
     fprintf(stderr, "\t\t 7 -> mimic VX767 OF fw recovery\n");
     fprintf(stderr, "\t\t 8 -> do a NAND dump\n");
     fprintf(stderr, "\t\t 9 -> do a ROM dump\n");
-    fprintf(stderr, "\t\t10 -> send Rockbox bootloader to SDRAM\n");
+    fprintf(stderr, "\t\t10 -> send Rockbox bootloader at [FILE] to SDRAM\n");
 
 #ifdef _WIN32
     fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000\n");
@@ -855,7 +842,6 @@
             fprintf(stderr, "[INFO] File size: %d bytes\n", n);
             
             return jzconnect(address, buf, len, cmd);
-        break;
         case 2:
             if (sscanf(argv[3], "0x%x", &address) <= 0)
             {
@@ -892,20 +878,28 @@
             fclose(fd);
             
             return err;
-        break;
+        case 10:
+            if(argc < 3)
+            {
+                print_usage();
+                return 1;
+            }
+            
+            if(!file_exists(argv[2]))
+            {
+                print_usage();
+                return 1;
+            }
+            return jzconnect(address, argv[2], 0, 10);
         case 3:
-        case 4:
         case 6:
         case 7:
         case 8:
         case 9:
-        case 10:
             return jzconnect(address, NULL, 0, cmd);
-        break;
         default:
             print_usage();
             return 1;
-        break;
     }
 
     return 0;