]> git.zerfleddert.de Git - hmcfgusb/blob - flash-hmmoduart.c
aa772bb615c558fc3c9fb9db98e5d2ca041637df
[hmcfgusb] / flash-hmmoduart.c
1 /* flasher for HM-MOD-UART
2 *
3 * Copyright (c) 2016-17 Michael Gernoth <michael@gernoth.net>
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
43 struct recv_data {
44 uint16_t ack;
45 };
46
47 static 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
59 void 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");
64 fprintf(stderr, "\nOptional parameters:\n");
65 fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
66
67 }
68
69 int 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':
90 printf("flash-hmmoduart " VERSION "\n");
91 printf("Copyright (c) 2016 Michael Gernoth\n\n");
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 printf("\nInitializing HM-MOD-UART...\n");
129
130 dev = hmuart_init(uart, parse_hmuartlgw, &rdata, 0);
131 if (!dev) {
132 fprintf(stderr, "Can't initialize HM-MOD-UART\n");
133 exit(EXIT_FAILURE);
134 }
135
136 printf("HM-MOD-UART opened.\n\n");
137
138 printf("Flashing %d blocks", fw->fw_blocks);
139 if (debug) {
140 printf("\n");
141 } else {
142 printf(": %c", twiddlie[0]);
143 fflush(stdout);
144 }
145
146 for (block = 0; block < fw->fw_blocks; block++) {
147 len = fw->fw[block][2] << 8;
148 len |= fw->fw[block][3];
149
150 len -= 1; /* + frametype, - crc crc */
151
152 framedata = (fw->fw[block]) + 3;
153 framedata[0] = HMUARTLGW_OS_UPDATE_FIRMWARE;
154
155 if (debug)
156 hexdump(framedata, len, "F> ");
157
158 rdata.ack = 0;
159
160 if (!hmuartlgw_send(dev, framedata, len, HMUARTLGW_OS)) {
161 perror("\n\nhmuartlgw_send");
162 exit(EXIT_FAILURE);
163 }
164
165 if (debug)
166 printf("Waiting for ack...\n");
167 do {
168 errno = 0;
169 pfd = hmuartlgw_poll(dev, 1000);
170 if ((pfd < 0) && errno) {
171 if (errno != ETIMEDOUT) {
172 perror("\n\nhmuartlgw_poll");
173 exit(EXIT_FAILURE);
174 }
175 }
176 if (rdata.ack) {
177 break;
178 }
179 } while (pfd < 0);
180
181 if (rdata.ack != 0x0401) {
182 fprintf(stderr, "\n\nError flashing block %d, status: %04x\n", block, rdata.ack);
183 exit(EXIT_FAILURE);
184 }
185
186 if (!debug) {
187 printf("\b%c", twiddlie[block % sizeof(twiddlie)]);
188 fflush(stdout);
189 }
190 }
191
192 if (rdata.ack == 0x0401) {
193 printf("\n\nFirmware update successfull!\n");
194 }
195
196
197 firmware_free(fw);
198
199 hmuartlgw_close(dev);
200
201 return EXIT_SUCCESS;
202 }
Impressum, Datenschutz