ldi
Wrloop:
ld
loophi, high(PAGESIZEB)
;not required for PAGESIZEB<=256
r0, Y+
ld
r1, Y+
ldi
spmcrval, (1<<SPMEN)
call Do_spm
adiw ZH:ZL, 2
sbiw loophi:looplo, 2
brne Wrloop
;use subi for PAGESIZEB<=256
; execute page write
subi ZL, low(PAGESIZEB)
sbci ZH, high(PAGESIZEB)
;restore pointer
;not required for PAGESIZEB<=256
ldi
spmcrval, (1<<PGWRT) | (1<<SPMEN)
call Do_spm
; re-enable the RWW section
ldi
spmcrval, (1<<RWWSRE) | (1<<SPMEN)
call Do_spm
; read back and check, optional
ldi
ldi
looplo, low(PAGESIZEB)
loophi, high(PAGESIZEB)
;init loop variable
;not required for PAGESIZEB<=256
;restore pointer
subi YL, low(PAGESIZEB)
sbci YH, high(PAGESIZEB)
Rdloop:
lpm
ld
r0, Z+
r1, Y+
cpse r0, r1
jmp Error
sbiw loophi:looplo, 1
brne Rdloop
;use subi for PAGESIZEB<=256
; return to RWW section
; verify that RWW section is safe to read
Return:
in
temp1, SPMCR
sbrs temp1, RWWSB
; If RWWSB is set, the RWW section is not
; ready yet
ret
; re-enable the RWW section
ldi
spmcrval, (1<<RWWSRE) | (1<<SPMEN)
call Do_spm
rjmp Return
Do_spm:
; check for previous SPM complete
Wait_spm:
in
temp1, SPMCR
sbrc temp1, SPMEN
rjmp Wait_spm
; input: spmcrval determines SPM action
; disable interrupts if enabled, store status
in
temp2, SREG
cli
; check that no EEPROM write access is present
Wait_ee:
sbic EECR, EEWE
rjmp Wait_ee
; SPM timed sequence
out
spm
SPMCR, spmcrval
; restore SREG (to enable interrupts if originally enabled)
out
ret
SREG, temp2
254
ATmega32(L)
2503J–AVR–10/06