1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Dave Chapman
12 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
14 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
15 * licensed under the GPL (v2)
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
32 #include <sys/types.h>
39 #define MAX_FIRMWARESIZE (10*1024*1024) /* Arbitrary limit (for safety) */
41 /* For win32 compatibility: */
55 static struct device_t devices
[] =
57 {"c100", "Sansa C100 series", 0xb021, 0x20000000, 0x42e97010 },
58 {"m200", "Sansa M200 series", 0xb021, 0x20000000, 0x42e97010 },
59 {"cowond2", "Cowon D2", 0xb011, 0x20000000, 0xa2e92010 },
60 {"iaudio6", "iAudio 6", 0xb021, 0x20000000, 0x62e97010 },
61 {"iaudio7", "iAudio 7", 0xb021, 0x20000000, 0x62e97010 },
62 {"logikdax", "Logik DAX 1GB DAB/MP3 player", 0xb021, 0x20000000, 0x52e97410 },
63 {"x20", "iRiver X20", 0xb051, 0x20000000, 0x02e92010 },
64 {"ypp2", "Samsung YP-P2", 0xb011, 0x20000000, 0x22e92010 },
65 {"ypk3", "Samsung YP-K3", 0xb021, 0x20000000, 0x62e92018 },
68 #define NUM_DEVICES ((sizeof(devices) / sizeof(struct device_t)))
70 int find_device(char* devname
)
74 while ((i
< NUM_DEVICES
) && (strcmp(devices
[i
].name
,devname
)))
83 void print_devices(void)
87 printf("Valid devices are:\n");
88 for (i
=0; i
<NUM_DEVICES
; i
++)
90 printf(" %10s - %s\n",devices
[i
].name
,devices
[i
].label
);
94 /* USB IDs for USB Boot Mode */
95 #define TCC_VENDORID 0x140e
99 #define PACKET_SIZE 64 /* Number of bytes to send in one write */
102 #define MAX(a,b) (((a)>(b))?(a):(b))
105 static void put_int32le(uint32_t x
, char* p
)
108 p
[1] = (x
>> 8) & 0xff;
109 p
[2] = (x
>> 16) & 0xff;
110 p
[3] = (x
>> 24) & 0xff;
113 int upload_app(usb_dev_handle
* dh
, int device
, char* p
, int len
)
115 char buf
[PACKET_SIZE
];
119 /* Send the header - Destination address, length and SDCFG value */
120 memset(buf
, 0, PACKET_SIZE
);
122 put_int32le(0xf0000000, buf
); /* Unknown - always the same */
123 put_int32le(len
/ PACKET_SIZE
, buf
+ 4);
124 put_int32le(devices
[device
].loadaddr
, buf
+ 8);
125 put_int32le(devices
[device
].sdcfg
, buf
+ 12);
127 err
= usb_bulk_write(dh
, TCC_BULK_TO
, buf
, PACKET_SIZE
, TOUT
);
131 fprintf(stderr
,"[ERR] Error writing header\n");
132 fprintf(stderr
,"[ERR] Bulk write error (%d, %s)\n", err
, strerror(-err
));
136 /* Now send the data, PACKET_SIZE bytes at a time. */
138 for (i
=0 ; i
< (len
/ PACKET_SIZE
) ; i
++)
140 err
= usb_bulk_write(dh
, TCC_BULK_TO
, p
, PACKET_SIZE
, TOUT
);
144 fprintf(stderr
,"[ERR] Error writing data\n");
145 fprintf(stderr
,"[ERR] Bulk write error (%d, %s)\n", err
, strerror(-err
));
156 /* The main function */
158 int do_patching(int device
, char* buf
, int len
)
160 struct usb_bus
*busses
;
162 struct usb_device
*tmp_dev
;
163 struct usb_device
*dev
= NULL
;
167 fprintf(stderr
,"[INFO] Searching for TCC device...\n");
170 if(usb_find_busses() < 0) {
171 fprintf(stderr
, "[ERR] Could not find any USB busses.\n");
175 if (usb_find_devices() < 0) {
176 fprintf(stderr
, "[ERR] USB devices not found(nor hubs!).\n");
180 /* C calling convention, it's not nice to use global stuff */
181 busses
= usb_get_busses();
183 for (bus
= busses
; bus
; bus
= bus
->next
) {
184 for (tmp_dev
= bus
->devices
; tmp_dev
; tmp_dev
= tmp_dev
->next
) {
185 //printf("Found Vendor %04x Product %04x\n",tmp_dev->descriptor.idVendor, tmp_dev->descriptor.idProduct);
186 if (tmp_dev
->descriptor
.idVendor
== TCC_VENDORID
&&
187 tmp_dev
->descriptor
.idProduct
== devices
[device
].productid
) {
197 fprintf(stderr
, "[ERR] TCC device not found.\n");
198 fprintf(stderr
, "[ERR] Ensure your TCC device is in USB boot mode and run tcctool again.\n");
203 if ( (dh
= usb_open(dev
)) == NULL
) {
204 fprintf(stderr
,"[ERR] Unable to open TCC device.\n");
208 err
= usb_set_configuration(dh
, 1);
211 fprintf(stderr
, "[ERR] usb_set_configuration failed (%d)\n", err
);
216 /* "must be called" written in the libusb documentation */
217 err
= usb_claim_interface(dh
, dev
->config
->interface
->altsetting
->bInterfaceNumber
);
219 fprintf(stderr
, "[ERR] Unable to claim interface (%d)\n", err
);
224 fprintf(stderr
,"[INFO] Found TCC device, uploading application.\n");
226 /* Now we can transfer the application to the device. */
228 if ( (err
= upload_app(dh
, device
, buf
, len
)) < 0)
230 fprintf(stderr
,"[ERR] Upload of application failed.\n");
234 fprintf(stderr
,"[INFO] Patching application uploaded successfully!\n");
237 /* release claimed interface */
238 usb_release_interface(dh
, dev
->config
->interface
->altsetting
->bInterfaceNumber
);
241 return err
< 0 ? -1: 0;
244 off_t
filesize(int fd
) {
247 if (fstat(fd
,&buf
) < 0) {
248 perror("[ERR] Checking filesize of input file");
255 void print_usage(void)
257 printf("Usage: tcctool -d devicename firmware.bin\n");
260 int main(int argc
, char* argv
[])
263 int n
,len
,padded_len
;
267 printf("tcctool v" VERSION
" - (C) 2007 Dave Chapman\n");
268 printf("This is free software; see the source for copying conditions. There is NO\n");
269 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
278 if (strcmp(argv
[1],"-d"))
285 device
= find_device(argv
[2]);
289 printf("[ERR] Unknown device \"%s\"\n",argv
[2]);
294 printf("[INFO] Using device \"%s\"\n",devices
[device
].label
);
295 fd
= open(argv
[3], O_RDONLY
|O_BINARY
);
298 printf("[ERR] Could not open %s\n", argv
[3]);
304 if (len
> MAX_FIRMWARESIZE
)
306 printf("[ERR] Firmware file too big\n");
311 /* Round len up to multiple of PACKET_SIZE */
312 padded_len
= (len
+ PACKET_SIZE
) & ~(PACKET_SIZE
-1);
314 buf
= malloc(padded_len
);
317 printf("[ERR] Could not allocate memory.\n");
322 n
= read(fd
, buf
, len
);
325 printf("[ERR] Short read.\n");
331 if (do_patching(device
, buf
, padded_len
))