cleanup warnings and errors
[ecpprog.git] / ecpprog.c
1 /*
2 * ecpprog -- simple programming tool for FTDI-based JTAG programmers
3 * Based on iceprog
4 *
5 * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
6 * Copyright (C) 2018 Piotr Esden-Tempski <piotr@esden.net>
7 * Copyright (C) 2020 Gregory Davill <greg.davill@gmail.com>
8 *
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 * Relevant Documents:
22 * -------------------
23 * http://www.latticesemi.com/~/media/Documents/UserManuals/EI/icestickusermanual.pdf
24 * http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_32mb_3v_65nm.pdf
25 */
26
27 #define _GNU_SOURCE
28
29 #include <stdio.h>
30 #include <stdint.h>
31 #include <stdbool.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <getopt.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #ifdef _WIN32
41 #include <io.h> /* _setmode() */
42 #include <fcntl.h> /* _O_BINARY */
43 #endif
44
45 #include "jtag.h"
46 #include "lattice_cmds.h"
47
48 static bool verbose = false;
49
50 // ---------------------------------------------------------
51 // FLASH definitions
52 // ---------------------------------------------------------
53
54 /* Flash command definitions */
55 /* This command list is based on the Winbond W25Q128JV Datasheet */
56 enum flash_cmd {
57 FC_WE = 0x06, /* Write Enable */
58 FC_SRWE = 0x50, /* Volatile SR Write Enable */
59 FC_WD = 0x04, /* Write Disable */
60 FC_RPD = 0xAB, /* Release Power-Down, returns Device ID */
61 FC_MFGID = 0x90, /* Read Manufacturer/Device ID */
62 FC_JEDECID = 0x9F, /* Read JEDEC ID */
63 FC_UID = 0x4B, /* Read Unique ID */
64 FC_RD = 0x03, /* Read Data */
65 FC_FR = 0x0B, /* Fast Read */
66 FC_PP = 0x02, /* Page Program */
67 FC_SE = 0x20, /* Sector Erase 4kb */
68 FC_BE32 = 0x52, /* Block Erase 32kb */
69 FC_BE64 = 0xD8, /* Block Erase 64kb */
70 FC_CE = 0xC7, /* Chip Erase */
71 FC_RSR1 = 0x05, /* Read Status Register 1 */
72 FC_WSR1 = 0x01, /* Write Status Register 1 */
73 FC_RSR2 = 0x35, /* Read Status Register 2 */
74 FC_WSR2 = 0x31, /* Write Status Register 2 */
75 FC_RSR3 = 0x15, /* Read Status Register 3 */
76 FC_WSR3 = 0x11, /* Write Status Register 3 */
77 FC_RSFDP = 0x5A, /* Read SFDP Register */
78 FC_ESR = 0x44, /* Erase Security Register */
79 FC_PSR = 0x42, /* Program Security Register */
80 FC_RSR = 0x48, /* Read Security Register */
81 FC_GBL = 0x7E, /* Global Block Lock */
82 FC_GBU = 0x98, /* Global Block Unlock */
83 FC_RBL = 0x3D, /* Read Block Lock */
84 FC_RPR = 0x3C, /* Read Sector Protection Registers (adesto) */
85 FC_IBL = 0x36, /* Individual Block Lock */
86 FC_IBU = 0x39, /* Individual Block Unlock */
87 FC_EPS = 0x75, /* Erase / Program Suspend */
88 FC_EPR = 0x7A, /* Erase / Program Resume */
89 FC_PD = 0xB9, /* Power-down */
90 FC_QPI = 0x38, /* Enter QPI mode */
91 FC_ERESET = 0x66, /* Enable Reset */
92 FC_RESET = 0x99, /* Reset Device */
93 };
94
95
96 // ---------------------------------------------------------
97 // JTAG -> SPI functions
98 // ---------------------------------------------------------
99
100 /*
101 * JTAG performrs all shifts LSB first, our FLSAH is expeting bytes MSB first,
102 * There are a few ways to fix this, for now we just bit-reverse all the input data to the JTAG core
103 */
104 uint8_t bit_reverse(uint8_t in){
105
106 uint8_t out = (in & 0x01) ? 0x80 : 0x00;
107 out |= (in & 0x02) ? 0x40 : 0x00;
108 out |= (in & 0x04) ? 0x20 : 0x00;
109 out |= (in & 0x08) ? 0x10 : 0x00;
110 out |= (in & 0x10) ? 0x08 : 0x00;
111 out |= (in & 0x20) ? 0x04 : 0x00;
112 out |= (in & 0x40) ? 0x02 : 0x00;
113 out |= (in & 0x80) ? 0x01 : 0x00;
114
115 return out;
116 }
117
118 void xfer_spi(uint8_t* data, uint32_t len){
119 /* Reverse bit order of all bytes */
120 for(int i = 0; i < len; i++){
121 data[i] = bit_reverse(data[i]);
122 }
123
124 /* Don't switch states if we're already in SHIFT-DR */
125 if(jtag_current_state() != STATE_SHIFT_DR)
126 jtag_go_to_state(STATE_SHIFT_DR);
127 jtag_tap_shift(data, data, len * 8, true);
128
129 /* Reverse bit order of all return bytes */
130 for(int i = 0; i < len; i++){
131 data[i] = bit_reverse(data[i]);
132 }
133 }
134
135 void send_spi(uint8_t* data, uint32_t len){
136 uint8_t unused[len];
137
138 /* Flip bit order of all bytes */
139 for(int i = 0; i < len; i++){
140 data[i] = bit_reverse(data[i]);
141 }
142
143 jtag_go_to_state(STATE_SHIFT_DR);
144 /* Stay in SHIFT-DR state, this keep CS low */
145 jtag_tap_shift(data, unused, len * 8, false);
146 }
147
148 // ---------------------------------------------------------
149 // FLASH function implementations
150 // ---------------------------------------------------------
151
152 static void flash_read_id()
153 {
154 /* JEDEC ID structure:
155 * Byte No. | Data Type
156 * ---------+----------
157 * 0 | FC_JEDECID Request Command
158 * 1 | MFG ID
159 * 2 | Dev ID 1
160 * 3 | Dev ID 2
161 * 4 | Ext Dev Str Len
162 */
163
164 uint8_t data[260] = { FC_JEDECID };
165 int len = 5; // command + 4 response bytes
166
167 if (verbose)
168 fprintf(stderr, "read flash ID..\n");
169
170 // Write command and read first 4 bytes
171 xfer_spi(data, len);
172
173 if (data[4] == 0xFF)
174 fprintf(stderr, "Extended Device String Length is 0xFF, "
175 "this is likely a read error. Ignorig...\n");
176 else {
177 // Read extended JEDEC ID bytes
178 if (data[4] != 0) {
179 len += data[4];
180 data[0] = FC_JEDECID;
181 xfer_spi(data, len);
182 }
183 }
184
185 fprintf(stderr, "flash ID:");
186 for (int i = 1; i < len; i++)
187 fprintf(stderr, " 0x%02X", data[i]);
188 fprintf(stderr, "\n");
189 }
190
191 static void flash_reset()
192 {
193 uint8_t data[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
194 xfer_spi(data, 8);
195 }
196
197 static uint8_t flash_read_status()
198 {
199 uint8_t data[2] = { FC_RSR1 };
200
201 xfer_spi(data, 2);
202
203 if (verbose) {
204 fprintf(stderr, "SR1: 0x%02X\n", data[1]);
205 fprintf(stderr, " - SPRL: %s\n",
206 ((data[1] & (1 << 7)) == 0) ?
207 "unlocked" :
208 "locked");
209 fprintf(stderr, " - SPM: %s\n",
210 ((data[1] & (1 << 6)) == 0) ?
211 "Byte/Page Prog Mode" :
212 "Sequential Prog Mode");
213 fprintf(stderr, " - EPE: %s\n",
214 ((data[1] & (1 << 5)) == 0) ?
215 "Erase/Prog success" :
216 "Erase/Prog error");
217 fprintf(stderr, "- SPM: %s\n",
218 ((data[1] & (1 << 4)) == 0) ?
219 "~WP asserted" :
220 "~WP deasserted");
221 fprintf(stderr, " - SWP: ");
222 switch((data[1] >> 2) & 0x3) {
223 case 0:
224 fprintf(stderr, "All sectors unprotected\n");
225 break;
226 case 1:
227 fprintf(stderr, "Some sectors protected\n");
228 break;
229 case 2:
230 fprintf(stderr, "Reserved (xxxx 10xx)\n");
231 break;
232 case 3:
233 fprintf(stderr, "All sectors protected\n");
234 break;
235 }
236 fprintf(stderr, " - WEL: %s\n",
237 ((data[1] & (1 << 1)) == 0) ?
238 "Not write enabled" :
239 "Write enabled");
240 fprintf(stderr, " - ~RDY: %s\n",
241 ((data[1] & (1 << 0)) == 0) ?
242 "Ready" :
243 "Busy");
244 }
245
246 return data[1];
247 }
248
249 static void flash_write_enable()
250 {
251 if (verbose) {
252 fprintf(stderr, "status before enable:\n");
253 flash_read_status();
254 }
255
256 if (verbose)
257 fprintf(stderr, "write enable..\n");
258
259 uint8_t data[1] = { FC_WE };
260 xfer_spi(data, 1);
261
262 if (verbose) {
263 fprintf(stderr, "status after enable:\n");
264 flash_read_status();
265 }
266 }
267
268 static void flash_bulk_erase()
269 {
270 fprintf(stderr, "bulk erase..\n");
271
272 uint8_t data[1] = { FC_CE };
273 xfer_spi(data, 1);
274 }
275
276 static void flash_4kB_sector_erase(int addr)
277 {
278 fprintf(stderr, "erase 4kB sector at 0x%06X..\n", addr);
279
280 uint8_t command[4] = { FC_SE, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
281
282 xfer_spi(command, 4);
283 }
284
285 static void flash_32kB_sector_erase(int addr)
286 {
287 fprintf(stderr, "erase 64kB sector at 0x%06X..\n", addr);
288
289 uint8_t command[4] = { FC_BE32, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
290
291 xfer_spi(command, 4);
292 }
293
294 static void flash_64kB_sector_erase(int addr)
295 {
296 fprintf(stderr, "erase 64kB sector at 0x%06X..\n", addr);
297
298 uint8_t command[4] = { FC_BE64, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
299
300 xfer_spi(command, 4);
301 }
302
303 static void flash_prog(int addr, uint8_t *data, int n)
304 {
305 if (verbose)
306 fprintf(stderr, "prog 0x%06X +0x%03X..\n", addr, n);
307
308 uint8_t command[4] = { FC_PP, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
309
310 send_spi(command, 4);
311 xfer_spi(data, n);
312
313 if (verbose)
314 for (int i = 0; i < n; i++)
315 fprintf(stderr, "%02x%c", data[i], i == n - 1 || i % 32 == 31 ? '\n' : ' ');
316 }
317
318 static void flash_read(int addr, uint8_t *data, int n)
319 {
320 if (verbose)
321 fprintf(stderr, "read 0x%06X +0x%03X..\n", addr, n);
322
323 uint8_t command[4] = { FC_RD, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
324
325 send_spi(command, 4);
326 memset(data, 0, n);
327 xfer_spi(data, n);
328
329 if (verbose)
330 for (int i = 0; i < n; i++)
331 fprintf(stderr, "%02x%c", data[i], i == n - 1 || i % 32 == 31 ? '\n' : ' ');
332 }
333
334 static void flash_wait()
335 {
336 if (verbose)
337 fprintf(stderr, "waiting..");
338
339 int count = 0;
340 while (1)
341 {
342 uint8_t data[2] = { FC_RSR1 };
343
344 xfer_spi(data, 2);
345
346 if ((data[1] & 0x01) == 0) {
347 if (count < 2) {
348 count++;
349 if (verbose) {
350 fprintf(stderr, "r");
351 fflush(stderr);
352 }
353 } else {
354 if (verbose) {
355 fprintf(stderr, "R");
356 fflush(stderr);
357 }
358 break;
359 }
360 } else {
361 if (verbose) {
362 fprintf(stderr, ".");
363 fflush(stderr);
364 }
365 count = 0;
366 }
367
368 usleep(1000);
369 }
370
371 if (verbose)
372 fprintf(stderr, "\n");
373
374 }
375
376 static void flash_disable_protection()
377 {
378 fprintf(stderr, "disable flash protection...\n");
379
380 // Write Status Register 1 <- 0x00
381 uint8_t data[2] = { FC_WSR1, 0x00 };
382 xfer_spi(data, 2);
383
384 flash_wait();
385
386 // Read Status Register 1
387 data[0] = FC_RSR1;
388
389 xfer_spi(data, 2);
390
391 if (data[1] != 0x00)
392 fprintf(stderr, "failed to disable protection, SR now equal to 0x%02x (expected 0x00)\n", data[1]);
393
394 }
395
396 // ---------------------------------------------------------
397 // ECP5 specific JTAG functions
398 // ---------------------------------------------------------
399
400
401 static void print_idcode(uint32_t idcode){
402 for(int i = 0; i < sizeof(ecp_devices)/sizeof(struct ecp_device_id); i++){
403 if(idcode == ecp_devices[i].device_id)
404 {
405 printf("IDCODE: 0x%08x (%s)\n", idcode ,ecp_devices[i].device_name);
406 return;
407 }
408 }
409 printf("IDCODE: 0x%08x does not match :(\n", idcode);
410 }
411
412 static void read_idcode(){
413
414 uint8_t data[4] = {READ_ID};
415
416 jtag_go_to_state(STATE_SHIFT_IR);
417 jtag_tap_shift(data, data, 8, true);
418
419 data[0] = 0;
420 jtag_go_to_state(STATE_SHIFT_DR);
421 jtag_tap_shift(data, data, 32, true);
422
423 uint32_t idcode = 0;
424
425 /* Format the IDCODE into a 32bit value */
426 for(int i = 0; i< 4; i++)
427 idcode = data[i] << 24 | idcode >> 8;
428
429 print_idcode(idcode);
430 }
431
432
433 static void print_status_register(uint32_t status){
434 printf("ECP5 Status Register: 0x%08x\n", status);
435
436 if(verbose){
437 printf(" Transparent Mode: %s\n", status & (1 << 0) ? "Yes" : "No" );
438 printf(" Config Target: %s\n", status & (7 << 1) ? "eFuse" : "SRAM" );
439 printf(" JTAG Active: %s\n", status & (1 << 4) ? "Yes" : "No" );
440 printf(" PWD Protection: %s\n", status & (1 << 5) ? "Yes" : "No" );
441 printf(" Decrypt Enable: %s\n", status & (1 << 7) ? "Yes" : "No" );
442 printf(" DONE: %s\n", status & (1 << 8) ? "Yes" : "No" );
443 printf(" ISC Enable: %s\n", status & (1 << 9) ? "Yes" : "No" );
444 printf(" Write Enable: %s\n", status & (1 << 10) ? "Writable" : "Not Writable");
445 printf(" Read Enable: %s\n", status & (1 << 11) ? "Readable" : "Not Readable");
446 printf(" Busy Flag: %s\n", status & (1 << 12) ? "Yes" : "No" );
447 printf(" Fail Flag: %s\n", status & (1 << 13) ? "Yes" : "No" );
448 printf(" Feature OTP: %s\n", status & (1 << 14) ? "Yes" : "No" );
449 printf(" Decrypt Only: %s\n", status & (1 << 15) ? "Yes" : "No" );
450 printf(" PWD Enable: %s\n", status & (1 << 16) ? "Yes" : "No" );
451 printf(" Encrypt Preamble: %s\n", status & (1 << 20) ? "Yes" : "No" );
452 printf(" Std Preamble: %s\n", status & (1 << 21) ? "Yes" : "No" );
453 printf(" SPIm Fail 1: %s\n", status & (1 << 22) ? "Yes" : "No" );
454
455 uint8_t bse_error = (status & (7 << 23)) >> 23;
456 switch (bse_error){
457 case 0b000: printf(" BSE Error Code: No Error (0b000)\n"); break;
458 case 0b001: printf(" BSE Error Code: ID Error (0b001)\n"); break;
459 case 0b010: printf(" BSE Error Code: CMD Error - illegal command (0b010)\n"); break;
460 case 0b011: printf(" BSE Error Code: CRC Error (0b011)\n"); break;
461 case 0b100: printf(" BSE Error Code: PRMB Error - preamble error (0b100)\n"); break;
462 case 0b101: printf(" BSE Error Code: ABRT Error - configuration aborted by the user (0b101)\n"); break;
463 case 0b110: printf(" BSE Error Code: OVFL Error - data overflow error (0b110)\n"); break;
464 case 0b111: printf(" BSE Error Code: SDM Error - bitstream pass the size of SRAM array (0b111)\n"); break;
465 }
466
467 printf(" Execution Error: %s\n", status & (1 << 26) ? "Yes" : "No" );
468 printf(" ID Error: %s\n", status & (1 << 27) ? "Yes" : "No" );
469 printf(" Invalid Command: %s\n", status & (1 << 28) ? "Yes" : "No" );
470 printf(" SED Error: %s\n", status & (1 << 29) ? "Yes" : "No" );
471 printf(" Bypass Mode: %s\n", status & (1 << 30) ? "Yes" : "No" );
472 printf(" Flow Through Mode: %s\n", status & (1 << 31) ? "Yes" : "No" );
473 }
474 }
475
476
477 static void read_status_register(){
478
479 uint8_t data[4] = {LSC_READ_STATUS};
480
481 jtag_go_to_state(STATE_SHIFT_IR);
482 jtag_tap_shift(data, data, 8, true);
483
484 data[0] = 0;
485 jtag_go_to_state(STATE_SHIFT_DR);
486 jtag_tap_shift(data, data, 32, true);
487
488 uint32_t status = 0;
489
490 /* Format the IDCODE into a 32bit value */
491 for(int i = 0; i< 4; i++)
492 status = data[i] << 24 | status >> 8;
493
494 print_status_register(status);
495 }
496
497
498
499 static void enter_spi_background_mode(){
500
501 uint8_t data_in[4] = {0,0,0,0};
502 uint8_t data_out[4] = {0,0,0,0};
503
504 data_in[0] = 0x3A;
505 jtag_go_to_state(STATE_SHIFT_IR);
506 jtag_tap_shift(data_in, data_out, 8, true);
507
508 /* These bytes seem to be required to un-lock the SPI interface */
509 data_in[0] = 0xFE;
510 data_in[1] = 0x68;
511 jtag_go_to_state(STATE_SHIFT_DR);
512 jtag_tap_shift(data_in, data_out, 16, true);
513
514 /* Entering IDLE is essential */
515 jtag_go_to_state(STATE_RUN_TEST_IDLE);
516 }
517
518
519 void ecp_jtag_cmd(uint8_t cmd){
520 uint8_t data[1] = {cmd};
521
522 jtag_go_to_state(STATE_SHIFT_IR);
523 jtag_tap_shift(data, data, 8, true);
524
525 jtag_go_to_state(STATE_RUN_TEST_IDLE);
526 jtag_wait_time(10);
527 }
528
529 // ---------------------------------------------------------
530 // iceprog implementation
531 // ---------------------------------------------------------
532
533 static void help(const char *progname)
534 {
535 fprintf(stderr, "Simple programming tool for FTDI-based Lattice ECP JTAG programmers.\n");
536 fprintf(stderr, "Usage: %s [-b|-n|-c] <input file>\n", progname);
537 fprintf(stderr, " %s -r|-R<bytes> <output file>\n", progname);
538 fprintf(stderr, " %s -S <input file>\n", progname);
539 fprintf(stderr, " %s -t\n", progname);
540 fprintf(stderr, "\n");
541 fprintf(stderr, "General options:\n");
542 fprintf(stderr, " -d <device string> use the specified USB device [default: i:0x0403:0x6010 or i:0x0403:0x6014]\n");
543 fprintf(stderr, " d:<devicenode> (e.g. d:002/005)\n");
544 fprintf(stderr, " i:<vendor>:<product> (e.g. i:0x0403:0x6010)\n");
545 fprintf(stderr, " i:<vendor>:<product>:<index> (e.g. i:0x0403:0x6010:0)\n");
546 fprintf(stderr, " s:<vendor>:<product>:<serial-string>\n");
547 fprintf(stderr, " -I [ABCD] connect to the specified interface on the FTDI chip\n");
548 fprintf(stderr, " [default: A]\n");
549 fprintf(stderr, " -o <offset in bytes> start address for read/write [default: 0]\n");
550 fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n");
551 fprintf(stderr, " or 'M' for size in megabytes)\n");
552 fprintf(stderr, " -s slow SPI (50 kHz instead of 6 MHz)\n");
553 fprintf(stderr, " -v verbose output\n");
554 fprintf(stderr, " -i [4,32,64] select erase block size [default: 64k]\n");
555 fprintf(stderr, "\n");
556 fprintf(stderr, "Mode of operation:\n");
557 fprintf(stderr, " [default] write file contents to flash, then verify\n");
558 fprintf(stderr, " -X write file contents to flash only\n");
559 fprintf(stderr, " -r read first 256 kB from flash and write to file\n");
560 fprintf(stderr, " -R <size in bytes> read the specified number of bytes from flash\n");
561 fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n");
562 fprintf(stderr, " or 'M' for size in megabytes)\n");
563 fprintf(stderr, " -c do not write flash, only verify (`check')\n");
564 fprintf(stderr, " -S perform SRAM programming\n");
565 fprintf(stderr, " -t just read the flash ID sequence\n");
566 fprintf(stderr, "\n");
567 fprintf(stderr, "Erase mode (only meaningful in default mode):\n");
568 fprintf(stderr, " [default] erase aligned chunks of 64kB in write mode\n");
569 fprintf(stderr, " This means that some data after the written data (or\n");
570 fprintf(stderr, " even before when -o is used) may be erased as well.\n");
571 fprintf(stderr, " -b bulk erase entire flash before writing\n");
572 fprintf(stderr, " -e <size in bytes> erase flash as if we were writing that number of bytes\n");
573 fprintf(stderr, " -n do not erase flash before writing\n");
574 fprintf(stderr, " -p disable write protection before erasing or writing\n");
575 fprintf(stderr, " This can be useful if flash memory appears to be\n");
576 fprintf(stderr, " bricked and won't respond to erasing or programming.\n");
577 fprintf(stderr, "\n");
578 fprintf(stderr, "Miscellaneous options:\n");
579 fprintf(stderr, " --help display this help and exit\n");
580 fprintf(stderr, " -- treat all remaining arguments as filenames\n");
581 fprintf(stderr, "\n");
582 fprintf(stderr, "Exit status:\n");
583 fprintf(stderr, " 0 on success,\n");
584 fprintf(stderr, " 1 if a non-hardware error occurred (e.g., failure to read from or\n");
585 fprintf(stderr, " write to a file, or invoked with invalid options),\n");
586 fprintf(stderr, " 2 if communication with the hardware failed (e.g., cannot find the\n");
587 fprintf(stderr, " iCE FTDI USB device),\n");
588 fprintf(stderr, " 3 if verification of the data failed.\n");
589 fprintf(stderr, "\n");
590 fprintf(stderr, "If you have a bug report, please file an issue on github:\n");
591 fprintf(stderr, " https://github.com/gregdavill/ecpprog/issues\n");
592 }
593
594 int main(int argc, char **argv)
595 {
596 /* used for error reporting */
597 const char *my_name = argv[0];
598 for (size_t i = 0; argv[0][i]; i++)
599 if (argv[0][i] == '/')
600 my_name = argv[0] + i + 1;
601
602 int read_size = 256 * 1024;
603 int erase_block_size = 64;
604 int erase_size = 0;
605 int rw_offset = 0;
606
607 bool read_mode = false;
608 bool check_mode = false;
609 bool erase_mode = false;
610 bool bulk_erase = false;
611 bool dont_erase = false;
612 bool prog_sram = false;
613 bool test_mode = false;
614 bool slow_clock = false;
615 bool disable_protect = false;
616 bool disable_verify = false;
617 const char *filename = NULL;
618 const char *devstr = NULL;
619 int ifnum = 0;
620
621 #ifdef _WIN32
622 _setmode(_fileno(stdin), _O_BINARY);
623 _setmode(_fileno(stdout), _O_BINARY);
624 #endif
625
626 static struct option long_options[] = {
627 {"help", no_argument, NULL, -2},
628 {NULL, 0, NULL, 0}
629 };
630
631 /* Decode command line parameters */
632 int opt;
633 char *endptr;
634 while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:cbnStvspX", long_options, NULL)) != -1) {
635 switch (opt) {
636 case 'd': /* device string */
637 devstr = optarg;
638 break;
639 case 'i': /* block erase size */
640 if (!strcmp(optarg, "4"))
641 erase_block_size = 4;
642 else if (!strcmp(optarg, "32"))
643 erase_block_size = 32;
644 else if (!strcmp(optarg, "64"))
645 erase_block_size = 64;
646 else {
647 fprintf(stderr, "%s: `%s' is not a valid erase block size (must be `4', `32' or `64')\n", my_name, optarg);
648 return EXIT_FAILURE;
649 }
650 break;
651 case 'I': /* FTDI Chip interface select */
652 if (!strcmp(optarg, "A"))
653 ifnum = 0;
654 else if (!strcmp(optarg, "B"))
655 ifnum = 1;
656 else if (!strcmp(optarg, "C"))
657 ifnum = 2;
658 else if (!strcmp(optarg, "D"))
659 ifnum = 3;
660 else {
661 fprintf(stderr, "%s: `%s' is not a valid interface (must be `A', `B', `C', or `D')\n", my_name, optarg);
662 return EXIT_FAILURE;
663 }
664 break;
665 case 'r': /* Read 256 bytes to file */
666 read_mode = true;
667 break;
668 case 'R': /* Read n bytes to file */
669 read_mode = true;
670 read_size = strtol(optarg, &endptr, 0);
671 if (*endptr == '\0')
672 /* ok */;
673 else if (!strcmp(endptr, "k"))
674 read_size *= 1024;
675 else if (!strcmp(endptr, "M"))
676 read_size *= 1024 * 1024;
677 else {
678 fprintf(stderr, "%s: `%s' is not a valid size\n", my_name, optarg);
679 return EXIT_FAILURE;
680 }
681 break;
682 case 'e': /* Erase blocks as if we were writing n bytes */
683 erase_mode = true;
684 erase_size = strtol(optarg, &endptr, 0);
685 if (*endptr == '\0')
686 /* ok */;
687 else if (!strcmp(endptr, "k"))
688 erase_size *= 1024;
689 else if (!strcmp(endptr, "M"))
690 erase_size *= 1024 * 1024;
691 else {
692 fprintf(stderr, "%s: `%s' is not a valid size\n", my_name, optarg);
693 return EXIT_FAILURE;
694 }
695 break;
696 case 'o': /* set address offset */
697 rw_offset = strtol(optarg, &endptr, 0);
698 if (*endptr == '\0')
699 /* ok */;
700 else if (!strcmp(endptr, "k"))
701 rw_offset *= 1024;
702 else if (!strcmp(endptr, "M"))
703 rw_offset *= 1024 * 1024;
704 else {
705 fprintf(stderr, "%s: `%s' is not a valid offset\n", my_name, optarg);
706 return EXIT_FAILURE;
707 }
708 break;
709 case 'c': /* do not write just check */
710 check_mode = true;
711 break;
712 case 'b': /* bulk erase before writing */
713 bulk_erase = true;
714 break;
715 case 'n': /* do not erase before writing */
716 dont_erase = true;
717 break;
718 case 'S': /* write to sram directly */
719 prog_sram = true;
720 break;
721 case 't': /* just read flash id */
722 test_mode = true;
723 break;
724 case 'v': /* provide verbose output */
725 verbose = true;
726 break;
727 case 's': /* use slow SPI clock */
728 slow_clock = true;
729 break;
730 case 'p': /* disable flash protect before erase/write */
731 disable_protect = true;
732 break;
733 case 'X': /* disable verification */
734 disable_verify = true;
735 break;
736 case -2:
737 help(argv[0]);
738 return EXIT_SUCCESS;
739 default:
740 /* error message has already been printed */
741 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
742 return EXIT_FAILURE;
743 }
744 }
745
746 /* Make sure that the combination of provided parameters makes sense */
747
748 if (read_mode + erase_mode + check_mode + prog_sram + test_mode > 1) {
749 fprintf(stderr, "%s: options `-r'/`-R', `-e`, `-c', `-S', and `-t' are mutually exclusive\n", my_name);
750 return EXIT_FAILURE;
751 }
752
753 if (bulk_erase && dont_erase) {
754 fprintf(stderr, "%s: options `-b' and `-n' are mutually exclusive\n", my_name);
755 return EXIT_FAILURE;
756 }
757
758 if (disable_protect && (read_mode || check_mode || prog_sram || test_mode)) {
759 fprintf(stderr, "%s: option `-p' only valid in programming mode\n", my_name);
760 return EXIT_FAILURE;
761 }
762
763 if (bulk_erase && (read_mode || check_mode || prog_sram || test_mode)) {
764 fprintf(stderr, "%s: option `-b' only valid in programming mode\n", my_name);
765 return EXIT_FAILURE;
766 }
767
768 if (dont_erase && (read_mode || check_mode || prog_sram || test_mode)) {
769 fprintf(stderr, "%s: option `-n' only valid in programming mode\n", my_name);
770 return EXIT_FAILURE;
771 }
772
773 if (rw_offset != 0 && prog_sram) {
774 fprintf(stderr, "%s: option `-o' not supported in SRAM mode\n", my_name);
775 return EXIT_FAILURE;
776 }
777
778 if (rw_offset != 0 && test_mode) {
779 fprintf(stderr, "%s: option `-o' not supported in test mode\n", my_name);
780 return EXIT_FAILURE;
781 }
782
783 if (optind + 1 == argc) {
784 if (test_mode) {
785 fprintf(stderr, "%s: test mode doesn't take a file name\n", my_name);
786 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
787 return EXIT_FAILURE;
788 }
789 filename = argv[optind];
790 } else if (optind != argc) {
791 fprintf(stderr, "%s: too many arguments\n", my_name);
792 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
793 return EXIT_FAILURE;
794 } else if (bulk_erase || disable_protect) {
795 filename = "/dev/null";
796 } else if (!test_mode && !erase_mode && !disable_protect) {
797 fprintf(stderr, "%s: missing argument\n", my_name);
798 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
799 return EXIT_FAILURE;
800 }
801
802 /* open input/output file in advance
803 so we can fail before initializing the hardware */
804
805 FILE *f = NULL;
806 long file_size = -1;
807
808 if (test_mode) {
809 /* nop */;
810 } else if (erase_mode) {
811 file_size = erase_size;
812 } else if (read_mode) {
813 f = (strcmp(filename, "-") == 0) ? stdout : fopen(filename, "wb");
814 if (f == NULL) {
815 fprintf(stderr, "%s: can't open '%s' for writing: ", my_name, filename);
816 perror(0);
817 return EXIT_FAILURE;
818 }
819 } else {
820 f = (strcmp(filename, "-") == 0) ? stdin : fopen(filename, "rb");
821 if (f == NULL) {
822 fprintf(stderr, "%s: can't open '%s' for reading: ", my_name, filename);
823 perror(0);
824 return EXIT_FAILURE;
825 }
826
827 /* For regular programming, we need to read the file
828 twice--once for programming and once for verifying--and
829 need to know the file size in advance in order to erase
830 the correct amount of memory.
831
832 See if we can seek on the input file. Checking for "-"
833 as an argument isn't enough as we might be reading from a
834 named pipe, or contrarily, the standard input may be an
835 ordinary file. */
836
837 if (!prog_sram && !check_mode) {
838 if (fseek(f, 0L, SEEK_END) != -1) {
839 file_size = ftell(f);
840 if (file_size == -1) {
841 fprintf(stderr, "%s: %s: ftell: ", my_name, filename);
842 perror(0);
843 return EXIT_FAILURE;
844 }
845 if (fseek(f, 0L, SEEK_SET) == -1) {
846 fprintf(stderr, "%s: %s: fseek: ", my_name, filename);
847 perror(0);
848 return EXIT_FAILURE;
849 }
850 } else {
851 FILE *pipe = f;
852
853 f = tmpfile();
854 if (f == NULL) {
855 fprintf(stderr, "%s: can't open temporary file\n", my_name);
856 return EXIT_FAILURE;
857 }
858 file_size = 0;
859
860 while (true) {
861 static unsigned char buffer[4096];
862 size_t rc = fread(buffer, 1, 4096, pipe);
863 if (rc <= 0)
864 break;
865 size_t wc = fwrite(buffer, 1, rc, f);
866 if (wc != rc) {
867 fprintf(stderr, "%s: can't write to temporary file\n", my_name);
868 return EXIT_FAILURE;
869 }
870 file_size += rc;
871 }
872 fclose(pipe);
873
874 /* now seek to the beginning so we can
875 start reading again */
876 fseek(f, 0, SEEK_SET);
877 }
878 }
879 }
880
881 // ---------------------------------------------------------
882 // Initialize USB connection to FT2232H
883 // ---------------------------------------------------------
884
885 fprintf(stderr, "init..");
886 jtag_init(ifnum, devstr, slow_clock);
887
888 fprintf(stderr, "idcode..\n");
889 read_idcode();
890
891 fprintf(stderr, "status..\n");
892 read_status_register();
893
894
895 /* Reset ECP5 to release SPI interface */
896 ecp_jtag_cmd(ISC_ENABLE);
897 ecp_jtag_cmd(ISC_ERASE);
898 ecp_jtag_cmd(ISC_DISABLE);
899
900 /* Put device into SPI bypass mode */
901 enter_spi_background_mode();
902 //usleep(20000);
903
904 if (test_mode)
905 {
906
907
908 flash_reset();
909 flash_read_id();
910 }
911 else if (prog_sram)
912 {
913 // ---------------------------------------------------------
914 // Reset
915 // ---------------------------------------------------------
916
917 fprintf(stderr, "Not Supported yet\n");
918 fprintf(stderr, "reset..\n");
919
920 //sram_reset();
921 usleep(100);
922
923 //sram_chip_select();
924 usleep(2000);
925
926
927 // ---------------------------------------------------------
928 // Program
929 // ---------------------------------------------------------
930
931 fprintf(stderr, "programming..\n");
932 while (1) {
933 static unsigned char buffer[4096];
934 int rc = fread(buffer, 1, 4096, f);
935 if (rc <= 0)
936 break;
937 if (verbose)
938 fprintf(stderr, "sending %d bytes.\n", rc);
939 //mpsse_send_spi(buffer, rc);
940 }
941
942 //mpsse_send_dummy_bytes(6);
943 //mpsse_send_dummy_bit();
944
945
946 }
947 else /* program flash */
948 {
949 // ---------------------------------------------------------
950 // Reset
951 // ---------------------------------------------------------
952
953 fprintf(stderr, "reset..\n");
954
955 //flash_chip_deselect();
956 usleep(250000);
957
958
959
960 flash_reset();
961
962 flash_read_id();
963
964
965 // ---------------------------------------------------------
966 // Program
967 // ---------------------------------------------------------
968
969 if (!read_mode && !check_mode)
970 {
971 if (disable_protect)
972 {
973 flash_write_enable();
974 flash_disable_protection();
975 }
976
977 if (!dont_erase)
978 {
979 if (bulk_erase)
980 {
981 flash_write_enable();
982 flash_bulk_erase();
983 flash_wait();
984 }
985 else
986 {
987 fprintf(stderr, "file size: %ld\n", file_size);
988
989 int block_size = erase_block_size << 10;
990 int block_mask = block_size - 1;
991 int begin_addr = rw_offset & ~block_mask;
992 int end_addr = (rw_offset + file_size + block_mask) & ~block_mask;
993
994 for (int addr = begin_addr; addr < end_addr; addr += block_size) {
995 flash_write_enable();
996 switch(erase_block_size) {
997 case 4:
998 flash_4kB_sector_erase(addr);
999 break;
1000 case 32:
1001 flash_32kB_sector_erase(addr);
1002 break;
1003 case 64:
1004 flash_64kB_sector_erase(addr);
1005 break;
1006 }
1007 if (verbose) {
1008 fprintf(stderr, "Status after block erase:\n");
1009 flash_read_status();
1010 }
1011 flash_wait();
1012 }
1013 }
1014 }
1015
1016 if (!erase_mode)
1017 {
1018 fprintf(stderr, "programming..\n");
1019
1020 for (int rc, addr = 0; true; addr += rc) {
1021 uint8_t buffer[256];
1022 int page_size = 256 - (rw_offset + addr) % 256;
1023 rc = fread(buffer, 1, page_size, f);
1024 if (rc <= 0)
1025 break;
1026 flash_write_enable();
1027 flash_prog(rw_offset + addr, buffer, rc);
1028 flash_wait();
1029 }
1030
1031 /* seek to the beginning for second pass */
1032 fseek(f, 0, SEEK_SET);
1033 }
1034 }
1035
1036 // ---------------------------------------------------------
1037 // Read/Verify
1038 // ---------------------------------------------------------
1039
1040 if (read_mode) {
1041 fprintf(stderr, "reading..\n");
1042 for (int addr = 0; addr < read_size; addr += 256) {
1043 uint8_t buffer[256];
1044 flash_read(rw_offset + addr, buffer, 256);
1045 fwrite(buffer, read_size - addr > 256 ? 256 : read_size - addr, 1, f);
1046 }
1047 } else if (!erase_mode && !disable_verify) {
1048 fprintf(stderr, "reading..\n");
1049 for (int addr = 0; true; addr += 256) {
1050 uint8_t buffer_flash[256], buffer_file[256];
1051 int rc = fread(buffer_file, 1, 256, f);
1052 if (rc <= 0)
1053 break;
1054 flash_read(rw_offset + addr, buffer_flash, rc);
1055 if (memcmp(buffer_file, buffer_flash, rc)) {
1056 fprintf(stderr, "Found difference between flash and file!\n");
1057 jtag_error(3);
1058 }
1059 }
1060
1061 fprintf(stderr, "VERIFY OK\n");
1062 }
1063 }
1064
1065 if (f != NULL && f != stdin && f != stdout)
1066 fclose(f);
1067
1068 // ---------------------------------------------------------
1069 // Exit
1070 // ---------------------------------------------------------
1071
1072 fprintf(stderr, "Bye.\n");
1073 jtag_deinit();
1074 return 0;
1075 }