beautypg.com

Simple assembly code example for a boot loader, Atmega169v/l – Rainbow Electronics Atmega169L User Manual

Page 262

background image

262

ATmega169V/L

2514A–AVR–08/02

Simple Assembly Code
Example for a Boot Loader

;-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

;-the routine must be placed inside the Boot space

; (at least the Do_spm sub routine). Only code inside NRWW section can

; be read during Self-Programming (Page Erase and Page Write).

;-registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),

; loophi (r25), spmcrval (r20)

; storing and restoring of registers is not included in the routine

; register usage can be optimized at the expense of code size

;-It is assumed that either the interrupt table is moved to the Boot

; loader section or that the interrupts are disabled.

.equ

PAGESIZEB = PAGESIZE*2

;PAGESIZEB is page size in BYTES, not words

.org SMALLBOOTSTART

Write_page:

; Page Erase

ldi

spmcrval, (1<

call

Do_spm

; re-enable the RWW section

ldi

spmcrval, (1<

call

Do_spm

; transfer data from RAM to Flash 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

spmcrval, (1<

call

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

spmcrval, (1<

call

Do_spm

; re-enable the RWW section

ldi

spmcrval, (1<

call

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+

ld

r1, Y+

cpse

r0, r1

jmp

Error

sbiw

loophi:looplo, 1

;use subi for PAGESIZEB<=256

brne

Rdloop

; return to RWW section

; verify that RWW section is safe to read

Return:

in

temp1, SPMCSR

sbrs

temp1, RWWSB

; If RWWSB is set, the RWW section is not ready yet