added code

This commit is contained in:
k 2023-08-01 15:13:18 +00:00
parent dc316f180a
commit 252d709ce2
3 changed files with 534 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.out
stm32up.*

14
mkfile Normal file
View File

@ -0,0 +1,14 @@
</$objtype/mkfile
BIN=/$objtype/bin
TARG=stm32up
OFILES=\
stm32up.$O\
UPDATE=\
mkfile\
$HFILES\
${OFILES:%.$O=%.c}\
${TARG:%=/386/bin/%}\
</sys/src/cmd/mkone

518
stm32up.c Normal file
View File

@ -0,0 +1,518 @@
#include <u.h>
#include <libc.h>
static int debug = 0;
static uchar buf[256];
enum {
Doinfo,
Doread,
Dowrite,
Dogo,
Doreadprot,
Doreadunprot,
Dowriteprot,
Dowriteunprot,
Docsum
};
enum Uartcmd {
Nop = 0x00,
Full = 0xFF,
Ack = 0x79,
Nack = 0x1F,
Conninit = 0x7F,
Get = 0x00,
Getversion = 0x01,
Getid = 0x02,
Read = 0x11,
Go = 0x21,
Write = 0x31,
Erase = 0x43,
Eraseext = 0x44,
Special = 0x50,
Specialext = 0x51,
Writeprot = 0x63,
Writeunprot = 0x73,
Readprot = 0x82,
Readunprot = 0x92,
Checksum = 0xA1 // this is not yet implemented
};
void
stm_info(int dev)
{
if(debug)
fprint(2, "acquiring device info\n");
// get the protocol version and commands
buf[0] = Get; buf[1] = Full ^ Get;
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write: %r\n");
exits("protoerr");;
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'get' rejected\n");
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");;
}
fprint(2, "protocol version: %x\n", buf[1]);
if(debug) {
for(int i = 0; i < 14; i++)
fprint(2, "0x%02x ", buf[i]);
fprint(2, "\n");
}
if(buf[2] != Get ||
buf[3] != Getversion ||
buf[4] != Getid ||
buf[5] != Read ||
buf[6] != Go ||
buf[7] != Write ||
(buf[8] != Erase && buf[8] != Eraseext) ||
buf[9] != Writeprot ||
buf[10] != Writeunprot ||
buf[11] != Readprot ||
buf[12] != Readunprot) {
fprint(2, "command code mismatch, run with -d\n");
return;
}
// get the device id
if(debug)
fprint(2, "getting device id\n");
buf[0] = Getid; buf[1] = Full ^ Getid;
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");;
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'get id' command rejected\n");
exits("protoerr");;
}
if(readn(dev, buf, 4) == 0 || buf[0] != 1 || buf[3] != Ack) {
fprint(2, "protocol error while getting device id\n");
exits("protoerr");;
}
fprint(2, "device id: %x%x\n", buf[1], buf[2]);
}
void
stm_protect(int dev, int acmd)
{
char *cmds;
int cmd;
switch(acmd) {
case Doreadprot: cmd = Readprot; cmds = "read protect"; break;
case Doreadunprot: cmd = Readunprot; cmds = "read unprotect"; break;
case Dowriteunprot: cmd = Writeunprot; cmds = "write unprotect"; break;
default:
fprint(2, "stm_protect does not handle this command\n");
exits("apperr");
}
if(debug)
fprint(2, "%s device\n", cmds);
buf[0] = cmd; buf[1] = Full ^ cmd;
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");;
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'%s' command rejected\n", cmds);
exits("protoerr");;
}
buf[0] = Ack;
if(write(dev, buf, 1) < 0) {
fprint(2, "unable to ack %s", cmds);
exits("protoerr");;
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'%s' unable to ack\n", cmds);
exits("protoerr");;
}
fprint(2, "%s done\n", cmds);
}
void
stm_readpage(int dev, uvlong addr, uchar sz) // size - 1
{
if(addr + (sz + 1) < addr) {
fprint(2, "addr + sz < addr; please check values\n");
exits("protoerr");
}
buf[0] = Read; buf[1] = Full ^ Read;
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'read memory' command rejected\n");
exits("protoerr");
}
// send the start address
buf[0] = (addr >> 24) & 0xFF;
buf[1] = (addr >> 16) & 0xFF;
buf[2] = (addr >> 8) & 0xFF;
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
if(write(dev, buf, 5) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "read memory address rejected\n");
exits("protoerr");
}
// send the size
buf[0] = sz; buf[1] = Full ^ buf[0];
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "read command rejected; check address and count\n");
exits("protoerr");
}
// read contents
int c = readn(dev, buf, sz + 1);
if(c != sz + 1) {
fprint(2, "memory read error, address 0x%08llx, size-1 0x%02x, c %d\n", addr, sz, c);
exits("apperr");
}
write(1, buf, c);
}
void
stm_writepage(int dev, uvlong addr, uchar sz) // size - 1
{
if(addr + (sz + 1) < 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) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'write memory' command rejected\n");
exits("protoerr");
}
// send the start address
buf[0] = (addr >> 24) & 0xFF;
buf[1] = (addr >> 16) & 0xFF;
buf[2] = (addr >> 8) & 0xFF;
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
if(write(dev, buf, 5) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "write memory address rejected\n");
exits("protoerr");
}
// send the size
buf[0] = sz; buf[1] = Full ^ buf[0];
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
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);
exits("apperr");
}
write(dev, buf, c);
}
void
stm_read(int dev, uvlong addr, uvlong sz)
{
if(sz == 0) {
fprint(2, "read size cannot be 0\n");
exits("protoerr");
}
if(addr + sz < addr) {
fprint(2, "addr + sz < addr; please check values\n");
exits("protoerr");
}
fprint(2, "reading device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
// start read memory command
uvlong caddr = addr;
uvlong csz = sz;
while(caddr < (addr + sz)) {
uchar rsz = 0xFF;
if(csz < 0x100)
rsz = csz - 1;
stm_readpage(dev, caddr, rsz);
caddr = caddr + (rsz + 1);
csz = csz - (rsz + 1);
}
fprint(2, "memory read\n");
}
void
stm_write(int dev, uvlong addr, uvlong sz)
{
if(sz == 0) {
fprint(2, "write size cannot be 0\n");
exits("protoerr");
}
if(addr + sz < addr) {
fprint(2, "addr + sz < addr; please check values\n");
exits("protoerr");
}
fprint(2, "writing device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
// start read memory command
uvlong caddr = addr;
uvlong csz = sz;
while(caddr < (addr + sz)) {
uchar rsz = 0xFF;
if(csz < 0x100)
rsz = csz - 1;
stm_writepage(dev, caddr, rsz);
caddr = caddr + (rsz + 1);
csz = csz - (rsz + 1);
}
fprint(2, "memory written\n");
}
void
stm_go(int dev, uvlong addr)
{
if(debug)
fprint(2, "device requested to jump to 0x%08llx\n", addr);
// get the protocol version and commands
buf[0] = Go; buf[1] = Full ^ Go;
if(write(dev, buf, 2) < 0) {
fprint(2, "unable to write: %r\n");
exits("protoerr");;
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "'go' rejected\n");
exits("protoerr");;
}
// send the start address
buf[0] = (addr >> 24) & 0xFF;
buf[1] = (addr >> 16) & 0xFF;
buf[2] = (addr >> 8) & 0xFF;
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
if(write(dev, buf, 5) < 0) {
fprint(2, "unable to write\n");
exits("protoerr");
}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {
fprint(2, "go address rejected\n");
exits("protoerr");
}
fprint(2, "device jumped to 0x%08llx\n", addr);
}
void
stm_checksum(int dev)
{
}
void
usage(void)
{
fprint(2, "usage: %s [-d] [-D device] command args ..\n", argv0);
fprint(2, " info\n");
fprint(2, " read addr size\n");
fprint(2, " write addr size\n");
fprint(2, " go addr\n");
fprint(2, " readp, readunp, writeunp\n");
fprint(2, " TODO: writep,csum\n");
exits("usage");
}
void
main(int argc, char **argv)
{
char* devpath = "/dev/eia0";
int action = -1;
int dev = -1;
uvlong addr = 0;
uvlong sz = 0;
ARGBEGIN {
case 'd':
debug = 1;
break;
case 'D':
devpath = EARGF(usage());
break;
default: usage();
} ARGEND
if(argv[0] == 0)
usage();
if(!strcmp(argv[0], "info"))
action = Doinfo;
if(!strcmp(argv[0], "read")) {
if(argv[1] == 0 || argv[2] == 0)
usage();
addr = strtoull(argv[1], nil, 16);
sz = strtoull(argv[2], nil, 16);
action = Doread;
}
if(!strcmp(argv[0], "write")) {
if(argv[1] == 0 || argv[2] == 0)
usage();
addr = strtoull(argv[1], nil, 16);
sz = strtoull(argv[2], nil, 16);
action = Dowrite;
}
if(!strcmp(argv[0], "go")) {
if(argv[1] == 0)
usage();
addr = strtoull(argv[1], nil, 16);
action = Dogo;
}
if(!strcmp(argv[0], "readp"))
action = Doreadprot;
if(!strcmp(argv[0], "readunp"))
action = Doreadunprot;
if(!strcmp(argv[0], "writeunp"))
action = Doreadunprot;
if(!strcmp(argv[0], "csum"))
action = Docsum;
if(action < 0)
usage();
// set serial operating parameters
if(debug)
fprint(2, "setting modem to 9600 8E1\n");
int devctl = open(smprint("%sctl", devpath), OWRITE);
if(devctl < 0) {
fprint(2, "unable to open device ctl %sctl: %r\n", devpath);
exits("deverr");
}
if(write(devctl, "b9600\n", 8) < 0) {
fprint(2, "error: unable to set serial baud: %r\n");
exits("deverr");
}
if(write(devctl, "l8\n", 3) < 0) {
fprint(2, "error: unable to set serial length: %r\n");
exits("deverr");
}
if(write(devctl, "pe\n", 3) < 0) {
fprint(2, "error: unable to set serial parity: %r\n");
exits("deverr");
}
if(write(devctl, "s1\n", 3) < 0) {
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(debug)
fprint(2, "modem set up accordingly\n");
// opening serial line
if(debug)
fprint(2, "opening %s\n", devpath);
dev = open(devpath, ORDWR);
if(dev < 0) {
fprint(2, "unable to open device %s: %r\n", devpath);
exits("deverr");
}
// initiate connection; send Conninit, and wait for Ack
if(debug)
fprint(2, "initiating connection\n");
buf[0] = Conninit;
if(write(dev, buf, 1) < 0) {
fprint(2, "error writing while initiating\n");
exits("connerr");
}
if(readn(dev, buf, 1) <= 0 || buf[0] != Ack) {
fprint(2, "connection could not be initiated, got %x\n", buf[0]);
exits("connerr");
}
// handle action
switch(action) {
case Doinfo: stm_info(dev); break;
case Doread: stm_read(dev, addr, sz); break;
case Dowrite: stm_write(dev, addr, sz); break;
case Doreadprot:
case Doreadunprot:
case Dowriteunprot:
stm_protect(dev, action); break;
case Dogo: stm_go(dev, addr); break;
case Docsum: stm_checksum(dev); break;
default: exits("apperr");
}
if(debug)
fprint(2, "exiting\n");
exits(nil);
}