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: