thumb; ;jump table for functions in this library b read ;Flash.read(adr) adr is word aligned (word size 4 bytes) b unlock ;Flash.unlock() b write ;Flash.write(adr,val) adr is word aligned (word size 4 bytes) b erase ;Flash.erase(adr) adr is page aligned (page size 2048 bytes) b cpymem ;Flash.copyMem(adrMem,adrFlash,size) b pagesf ;Flash.isPageSafe(adr) adr is page aligned ;Flash.copyMem(Source adress, target adress in flash memory, bytes to copy) ;all values will be word aligned (4 bytes = 1 word) pagesf: mov r1,0x7ff ;r1 = 2047 bic r0,r1 ;align address to page start mov r1,0x800 ;length of page mov r3,-1 ;memory is -1 if empty pagel: ldr r2,[r0] ;load value cmp r2,r3 ;is it -1 ? bne pagef ;no add r0,4 ;next word sub r1,4 cmp r1,0 ;all done bgt pagel ;if not pagef: mov r0,r1 ;return 0 if page safe, else 1st bad adress on page bx lr cpymem: push {r4-r7,lr} ;save register to stack mov r3,3 ;r3 = 3 bic r0,r3 ;align source adress for word bic r1,r3 ;align target adress for word bic r2,r3 ;align bytes to copy bl initw ;initialize writing mov r4,r0 ;r4 = sourceadr mov r5,r1 ;r5 = targetadr mov r6,r2 ;r6 = length to copy copym1: mov r0,r5 ;r0 = targetadress ldr r1,[r4] ;r1 value from sourceadress bl writew ;write word add r4,4 ;move sourceadr to next word add r5,4 ;move targetadr to next word sub r6,4 ;count = count - 4 bytes (1 word) cmp r6,0 ;set flags bgt copym1 ;more to do ? bl exitw ;set writing off pop {r4-r7,lr} ;get register back bx lr ;end of function return to interpreter ;Flash.read(adress to read) reads one word (similar to peek32) ;adress will be aligned to word read: push {r4-r7} ;save register to stack mov r1,3 ;r1 = 3 bic r0,r1 ;align for word ldr r0,[r0] ;peek(r0) pop {r4-r7} bx lr ;Flash.unlock() unlocks writing to flash unlock: push {r4-r7} ;save register to stack ldr r7,[KEYR] ;r7 = KEYR ldr r0,[unl1] ;r0 = 45670123 str r0,[r7] ;poke32(KEYR,r0) ldr r0,[unl2] ;r0 = CDEF89AB str r0,[r7] ;poke32(KEYR,r0) pop {r4-r7} bx lr ;Flash.write(targetadress in flash,value) ;targetadress will be aligned to word, value is a word (4 bytes) write: push {r4-r7,lr} ;save register to stack mov r4,3 ;r3 = 3 bic r0,r4 ;align for word bl initw ;initialize writing bl writew ;write word to flash bl exitw ;set writing off pop {r4-r7,lr} bx lr ;local subroutine to initialize writing mode initw: push {r4,lr} ldr r7,[CR] ;r7 = CR bl waits ldr r4,[r7] ;r4 = peek32(CR) orr r4,#1 ;set bit 0 str r4,[r7] ;poke32(CR,r4) pop {r4,lr} bx lr ;local subroutine to exit writing mode exitw: push {r4,r5} ldr r4,[r7] ;r4 = peek32(CR) mov r5,#1 ;r5 = 1 bic r4,r5 ;reset bit 0 str r4,[r7] ;poke32(CR,r4) pop {r4,r5} bx lr ;local subroutine to write value given in r1 to adress given in r0 writew: push {lr} ; strh r1,[r0] ;poke16(adr,r1) bl waits lsr r1,16 ;shift right add r0,#2 ;addr + 2 strh r1,[r0] ;poke16(adr,r1) bl waits ;wait for operation done pop {lr} bx lr ;Flash.erase(adress to erase) ;adress will be page aligned (2048 bytes) erase: push {r4-r7,lr} ;save register to stack bl waits mov r1,0x7ff ;r1 = 2047 bic r0,r1 ;align address to page start ldr r7,[CR] ;r7 = CR ldr r6,[AR] ;r6 = AR ldr r3,[r7] ;r3 = peek32(CR) orr r3,#2 ;r3 or 2 str r3,[r7] ;poke32(CR,r3) str r0,[r6] ;poke32(AR,r0) ldr r3,[r7] ;r3 = peek32(CR) orr r3,#64 ;r3 or 64 str r3,[r7] ;poke32(CR,r3) bl waits ldr r3,[r7] ;r3 = peek32(CR) mov r2,#2 ;r2 = 2 bic r3,r2 ;bit clear 2 str r3,[r7] ;poke32(CR,r3) pop {r4-r7,lr} bx lr ;for testing purposes only wait: push {r4-r7,lr} bl waits push {r4-r7,lr} bx lr ;local subroutine to wait for finishing last Flash command waits: push {r4-r7} ldr r7,[SR] waits1: ldr r6,[r7] and r6,#1 mov r5,0 cmp r6,r5 bne waits1 pop {r4-r7} mov pc,lr ;adress of register, used to handle Flash KEYR: dw 0x40022004 SR: dw 0x4002200c CR: dw 0x40022010 AR: dw 0x40022014 unl1: dw 0x45670123 unl2: dw 0xcdef89ab