SPM simulation

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there,

has anyone had the problem of AVR studio executing the SPM command and giving different results compared to a device running the same code?

My program simulates fine in AVR studio 4, but when I run the program on my ATMEGA16, it just clears the page, and does not write the page. Most odd.

Any ideas welcome.

Cheers, Brian.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

here is my assembler code for the page writing and erasing. I can't see why it's not writing the page. I have only got the bootloader set to 128bytes on my processor though, and this code is situated outside the bootloader area. Does this matter? It's still up in the NRWW memory area. Studio 4 doesn't want to program my bootloader size bits for some reason !?

.org 0x1C01

erasepage:
push r14
push r15
push r16
push r17
push r18
push r19

ld ZL, y
ldd ZH, y+1

ldi spmcrval, (1<<PGERS) + (1<<SPMEN);set the SPM command to page erase

call do_spm
call wait_RWW ; wait for the RWW section to become non-busy
pop r19
pop r18
pop r17
pop r16
pop r15
pop r14
ret

writepage:
push r14
push r15
push r16
push r17
push r18
push r19
cli
ld r16, y ; load the LSB of the page address to be written
ldd r17, y+1 ; load the MSB of the page address to be written
ldd r18, y+2 ; load the LSB of the ram address
ldd r19, y+3 ; load the MSB of the ram address

mov ZL, r16 ; load the LSB of the page address to be written
mov ZH, r17 ; load the MSB of the page address to be written
mov YL, r18 ; load the LSB of the ram address
mov YH, r19 ; load the MSB of the ram address

ldi loop, pagesize
wrloop:
ld r0, y+ ; load the first byte to store
ld r1, y+ ; load the second byte to store
ldi spmcrval, (1<<SPMEN) ; just set the enable flag
call do_spm ; write the word to the temporary flash buffer
adiw ZH:ZL, 2 ; move to the next word in the temp buffer*/
dec loop ; decrement page loop counter
brne wrloop ; loop back to the next word if not yet complete

subi ZL, pagesize ; reset the pointer to the start of our flash page
ldi spmcrval, (1<<PGWRT) + (1<< SPMEN) ; set the program page command and SPM enable
call do_spm ; write the page in flash
call wait_RWW ; wait for the section to be non-busy
sei

pop r19
pop r18
pop r17
pop r16
pop r15
pop r14

ret

do_spm:
in tempSREG, SREG ; store the current SREG contents
spm_wait: ; waits for any previous SPM routine to finish
in temp1, SPMCR ; grab the SPMCR register for branch testing
sbrc temp1, SPMEN ; skip the next, if the SPMCR register has cleared the SPMEN bit
rjmp spm_wait ; until it does, carry on waiting

out SPMCR, spmcrval ; load the instruction setup
spm ; do the page erase function

spm_wait2: ; waits for any previous SPM routine to finish
in temp1, SPMCR ; grab the SPMCR register for branch testing
sbrc temp1, SPMEN ; skip the next, if the SPMCR register has cleared the SPMEN bit
rjmp spm_wait2 ; until it does, carry on waiting

ldi spmcrval, (1<<RWWSRE) + (1<<SPMEN) ; setup the instruction (re-enable the RWW memory section)
out SPMCR, spmcrval ; instruct
spm ; execute SPM
out SREG, tempSREG
ret

wait_RWW: ; wait for the RWW section to become ready
in temp1, SPMCR
sbrc temp1, RWWSB
rjmp wait_RWW
ret