Problem beim Zugriff auf Flash

pmac

Neues Mitglied
23. Sep. 2008
54
0
0
Sprachen
Hallo,
für einen AVR328P muss ich eine Blockschreiberoutine für das Flash erstellen. Als Grundlage habe ich das Beispiel aus dem Manual verwendet. Im Prinzip funktioniert es auch ganz gut, jedoch werden immer abwechselnd nur 64 Byte geschrieben. D.h. 64 Worte werden korrekt geschrieben, die nächten 64 Worte stehen auf 0, usw.
Dafür habe ich keine Erklärung ...
Hat jemand eine IDee ?

Danke
p.s. es soll natürlich Flash heissen in der Überschrift, aber diese lässt sich nicht ändern ...
 
Hallo Pmac,

eventuell adressierst du innerhalb der Page nicht richtig. Eine Page ist word-organisiert. Den Z-Pointer, welcher die Pageadresse enthält, musst du jedesmal um zwei erhöhen, nachdem du r0/r1 in die Page schreibst. Vielleicht erhöhst du nur um 1, dann würde die zweite Hälfte der Page nicht gefüllt.

... ist nurmal so eine Vermutung, genaueres kann ich vielleicht sagen, wenn du ein bisschen Sourcecode postest.

Gruß,
Dirk
 
Hallo Dirk,
ich poste den Code am Montag, da ich jetzt los muss un morgen nicht im Büro bin.
Peter
 
Hallo Dirk,
hier ist der Code (die Formatierung ist leider irgendwie abhanden gekommen ...) Im wesentlichen ist er aus der Doku des 328P übernommen ...
Danke für Deine Unterstützung.
Peter

.equ PAGESIZEB = 128 ;pagesize in bytes
.equ PGERS = 1 ;page erase bit
.equ SELFPRGEN = 0 ;SP enable bit
.equ RWWSRE = 4 ;App section read enable
.equ PGWRT = 2 ;page write bit
.equ RWWSB = 6 ;app section busy bit
.equ SPMCSR = 0x57 ;spm control register

.equ TCNT2 = 0x24 ;TCNT2 addresses (Borrow as a temp storage)..

.def spmcrval = R19 ;spm value for subroutine
.def temp1 = R20 ;temp register
.def temp2 = R21 ;ditto
.def errors = R18
.def looplo = R26 ;loop counter
.def loophi = R27

CLI ; disable all interrupts

;get page from data stack into Z
LDD R30,Y+2
LDD R31,Y+3

;get ram image buffer address from stack
LD R22,Y
LDD R23,Y+1

;save registers for return
ST -Y, R0
ST -Y, R1
ST -Y, R16
ST -Y, R18
ST -Y, R19
ST -Y, R20
ST -Y, R21
ST -Y, R22
ST -Y, R23
ST -Y, R26
ST -Y, R27
ST -Y, R30
ST -Y, R31

IN R0, SREG
ST -Y, R0
MOV R14,R28 ;save Y
MOV R15,R29

;get image data storage location into Y
mov R28, R22
mov R29, R23

Write_page:
; page erase
ldi spmcrval, (1<<PGERS) | (1<<SELFPRGEN)
call Do_spm
; re-enable the Application Section
ldi spmcrval, (1<<RWWSRE) | (1<<SELFPRGEN)
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+ ;get data byte from ram
ld r1, Y+
ldi spmcrval, (1<<SELFPRGEN)
call Do_spm
adiw R31:R30, 2 ; bump z
sbiw loophi:looplo, 2 ; (use with PAGESIZEB>256)
brne Wrloop
; execute page write
subi R30, low(PAGESIZEB) ; restore pointer
sbci R31, high(PAGESIZEB) ; restore upper byte of pointer
ldi spmcrval, (1<<PGWRT) | (1<<SELFPRGEN)
call Do_spm
; re-enable the Application Section
ldi spmcrval, (1<<RWWSRE) | (1<<SELFPRGEN)
call Do_spm
; read back and check, optional
ldi looplo,low(PAGESIZEB) ;init loop variable
ldi loophi,high(PAGESIZEB) ;not required for PAGESIZEB<=256
ldi errors,0 ;load error tester
subi R28, low(PAGESIZEB) ;restore pointer
sbci R29, high(PAGESIZEB)
Rdloop:
lpm r0, Z+
ld r1, Y+
cpse r0, r1
inc errors ;count errors
sbiw loophi:looplo, 2 ;(use for PAGESIZEB>256)
brne Rdloop
; return to Application Section
; verify that Application Section is safe to read
Return:
lds temp1, SPMCSR
sbrs temp1, RWWSB ; If ASB is set, the AS is not ready yet
rjmp goback ; go back to calling function
; re-enable the Applicaiton Section
ldi spmcrval, (1<<RWWSRE) | (1<<SELFPRGEN)
call Do_spm
rjmp Return
Do_spm:
; check for previous SPM activity..
Wait_spm:
lds temp1, SPMCSR
sbrc temp1, SELFPRGEN
rjmp Wait_spm
; input: spmcrval determines SPM action
; check that no EEPROM write access is running
Wait_ee:
sbic EECR, EEWE
rjmp Wait_ee
; SPM timed sequence
sts SPMCSR, spmcrval
spm
nop ; of next instruction
; check for SPM complete on next round..
ret

goback:
out TCNT2,errors ; load error indicator
MOV R28,R14 ; restore Y
MOV R29,R15
LD R0, Y+ ; restore registers
OUT SREG, R0
LD R31, Y+
LD R30, Y+
LD R27, Y+
LD R26, Y+
LD R23, Y+
LD R22, Y+
LD R21, Y+
LD R20, Y+
LD R19, Y+
LD R18, Y+
LD R16, Y+
LD R1, Y+
LD R0, Y+

SEI ; enable Interrupts
#endasm

return (TCNT2); //return error status
 
Problem hat sich erledigt. Die Routine ist ok, es lag am aufrufenden Programm.
Manchmal ist es gut, ein Wochenende vergehen zu lassen, bevor man sich den Code nochmals ansieht ...
Trotzdem Danke für die Hilfe
Peter
 
Hallo Peter,
Problem hat sich erledigt. Die Routine ist ok, es lag am aufrufenden Programm.
Manchmal ist es gut, ein Wochenende vergehen zu lassen, bevor man sich den Code nochmals ansieht ...

das kenne ich auch. Manchmal braucht man nur ein bisschen Abstand und plötzlich hat man den Fehler gefunden. ;)

Grüße,
Dirk
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)