X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb/blobdiff_plain/9fb0f4d2becd19b6ef278ebe01159a2a3899abea..b5e57d268fe86cf58116c03166d45c130280dfb6:/flash-hmcfgusb.c diff --git a/flash-hmcfgusb.c b/flash-hmcfgusb.c index 0308442..aebf781 100644 --- a/flash-hmcfgusb.c +++ b/flash-hmcfgusb.c @@ -39,23 +39,17 @@ #include "hmcfgusb.h" struct recv_data { + int ack; }; static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) { - if (buf_len < 1) + struct recv_data *rdata = data; + + if (buf_len != 1) return 1; - switch(buf[0]) { - case 'E': - case 'H': - case 'R': - case 'I': - break; - default: - hexdump(buf, buf_len, "Unknown> "); - break; - } + rdata->ack = buf[0]; return 1; } @@ -79,48 +73,122 @@ int main(int argc, char **argv) { struct hmcfgusb_dev *dev; struct recv_data rdata; - uint8_t out[0x40]; //FIXME!!! - uint8_t buf[0x80]; + uint8_t out[4096]; + uint8_t buf[4096]; + uint8_t *outp; int fd; + int pfd; int r; int i; int cnt; + int pkt; + int debug = 0; - hmcfgusb_set_debug(0); + hmcfgusb_set_debug(debug); memset(&rdata, 0, sizeof(rdata)); + fd = open("hmusbif.enc", O_RDONLY); + if (fd < 0) { + perror("Can't open hmusbif.enc"); + exit(EXIT_FAILURE); + } + dev = hmcfgusb_init(parse_hmcfgusb, &rdata); if (!dev) { fprintf(stderr, "Can't initialize HM-CFG-USB\n"); exit(EXIT_FAILURE); } - printf("HM-CFG-USB opened!\n"); - fd = open("hmusbif.enc", O_RDONLY); - if (fd < 0) { - perror("Can't open hmusbif.enc"); - exit(EXIT_FAILURE); + if (!dev->bootloader) { + fprintf(stderr, "HM-CFG-USB not in bootloader mode, entering bootloader.\n"); + hmcfgusb_enter_bootloader(dev); + fprintf(stderr, "\nWaiting for device to reappear...\n"); + + do { + sleep(1); + } while ((dev = hmcfgusb_init(parse_hmcfgusb, &rdata)) == NULL); + + if (!dev->bootloader) { + fprintf(stderr, "Can't enter bootloader, giving up!\n"); + exit(EXIT_FAILURE); + } } + printf("HM-CFG-USB opened!\n"); + cnt = 0; + pkt = 0; do { + int len; + memset(buf, 0, sizeof(buf)); - r = read(fd, buf, sizeof(buf)); + r = read(fd, buf, 4); if (r < 0) { perror("read"); exit(EXIT_FAILURE); } else if (r == 0) { break; + } else if (r != 4) { + printf("can't get length information!\n"); + exit(EXIT_FAILURE); + } + + len = (ascii_to_nibble(buf[0]) & 0xf)<< 4; + len |= ascii_to_nibble(buf[1]) & 0xf; + len <<= 8; + len |= (ascii_to_nibble(buf[2]) & 0xf)<< 4; + len |= ascii_to_nibble(buf[3]) & 0xf; + + r = read(fd, buf, len * 2); + if (r < 0) { + perror("read"); + exit(EXIT_FAILURE); + } else if (r < len * 2) { + printf("short read, aborting (%d < %d)\n", r, len * 2); + break; } + memset(out, 0, sizeof(out)); + outp = out; + *outp++ = (pkt >> 8) & 0xff; + *outp++ = pkt & 0xff; + *outp++ = (len >> 8) & 0xff; + *outp++ = len & 0xff; for (i = 0; i < r; i+=2) { - out[i/2] = (ascii_to_nibble(buf[i]) & 0xf)<< 4; - out[i/2] |= ascii_to_nibble(buf[i+1]) & 0xf; + *outp = (ascii_to_nibble(buf[i]) & 0xf)<< 4; + *outp |= ascii_to_nibble(buf[i+1]) & 0xf; + outp++; } - cnt += r/2; + cnt = outp - out; printf("Flashing %d bytes...\n", cnt); - hmcfgusb_send(dev, out, r/2, 1); + if (debug) + hexdump(out, cnt, "F> "); + + rdata.ack = 0; + if (!hmcfgusb_send(dev, out, cnt, 0)) { + perror("hmcfgusb_send"); + exit(EXIT_FAILURE); + } + + printf("Waiting for ack...\n"); + do { + errno = 0; + pfd = hmcfgusb_poll(dev, 1); + if ((pfd < 0) && errno) { + perror("hmcfgusb_poll"); + exit(EXIT_FAILURE); + } + if (rdata.ack) { + break; + } + } while (pfd < 0); + + if (rdata.ack == 2) { + printf("Firmware update successfull!\n"); + break; + } + pkt++; } while (r > 0); hmcfgusb_close(dev);