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