Datasheet

223
7728G–AVR–06/10
ATtiny87/ATtiny167
20.2.7 Simple Assembly Code Example for a Boot Loader
Note that the RWWSB bit will always be read as zero in ATtiny87/167. Nevertheless, it is
recommended to check this bit as shown in the code example, to ensure compatibility with
devices supporting Read-While-Write.
;- The routine writes one page of data from RAM to Flash
; the first data location in RAM is pointed to by the Y-pointer
; the first data location in Flash is pointed to by the Z-pointer
;- Error handling is not included
;- Registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
; loophi (r25), spmcsrval (r20)
; - Storing and restoring of registers is not included in the routine
; register usage can be optimized at the expense of code size
.equ PAGESIZEB = PAGESIZE*2 ; AGESIZEB is page size in BYTES, not words
.org SMALLBOOTSTART
Write_page:
; Page Erase
ldi spmcsrval, (1<<PGERS) | (1<<SELFPGEN)
rcall Do_spm
; Clear temporary page buffer
ldi spmcsrval, (1<<CPTB) | (1<<SELFPGEN)
rcall Do_spm
; Transfer data from RAM to Flash temporary page buffer
ldi looplo, low(PAGESIZEB) ; init loop variable
ldi loophi, high(PAGESIZEB) ; not required for PAGESIZEB<=256
Wrloop:
ld r0, Y+
ld r1, Y+
ldi spmcsrval, (1<<SELFPGEN)
rcall Do_spm
adiw ZH:ZL, 2
sbiw loophi:looplo, 2 ; use subi for PAGESIZEB<=256
brne Wrloop
; Execute Page Write
subi ZL, low(PAGESIZEB) ; restore pointer
sbci ZH, high(PAGESIZEB) ; not required for PAGESIZEB<=256
ldi spmcsrval, (1<<PGWRT) | (1<<SELFPGEN)
rcall Do_spm
; Clear temporary page buffer
ldi spmcsrval, (1<<CPTB) | (1<<SELFPGEN)
rcall Do_spm
; Read back and check, optional
ldi looplo, low(PAGESIZEB) ; init loop variable
ldi loophi, high(PAGESIZEB) ; not required for PAGESIZEB<=256
subi YL, low(PAGESIZEB) ; restore pointer
sbci YH, high(PAGESIZEB)
Rdloop:
lpm r0, Z+