added code
This commit is contained in:
parent
dc316f180a
commit
252d709ce2
|
@ -0,0 +1,2 @@
|
||||||
|
*.out
|
||||||
|
stm32up.*
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue