<*+ M2EXTENSIONS *> <*-CHECKDIV *> <*-CHECKRANGE *> <*-COVERFLOW *> <*-IOVERFLOW*> MODULE tinyburn; (*atmega attiny13 attiny2313 burner*) FROM SYSTEM IMPORT ADR, CAST; FROM FIO IMPORT IsOpen, OpenMode, Create, write, read, Close, File, oRDWR, oNONBLOCK; IMPORT mlib, IO, Str, Lib; TYPE BYTESET=SET OF [0..7]; VAR saved: mlib.termios; rdpos, rdcnt:CARDINAL; parallel:BOOLEAN; rdbuf:ARRAY[0..1023] OF CHAR; CONST NL=12C; EMPTY=377C; MAXFLASHSIZE=2048; RST0V=4; RST5V=0; RST12V=8; VCC5V=16; REPLY=1; SETVOLT=2; SCI= 16; (*PB3*) SDI= 128; (*PB0*) SDO= 32; (*PB2*) SII= 64; (*PB1*) CLK= 32; (*PB2*) MOSI=128; (*PB0*) MISO=64; (*PB1*) PROCEDURE WrHex(c:CHAR); VAR n:CARDINAL; BEGIN IO.WrChar(" "); n:=ORD(c) DIV 16; IF n<=9 THEN IO.WrChar(CHR(n+ORD("0"))) ELSE IO.WrChar(CHR(n+(ORD("a")-10))) END; n:=ORD(c) MOD 16; IF n<=9 THEN IO.WrChar(CHR(n+ORD("0"))) ELSE IO.WrChar(CHR(n+(ORD("a")-10))) END; END WrHex; PROCEDURE Fatal(why:ARRAY OF CHAR); BEGIN IO.WrStrLn(why); HALT; END Fatal; PROCEDURE ResetComMode(fd:File); VAR i:INTEGER; BEGIN i:=mlib.tcsetattr(fd, mlib.TCSANOW, saved); END ResetComMode; PROCEDURE SetComMode(fd:File); VAR term: mlib.termios; res : INTEGER; BEGIN res:=mlib.tcgetattr(fd, saved); res:=mlib.tcgetattr(fd, term); WITH term DO c_lflag :=0; c_oflag :=0; c_iflag :=0; (*IO.WrHex(c_cflag,20);IO.WrLn;*) c_cflag :=mlib.CS8+mlib.CSTOPB+mlib.CLOCAL+mlib.CREAD(*+CRTSCTS*)+mlib.B115200; END; res:=mlib.tcsetattr(fd, mlib.TCSAFLUSH, term); END SetComMode; PROCEDURE Rdtty(tty:File):CHAR; VAR retr:CARDINAL; i:INTEGER; BEGIN IF rdpos>=rdcnt THEN retr:=0; LOOP i:=read(tty, ADR(rdbuf), SIZE(rdbuf)); IF i>0 THEN EXIT END; mlib.usleep(500); INC(retr); IF retr>1000 THEN Fatal("Timeout waiting for Byte") END; END; rdpos:=0; rdcnt:=i; END; INC(rdpos); (* WrHex(rdbuf[rdpos-1]); *) RETURN rdbuf[rdpos-1] END Rdtty; PROCEDURE Clrtty(tty:File); VAR b:ARRAY[0..1023] OF CHAR; BEGIN REPEAT UNTIL read(tty, ADR(b), SIZE(b))<=0; (*clear input buffer*) END Clrtty; PROCEDURE Echotest(tty:File):BOOLEAN; VAR i:CARDINAL; b:ARRAY[0..1023] OF CHAR; BEGIN REPEAT UNTIL read(tty, ADR(b[0]), SIZE(b))<=0; b[0]:=0C; i:=write(tty, ADR(b), 1); mlib.usleep(50000); IF read(tty, ADR(b[0]), SIZE(b))>0 THEN RETURN FALSE END; (* echoes all *) b[0]:=CHR(REPLY); i:=write(tty, ADR(b), 1); FOR i:=0 TO 99 DO IF read(tty, ADR(b[0]), SIZE(b))=1 THEN RETURN TRUE END; (* echo ok *) mlib.usleep(1000); END; RETURN FALSE (* timeout *) END Echotest; PROCEDURE SetVolt(tty:File; v:CARDINAL); VAR i:CARDINAL; b:ARRAY[0..1023] OF CHAR; BEGIN b[0]:=CHR(CAST(CARDINAL,CAST(BITSET,v)/BITSET{3,4} + CAST(BITSET,SETVOLT))); b[1]:=CHR(0); i:=write(tty, ADR(b), 2); END SetVolt; PROCEDURE HighVByte(tty:File; data, cmd:CHAR; rep:BOOLEAN; VAR ch:CHAR); VAR sb:ARRAY[0..255] OF CHAR; sp, i:CARDINAL; c:CHAR; PROCEDURE SendBit(d,c:BOOLEAN); BEGIN sb[sp]:=CHR(SDO + SDI*ORD(d) + SII*ORD(c) + REPLY*ORD(rep)); INC(sp); sb[sp]:=CHR(SDO + SDI*ORD(d) + SII*ORD(c) + SCI); INC(sp); END SendBit; BEGIN sp:=0; SendBit(FALSE, FALSE); FOR i:=0 TO 7 DO SendBit(data>=200C, cmd>=200C); data:=CHR(ORD(data)*2 MOD 256); cmd :=CHR(ORD(cmd )*2 MOD 256); END; FOR i:=0 TO 1 DO SendBit(FALSE, FALSE) END; i:=write(tty, ADR(sb), sp); ch:=0C; IF rep THEN FOR i:=0 TO 8 DO ch:=CHR(ORD(ch)*2 + ORD(CAST(BYTESET, SDO) * CAST(BYTESET, Rdtty(tty))<>BYTESET{})); END; FOR i:=0 TO 1 DO c:=Rdtty(tty) END; END; END HighVByte; PROCEDURE SendSerByte(tty:File; data:CHAR); VAR sb:ARRAY[0..255] OF CHAR; sp, i:CARDINAL; PROCEDURE SendBit(b:BOOLEAN); BEGIN IF b THEN sb[sp]:=CHR(MOSI+MISO); INC(sp); sb[sp]:=CHR(MOSI+MISO+CLK); ELSE sb[sp]:=CHR( MISO); INC(sp); sb[sp]:=CHR( MISO+CLK); END; INC(sp); END SendBit; BEGIN sp:=0; FOR i:=0 TO 7 DO SendBit(data>=200C); data:=CHR(ORD(data)*2 MOD 256); END; i:=write(tty, ADR(sb), sp); END SendSerByte; PROCEDURE ReadSerByte(tty:File; VAR ch:CHAR); VAR i: INTEGER; sp:CARDINAL; sb:ARRAY[0..255] OF CHAR; BEGIN sp:=0; FOR i:=0 TO 7 DO sb[sp]:=CHR(MISO); INC(sp); sb[sp]:=CHR(MISO+CLK+REPLY); INC(sp); END; i:=write(tty, ADR(sb), sp); ch:=0C; FOR i:=0 TO 7 DO ch:=CHR(ORD(ch)*2 + ORD(CAST(BYTESET, MISO) * CAST(BYTESET, Rdtty(tty))<>BYTESET{})); (* IO.WrHex(ORD(Rdtty(tty)), 4); *) END; (* IO.WrLn; *) END ReadSerByte; PROCEDURE ProgramEnable(tty:File):BOOLEAN; VAR ch:CHAR; BEGIN SendSerByte(tty, CHR(0ACH)); SendSerByte(tty, CHR(053H)); Clrtty(tty); ReadSerByte(tty, ch); IF ch<>CHR(053H) THEN RETURN FALSE END; ReadSerByte(tty, ch); RETURN TRUE END ProgramEnable; PROCEDURE Init5V(tty:File); VAR retr:CARDINAL; BEGIN retr:=0; REPEAT INC(retr); IF retr>1 THEN Fatal("Cannot enable 5v program mode") END; Clrtty(tty); SetVolt(tty, RST0V); mlib.usleep(20000); SetVolt(tty, RST0V+VCC5V); mlib.usleep(20000); UNTIL ProgramEnable(tty); END Init5V; PROCEDURE Init12V(tty:File); VAR sb:ARRAY[0..255] OF CHAR; sp, i:CARDINAL; BEGIN Clrtty(tty); SetVolt(tty, RST5V); mlib.usleep(20000); SetVolt(tty, RST0V+VCC5V); mlib.usleep(20000); (*toggle clock*) sp:=0; FOR i:=0 TO 5 DO sb[sp]:=CHR(SCI); INC(sp); sb[sp]:=CHR(0); INC(sp); END; i:=write(tty, ADR(sb), sp); SetVolt(tty, RST12V+VCC5V); (* sp:=0; FOR i:=0 TO 30 DO sb[sp]:=CHR(SCI); INC(sp); sb[sp]:=CHR(0); INC(sp); END; i:=write(tty, ADR(sb), sp); *) mlib.usleep(10000); Clrtty(tty); END Init12V; PROCEDURE Exit5V(tty:File); BEGIN SetVolt(tty, RST0V); mlib.usleep(20000); END Exit5V; PROCEDURE Exit12V(tty:File); BEGIN SetVolt(tty, RST0V); mlib.usleep(20000); END Exit12V; PROCEDURE GetMark(tty:File; VAR b:ARRAY OF CHAR); VAR i:CARDINAL; c:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(008H), CHR(04CH), FALSE, c); FOR i:=0 TO 2 DO HighVByte(tty, CHR(i), CHR(00CH), FALSE, c); HighVByte(tty, CHR(000H), CHR(068H), FALSE, c); HighVByte(tty, CHR(000H), CHR(06CH), TRUE, b[i]); END; ELSE FOR i:=0 TO 2 DO SendSerByte(tty, CHR(030H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(i)); ReadSerByte(tty, b[i]); END; END; END GetMark; PROCEDURE GetCalibrate(tty:File):CHAR; VAR ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(008H), CHR(04CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(00CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(078H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07CH), TRUE, ch); ELSE SendSerByte(tty, CHR(038H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(000H)); ReadSerByte(tty, ch); END; RETURN ch END GetCalibrate; PROCEDURE GetLocks(tty:File):CHAR; VAR ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(004H), CHR(04CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(078H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07CH), TRUE, ch); ELSE SendSerByte(tty, CHR(058H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(000H)); ReadSerByte(tty, ch); END; RETURN ch END GetLocks; PROCEDURE GetFuses(tty:File; high:BOOLEAN):CHAR; VAR ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(004H), CHR(04CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(068H + 012H*ORD(high)), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH + 012H*ORD(high)), TRUE, ch); ELSE SendSerByte(tty, CHR(050H + 008H*ORD(high))); SendSerByte(tty, CHR(000H + 008H*ORD(high))); SendSerByte(tty, CHR(000H)); ReadSerByte(tty, ch); END; RETURN ch END GetFuses; PROCEDURE RdFile(fn:ARRAY OF CHAR; VAR b:ARRAY OF CHAR); VAR f, l, i:INTEGER; BEGIN IF IsOpen(f, fn) THEN l:=read(f, ADR(b), SIZE(b)); FOR i:=l TO VAL(INTEGER, HIGH(b)) DO b[i]:=EMPTY END; ELSE IO.WrStr("file not found: "); Fatal(fn) END; END RdFile; PROCEDURE WrFile(fn:ARRAY OF CHAR; VAR b:ARRAY OF CHAR; size:CARDINAL); VAR f:File; res:INTEGER; BEGIN f:=Create(fn); res:=write(f, ADR(b), size); Close(f); END WrFile; PROCEDURE ReadFlash(tty:File; start, end:CARDINAL; VAR buf:ARRAY OF CHAR); VAR i:CARDINAL; ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(002H), CHR(04CH), FALSE, ch); FOR i:=start TO end DO HighVByte(tty, CHR(i MOD 256), CHR(00CH), FALSE, ch); HighVByte(tty, CHR(i DIV 256), CHR(01CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(068H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(068H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH), TRUE, buf[i*2]); HighVByte(tty, CHR(000H), CHR(078H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07CH), TRUE, buf[i*2+1]); END; ELSE FOR i:=start TO end DO SendSerByte(tty, CHR(020H)); SendSerByte(tty, CHR(i DIV 256)); SendSerByte(tty, CHR(i MOD 256)); ReadSerByte(tty, buf[i*2]); SendSerByte(tty, CHR(028H)); SendSerByte(tty, CHR(i DIV 256)); SendSerByte(tty, CHR(i MOD 256)); ReadSerByte(tty, buf[i*2+1]); END; END; END ReadFlash; PROCEDURE Chiperase(tty:File); VAR ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(080H), CHR(04CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(064H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH), FALSE, ch); ELSE SendSerByte(tty, CHR(0ACH)); SendSerByte(tty, CHR(080H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(000H)); END; mlib.usleep(500000); END Chiperase; PROCEDURE WaitReady(tty:File); VAR ch:CHAR; i:CARDINAL; BEGIN i:=1000; REPEAT SendSerByte(tty, CHR(0F0H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(000H)); ReadSerByte(tty, ch); DEC(i); IF i=0 THEN Fatal("waiting forever for flash write ready signal.... aborted") END; UNTIL NOT ODD(ORD(ch)); END WaitReady; PROCEDURE WriteFlash(tty:File; last:CARDINAL; wbuf:ARRAY OF CHAR); VAR i:CARDINAL; ch:CHAR; BEGIN LOOP IF wbuf[last]<>377C THEN INC(last); EXIT END; IF last=0 THEN EXIT END; DEC(last); END; IF ODD(last) THEN INC(last) END; IF last>0 THEN IF parallel THEN HighVByte(tty, CHR(010H), CHR(04CH), FALSE, ch); FOR i:=0 TO last-1 BY 2 DO HighVByte(tty, CHR(i DIV 2 MOD 256), CHR(00CH), FALSE, ch); HighVByte(tty, wbuf[i], CHR(02CH), FALSE, ch); HighVByte(tty, wbuf[i+1], CHR(03CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07DH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07CH), FALSE, ch); IF (i MOD 32=30) OR (i=last-2) THEN HighVByte(tty, CHR(i DIV 512), CHR(01CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(064H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH), TRUE, ch); mlib.usleep(10000); END; END; ELSE FOR i:=0 TO last-1 BY 2 DO SendSerByte(tty, CHR(040H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(i DIV 2 MOD 256)); SendSerByte(tty, wbuf[i]); SendSerByte(tty, CHR(048H)); SendSerByte(tty, CHR(000H)); SendSerByte(tty, CHR(i DIV 2 MOD 256)); SendSerByte(tty, wbuf[i+1]); IF (i MOD 32=30) OR (i=last-2) THEN SendSerByte(tty, CHR(04CH)); SendSerByte(tty, CHR(i DIV 512)); SendSerByte(tty, CHR(i DIV 2 MOD 256)); SendSerByte(tty, CHR(000H)); WaitReady(tty); END; END; END; END; END WriteFlash; PROCEDURE WrFuse(tty:File; c:CHAR; lowfuses:BOOLEAN); VAR ch:CHAR; BEGIN IF parallel THEN IF lowfuses THEN HighVByte(tty, CHR(040H), CHR(04CH), FALSE, ch); HighVByte(tty, c , CHR(02CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(064H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH), FALSE, ch); ELSE HighVByte(tty, CHR(040H), CHR(04CH), FALSE, ch); HighVByte(tty, c, CHR(02CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(074H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(07CH), FALSE, ch); END; ELSE SendSerByte(tty, CHR(0ACH)); SendSerByte(tty, CHR(0A0H + 8*ORD(NOT lowfuses))); SendSerByte(tty, CHR(000H)); SendSerByte(tty, c); END; mlib.usleep(10000); END WrFuse; PROCEDURE WrLock(tty:File; c:CHAR); VAR ch:CHAR; BEGIN IF parallel THEN HighVByte(tty, CHR(020H), CHR(04CH), FALSE, ch); HighVByte(tty, CHR(ORD(c) MOD 4), CHR(02CH), FALSE, ch); HighVByte(tty, CHR(000H), CHR(064H), FALSE, ch); HighVByte(tty, CHR(000H), CHR(06CH), FALSE, ch); ELSE SendSerByte(tty, CHR(0ACH)); SendSerByte(tty, CHR(0E0H)); SendSerByte(tty, CHR(0E0H)); SendSerByte(tty, CHR(CARDINAL(BITSET(ORD(c))+BITSET(0FCH)))); END; mlib.usleep(10000); END WrLock; VAR ttyname, fname:ARRAY[0..4095] OF CHAR; hexlist, testempty, erase, burn, verify, readdump, wrfuselow, wrfusehigh, wrlock, override:BOOLEAN; fuselow, fusehigh, lock:CHAR; PROCEDURE GetBitset(VAR c:CHAR); VAR err:BOOLEAN; h:ARRAY[0..255] OF CHAR; i:CARDINAL; BEGIN err:=TRUE; Lib.NextArg(h); i:=0; c:=0C; LOOP IF (i>HIGH(h)) OR (h[i]=0C) THEN EXIT END; IF (h[i]="0") OR (h[i]="1") THEN c:=CHR(ORD(c)*2 MOD 256 + ORD(h[i]) MOD 2); err:=FALSE; ELSE err:=TRUE; EXIT END; INC(i); END; IF err THEN Fatal("Parameter bitset: 0|1") END; END GetBitset; PROCEDURE Parms; VAR err:BOOLEAN; h:ARRAY[0..4095] OF CHAR; BEGIN testempty:=FALSE; erase:=FALSE; burn:=FALSE; hexlist:=FALSE; verify:=FALSE; readdump:=FALSE; wrfuselow:=FALSE; wrfusehigh:=FALSE; wrlock:=FALSE; override:=FALSE; (* Str.Assign(ttyname, "/dev/ttyS0"); *) ttyname[0]:=0C; fname[0]:=0C; err:=FALSE; LOOP Lib.NextArg(h); IF h[0]=0C THEN EXIT END; IF (h[0]="-") & (h[1]<>0C) THEN IF h[1]="t" THEN testempty:=TRUE; ELSIF h[1]="e" THEN erase:=TRUE; ELSIF h[1]="p" THEN parallel:=TRUE; ELSIF h[1]="w" THEN burn:=TRUE; ELSIF h[1]="l" THEN hexlist:=TRUE; ELSIF h[1]="v" THEN verify:=TRUE; ELSIF h[1]="r" THEN readdump:=TRUE; ELSIF h[1]="c" THEN Lib.NextArg(ttyname); ELSIF h[1]="f" THEN wrfuselow:=TRUE; GetBitset(fuselow); ELSIF h[1]="F" THEN wrfusehigh:=TRUE; GetBitset(fusehigh); ELSIF h[1]="L" THEN wrlock:=TRUE; GetBitset(lock); ELSIF h[1]="o" THEN override:=TRUE; ELSIF h[1]="h" THEN IO.WrStrLn("-p parallel mode"); IO.WrStrLn("-t test if erased"); IO.WrStrLn("-e erase flash"); IO.WrStrLn("-w burn file to flash"); IO.WrStrLn("-h this text"); IO.WrStrLn("-l list flash in hex"); IO.WrStrLn("-o override signature test"); IO.WrStrLn("-v verify flash with file"); IO.WrStrLn("-r read flash to file"); IO.WrStrLn("-f write low fuses"); IO.WrStrLn("-F write high fuses"); IO.WrStrLn("-L write locks"); IO.WrStrLn("-c tty port eg /dev/ttyS0"); HALT ELSE err:=TRUE END; h[0]:=0C; ELSE Str.Assign(fname, h) END; END; IF err THEN Fatal("Parameters: -c com -t testempty, -e erase, -w burnfile, -l list, -r readtofile, -v verifyfile, -f fuselow -F fusehigh -L locks"); END; END Parms; PROCEDURE Main(tty:File); VAR buf, wbuf:ARRAY [0..MAXFLASHSIZE-1] OF CHAR; i, err, flashsize:CARDINAL; ok:BOOLEAN; BEGIN flashsize:=1024; IF NOT Echotest(tty) THEN Fatal("Programmer does not answer") END; IF parallel THEN Init12V(tty) ELSE Init5V(tty) END; IO.WrStr("signature:"); GetMark(tty, buf); FOR i:=0 TO 2 DO WrHex(buf[i]) END; IF (buf[0]=36C) & (buf[1]=220C) & (buf[2]=007C) THEN (*tiny13*) IO.WrStr(" Signature tiny13"); flashsize:=1024; ELSIF (buf[0]=36C) & (buf[1]=221C) & (buf[2]=012C) THEN (*tiny2313*) IO.WrStr(" Signature tiny2313"); flashsize:=2048; ELSE IF NOT override THEN IF parallel THEN Exit12V(tty) ELSE Exit5V(tty) END; Fatal(" no signature match!"); ELSE IO.WrStr(" (overriding signature test, guess flashsize 1k)") END; END; IO.WrStr(" calibrate:"); WrHex(GetCalibrate(tty)); IO.WrStr(" lock:"); WrHex(CHR(ORD(GetLocks(tty)) MOD 4)); IO.WrStr(" fuses(low):"); WrHex(GetFuses(tty, FALSE)); IO.WrStr(" fuses(high):"); WrHex(GetFuses(tty, TRUE)); IO.WrLn; IF hexlist OR readdump THEN (*list*) ReadFlash(tty, 0, flashsize DIV 2-1, buf); FOR i:=0 TO flashsize-1 DO IF i MOD 16=0 THEN IO.WrLn END; WrHex(buf[i]); END; IO.WrLn; IF readdump & (fname[0]<>0C) THEN WrFile(fname, buf, flashsize) END; END; IF testempty THEN (*testempty*) ok:=TRUE; ReadFlash(tty, 0, flashsize DIV 2-1, buf); FOR i:=0 TO flashsize-1 DO IF buf[i]<>EMPTY THEN ok:=FALSE END; END; IF ok THEN IO.WrStr("empty") ELSE IO.WrStr("not empty") END; IO.WrLn; END; IF verify THEN (*verify*) RdFile(fname, wbuf); ReadFlash(tty, 0, flashsize DIV 2-1, buf); err:=0; FOR i:=0 TO flashsize-1 DO IF buf[i]<>wbuf[i] THEN INC(err) END; END; IF err<>0 THEN IO.WrCard(err, 1); IO.WrStrLn(" byte different") END; END; IF erase THEN (*erase*) (*IO.WrStr("chiperase:");*) Chiperase(tty); END; IF burn THEN (*burn*) RdFile(fname, wbuf); (* WaitReady(tty); WaitReady(tty); *) WriteFlash(tty, flashsize-1, wbuf); END; IF wrfuselow THEN (*fuselow*) IF ORD(fuselow) DIV 4 MOD 4 = 0 THEN IO.WrStr("Dangerous startup time fuse!"); IO.WrLn; ELSE WrFuse(tty, fuselow, TRUE) END; END; IF wrfusehigh THEN (*fusehigh*) WrFuse(tty, fusehigh, FALSE); END; IF wrlock THEN (*lock*) WrLock(tty, lock); END; IF parallel THEN Exit12V(tty) ELSE Exit5V(tty) END; END Main; VAR tty:File; BEGIN rdcnt:=0; rdpos:=0; parallel:=FALSE; Parms; tty:=OpenMode(ttyname, oRDWR+oNONBLOCK); IF (tty>0) AND (tty<256) THEN SetComMode(tty); Main(tty); ResetComMode(tty); Close(tty); ELSE IO.WrStr("tty open failure "); IO.WrStrLn(ttyname) END; END tinyburn. (* filter destroy condition fuses check signature set 12v 12v: sdi mosi pb0 5, sii miso pb1 6, sck sdo pb2 7, sci clock pb3 2, reset pb5 1 1E 90 07 id: 30 144 7 tune: 89 lock: 255 fuse: 255 255 signature: 1e 90 07 calibrate: 51 lock: 03 fuses(low): ea fuses(high): fe *)