changeset 666:51bcfb251b23

fc-loadtool flash program-m0 changed to use binary protocol
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 07 Mar 2020 19:28:09 +0000
parents b43d8c2725b9
children 2772cf8435b4
files loadtools/chainload.c loadtools/flprogbin.c loadtools/flprogsrec.c
diffstat 3 files changed, 55 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/chainload.c	Sat Mar 07 18:34:39 2020 +0000
+++ b/loadtools/chainload.c	Sat Mar 07 19:28:09 2020 +0000
@@ -9,6 +9,7 @@
 #include <string.h>
 #include <strings.h>
 #include <time.h>
+#include <unistd.h>
 #include "../libserial/baudrate.h"
 #include "discontig.h"
 #include "srecreader.h"
--- a/loadtools/flprogbin.c	Sat Mar 07 18:34:39 2020 +0000
+++ b/loadtools/flprogbin.c	Sat Mar 07 19:28:09 2020 +0000
@@ -9,6 +9,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <time.h>
+#include <unistd.h>
 #include "flash.h"
 
 extern int target_fd;
--- a/loadtools/flprogsrec.c	Sat Mar 07 18:34:39 2020 +0000
+++ b/loadtools/flprogsrec.c	Sat Mar 07 19:28:09 2020 +0000
@@ -8,10 +8,13 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <time.h>
+#include <unistd.h>
 #include "flash.h"
 #include "discontig.h"
 #include "srecreader.h"
 
+extern int target_fd;
+
 extern struct flash_bank_info flash_bank_info[2];
 extern uint32_t crc32_table[];
 
@@ -191,8 +194,8 @@
 	unsigned nregions, reg;
 	uint32_t total_len, bytesdone, addr, len;
 	FILE *tmpfile;
-	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, rc;
 	time_t initial_time, curtime, last_time;
 	unsigned duration, mm, ss;
@@ -225,11 +228,15 @@
 		return(-1);
 	}
 	rewind(tmpfile);
-	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(tmpfile);
+		return(-1);
+	}
 	printf("Programming flash\n");
+	databuf[0] = 0x01;
 	bytesdone = 0;
 	last_time = 0;
 	time(&initial_time);
@@ -237,30 +244,51 @@
 		addr = regp->start;
 		len = regp->end - addr;
 		while (len) {
-			if (len >= 256)
-				reclen = 256;
+			if (len >= 2048)
+				reclen = 2048;
 			else
 				reclen = len;
-			cc = fread(databuf, 1, reclen, tmpfile);
+			cc = fread(databuf + 7, 1, reclen, tmpfile);
 			if (cc != reclen) {
 				fclose(tmpfile);
 				fprintf(stderr,
 					"error reading from temp file!\n");
+				/* don't leave loadagent in binary flash mode */
+				databuf[0] = 0x04;
+				write(target_fd, databuf, 1);
+				tpinterf_pass_output(1);
 				return(-1);
 			}
-			sprintf(shortarg, "%lx", addr);
-			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] = addr >> 24;
+			databuf[2] = addr >> 16;
+			databuf[3] = addr >> 8;
+			databuf[4] = addr;
+			databuf[5] = reclen >> 8;
+			databuf[6] = reclen;
+			cc = write(target_fd, databuf, reclen + 7);
+			if (cc != reclen + 7) {
 				fclose(tmpfile);
+				perror("binary write to target");
 				return(-1);
 			}
-			rc = tpinterf_pass_output(8);	/* 8 s timeout */
+			rc = collect_binblock_from_target(&ackbyte, 1, 8);
 			if (rc) {
 				fclose(tmpfile);
 				return(rc);
 			}
+			if (ackbyte == 0x15) {	/* NAK */
+				fclose(tmpfile);
+				tpinterf_pass_output(1);
+				return(-1);
+			}
+			if (ackbyte != 0x06) {	/* ACK */
+				fclose(tmpfile);
+				fprintf(stderr,
+				"binary protocol error: bad ack 0x%02X\n",
+					ackbyte);
+				return(-1);
+			}
 			addr += reclen;
 			len -= reclen;
 			bytesdone += reclen;
@@ -276,6 +304,16 @@
 	}
 	putchar('\n');
 	fclose(tmpfile);
+	databuf[0] = 0x04;	/* EOT */
+	write(target_fd, databuf, 1);
+	rc = collect_binblock_from_target(&ackbyte, 1, 1);
+	if (rc)
+		return(rc);
+	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;