avr: allow writing to flash
This commit is contained in:
parent
4910b9caef
commit
5b4917dbe9
2
blk/690
2
blk/690
@ -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
25
blk/691
@ -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
7
blk/692
Normal 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
13
blk/693
Normal 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 ;
|
19
doc/avr.txt
19
doc/avr.txt
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user