blob: c5a5507e49254947b30e2d99cf192f93561b8827 [file] [log] [blame]
Stefan Reinauer0ce691f2012-08-03 14:20:24 -07001/*
Stefan Reinauer5cf0da72015-08-17 15:22:20 -07002 * Copyright 2012-2015 Google Inc.
Stefan Reinauer0ce691f2012-08-03 14:20:24 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
Martin Roth92c453b2015-09-01 10:35:02 -060021#include <strings.h>
Patrick Georgif3558c62014-10-28 18:16:57 +010022#include <signal.h>
Stefan Reinauer0ce691f2012-08-03 14:20:24 -070023#include <getopt.h>
Stefan Reinauerc566d202015-08-25 09:52:42 -070024#include "em100.h"
Martin Roth4203a382014-08-02 08:14:37 -060025
Stefan Reinauer0ce691f2012-08-03 14:20:24 -070026/* SPI flash chips parameters definition */
27#include "em100pro_chips.h"
28
Patrick Georgif3558c62014-10-28 18:16:57 +010029volatile int do_exit_flag = 0;
30
31void exit_handler(int sig) {
32 do_exit_flag = 1;
33}
34
Aaron Durbin637fe482012-10-17 17:39:19 -050035struct em100_hold_pin_states {
36 const char *description;
37 int value;
38};
39
Stefan Reinauerfba00632012-10-18 09:17:00 -070040static const struct em100_hold_pin_states hold_pin_states[] = {
Aaron Durbin637fe482012-10-17 17:39:19 -050041 { "FLOAT", 0x2 },
42 { "LOW", 0x0 },
43 { "INPUT", 0x3 },
44 { NULL, 0x0 },
45};
46
Stefan Reinauer54f91d92015-08-18 12:00:07 -070047/* High Level functions */
48
Stefan Reinauerb82d79b2015-08-18 11:14:33 -070049static int set_state(struct em100 *em100, int run)
50{
51 return write_fpga_register(em100, 0x28, run & 1);
52}
53
54static int set_hold_pin_state(struct em100 *em100, int pin_state)
55{
56 uint16_t val;
57
58 /* Read and acknowledge hold pin state setting bit 2 of pin state respone. */
59 if (!read_fpga_register(em100, 0x2a, &val)) {
60 printf("Couldn't get hold pin state.\n");
61 return 0;
62 }
63 write_fpga_register(em100, 0x2a, (1 << 2) | val);
64
65
66 if (!read_fpga_register(em100, 0x2a, &val)) {
67 printf("Couldn't get hold pin state.\n");
68 return 0;
69 }
70
71 /* Now set desired pin state. */
72 write_fpga_register(em100, 0x2a, pin_state);
73
74 /* Read the pin state. */
75 if (!read_fpga_register(em100, 0x2a, &val)) {
76 printf("Couldn't get hold pin state.\n");
77 return 0;
78 }
79
80 if (val != pin_state) {
81 printf("Invalid pin state response: 0x%04x (expected 0x%04x)\n",
82 val, pin_state);
83 return 0;
84 }
85
86 return 1;
87}
88
89static int set_hold_pin_state_from_str(struct em100 *em100, const char *state)
90{
91 int pin_state;
92 const struct em100_hold_pin_states *s = &hold_pin_states[0];
93
94 while (s->description != NULL) {
95 if (!strcmp(s->description, state))
96 break;
97 s++;
98 }
99 if (s->description == NULL) {
100 printf("Invalid hold pin state: %s\n", state);
101 return 0;
102 }
103 pin_state = s->value;
104
105 return set_hold_pin_state(em100, pin_state);
106}
107
Stefan Reinauer52875112015-08-20 13:57:20 -0700108/**
109 * get_serialno: fetch device's serial number
110 * @param em100: initialized em100 device structure
111 */
112static int get_serialno(struct em100 *em100)
113{
114 unsigned char data[256];
115 if (read_spi_flash_page(em100, 0x1fff00, data)) {
116 em100->serialno = (data[5] << 24) | (data[4] << 16) | \
117 (data[3] << 8) | data[2];
118 return 1;
119 }
120 return 0;
121}
122
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700123static int set_serialno(struct em100 *em100, unsigned int serialno)
124{
125 unsigned char data[512];
126 unsigned int old_serialno;
127
128 if (!read_spi_flash_page(em100, 0x1fff00, data))
129 return 0;
130
131 old_serialno = (data[5] << 24) | (data[4] << 16) | \
132 (data[3] << 8) | data[2];
133
134 if (old_serialno == serialno) {
135 printf("Serial number unchanged.\n");
136 return 1;
137 }
138
139 data[2] = serialno;
140 data[3] = serialno >> 8;
141 data[4] = serialno >> 16;
142 data[5] = serialno >> 24;
143
144 if (old_serialno != 0xffffffff) {
145 /* preserve magic */
146 read_spi_flash_page(em100, 0x1f0000, data + 256);
147 /* Unlock and erase sector. Reading
148 * the SPI flash ID is requires to
149 * actually unlock the chip.
150 */
151 unlock_spi_flash(em100);
152 get_spi_flash_id(em100);
153 erase_spi_flash_sector(em100, 0x1f);
154 /* write back magic */
155 write_spi_flash_page(em100, 0x1f0000, data + 256);
156 }
157
158 if (!write_spi_flash_page(em100, 0x1fff00, data)) {
159 printf("Error: Could not write SPI flash.\n");
160 return 0;
161 }
162 get_serialno(em100);
163 if (em100->serialno != 0xffffffff)
164 printf("New serial number: DP%06d\n", em100->serialno);
165 else
166 printf("New serial number: N.A.\n");
167
168 return 1;
169}
170
Stefan Reinauer14d35122015-09-03 16:02:55 -0700171static int em100_debug(struct em100 *em100)
172{
173 int i;
174 printf("\nVoltages:\n");
175 set_led(em100, both_off);
176 printf(" 1.2V: %dmV\n", get_voltage(em100, in_v1_2));
177 printf(" E_VCC: %dmV\n", get_voltage(em100, in_e_vcc));
178 set_led(em100, both_on);
179 printf(" REF+: %dmV\n", get_voltage(em100, in_ref_plus));
180 printf(" REF-: %dmV\n", get_voltage(em100, in_ref_minus));
181 set_led(em100, red_on);
182 printf(" Buffer VCC: %dmV\n", get_voltage(em100, in_buffer_vcc));
183 printf(" Trig VCC: %dmV\n", get_voltage(em100, in_trigger_vcc));
184 set_led(em100, both_on);
185 printf(" RST VCC: %dmV\n", get_voltage(em100, in_reset_vcc));
186 printf(" 3.3V: %dmV\n", get_voltage(em100, in_v3_3));
187 set_led(em100, red_on);
188 printf(" Buffer 3.3V: %dmV\n", get_voltage(em100, in_buffer_v3_3));
189 printf(" 5V: %dmV\n", get_voltage(em100, in_v5));
190 set_led(em100, green_on);
191 printf("\nFPGA registers:");
192 for (i = 0; i < 256; i += 2) {
193 uint16_t val;
194 if ((i % 16) == 0)
195 printf("\n %04x: ", i);
196 if (read_fpga_register(em100, i, &val))
197 printf("%04x ", val);
198 else
199 printf("XXXX ");
200 }
201
202 printf("\n");
203 return 1;
204}
205
Stefan Reinauer52875112015-08-20 13:57:20 -0700206static int check_status(struct em100 *em100)
207{
208 int spi_flash_id;
209
210 spi_flash_id = get_spi_flash_id(em100);
Stefan Reinauer22340e82015-08-24 12:26:20 -0700211 /* Check for Micron (formerly Numonyx, formerly STMicro)
212 * M25P16 spi flash part
213 */
Stefan Reinauer52875112015-08-20 13:57:20 -0700214 if (spi_flash_id == 0x202015)
215 return 1;
216 return 0;
217}
218
Stefan Reinauer081bb822015-09-03 16:26:10 -0700219static int em100_attach(struct em100 *em100, int bus, int device)
Stefan Reinauer52875112015-08-20 13:57:20 -0700220{
Stefan Reinauer52875112015-08-20 13:57:20 -0700221 libusb_device_handle *dev;
222 libusb_context *ctx = NULL;
223
224 if (libusb_init(&ctx) < 0) {
225 printf("Could not init libusb.\n");
226 return 0;
227 }
228
229 libusb_set_debug(ctx, 3);
230
Stefan Reinauer081bb822015-09-03 16:26:10 -0700231 if (!bus || !device) {
232 dev = libusb_open_device_with_vid_pid(ctx, 0x4b4, 0x1235);
233 } else {
234 libusb_device **devs, *d;
235 int i;
236
237 if (libusb_get_device_list(ctx, &devs) < 0) {
238 printf("Could not find USB devices.\n");
239 return 0;
240 }
241
242 for (i = 0; (d = devs[i]) != NULL; i++) {
243 if ((bus > 0 && (libusb_get_bus_number(d) == bus)) &&
244 (device > 0 && (libusb_get_device_address(d) == device))) {
245 struct libusb_device_descriptor desc;
246 libusb_get_device_descriptor(d, &desc);
247 if (desc.idVendor == 0x4b4 && desc.idProduct == 0x1235) {
248 if (libusb_open(d, &dev)) {
249 printf("Couldn't open EM100pro device.\n");
250 return 0;
251 }
252 } else {
253 printf("USB device on bus %03d:%02d is not an EM100pro.\n", bus, device);
254 return 0;
255 }
256 break;
257 }
258 }
259 libusb_free_device_list(devs, 1);
Stefan Reinauer52875112015-08-20 13:57:20 -0700260 }
261
Stefan Reinauer52875112015-08-20 13:57:20 -0700262 if (!dev) {
Stefan Reinauer081bb822015-09-03 16:26:10 -0700263 printf("Could not find EM100pro.\n");
Stefan Reinauer52875112015-08-20 13:57:20 -0700264 return 0;
265 }
266
Stefan Reinauer52875112015-08-20 13:57:20 -0700267 if (libusb_kernel_driver_active(dev, 0) == 1) {
268 if (libusb_detach_kernel_driver(dev, 0) != 0) {
269 printf("Could not detach kernel driver.\n");
270 return 0;
271 }
272 }
273
274 if (libusb_claim_interface(dev, 0) < 0) {
275 printf("Could not claim interface.\n");
276 return 0;
277 }
278
279 em100->dev = dev;
280 em100->ctx = ctx;
281
282 if (!check_status(em100)) {
283 printf("Device status unknown.\n");
284 return 0;
285 }
286
287 if (!get_version(em100)) {
288 printf("Failed fetching version information.\n");
289 return 0;
290 }
291
292 if (!get_serialno(em100)) {
293 printf("Failed fetching serial number.\n");
294 return 0;
295 }
296
297 return 1;
298}
299
300static int em100_detach(struct em100 *em100)
301{
302 if (libusb_release_interface(em100->dev, 0) != 0) {
303 printf("releasing interface failed.\n");
304 return 1;
305 }
306
307 libusb_close(em100->dev);
308 libusb_exit(em100->ctx);
309
310 return 0;
311}
312
Stefan Reinauer7eda75e2015-09-03 16:32:13 -0700313static int em100_list(void)
314{
315 struct em100 em100;
316 libusb_device **devs, *dev;
317 libusb_context *ctx = NULL;
318 int i, count = 0;
319
320 if (libusb_init(&ctx) < 0) {
321 printf("Could not init libusb.\n");
322 return 0;
323 }
324
325 libusb_set_debug(ctx, 3);
326
327 if (libusb_get_device_list(ctx, &devs) < 0) {
328 printf("Could not find USB devices.\n");
329 return 0;
330 }
331
332 for (i = 0; (dev = devs[i]) != NULL; i++) {
333 struct libusb_device_descriptor desc;
334 libusb_get_device_descriptor(dev, &desc);
335 if (desc.idVendor != 0x4b4 || desc.idProduct != 0x1235)
336 continue;
337
338 em100_attach(&em100, libusb_get_bus_number(dev),
339 libusb_get_device_address(dev));
340 printf(" Bus %03d Device %03d: EM100pro DP%06d\n",
341 libusb_get_bus_number(dev),
342 libusb_get_device_address(dev),
343 em100.serialno);
344 em100_detach(&em100);
345 count++;
346 }
347 if (count == 0)
348 printf("No EM100pro devices found.\n");
349 libusb_exit(ctx);
350 return 1;
351}
352
Stefan Reinauer52875112015-08-20 13:57:20 -0700353static int set_chip_type(struct em100 *em100, const chipdesc *desc)
354{
355 unsigned char cmd[16];
356 /* result counts unsuccessful send_cmd()s.
357 * These are then converted in a boolean success value
358 */
359 int result = 0;
360 int i;
Stefan Reinauer53cf2342015-08-28 16:56:40 -0700361 int fpga_voltage, chip_voltage = 0, wrong_voltage = 0;
Stefan Reinauer52875112015-08-20 13:57:20 -0700362
363 printf("Sending flash chip configuration\n");
364
365 memset(cmd, 0, 16);
366
Stefan Reinauer53cf2342015-08-28 16:56:40 -0700367 fpga_voltage = em100->fpga & 0x8000 ? 1800 : 3300;
368
369 for (i = 0; i < desc->init_len; i++) {
370 if(desc->init[i][0] != 0x11 || desc->init[i][1] != 0x04)
371 continue;
372
373 chip_voltage = (desc->init[i][2] << 8) | desc->init[i][3];
374
375 switch (chip_voltage) {
376 case 1601: /* 1.65V-2V */
377 case 1800:
378 if (fpga_voltage == 3300)
379 wrong_voltage = 1;
380 break;
381 case 2500: /* supported by both 1.8V and 3.3V FPGA */
382 break;
383 case 3300:
384 if (fpga_voltage == 1800)
385 wrong_voltage = 1;
386 }
387 break;
388 }
389
390 if (wrong_voltage) {
391 printf("Error: The current FPGA firmware (%.1fV) does not "
392 "support %s %s (%.1fV)\n", (float)fpga_voltage/1000,
393 desc->vendor, desc->name, (float)chip_voltage/1000);
394 return 0;
395 }
396
Stefan Reinauer52875112015-08-20 13:57:20 -0700397 for (i = 0; i < desc->init_len; i++) {
398 memcpy(&cmd[0], &desc->init[i][0], BYTES_PER_INIT_ENTRY);
399 result += !send_cmd(em100->dev, cmd);
400 }
401
402 return !result;
403}
404
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700405static const struct option longopts[] = {
406 {"set", 1, 0, 'c'},
407 {"download", 1, 0, 'd'},
408 {"start", 0, 0, 'r'},
409 {"stop", 0, 0, 's'},
410 {"verify", 0, 0, 'v'},
Aaron Durbin637fe482012-10-17 17:39:19 -0500411 {"holdpin", 1, 0, 'p'},
Stefan Reinauer14d35122015-09-03 16:02:55 -0700412 {"debug", 0, 0, 'D'},
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700413 {"help", 0, 0, 'h'},
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700414 {"trace", 0, 0, 't'},
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700415 {"set-serialno", 1, 0, 'S'},
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700416 {"firmware-update", 1, 0, 'F'},
417 {"firmware-dump", 1, 0, 'f'},
Stefan Reinauer7eda75e2015-09-03 16:32:13 -0700418 {"device", 1, 0, 'x'},
419 {"list-devices", 0, 0, 'l'},
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700420 {NULL, 0, 0, 0}
421};
422
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700423static void usage(char *name)
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700424{
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700425 printf("em100: EM100pro command line utility\n\nExample:\n"
426 " %s --stop --set M25P80 -d file.bin -v --start\n"
427 "\nUsage:\n"
428 " -c|--set CHIP: select chip emulation\n"
429 " -d|--download FILE: upload FILE into EM100pro\n"
Stefan Reinauer75bcb1f2015-08-24 12:21:02 -0700430 " -r|--start: em100 shall run\n"
431 " -s|--stop: em100 shall stop\n"
432 " -v|--verify: verify EM100 content matches the file\n"
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700433 " -t|--trace: trace mode\n"
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700434 " -F|--firmware-update FILE: update firmware in EM100pro (dangerous)\n"
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700435 " -f|--firmware-dump FILE: export firmware in EM100pro to file\n"
436 " -S|--set-serialno NUM: set serial number to NUM\n"
437 " -p|--holdpin [LOW|FLOAT|INPUT]: set the hold pin state\n"
Stefan Reinauer7eda75e2015-09-03 16:32:13 -0700438 " -x|--device BUS:DEV use EM100pro on USB bus/device\n"
439 " -l|--list-devices list all connected EM100pro devices\n"
Stefan Reinauer14d35122015-09-03 16:02:55 -0700440 " -D|--debug: print debug information.\n"
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700441 " -h|--help: this help text\n\n", name);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700442}
443
444/* get MCU and FPGA version, *100 encoded */
445int main(int argc, char **argv)
446{
447 int opt, idx;
448 const char *desiredchip = NULL;
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700449 const char *serialno = NULL;
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700450 const char *filename = NULL;
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700451 const char *firmware_in = NULL, *firmware_out = NULL;
Aaron Durbin637fe482012-10-17 17:39:19 -0500452 const char *holdpin = NULL;
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700453 int do_start = 0, do_stop = 0;
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700454 int verify = 0, trace = 0;
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700455 int debug = 0;
Stefan Reinauer081bb822015-09-03 16:26:10 -0700456 int bus = 0, device = 0;
Stefan Reinauer7eda75e2015-09-03 16:32:13 -0700457 while ((opt = getopt_long(argc, argv, "c:d:rsvtF:f:S:p:Dx:lh",
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700458 longopts, &idx)) != -1) {
459 switch (opt) {
460 case 'c':
461 desiredchip = optarg;
462 break;
463 case 'd':
464 filename = optarg;
465 /* TODO: check that file exists */
466 break;
Aaron Durbin637fe482012-10-17 17:39:19 -0500467 case 'p':
468 holdpin = optarg;
469 break;
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700470 case 'r':
471 do_start = 1;
472 break;
473 case 's':
Aaron Durbinf5587022012-10-16 15:37:12 -0500474 do_stop = 1;
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700475 break;
476 case 'v':
477 verify = 1;
478 break;
Patrick Georgif3558c62014-10-28 18:16:57 +0100479 case 't':
480 trace = 1;
481 break;
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700482 case 'S':
483 serialno = optarg;
Stefan Reinauer14d35122015-09-03 16:02:55 -0700484 case 'D':
485 debug=1;
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700486 break;
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700487 case 'F':
488 firmware_in = optarg;
489 break;
490 case 'f':
491 firmware_out = optarg;
492 break;
Stefan Reinauer7eda75e2015-09-03 16:32:13 -0700493 case 'x':
494 sscanf(optarg, "%d:%d", &bus, &device);
495 break;
496 case 'l':
497 em100_list();
498 return 0;
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700499 default:
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700500 case 'h':
Stefan Reinauera5b46d42015-09-03 16:14:25 -0700501 usage(argv[0]);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700502 return 0;
503 }
504 }
505
506 const chipdesc *chip = chips;
507 if (desiredchip) {
508 do {
Martin Roth92c453b2015-09-01 10:35:02 -0600509 if (strcasecmp(desiredchip, chip->name) == 0) {
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700510 printf("will emulate '%s'\n", chip->name);
511 break;
512 }
513 } while ((++chip)->name);
514
515 if (chip->name == NULL) {
Stefan Reinauer677b4fe2012-08-15 13:44:45 -0700516 printf("Supported chips:\n");
517 chip = chips;
518 do {
519 printf("%s ", chip->name);
520 } while ((++chip)->name);
521 printf("\n\nCould not find emulation for '%s'.\n", desiredchip);
522
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700523 return 1;
524 }
525 }
526
527 struct em100 em100;
Stefan Reinauer081bb822015-09-03 16:26:10 -0700528 if (!em100_attach(&em100, bus, device)) {
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700529 return 1;
530 }
531
Stefan Reinauer56658b12015-08-18 12:41:49 -0700532 printf("MCU version: %d.%02d\n", em100.mcu >> 8, em100.mcu & 0xff);
Stefan Reinauer14deb032015-08-28 16:33:00 -0700533 if (em100.fpga > 0x0033) { /* 0.51 */
534 printf("FPGA version: %d.%02d (%s)\n",
535 em100.fpga >> 8 & 0x7f, em100.fpga & 0xff,
536 em100.fpga & 0x8000 ? "1.8V" : "3.3V");
537 } else {
538 /* While the Dediprog software for Windows will refuse to work
539 * with 1.8V chips on older FPGA versions, it does not
540 * specifically output a voltage when reporting the FPGA
541 * version. We emulate this behavior here. Version 0.51 is
542 * known to behave the old way, 0.75 is behaving the new
543 * way.
544 */
545 printf("FPGA version: %d.%02d\n", em100.fpga >> 8, em100.fpga & 0xff);
546 }
547
548 if (em100.serialno != 0xffffffff)
549 printf("Serial number: DP%06d\n", em100.serialno);
550 else
551 printf("Serial number: N.A.\n");
Stefan Reinauer48595922015-08-24 12:24:05 -0700552 printf("SPI flash database: %s\n", VERSION);
Stefan Reinauer14d35122015-09-03 16:02:55 -0700553 if(debug) {
554 em100_debug(&em100);
555 }
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700556
Stefan Reinauera2b67d32015-09-01 16:30:43 -0700557 if (firmware_in) {
558 firmware_update(&em100, firmware_in, verify);
559 return em100_detach(&em100);
560 }
561
562 if (firmware_out) {
563 firmware_dump(&em100, firmware_out);
564 return em100_detach(&em100);
565 }
566
Stefan Reinauere636d2a2015-08-28 16:58:57 -0700567 if (serialno) {
568 unsigned int serial_number;
569 if (sscanf(serialno, "%d", &serial_number) != 1)
570 printf("Error: Can't parse serial number '%s'\n",
571 serialno);
572 else
573 set_serialno(&em100, serial_number);
574
575 return em100_detach(&em100);
576 }
577
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700578 if (do_stop) {
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700579 set_state(&em100, 0);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700580 }
581
582 if (desiredchip) {
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700583 if (!set_chip_type(&em100, chip)) {
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700584 printf("Failed configuring chip type.\n");
585 return 0;
586 }
587 }
588
Aaron Durbin637fe482012-10-17 17:39:19 -0500589 if (holdpin) {
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700590 if (!set_hold_pin_state_from_str(&em100, holdpin)) {
Aaron Durbin637fe482012-10-17 17:39:19 -0500591 printf("Failed configuring hold pin state.\n");
592 return 0;
593 }
594 }
595
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700596 if (filename) {
Martin Rothac82bea2014-08-02 09:04:17 -0600597 int maxlen = 0x1000000; /* largest size - 16MB */
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700598 void *data = malloc(maxlen);
599 if (data == NULL) {
600 printf("FATAL: couldn't allocate memory\n");
601 return 1;
602 }
603 FILE *fdata = fopen(filename, "rb");
604 if (!fdata) {
605 perror("Could not open upload file");
606 return 1;
607 }
608
609 int length = 0;
610 while ((!feof(fdata)) && (length < maxlen)) {
611 int blocksize = 65536;
612 length += blocksize * fread(data+length, blocksize, 1, fdata);
613 }
614 fclose(fdata);
615
616 if (length > maxlen) {
617 printf("FATAL: length > maxlen\n");
618 return 1;
619 }
620
Stefan Reinaueref3ec9f2015-08-18 09:55:00 -0700621 write_sdram(&em100, (unsigned char *)data, 0x00000000, length);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700622 if (verify) {
623 int done;
624 void *readback = malloc(length);
625 if (data == NULL) {
626 printf("FATAL: couldn't allocate memory\n");
627 return 1;
628 }
Stefan Reinaueref3ec9f2015-08-18 09:55:00 -0700629 done = read_sdram(&em100, readback, 0x00000000, length);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700630 if (done && (memcmp(data, readback, length) == 0))
631 printf("Verify: PASS\n");
632 else
633 printf("Verify: FAIL\n");
634 free(readback);
635 }
636
637 free(data);
638 }
639
640 if (do_start) {
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700641 set_state(&em100, 1);
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700642 }
643
Patrick Georgif3558c62014-10-28 18:16:57 +0100644 if (trace) {
645 struct sigaction signal_action;
646
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700647 if (!set_hold_pin_state(&em100, 3)) {
Stefan Reinauercf24ed72015-08-24 12:21:45 -0700648 printf("Error: Failed to set EM100 to input\n");
Patrick Georgif3558c62014-10-28 18:16:57 +0100649 return 1;
650 }
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700651 set_state(&em100, 1);
652 reset_spi_trace(&em100);
Patrick Georgif3558c62014-10-28 18:16:57 +0100653
654 signal_action.sa_handler = exit_handler;
655 signal_action.sa_flags = 0;
656 sigemptyset(&signal_action.sa_mask);
657 sigaction(SIGINT, &signal_action, NULL);
658
659 while (!do_exit_flag) {
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700660 read_spi_trace(&em100);
Patrick Georgif3558c62014-10-28 18:16:57 +0100661 }
662
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700663 set_state(&em100, 0);
664 reset_spi_trace(&em100);
Patrick Georgif3558c62014-10-28 18:16:57 +0100665
Stefan Reinauer4e5f04a2015-08-18 09:23:22 -0700666 if (!set_hold_pin_state(&em100, 2)) {
Stefan Reinauercf24ed72015-08-24 12:21:45 -0700667 printf("Error: Failed to set EM100 to float\n");
Patrick Georgif3558c62014-10-28 18:16:57 +0100668 return 1;
669 }
670 }
671
Stefan Reinauer0ce691f2012-08-03 14:20:24 -0700672 return em100_detach(&em100);
673}