hmuartlgw: Add minimal support for DualCoPro-firmware
[hmcfgusb] / flash-hmmoduart.c
CommitLineData
8a6d76dd 1/* flasher for HM-MOD-UART
853cbce9 2 *
8a6d76dd 3 * Copyright (c) 2016 Michael Gernoth <michael@gernoth.net>
853cbce9
MG
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <stdint.h>
28#include <string.h>
29#include <strings.h>
30#include <poll.h>
31#include <errno.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <sys/time.h>
36#include <libusb-1.0/libusb.h>
37
38#include "hexdump.h"
39#include "firmware.h"
40#include "version.h"
41#include "hmuartlgw.h"
42
43struct recv_data {
44 uint16_t ack;
45};
46
47static int parse_hmuartlgw(enum hmuartlgw_dst dst, uint8_t *buf, int buf_len, void *data)
48{
49 struct recv_data *rdata = data;
50
51 if (buf_len != 2)
52 return 1;
53
54 rdata->ack = (buf[0] << 8) | (buf[1] & 0xff);
55
56 return 1;
57}
58
59void flash_hmmoduart_syntax(char *prog)
60{
61 fprintf(stderr, "Syntax: %s [options] -U /dev/ttyAMA0 filename.eq3\n\n", prog);
62 fprintf(stderr, "Mandatory parameter:\n");
63 fprintf(stderr, "\t-U device\tuse HM-MOD-UART on given device\n");
8a6d76dd 64 fprintf(stderr, "\nOptional parameters:\n");
853cbce9
MG
65 fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
66
67}
68
69int main(int argc, char **argv)
70{
71 const char twiddlie[] = { '-', '\\', '|', '/' };
72 struct hmuartlgw_dev *dev;
73 uint8_t *framedata;
74 struct recv_data rdata;
75 uint16_t len;
76 struct firmware *fw;
77 char *uart = NULL;
78 char *filename = NULL;
79 int block;
80 int pfd;
81 int opt;
82 int debug = 0;
83
84 while((opt = getopt(argc, argv, "U:V")) != -1) {
85 switch (opt) {
86 case 'U':
87 uart = optarg;
88 break;
89 case 'V':
8a6d76dd
MG
90 printf("flash-hmmoduart " VERSION "\n");
91 printf("Copyright (c) 2016 Michael Gernoth\n\n");
853cbce9
MG
92 exit(EXIT_SUCCESS);
93 case 'h':
94 case ':':
95 case '?':
96 default:
97 flash_hmmoduart_syntax(argv[0]);
98 exit(EXIT_FAILURE);
99 break;
100 }
101 }
102
103 if (optind == argc - 1) {
104 filename = argv[optind];
105 }
106
107 if (!uart) {
108 flash_hmmoduart_syntax(argv[0]);
109 exit(EXIT_FAILURE);
110 }
111
112 printf("HM-MOD-UART flasher version " VERSION "\n\n");
113
114 if (!filename) {
115 fprintf(stderr, "Missing firmware filename!\n\n");
116 flash_hmmoduart_syntax(argv[0]);
117 exit(EXIT_FAILURE);
118 }
119
120 fw = firmware_read_firmware(filename, debug);
121 if (!fw)
122 exit(EXIT_FAILURE);
123
124 hmuartlgw_set_debug(debug);
125
126 memset(&rdata, 0, sizeof(rdata));
127
128 dev = hmuart_init(uart, parse_hmuartlgw, &rdata, 0);
129 if (!dev) {
130 fprintf(stderr, "Can't initialize HM-MOD-UART\n");
131 exit(EXIT_FAILURE);
132 }
133
134 printf("\nHM-MOD-UART opened.\n\n");
135
136 printf("Flashing %d blocks", fw->fw_blocks);
137 if (debug) {
138 printf("\n");
139 } else {
140 printf(": %c", twiddlie[0]);
141 fflush(stdout);
142 }
143
144 for (block = 0; block < fw->fw_blocks; block++) {
145 len = fw->fw[block][2] << 8;
146 len |= fw->fw[block][3];
147
148 len -= 1; /* + frametype, - crc crc */
149
150 framedata = (fw->fw[block]) + 3;
151 framedata[0] = HMUARTLGW_OS_UPDATE_FIRMWARE;
152
153 if (debug)
154 hexdump(framedata, len, "F> ");
155
156 rdata.ack = 0;
157
158 if (!hmuartlgw_send(dev, framedata, len, HMUARTLGW_OS)) {
159 perror("\n\nhmuartlgw_send");
160 exit(EXIT_FAILURE);
161 }
162
163 if (debug)
164 printf("Waiting for ack...\n");
165 do {
166 errno = 0;
167 pfd = hmuartlgw_poll(dev, 1000);
168 if ((pfd < 0) && errno) {
169 if (errno != ETIMEDOUT) {
170 perror("\n\nhmuartlgw_poll");
171 exit(EXIT_FAILURE);
172 }
173 }
174 if (rdata.ack) {
175 break;
176 }
177 } while (pfd < 0);
178
179 if (rdata.ack != 0x0401) {
0a1d4b5e 180 fprintf(stderr, "\n\nError flashing block %d, status: %04x\n", block, rdata.ack);
853cbce9
MG
181 exit(EXIT_FAILURE);
182 }
183
184 if (!debug) {
185 printf("\b%c", twiddlie[block % sizeof(twiddlie)]);
186 fflush(stdout);
187 }
188 }
189
190 if (rdata.ack == 0x0401) {
191 printf("\n\nFirmware update successfull!\n");
192 }
193
194
195 firmware_free(fw);
196
197 hmuartlgw_close(dev);
198
199 return EXIT_SUCCESS;
200}
Impressum, Datenschutz