X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb/blobdiff_plain/da4ab9712d756cdf258cc51c6d3ced0fb5826fc6..bf1b6cb6823018a9c9a0b26ad6a756b69eb6d3f8:/flash-ota.c diff --git a/flash-ota.c b/flash-ota.c index 1fd11d8..cbda024 100644 --- a/flash-ota.c +++ b/flash-ota.c @@ -42,6 +42,7 @@ #include "hmcfgusb.h" uint32_t hmid = 0; +uint32_t my_hmid = 0; enum message_type { MESSAGE_TYPE_E, @@ -53,6 +54,7 @@ struct recv_data { enum message_type message_type; uint16_t status; int speed; + uint16_t hmcfgusb_version; }; static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) @@ -82,6 +84,10 @@ static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) case 'G': rdata->speed = buf[1]; break; + case 'H': + rdata->hmcfgusb_version = (buf[11] << 8) | buf[12]; + my_hmid = (buf[0x1b] << 16) | (buf[0x1c] << 8) | buf[0x1d]; + break; default: break; } @@ -121,7 +127,7 @@ int send_hm_message(struct hmcfgusb_dev *dev, struct recv_data *rdata, uint8_t * memcpy(&out[0x0f], msg, msg[0] + 1); memset(rdata, 0, sizeof(struct recv_data)); - hmcfgusb_send(dev, out, sizeof(out), 2); + hmcfgusb_send(dev, out, sizeof(out), 1); while (1) { if (rdata->message_type == MESSAGE_TYPE_R) { @@ -129,7 +135,7 @@ int send_hm_message(struct hmcfgusb_dev *dev, struct recv_data *rdata, uint8_t * ((rdata->status & 0xff) == 0x02)) { break; } else { - fprintf(stderr, "\n\nInvalid status: %04x\n\n", rdata->status); + fprintf(stderr, "\nInvalid status: %04x\n", rdata->status); return 0; } } @@ -158,7 +164,7 @@ static int switch_speed(struct hmcfgusb_dev *dev, struct recv_data *rdata, uint8 out[0] = 'G'; out[1] = speed; - hmcfgusb_send(dev, out, sizeof(out), 2); + hmcfgusb_send(dev, out, sizeof(out), 1); while (1) { errno = 0; @@ -223,12 +229,36 @@ int main(int argc, char **argv) } if (dev->bootloader) { - fprintf(stderr, "\nHM-CFG-USB not in bootloader mode, aborting!\n"); + fprintf(stderr, "\nHM-CFG-USB in bootloader mode, aborting!\n"); exit(EXIT_FAILURE); } printf("\nHM-CFG-USB opened\n\n"); + memset(out, 0, sizeof(out)); + out[0] = 'K'; + hmcfgusb_send(dev, out, sizeof(out), 1); + + while (1) { + errno = 0; + pfd = hmcfgusb_poll(dev, 1); + if ((pfd < 0) && errno) { + if (errno != ETIMEDOUT) { + perror("\n\nhmcfgusb_poll"); + exit(EXIT_FAILURE); + } + } + if (rdata.hmcfgusb_version) + break; + } + + if (rdata.hmcfgusb_version < 0x3c7) { + fprintf(stderr, "HM-CFG-USB firmware too low: %u < 967\n", rdata.hmcfgusb_version); + exit(EXIT_FAILURE); + } + + printf("HM-CFG-USB firmware version: %u\n", rdata.hmcfgusb_version); + if (!switch_speed(dev, &rdata, 10)) { fprintf(stderr, "Can't switch speed!\n"); exit(EXIT_FAILURE); @@ -271,7 +301,7 @@ int main(int argc, char **argv) out[2] = (hmid >> 8) & 0xff; out[3] = hmid & 0xff; - hmcfgusb_send(dev, out, sizeof(out), 2); + hmcfgusb_send(dev, out, sizeof(out), 1); switchcnt = 3; do { @@ -282,7 +312,7 @@ int main(int argc, char **argv) out[MSGID] = msgid++; out[CTL] = 0x00; out[TYPE] = 0xCB; - SET_SRC(out, 0x000000); + SET_SRC(out, my_hmid); SET_DST(out, hmid); memcpy(&out[PAYLOAD], switch_msg, sizeof(switch_msg)); @@ -304,7 +334,7 @@ int main(int argc, char **argv) out[MSGID] = msgid++; out[CTL] = 0x20; out[TYPE] = 0xCB; - SET_SRC(out, 0x000000); + SET_SRC(out, my_hmid); SET_DST(out, hmid); memcpy(&out[PAYLOAD], switch_msg, sizeof(switch_msg)); @@ -330,6 +360,10 @@ int main(int argc, char **argv) } } while ((!switched) && (switchcnt--)); + if (!switched) { + fprintf(stderr, "Too many errors, giving up!\n"); + exit(EXIT_FAILURE); + } printf("Yes!\n"); @@ -379,7 +413,7 @@ int main(int argc, char **argv) if (ack) out[CTL] = 0x20; out[TYPE] = 0xCA; - SET_SRC(out, 0x000000); + SET_SRC(out, my_hmid); SET_DST(out, hmid); memcpy(&out[PAYLOAD], pos, payloadlen);