shithub: stm32up

Download patch

ref: 4ff7f599491c5d29de20583490b5dc4b8d43c8fc
parent: 252d709ce24e5544d9a6fc6faea2adf861c957ff
author: k <k@santiago>
date: Mon Oct 30 15:43:43 EDT 2023

new commands; now can flash

--- a/README.md
+++ b/README.md
@@ -10,6 +10,8 @@
 	info	- get device information and id
 	read	- read device memory
 	write	- write device memory
+	erase	- erase memory
+	flash	- erase everything, write, and go
 	go		- jump to address
 	readp	- protect memory from reads
 	readunp	- unprotect memory from reads
--- a/stm32up.c
+++ b/stm32up.c
@@ -8,6 +8,8 @@
 	Doinfo,
 	Doread,
 	Dowrite,
+	Doerase,
+	Doflash,
 	Dogo,
 	Doreadprot,
 	Doreadunprot,
@@ -47,18 +49,18 @@
 
 	// get the protocol version and commands
 	buf[0] = Get; buf[1] = Full ^ Get;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write: %r\n");
-		exits("protoerr");;
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
 		fprint(2, "'get' rejected\n");
-		exits("protoerr");;
+		exits("protoerr");
 	}
 	if(readn(dev, buf, 14) == 0 || buf[0] != 11 || buf[13] != Ack) {
 		fprint(2, "protocol error while getting device info\n");
-		exits("protoerr");;
+		exits("protoerr");
 	}
 
 	fprint(2, "protocol version: %x\n", buf[1]);
@@ -88,7 +90,7 @@
 	if(debug)
 		fprint(2, "getting device id\n");
 	buf[0] = Getid; buf[1] = Full ^ Getid;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write\n");
 		exits("protoerr");;
 	}
@@ -124,9 +126,9 @@
 		fprint(2, "%s device\n", cmds);
 
 	buf[0] = cmd; buf[1] = Full ^ cmd;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");;
+		exits("deverr");;
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -135,9 +137,9 @@
 	}
 
 	buf[0] = Ack;
-	if(write(dev, buf, 1) < 0) {
+	if(write(dev, buf, 1) != 1) {
 		fprint(2, "unable to ack %s", cmds);
-		exits("protoerr");;
+		exits("deverr");;
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -157,9 +159,9 @@
 	}
 
 	buf[0] = Read; buf[1] = Full ^ Read;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -174,9 +176,9 @@
 	buf[3] = addr & 0xFF;
 	buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
 
-	if(write(dev, buf, 5) < 0) {
+	if(write(dev, buf, 5) != 5) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -187,9 +189,9 @@
 	// send the size
 	buf[0] = sz; buf[1] = Full ^ buf[0];
 
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -207,21 +209,21 @@
 }
 
 void
-stm_writepage(int dev, uvlong addr, uchar sz) // size - 1
+stm_writepage(int dev, uvlong addr, uchar sz)
 {
-	if(addr + (sz + 1) < addr) {
+	if(addr + sz < addr) {
 		fprint(2, "addr + sz < addr; please check values\n");
 		exits("protoerr");
 	}
 
 	buf[0] = Write; buf[1] = Full ^ Write;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
-		fprint(2, "'write memory' command rejected\n");
+		fprint(2, "'write memory' command rejected 0x%02x\n", buf[0]);
 		exits("protoerr");
 	}
 
@@ -232,9 +234,9 @@
 	buf[3] = addr & 0xFF;
 	buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
 
-	if(write(dev, buf, 5) < 0) {
+	if(write(dev, buf, 5) != 5) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
@@ -243,25 +245,39 @@
 	}
 
 	// send the size
-	buf[0] = sz; buf[1] = Full ^ buf[0];
+	buf[0] = sz - 1;
 
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 1) != 1) {
 		fprint(2, "unable to write\n");
-		exits("protoerr");
+		exits("deverr");
 	}
 
-	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
-		fprint(2, "write command rejected; check address and count\n");
-		exits("protoerr");
-	}
-
 	// write contents
-	int c = readn(0, buf, sz + 1);
-	if(c != sz + 1) {
-		fprint(2, "memory write error, address 0x%08llx, size-1 0x%02x, c %d\n", addr, sz, c);
+	int c = readn(0, buf, sz);
+	if(c != sz) {
+		fprint(2, "error reading stdin\n");
 		exits("apperr");
 	}
-	write(dev, buf, c);
+	if(write(dev, buf, c) != c) {
+		fprint(2, "unable to write data\n");
+		exits("deverr");
+	}
+
+	// write data checksum
+	buf[0] = (sz - 1) ^ buf[0];
+	for(int i = 1; i < c; i++)
+		buf[0] ^= buf[i];
+
+	if(write(dev, buf, 1) != 1) {
+		fprint(2, "unable to write checksum\n");
+		exits("deverr");
+	}
+
+	// ack the command and finish
+	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
+		fprint(2, "write data rejected, got 0x%02x\n", buf[0]);
+		exits("protoerr");
+	}
 }
 
 void
@@ -276,7 +292,6 @@
 		exits("protoerr");
 	}
 
-
 	fprint(2, "reading device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
 
 	// start read memory command
@@ -304,6 +319,10 @@
 		fprint(2, "write size cannot be 0\n");
 		exits("protoerr");
 	}
+	if(addr & 0x3 || sz & 0x3) {
+		fprint(2, "address and lenght must be 4 byte aligned\n");
+		exits("apperr");
+	}
 	if(addr + sz < addr) {
 		fprint(2, "addr + sz < addr; please check values\n");
 		exits("protoerr");
@@ -312,18 +331,22 @@
 	fprint(2, "writing device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
 
 	// start read memory command
-	uvlong caddr = addr;
+	uvlong caddr = addr, laddr = addr;
 	uvlong csz = sz;
 
 	while(caddr < (addr + sz)) {
-		uchar rsz = 0xFF;
-		if(csz < 0x100)
-			rsz = csz - 1;
+		uchar rsz = 0x20;
+		if(csz < 0x20)
+			rsz = csz;
 
 		stm_writepage(dev, caddr, rsz);
 
-		caddr = caddr + (rsz + 1);
-		csz = csz - (rsz + 1);
+		if(debug && caddr - laddr >= 2048) {
+			fprint(2, "progress: 0x%08llx / 0x%08llx\n", caddr, addr + sz);
+			laddr = caddr;
+		}
+		caddr = caddr + rsz;
+		csz = csz - rsz;
 	}
 
 	fprint(2, "memory written\n");
@@ -330,6 +353,83 @@
 }
 
 void
+stm_erase(int dev, uint n, uchar spage)
+{
+	if(n > 256) {
+		fprint(2, "unable to erase more than 256 pages\n");
+		exits("apperr");
+	}
+
+	if(debug)
+		fprint(2, "erasing memory, %d pages, start %d\n", n, spage);
+
+	uchar csum = 0;
+
+	// send erase command
+	buf[0] = Erase; buf[1] = Full ^ Erase;
+	if(write(dev, buf, 2) != 2) {
+		fprint(2, "unable to write: %r\n");
+		exits("deverr");
+	}
+
+	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
+		fprint(2, "'erase' rejected\n");
+		exits("protoerr");
+	}
+
+	buf[0] = n - 1;
+	if(write(dev, buf, 1) != 1) {
+		fprint(2, "unable to write: %r\n");
+		exits("deverr");
+	}
+
+	// full erase
+	if(n == 256) {
+		if(debug)
+			fprint(2, "trying a full erase\n");
+
+		buf[0] = 0;
+		if(write(dev, buf, 1) != 1) {
+			fprint(2, "unable to write: %r\n");
+			exits("deverr");
+		}
+
+		if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
+			fprint(2, "unable to fully erase, got 0x%02x\n", buf[0]);
+			exits("protoerr");
+		}
+
+		if(debug)
+			fprint(2, "performed a full erase\n");
+
+		return;
+	}
+
+	csum = n - 1;
+	for(int i = 0; i < n; i++) {
+		buf[i] = spage + i;
+		csum ^= buf[i];
+	}
+	buf[n] = csum;
+	for(int i = 0; i < n + 1; i++)
+		fprint(2, "0x%02x ", buf[i]);
+	fprint(2, "\n");
+
+	if(write(dev, buf, (uint)n + 1) != (uint)n + 1) {
+		fprint(2, "unable to write: %r\n");
+		exits("deverr");
+	}
+
+	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
+		fprint(2, "'erase' rejected\n");
+		exits("protoerr");
+	}
+
+	if(debug)
+		fprint(2, "erased successfully performed\n");
+}
+
+void
 stm_go(int dev, uvlong addr)
 {
 	if(debug)
@@ -337,14 +437,14 @@
 
 	// get the protocol version and commands
 	buf[0] = Go; buf[1] = Full ^ Go;
-	if(write(dev, buf, 2) < 0) {
+	if(write(dev, buf, 2) != 2) {
 		fprint(2, "unable to write: %r\n");
-		exits("protoerr");;
+		exits("deverr");
 	}
 
 	if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
 		fprint(2, "'go' rejected\n");
-		exits("protoerr");;
+		exits("protoerr");
 	}
 
 	// send the start address
@@ -354,7 +454,7 @@
 	buf[3] = addr & 0xFF;
 	buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
 
-	if(write(dev, buf, 5) < 0) {
+	if(write(dev, buf, 5) != 5) {
 		fprint(2, "unable to write\n");
 		exits("protoerr");
 	}
@@ -375,10 +475,12 @@
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-d] [-D device] command args ..\n", argv0);
+	fprint(2, "usage: %s [-d] [-D device] [-b baud] command args ..\n", argv0);
 	fprint(2, "	info\n");
 	fprint(2, "	read 	addr size\n");
 	fprint(2, "	write 	addr size\n");
+	fprint(2, "	erase	page n\n");
+	fprint(2, "	flash	addr size\n");
 	fprint(2, "	go		addr\n");
 	fprint(2, "	readp, readunp, writeunp\n");
 	fprint(2, "	TODO: writep,csum\n");
@@ -389,6 +491,8 @@
 main(int argc, char **argv)
 {
 	char* devpath = "/dev/eia0";
+	char* baudstr = "9600";
+	char tmp[256];
 	int action = -1;
 	int dev = -1;
 
@@ -396,6 +500,9 @@
 	uvlong sz = 0;
 
 	ARGBEGIN {
+	case 'b':
+		baudstr = ARGF();
+		break;
 	case 'd':
 		debug = 1;
 		break;
@@ -424,6 +531,20 @@
 		sz = strtoull(argv[2], nil, 16);
 		action = Dowrite;
 	}
+	if(!strcmp(argv[0], "erase")) {
+		if(argv[1] == 0 || argv[2] == 0)
+			usage();
+		addr = strtoull(argv[1], nil, 16);
+		sz = strtoull(argv[2], nil, 16);
+		action = Doerase;
+	}
+	if(!strcmp(argv[0], "flash")) {
+		if(argv[1] == 0 || argv[2] == 0)
+			usage();
+		addr = strtoull(argv[1], nil, 16);
+		sz = strtoull(argv[2], nil, 16);
+		action = Doflash;
+	}
 	if(!strcmp(argv[0], "go")) {
 		if(argv[1] == 0)
 			usage();
@@ -443,7 +564,7 @@
 
 	// set serial operating parameters
 	if(debug)
-		fprint(2, "setting modem to 9600 8E1\n");
+		fprint(2, "setting modem to b%s 8E1\n", baudstr);
 	int devctl = open(smprint("%sctl", devpath), OWRITE);
 	if(devctl < 0) {
 		fprint(2, "unable to open device ctl %sctl: %r\n", devpath);
@@ -450,7 +571,8 @@
 		exits("deverr");
 	}
 
-	if(write(devctl, "b9600\n", 8) < 0) {
+	sprint(tmp, "b%s\n", baudstr);
+	if(write(devctl, tmp, 8) < 0) {
 		fprint(2, "error: unable to set serial baud: %r\n");
 		exits("deverr");
 	}
@@ -466,13 +588,14 @@
 		fprint(2, "error: unable to set serial stop bits: %r\n");
 		exits("deverr");
 	}
-	if(write(devctl, "f\n", 3) < 0) {
-		fprint(2, "error: unable to flush the serial line: %r\n");
-		exits("deverr");
-	}
+	// if(write(devctl, "f\n", 3) < 0) {
+	// 	fprint(2, "error: unable to flush the serial line: %r\n");
+	// 	exits("deverr");
+	// }
 
 	if(debug)
 		fprint(2, "modem set up accordingly\n");
+	close(devctl);
 
 	// opening serial line
 	if(debug)
@@ -487,12 +610,12 @@
 	if(debug)
 		fprint(2, "initiating connection\n");
 	buf[0] = Conninit;
-	if(write(dev, buf, 1) < 0) {
+	if(write(dev, buf, 1) != 1) {
 		fprint(2, "error writing while initiating\n");
 		exits("connerr");
 	}
 
-	if(readn(dev, buf, 1) <= 0 || buf[0] != Ack) {
+	if(readn(dev, buf, 1) != 1 || buf[0] != Ack) {
 		fprint(2, "connection could not be initiated, got %x\n", buf[0]);
 		exits("connerr");
 	}
@@ -502,6 +625,12 @@
 	case Doinfo: stm_info(dev); break;
 	case Doread: stm_read(dev, addr, sz); break;
 	case Dowrite: stm_write(dev, addr, sz); break;
+	case Doerase: stm_erase(dev, addr, sz); break;
+	case Doflash:
+		stm_erase(dev, 256, 0);
+		stm_write(dev, addr, sz);
+		stm_go(dev, addr);
+		break;
 	case Doreadprot:
 	case Doreadunprot:
 	case Dowriteunprot: