1 /* usb_sendhex - program for manage device firmware by USB
2 * R.Bartosinski <bartosr@centrum.cz> (C)2004
4 * Based on 'ul_sendhex'
6 * Version 1.1 - 2013/08/26
19 #if !defined(_WIN32) && !defined(__DJGPP__) && !defined(HAS_GETDELIM)
22 #define HAS_GETOPT_LONG
24 #define USB_DEV_VID 0xDEAD
25 #define USB_DEV_PID 0x1000
27 #define USB_TIMEOUT 500
31 #define USB_VENDOR_GET_CAPABILITIES 0x00 // get capabilities
32 #define USB_VENDOR_RESET_DEVICE 0x08
33 // #define USB_VENDOR_SET_BYTE 0x10
34 // #define USB_VENDOR_SET_WORD 0x20
35 #define USB_VENDOR_GET_SET_MEMORY 0x30
36 #define USB_VENDOR_ERASE_MEMORY 0x40 // erase memory for 1 Byte
37 #define USB_VENDOR_ERASE_1KB_MEMORY 0x48 // erase memory for 1 KB
38 #define USB_VENDOR_MASS_ERASE 0x50 // erase all device memory
39 #define USB_VENDOR_GOTO 0x60
40 #define USB_VENDOR_CALL 0x70
41 #define USB_VENDOR_GET_STATUS 0xF0
42 #define USB_VENDOR_MASK 0xF8 // mask for vendor commands
44 #define USB_VENDOR_MEMORY_BY_BULK 0x80
46 int vid = USB_DEV_VID;
47 int pid = USB_DEV_PID;
50 unsigned long mem_start = 0;
51 unsigned long mem_length = 0xff00;
52 unsigned long max_block = 1024;
53 unsigned long go_addr = 3;
63 int wait_for_device_flg = 0;
64 char *file_format = NULL;
66 int masserase_flg = 0;
67 unsigned long masserase_mode = 0;
69 /*****************************************************************************/
71 typedef struct tform_file
78 unsigned char *line_buf;
84 int (*read)(struct tform_file *tform);
85 int (*done)(struct tform_file *tform);
88 /*****************************************************************************/
90 #if __BYTE_ORDER == __BIG_ENDIAN
91 uint16_t usb_swab16(uint16_t x)
93 return x << 8 | x >> 8;
96 uint16_t usb_swab16(uint16_t x)
103 int getdelim(char **line, size_t *linelen, char delim, FILE *F)
110 if (l + 1 >= *linelen)
115 *line = (char *)malloc(*linelen);
117 *line = (char *)realloc(*line, *linelen);
140 int get_hex(char **p, unsigned *v, int chars)
154 if ((c >= '0') && (c <= '9'))
156 else if ((c >= 'A') && (c <= 'F'))
169 int tform_init(tform_file *tform, int buf_len)
171 if (!buf_len) buf_len = 1024;
174 tform->buf_len = buf_len;
175 tform->buf = malloc(tform->buf_len);
177 tform->line_buf = NULL;
178 tform->line_offs = 0;
179 tform->line_bytes = 0;
180 tform->start_addr = -1;
181 tform->buf_bytes = 0;
184 tform->ext_base_addr = 0;
188 int tform_done(tform_file *tform)
191 return tform->done(tform);
199 free(tform->line_buf);
204 int tform_read(tform_file *tform)
206 return tform->read(tform);
209 int tform_read_ihex(tform_file *tform)
219 while (len < tform->buf_len)
221 if (!tform->line_bytes)
226 tform->line_offs = 0;
228 if (getdelim(&line, &line_len, '\n', tform->file) == -1)
234 printf("tform_read : strange line %s\n", line);
237 if (get_hex(&p, &u, 2) < 0)
239 printf("tform_read_ihex : bad ihex cnt\n");
243 checksum += cn = tform->line_bytes = u;
245 if (!tform->line_buf)
246 tform->line_buf = malloc(cn);
248 tform->line_buf = realloc(tform->line_buf, cn);
250 if (get_hex(&p, &u, 2) < 0)
252 printf("tform_read_ihex : bad ihex addr\n");
256 if (get_hex(&p, &v, 2) < 0)
258 printf("tform_read_ihex : bad ihex addr\n");
263 tform->line_addr = (u << 8) + v;
265 if (get_hex(&p, &u, 2) < 0)
267 printf("tform_read_ihex : bad ihex type\n");
271 checksum += ihex_type = u;
273 if ((ihex_type >= 0) && (ihex_type <= 5))
279 if (get_hex(&p, &u, 2) < 0)
281 printf("tform_read_ihex : bad ihex data\n");
285 checksum += *r++ = u;
288 if (get_hex(&p, &u, 2) < 0)
290 printf("tform_read_ihex : bad ihex csum\n");
298 printf("tform_read_ihex : error ihex csum %d\n",
303 while ((u = *p++)) if (u != ' ' && u != '\n' && u != '\r')
305 printf("tform_read_ihex : residual chars on line\n");
312 tform->line_bytes = 0;
313 if(tform->start_addr == -1)
314 tform->start_addr = tform->line_addr;
317 tform->line_addr+=tform->ext_base_addr;
319 if((ihex_type >= 2) && (ihex_type <= 5))
321 cn = tform->line_bytes;
331 tform->ext_base_addr=addr << 4;
332 else if(ihex_type == 4)
333 tform->ext_base_addr = addr << 16;
334 else if(ihex_type == 5)
335 tform->start_addr = addr;
337 tform->line_bytes = 0;
342 if (tform->line_bytes)
345 addr = tform->buf_addr = tform->line_addr + tform->line_offs;
346 else if (addr != tform->line_addr + tform->line_offs)
349 cn = tform->line_bytes - tform->line_offs;
351 if (cn + len > tform->buf_len) cn = tform->buf_len - len;
353 memcpy(tform->buf + len, tform->line_buf + tform->line_offs, cn);
356 tform->line_offs += cn;
358 if (tform->line_bytes == tform->line_offs)
359 tform->line_bytes = 0;
363 tform->buf_bytes = len;
368 int tform_read_binary(tform_file *tform)
372 tform->buf_addr += tform->buf_bytes;
373 len = fread(tform->buf, 1, tform->buf_len, tform->file);
377 perror("tform_read_binary : read error");
381 tform->buf_bytes = len;
385 int tform_open(tform_file *tform, char *file_name,
386 char *format, int buf_len, int wr_fl)
390 if (!format || !strcmp("ihex", format))
392 if ((file = fopen(file_name, "r")) == NULL)
394 perror("download_file : hex file open");
398 tform_init(tform, buf_len);
400 tform->read = tform_read_ihex;
402 else if (!strcmp("binary", format))
404 if ((file = fopen(file_name, "rb")) == NULL)
406 perror("download_file : binary file open");
410 tform_init(tform, buf_len);
412 tform->read = tform_read_binary;
416 fprintf(stderr, "requested unknown format %s\n", format);
424 /*****************************************************************************/
425 /*****************************************************************************/
426 /*****************************************************************************/
428 void print_devices(void)
431 struct usb_device *dev;
434 usb_init(); // NO for more devices
438 printf("All connected usb devices\n");
439 printf(" bus/device idVendor/idProduct\n");
441 for (bus = usb_busses; bus; bus = bus->next)
443 for (dev = bus->devices; dev; dev = dev->next)
446 printf(" %s/%s 0x%04X/0x%04X\n", bus->dirname, dev->filename, dev->descriptor.idVendor, dev->descriptor.idProduct);
451 printf(" -- no device.\n");
454 struct usb_device *find_usb_device(int vendor, int product)
457 struct usb_device *dev;
459 for (bus = usb_busses; bus; bus = bus->next)
461 for (dev = bus->devices; dev; dev = dev->next)
463 if ((dev->descriptor.idVendor == vendor) &&
464 (dev->descriptor.idProduct) == product)
472 usb_dev_handle *usb_open_device(int uvid, int upid)
474 struct usb_device *dev;
475 usb_dev_handle *hdev;
477 usb_init(); // NO for more devices
481 dev = find_usb_device(uvid, upid);
486 printf("!!! Cannot find device 0x%04X:0x%04X\n", uvid, upid);
491 if ((hdev = usb_open(dev)) == NULL)
494 printf("!!! USB device wasn't opened !!!\n");
499 usb_claim_interface(hdev, 0);
502 printf(" USB Device 0x%04X:0x%04X '%s' is open.\n", uvid, upid, dev->filename);
507 int usb_close_device(usb_dev_handle *hdev)
510 usb_release_interface(hdev, 0);
511 bRes = usb_close(hdev);
514 printf("!!! USB Device wasn't closed !!!\n");
519 /*****************************************************************************/
520 /*****************************************************************************/
521 /*****************************************************************************/
523 int download_file(char *file_name, char *format)
525 usb_dev_handle *hdev;
531 unsigned long shift_addr = 0;
533 struct timeval time1, time2;
536 shift_addr = mem_start;
538 hdev = usb_open_device(vid, pid);
542 perror("download_file : usb device open failed");
546 /* ul_drv_debflg(ul_fd,0x11); */ /* 0x9 0x11 */
548 if (tform_open(&tform, file_name, format, max_block, 0) < 0)
550 usb_close_device(hdev);
554 gettimeofday(&time1, &tz);
558 len = tform_read(&tform);
564 perror("download_file : ihex");
569 printf("addr %4lX len %4X\n", tform.buf_addr + shift_addr, len);
573 // if((stamp=ul_new_memrq_write(ul_fd,module,mem_type,
574 // tform.buf_addr+shift_addr,len,tform.buf))<0)
575 // { printf("download_file : send message error\n");
582 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_VENDOR_GET_SET_MEMORY | mem_type /*USB_VENDOR_TARGET_XDATA*/,
583 (unsigned long)(tform.buf_addr + shift_addr) & 0xffff, (((unsigned long)(tform.buf_addr + shift_addr)) >> 16) & 0xffff, (void *)tform.buf, len, 150 + len); //USB_TIMEOUT);
584 // ret = usb_bulk_write( hdev, USB_ENDPOINT_IN | 0x02, buf, len, 1000);
586 if (verbose && ret < 0) printf("Mem read error %d - again\n", ret);
590 while (ret < 0 && i);
595 gettimeofday(&time2, &tz);
599 long dus = (time2.tv_sec * 1000000 + time2.tv_usec) - (time1.tv_sec * 1000000 + time1.tv_usec);
600 printf("Upload time %lu.%lu s\n", dus / 1000000, dus % 1000000);
604 if (tform.start_addr != -1)
605 printf("Found start address %4X\n", tform.start_addr);
608 usb_close_device(hdev);
612 int send_cmd_call(int cmd, int val)
615 usb_dev_handle *hdev;
618 hdev = usb_open_device(vid, pid);
622 perror("send_cmd_call : USB open failed");
626 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
627 USB_VENDOR_CALL, val & 0xffff, cmd & 0xffff, resp, sizeof(resp), USB_TIMEOUT);
628 resp_val = usb_swab16(*((uint16_t *)(resp)));
631 printf("Call %4X (%4X) ERROR %d: %s\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), ret, usb_strerror());
633 printf("Call %4X (%4X): %4X\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), resp_val);
635 usb_close_device(hdev);
639 int send_cmd_go(unsigned long addr)
642 usb_dev_handle *hdev;
644 hdev = usb_open_device(vid, pid);
648 perror("send_cmd_go : USB open failed");
652 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
653 USB_VENDOR_GOTO, addr & 0xffff, (addr >> 16) & 0xffff, NULL, 0, USB_TIMEOUT);
655 if (ret < 0) printf("Goto to %4lX ERROR %d: %s\n", addr, ret, usb_strerror());
656 else printf("Goto to %4lX OK\n", addr);
658 usb_close_device(hdev);
665 usb_dev_handle *hdev;
667 hdev = usb_open_device(vid, pid);
671 perror("send_cmd_reset : USB open failed");
675 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
676 USB_VENDOR_RESET_DEVICE, 0, 0, NULL, 0, USB_TIMEOUT);
679 printf("Reset device ERROR %d: %s\n", ret, usb_strerror());
681 printf("Reset OK\n");
683 usb_close_device(hdev);
688 int send_cmd_regerase(unsigned long addr, unsigned long len)
691 usb_dev_handle *hdev;
693 hdev = usb_open_device(vid, pid);
697 perror("send_cmd_regerase : USB open failed");
701 if (addr + len < 0x10000)
703 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
704 USB_VENDOR_ERASE_MEMORY, addr, len, NULL, 0, USB_TIMEOUT * 5);
709 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
710 USB_VENDOR_ERASE_1KB_MEMORY, addr >> 10, len >> 10, NULL, 0, USB_TIMEOUT * 10);
714 printf("Region Erase from %4lX ERROR %d: %s\n", addr, ret, usb_strerror());
716 printf("Region Erase from %4lX OK\n", addr);
718 usb_close_device(hdev);
724 int send_cmd_masserase(unsigned long mode)
727 usb_dev_handle *hdev;
729 hdev = usb_open_device(vid, pid);
733 perror("send_cmd_masserase : USB open failed");
737 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
738 USB_VENDOR_MASS_ERASE, mode & 0xffff, (mode >> 16) & 0xffff, NULL, 0, USB_TIMEOUT * 20);
741 printf("Mass Erase to %4lX ERROR %d: %s\n", mode, ret, usb_strerror());
742 else printf("Mass Erase to %4lX OK\n", mode);
744 usb_close_device(hdev);
749 int upload_file(char *file_name, char *format)
751 usb_dev_handle *hdev;
754 unsigned char buf[0x400];
757 enum {fmt_ihex, fmt_binary, fmt_dump} fmt;
759 unsigned long mem_adr = mem_start;
760 unsigned long mem_len = mem_length;
762 unsigned long ext_addr = 0; /* for Intel HEX format */
764 struct timeval time1, time2;
767 if (max_block > 0x400)
770 if (!format || !strcmp("ihex", format))
772 else if (!strcmp("binary", format))
777 else if (!strcmp("dump", format))
781 fprintf(stderr, "requested unknown format %s\n", format);
785 if (!strcmp(file_name, "-"))
788 hdev = usb_open_device(vid, pid);
792 perror("upload_file : open failed");
796 /* ul_drv_debflg(ul_fd,0x11); */ /* 0x9 0x11 */
800 if ((file = fopen(file_name, mode)) == NULL)
802 perror("upload_file : file open");
803 usb_close_device(hdev);
809 gettimeofday(&time1, &tz);
811 // ret = usb_control_msg( hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USB_VENDOR_MEMORY_BY_BULK | USB_VENDOR_TARGET_XDATA,
812 // mem_adr & 0xffff, mem_len, NULL, 0, 2000); //USB_TIMEOUT);
816 printf("ERR ctrl msg\n");
822 len = mem_len < max_block ? mem_len : max_block;
828 ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USB_VENDOR_GET_SET_MEMORY | mem_type /*USB_VENDOR_TARGET_XDATA*/,
829 mem_adr & 0xffff, (mem_adr >> 16) & 0xffff, (void *)buf, len, 100 + len); //USB_TIMEOUT);
830 // ret = usb_bulk_read( hdev, USB_ENDPOINT_IN | 0x02, buf, len, 1000);
832 if (verbose && ret < 0)
833 printf("Mem read error - again\n");
837 while (ret < 0 && i);
841 printf("Mem read returns %d: %s\n", ret, usb_strerror());
845 if (file_name) printf("%04lX\n", mem_adr);
855 unsigned long a = mem_adr + i;
857 if ((a & ~0xFFFF) != ext_addr)
862 ext_addr = a & ~0xFFFF;
863 val = ext_addr >> 16;
871 fprintf(file, ":%02X000004", l);
873 val = ext_addr >> 16;
876 b = (val >> (8 * l)) & 0xff;
877 fprintf(file, "%02X", b);
880 fprintf(file, "%02X\n", (-csum) & 0xFF);
887 csum = l + a + (a >> 8);
888 fprintf(file, ":%02X%04lX00", l, a & 0xffff);
892 fprintf(file, "%02X", buf[i]);
896 fprintf(file, "%02X\n", (-csum) & 0xFF);
902 if (fwrite(buf, len, 1, file) != 1)
904 perror("upload_file : file write");
916 if (i & 0xf) printf(" %02X", *(p++));
917 else printf(i ? "\n%04lX:%02X" : "%04lX:%02X", mem_adr + i, *(p++));
930 gettimeofday(&time2, &tz);
934 long dus = (time2.tv_sec * 1000000 + time2.tv_usec) - (time1.tv_sec * 1000000 + time1.tv_usec);
935 printf("Upload time %lu.%lu s\n", dus / 1000000, dus % 1000000);
939 fprintf(file, ":00000001FF\n");
944 usb_close_device(hdev);
949 static int wait_for_device(int timeout)
951 usb_dev_handle *hdev;
955 hdev = usb_open_device(vid, pid);
968 return timeout ? 0 : -1;
971 /*****************************************************************************/
972 /*****************************************************************************/
973 /*****************************************************************************/
978 printf("Usage: usb_sendhex <parameters> <hex_file>\n");
979 printf(" -d, --vid <num> device vendor id (VID) [0x%04X]\n", USB_DEV_VID);
980 printf(" -i, --pid <num> product id (PID) [0x%04X]\n", USB_DEV_PID);
981 printf(" -t, --type <num> target module memory space\n");
982 printf(" -s, --start <addr> start address of transfer\n");
983 printf(" -l, --length <num> length of upload block\n");
984 printf(" -b, --block <num> maximal block length\n");
985 printf(" -c, --call <num> vendor custom call\n");
986 printf(" -a, --argument <num> argument for vendor custom call\n");
987 printf(" -g, --go <addr> start program from address\n");
988 printf(" -r, --reset reset before download\n");
989 printf(" -E, --mass-erase <mode> full device erase\n");
990 printf(" -e, --erase erase region defined by -s -l\n");
991 printf(" -u, --upload upload memory block [download]\n");
992 printf(" -w, --wait wait for device to be on\n");
993 printf(" -f, --format <format> format of data file [ihex]\n");
994 printf(" -p, --print print devices\n");
995 printf(" --debug-kernel <m> flags to debug kernel\n");
996 printf(" -v, --verbose verbose program\n");
997 printf(" -V, --version show version\n");
998 printf(" -h, --help this usage screen\n");
1001 int main(int argc, char *argv[])
1003 static struct option long_opts[] =
1005 { "vid", 1, 0, 'd' },
1006 { "pid", 1, 0, 'i' },
1007 { "type", 1, 0, 't' },
1008 { "start", 1, 0, 's' },
1009 { "length", 1, 0, 'l' },
1010 { "block", 1, 0, 'b' },
1011 { "call", 1, 0, 'c' },
1012 { "argument", 1, 0, 'a' },
1013 { "go", 1, 0, 'g' },
1014 { "reset", 0, 0, 'r' },
1015 { "mass-erase", 1, 0, 'E' },
1016 { "erase", 0, 0, 'e' },
1017 { "upload", 0, 0, 'u' },
1018 { "wait", 0, 0, 'w' },
1019 { "format", 1, 0, 'f' },
1020 { "print", 0, 0, 'p' },
1021 { "verbose", 0, 0, 'v' },
1022 { "version", 0, 0, 'V' },
1023 { "help", 0, 0, 'h' },
1024 { "debug-kernel", 1, 0, 'D' },
1029 #ifndef HAS_GETOPT_LONG
1030 while ((opt = getopt(argc, argv, "d:i:t:s:l:b:c:a::g:rE:euwf:pvVhD:")) != EOF)
1032 while ((opt = getopt_long(argc, argv, "d:i:t:s:l:b:c:a:g:rE:euwf:pvVh", &long_opts[0], NULL)) != EOF)
1039 vid = strtol(optarg, &p, 16);
1041 if (!p || (p == optarg))
1043 printf("usb_sendhex : vendor ID is not hexadecimal number\n");
1050 pid = strtol(r, &p, 16);
1054 printf("usb_sendhex : product ID is not hexadecimal number\n");
1061 pid = strtol(optarg, &p, 16);
1064 mem_type = strtol(optarg, NULL, 0);
1067 mem_start = strtoul(optarg, NULL, 0);
1070 mem_length = strtoul(optarg, NULL, 0);
1073 max_block = strtoul(optarg, NULL, 0);
1076 call = strtoul(optarg, NULL, 0);
1080 arg = strtoul(optarg, NULL, 0);
1083 go_addr = strtoul(optarg, NULL, 0);
1090 masserase_mode = strtoul(optarg, NULL, 0);
1100 wait_for_device_flg = 1;
1103 file_format = optarg;
1109 debugk = strtol(optarg, NULL, 0);
1116 fputs("USB sendhex v.1.1\n", stdout);
1121 exit(opt == 'h' ? 0 : 1);
1124 if ((optind >= argc) && !go_flg && !call_flg && !prt_modules && !debugk_flg
1125 && !masserase_flg && !regerase_flg && !reset_flg)
1134 if (wait_for_device_flg)
1135 if (wait_for_device(100) < 0)
1142 send_cmd_regerase(mem_start, mem_length);
1145 send_cmd_masserase(masserase_mode);
1149 while (optind < argc)
1150 if (download_file(argv[optind++], file_format) < 0)
1155 if (optind + 1 != argc)
1157 printf("upload_file : needs exactly one filename\n");
1161 if (upload_file(argv[optind], file_format) < 0)
1167 if (send_cmd_call(call, arg) < 0)
1173 if (send_cmd_go(go_addr) < 0)