changeset 665:b43d8c2725b9

fc-loadtool flash program-bin changed to use binary protocol
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 07 Mar 2020 18:34:39 +0000
parents 77a0001d8849
children 51bcfb251b23
files loadtools/flprogbin.c
diffstat 1 files changed, 53 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/flprogbin.c	Sat Mar 07 17:58:49 2020 +0000
+++ b/loadtools/flprogbin.c	Sat Mar 07 18:34:39 2020 +0000
@@ -11,6 +11,8 @@
 #include <time.h>
 #include "flash.h"
 
+extern int target_fd;
+
 extern struct flash_bank_info flash_bank_info[2];
 extern uint32_t crc32_table[];
 
@@ -24,8 +26,8 @@
 	char *strtoul_endp;
 	FILE *binf;
 	struct stat filestat;
-	char *targv[4], shortarg[10], longarg[513];
-	u_char databuf[256];
+	char *targv[3], shortarg[10];
+	u_char databuf[2048 + 7], ackbyte;
 	int reclen, cc, i;
 	time_t initial_time, curtime, last_time;
 	unsigned duration, mm, ss;
@@ -131,42 +133,68 @@
 		return(-1);
 	}
 	fseek(binf, fileoff, SEEK_SET);
-	targv[0] = bi->ops->loadagent_program_cmd;
-	targv[1] = shortarg;
-	targv[2] = longarg;
-	targv[3] = 0;
+	targv[0] = bi->ops->loadagent_binmode_cmd;
+	targv[1] = 0;
+	tpinterf_make_cmd(targv);
+	if (tpinterf_send_cmd() < 0) {
+		fclose(binf);
+		return(-1);
+	}
 	printf("Programming flash: %lu (0x%lx) bytes\n", len, len);
+	databuf[0] = 0x01;
 	origlen = len;
 	bytesdone = 0;
 	last_time = 0;
 	crcaccum = 0xFFFFFFFF;
 	time(&initial_time);
 	while (len) {
-		if (len >= 256)
-			reclen = 256;
+		if (len >= 2048)
+			reclen = 2048;
 		else
 			reclen = len;
-		cc = fread(databuf, 1, reclen, binf);
+		cc = fread(databuf + 7, 1, reclen, binf);
 		if (cc != reclen) {
 			fclose(binf);
 			fprintf(stderr, "error reading from %s\n", argv[3]);
+			/* don't leave loadagent in binary flash mode */
+			databuf[0] = 0x04;
+			write(target_fd, databuf, 1);
+			tpinterf_pass_output(1);
 			return(-1);
 		}
 		for (i = 0; i < reclen; i++)	/* update running CRC */
-			crcaccum = crc32_table[crcaccum & 0xFF ^ databuf[i]]
+			crcaccum = crc32_table[crcaccum & 0xFF ^ databuf[i+7]]
 				^ (crcaccum >> 8);
-		sprintf(shortarg, "%lx", flashoff);
-		build_flashw_hex_string(databuf, longarg, reclen >> 1, 0);
-		tpinterf_make_cmd(targv);
-		if (tpinterf_send_cmd() < 0) {
+		/* binary flash write command to loadagent */
+		databuf[1] = flashoff >> 24;
+		databuf[2] = flashoff >> 16;
+		databuf[3] = flashoff >> 8;
+		databuf[4] = flashoff;
+		databuf[5] = reclen >> 8;
+		databuf[6] = reclen;
+		cc = write(target_fd, databuf, reclen + 7);
+		if (cc != reclen + 7) {
 			fclose(binf);
+			perror("binary write to target");
 			return(-1);
 		}
-		i = tpinterf_pass_output(8);	/* 8 s timeout */
+		i = collect_binblock_from_target(&ackbyte, 1, 8);
 		if (i) {
 			fclose(binf);
 			return(i);
 		}
+		if (ackbyte == 0x15) {	/* NAK */
+			fclose(binf);
+			tpinterf_pass_output(1);
+			return(-1);
+		}
+		if (ackbyte != 0x06) {	/* ACK */
+			fclose(binf);
+			fprintf(stderr,
+				"binary protocol error: bad ack 0x%02X\n",
+				ackbyte);
+			return(-1);
+		}
 		flashoff += reclen;
 		len -= reclen;
 		bytesdone += reclen;
@@ -181,6 +209,16 @@
 	}
 	putchar('\n');
 	fclose(binf);
+	databuf[0] = 0x04;	/* EOT */
+	write(target_fd, databuf, 1);
+	i = collect_binblock_from_target(&ackbyte, 1, 1);
+	if (i)
+		return(i);
+	time(&last_time);
+	if (ackbyte != '=') {
+		fprintf(stderr, "error: \'=\' not received as expected\n");
+		return(-1);
+	}
 	duration = last_time - initial_time;
 	mm = duration / 60;
 	ss = duration - mm * 60;