Fix a mistake + be more verbose
[Rockbox.git] / utils / jz4740_usbtool / jz4740_usbtool.c
blob84ffbf70980d34b2c13c6078af8714e7a0173410
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * based on tcctool.c by Dave Chapman
14 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
16 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
17 * licensed under the GPL (v2)
20 * All files in this archive are subject to the GNU General Public License.
21 * See the file COPYING in the source tree root for full license agreement.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
28 #include <stdio.h>
29 #include <inttypes.h>
30 #include <usb.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include "jz4740.h"
38 #define VERSION "0.2"
40 #define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */
42 /* For win32 compatibility: */
43 #ifndef O_BINARY
44 #define O_BINARY 0
45 #endif
47 /* USB IDs for USB Boot Mode */
48 #define VID 0x601A
49 #define PID 0x4740
51 #define EP_BULK_TO 0x01
52 #define TOUT 5000
54 #ifndef MAX
55 #define MAX(a,b) (((a)>(b))?(a):(b))
56 #endif
58 enum USB_JZ4740_REQUEST
60 VR_GET_CPU_INFO = 0,
61 VR_SET_DATA_ADDRESS,
62 VR_SET_DATA_LENGTH,
63 VR_FLUSH_CACHES,
64 VR_PROGRAM_START1,
65 VR_PROGRAM_START2,
66 VR_NOR_OPS,
67 VR_NAND_OPS,
68 VR_SDRAM_OPS,
69 VR_CONFIGURATION
72 enum NOR_OPS_TYPE
74 NOR_INIT = 0,
75 NOR_QUERY,
76 NOR_WRITE,
77 NOR_ERASE_CHIP,
78 NOR_ERASE_SECTOR
81 enum NOR_FLASH_TYPE
83 NOR_AM29 = 0,
84 NOR_SST28,
85 NOR_SST39x16,
86 NOR_SST39x8
89 enum NAND_OPS_TYPE
91 NAND_QUERY = 0,
92 NAND_INIT,
93 NAND_MARK_BAD,
94 NAND_READ_OOB,
95 NAND_READ_RAW,
96 NAND_ERASE,
97 NAND_READ,
98 NAND_PROGRAM,
99 NAND_READ_TO_RAM
102 enum SDRAM_OPS_TYPE
104 SDRAM_LOAD,
108 enum DATA_STRUCTURE_OB
110 DS_flash_info ,
111 DS_hand
114 enum OPTION
116 OOB_ECC,
117 OOB_NO_ECC,
118 NO_OOB,
121 #define SEND_COMMAND(cmd, arg) err = usb_control_msg(dh, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, cmd, arg>>16, arg&0xFFFF, NULL, 0, TOUT);\
122 if (err < 0) \
124 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
125 return -1; \
128 #define GET_CPU_INFO(s) err = usb_control_msg(dh, USB_ENDPOINT_IN | USB_TYPE_VENDOR, VR_GET_CPU_INFO, 0, 0, buf, 8, TOUT); \
129 if (err < 0) \
131 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
132 return -1; \
135 #define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \
136 if (err != len) \
138 fprintf(stderr,"\n[ERR] Error writing data\n"); \
139 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
140 return -1; \
143 #define GET_DATA(ptr, size) err = usb_bulk_read(dh, USB_ENDPOINT_IN | EP_BULK_TO, ptr, size, TOUT); \
144 if (err != size) \
146 fprintf(stderr,"\n[ERR] Error writing data\n"); \
147 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
148 return -1; \
151 int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len)
153 int err;
154 char buf[8];
155 unsigned char* tmp_buf;
157 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
158 GET_CPU_INFO(buf);
159 buf[8] = 0;
160 fprintf(stderr, "%s\n", buf);
162 fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address);
163 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
164 fprintf(stderr, " Done!\n");
166 fprintf(stderr, "[INFO] Sending data...");
167 /* Must not split the file in several packages! */
168 SEND_DATA(p, len);
169 fprintf(stderr, " Done!\n");
171 fprintf(stderr, "[INFO] Verifying data...");
172 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
173 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
174 tmp_buf = malloc(len);
175 if (tmp_buf == NULL)
177 fprintf(stderr, "\n[ERR] Could not allocate memory.\n");
178 return -1;
180 GET_DATA(tmp_buf, len);
181 if (memcmp(tmp_buf, p, len) != 0)
183 fprintf(stderr, "\n[ERR] Sent data isn't the same as received data...\n");
184 free(tmp_buf);
185 return -1;
187 free(tmp_buf);
188 fprintf(stderr, " Done !\n");
190 fprintf(stderr, "[INFO] Booting device...");
191 SEND_COMMAND(VR_PROGRAM_START1, address);
192 fprintf(stderr, " Done!\n");
194 return 0;
197 int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len)
199 int err;
200 char buf[8];
202 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
203 GET_CPU_INFO(buf);
204 buf[8] = 0;
205 fprintf(stderr, "%s\n", buf);
207 fprintf(stderr, "[INFO] Reading data...");
208 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
209 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
210 GET_DATA(p, len);
211 fprintf(stderr, " Done!\n");
212 return 0;
215 unsigned int read_reg(usb_dev_handle* dh, int address)
217 int err;
218 unsigned char buf[4];
220 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
221 SEND_COMMAND(VR_SET_DATA_LENGTH, 4);
222 GET_DATA(buf, 4);
224 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
227 #define TEST(m) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m));
228 int test_device(usb_dev_handle* dh)
230 TEST(INTC_ISR);
231 TEST(INTC_IMR);
232 TEST(INTC_IMSR);
233 TEST(INTC_IMCR);
234 TEST(INTC_IPR);
236 fprintf(stderr, "\n");
237 TEST(RTC_RCR);
238 TEST(RTC_RSR);
239 TEST(RTC_RSAR);
240 TEST(RTC_RGR);
241 TEST(RTC_HCR);
242 TEST(RTC_RCR);
243 TEST(RTC_HWFCR);
244 TEST(RTC_HRCR);
245 TEST(RTC_HWCR);
246 TEST(RTC_HWSR);
248 fprintf(stderr, "\n");
249 TEST(GPIO_PXPIN(0));
250 TEST(GPIO_PXPIN(1));
251 TEST(GPIO_PXPIN(2));
252 TEST(GPIO_PXPIN(3));
253 return 0;
256 void jzconnect(int address, unsigned char* buf, int len, int func)
258 struct usb_bus *bus;
259 struct usb_device *tmp_dev;
260 struct usb_device *dev = NULL;
261 usb_dev_handle *dh;
262 int err;
264 fprintf(stderr,"[INFO] Searching for device...\n");
266 usb_init();
267 if(usb_find_busses() < 0)
269 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
270 return;
273 if (usb_find_devices() < 0)
275 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
276 return;
279 for (bus = usb_get_busses(); bus; bus = bus->next)
281 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next)
283 //printf("Found Vendor %04x Product %04x\n",tmp_dev->descriptor.idVendor, tmp_dev->descriptor.idProduct);
284 if (tmp_dev->descriptor.idVendor == VID &&
285 tmp_dev->descriptor.idProduct == PID)
287 dev = tmp_dev;
288 goto found;
294 if (dev == NULL)
296 fprintf(stderr, "[ERR] Device not found.\n");
297 fprintf(stderr, "[ERR] Ensure your device is in USB boot mode and run usbtool again.\n");
298 return;
301 found:
302 if ( (dh = usb_open(dev)) == NULL)
304 fprintf(stderr,"[ERR] Unable to open device.\n");
305 return;
308 err = usb_set_configuration(dh, 1);
310 if (err < 0)
312 fprintf(stderr, "[ERR] usb_set_configuration failed (%d, %s)\n", err, usb_strerror());
313 usb_close(dh);
314 return;
317 /* "must be called" written in the libusb documentation */
318 err = usb_claim_interface(dh, 0);
319 if (err < 0)
321 fprintf(stderr, "[ERR] Unable to claim interface (%d, %s)\n", err, usb_strerror());
322 usb_close(dh);
323 return;
326 fprintf(stderr,"[INFO] Found device, uploading application.\n");
328 /* Now we can transfer the application to the device. */
330 switch(func)
332 case 1:
333 err = upload_app(dh, address, buf, len);
334 break;
335 case 2:
336 err = read_data(dh, address, buf, len);
337 break;
338 case 3:
339 err = test_device(dh);
340 break;
343 /* release claimed interface */
344 usb_release_interface(dh, 0);
346 usb_close(dh);
349 int filesize(FILE* fd)
351 int tmp;
352 fseek(fd, 0, SEEK_END);
353 tmp = ftell(fd);
354 fseek(fd, 0, SEEK_SET);
355 return tmp;
358 void print_usage(void)
360 #ifdef _WIN32
361 fprintf(stderr, "Usage: usbtool.exe [CMD] [FILE] [ADDRESS] [LEN]\n");
362 #else
363 fprintf(stderr, "Usage: usbtool [CMD] [FILE] [ADDRESS] [LEN]\n");
364 #endif
365 fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n");
366 fprintf(stderr, "\t[CMD]:\n\t\t1 -> upload file to specified address and boot from it\n\t\t2 -> read data from [ADDRESS] with length [LEN] to [FILE]\n");
367 fprintf(stderr, "\t\t3 -> read device status\n");
368 #ifdef _WIN32
369 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000");
370 fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024");
371 #else
372 fprintf(stderr, "\nExample:\n\t usbtool 1 fw.bin 0x80000000");
373 fprintf(stderr, "\n\t usbtool 2 save.bin 0x81000000 1024");
374 #endif
377 int main(int argc, char* argv[])
379 unsigned char* buf;
380 int n, len, address, cmd=0;
381 FILE* fd;
383 fprintf(stderr, "USBtool v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
384 fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
385 fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
387 if(argc > 1)
388 sscanf(argv[1], "%d", &cmd);
389 switch(cmd)
391 case 1:
392 if (sscanf(argv[3], "0x%x", &address) <= 0)
394 print_usage();
395 return -1;
398 fd = fopen(argv[2], "rb");
399 if (fd < 0)
401 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
402 return 4;
405 len = filesize(fd);
407 if (len > MAX_FIRMWARESIZE)
409 fprintf(stderr, "[ERR] Firmware file too big\n");
410 fclose(fd);
411 return 5;
414 buf = malloc(len);
415 if (buf == NULL)
417 fprintf(stderr, "[ERR] Could not allocate memory.\n");
418 fclose(fd);
419 return 6;
422 n = fread(buf, 1, len, fd);
423 if (n != len)
425 fprintf(stderr, "[ERR] Short read.\n");
426 fclose(fd);
427 return 7;
429 fclose(fd);
431 fprintf(stderr, "[INFO] File size: %d bytes\n", n);
433 jzconnect(address, buf, len, 1);
434 break;
435 case 2:
436 if (sscanf(argv[3], "0x%x", &address) <= 0)
438 print_usage();
439 return -1;
442 fd = fopen(argv[2], "wb");
443 if (fd < 0)
445 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
446 return 4;
449 sscanf(argv[4], "%d", &len);
451 buf = malloc(len);
452 if (buf == NULL)
454 fprintf(stderr, "[ERR] Could not allocate memory.\n");
455 fclose(fd);
456 return 6;
459 jzconnect(address, buf, len, 2);
461 n = fwrite(buf, 1, len, fd);
462 if (n != len)
464 fprintf(stderr, "[ERR] Short write.\n");
465 fclose(fd);
466 return 7;
468 fclose(fd);
469 break;
470 case 3:
471 jzconnect(address, NULL, 0, 3);
472 break;
473 default:
474 print_usage();
475 return 1;
476 break;
479 return 0;