avr: allow writing to flash

This commit is contained in:
Virgil Dupras 2020-09-05 14:07:13 -04:00
parent 4910b9caef
commit 5b4917dbe9
5 changed files with 53 additions and 13 deletions

View File

@ -4,4 +4,4 @@ This program allows you to access AVR chips Flash memory, EEPROM
and fuses using a SPI relay. This requires drivers that imple- and fuses using a SPI relay. This requires drivers that imple-
ment the SPI Relay protocol. ment the SPI Relay protocol.
Load range: B691-BXXX Load range: B691-B693

25
blk/691
View File

@ -1,14 +1,15 @@
: _cmd ( b4 b3 b2 b1 -- r4 ) ( page size in words, 64 is default on atmega328P )
(spix) DROP DUP (spix) DROP SWAP (spix) = ( b4 f ) CREATE aspfpgsz 64 ,
SWAP (spix) SWAP ( r4 f ) NOT IF ABORT" AVR err" THEN ; VARIABLE aspprevx
: _x ( a -- b ) DUP aspprevx ! (spix) ;
: _xc ( a -- b ) DUP (spix) ( a b )
DUP aspprevx @ = NOT IF ABORT" AVR err" THEN ( a b )
SWAP aspprevx ! ( b ) ;
: _cmd ( b4 b3 b2 b1 -- r4 ) _xc DROP _x DROP _xc DROP _x ;
: asprdy ( -- ) BEGIN 0 0 0 0xf0 _cmd 1 AND NOT UNTIL ;
: asp$ ( -- ) : asp$ ( -- )
( RESET pulse ) (spie) (spid) (spie) ( RESET pulse ) (spie) (spid) (spie)
( wait 20ms ) 2000 0 DO LOOP ( wait >20ms ) 5000 0 DO LOOP
( enable prog ) 0 0 0x53 0xac _cmd DROP ; ( enable prog ) 0xac (spix) DROP
: asprdy ( -- f ) 0 0 0 0xf0 _cmd NOT ; 0x53 _x DROP 0 _xc DROP 0 _x DROP ;
: aspfl@ ( -- lfuse ) 0 0 0 0x50 _cmd ; : asperase 0 0 0x80 0xac _cmd asprdy ;
: aspfh@ ( -- hfuse ) 0 0 0x08 0x58 _cmd ;
: aspfe@ ( -- efuse ) 0 0 0x00 0x58 _cmd ;
: aspfl! ( lfuse -- ) 0 0xa0 0xac _cmd ;
: aspfh! ( hfuse -- ) 0 0xa8 0xac _cmd ;
: aspfe! ( efuse -- ) 0 0xa4 0xac _cmd ;

7
blk/692 Normal file
View File

@ -0,0 +1,7 @@
( fuse access. read/write one byte at a time )
: aspfl@ ( -- lfuse ) 0 0 0 0x50 _cmd ;
: aspfh@ ( -- hfuse ) 0 0 0x08 0x58 _cmd ;
: aspfe@ ( -- efuse ) 0 0 0x00 0x58 _cmd ;
: aspfl! ( lfuse -- ) 0 0xa0 0xac _cmd ;
: aspfh! ( hfuse -- ) 0 0xa8 0xac _cmd ;
: aspfe! ( efuse -- ) 0 0xa4 0xac _cmd ;

13
blk/693 Normal file
View File

@ -0,0 +1,13 @@
: aspfb! ( n a --, write word n to flash buffer addr a )
SWAP 256 /MOD ( a lo hi ) SWAP ROT ( hi lo a )
DUP ROT ( hi a a lo ) SWAP ( hi a lo a )
0 0x40 ( hi a lo a 0 0x40 ) _cmd DROP ( hi a )
0 0x48 _cmd DROP ;
: aspfp! ( page --, write buffer to page )
0 SWAP aspfpgsz @ * 256 /MOD ( 0 lsb msb )
0x4c _cmd DROP asprdy ;
: aspf@ ( page a -- n, read word from flash )
SWAP aspfpgsz @ * OR ( addr ) 256 /MOD ( lsb msb )
2DUP 0 ROT ROT ( lsb msb 0 lsb msb )
0x20 _cmd ( lsb msb low )
ROT ROT 0 ROT ROT ( low 0 lsb msb ) 0x28 _cmd 8 LSHIFT OR ;

View File

@ -48,3 +48,22 @@ batch, that is, running your commands right after the "asp$" command, ending
your batch with "(spid)" so that the next batch works. In my tests, interacting your batch with "(spid)" so that the next batch works. In my tests, interacting
with the chip "live" in a single "asp$" session sometimes resulted in unreliable with the chip "live" in a single "asp$" session sometimes resulted in unreliable
data that didn't properly detect sync errors. TODO: investigate further. data that didn't properly detect sync errors. TODO: investigate further.
# Writing data to Flash
Writing to AVR's flash is done in batch mode, page by page. To this end, the
chip has a buffer which is writable byte-by-byte. To write to the flash, you
begin by writing to that buffer using aspfb! and then write to a page using
aspfp!.
Please note that aspfb! deals with *words*, not bytes. If, for example, you want
to hook it to A!*, make sure you use AMOVEW instead of AMOVE. You will need to
create a wrapper word around aspfb! that divides dst addr by 2 because AMOVEW
use byte-based addresses but aspfb! uses word-based ones. You also have to make
sure that A@* points to @ (or another word-based fetcher) instead of its default
value of C@.
Beware of bootloader sections! By default, AVR chips have a bootloader using the
first few pages (by default, the ATMega328P uses 4 pages for its bootloader).
Check (or modify) the BOOTSZ fuses to confirm where you whould start writing
your program.