Pag 79 - Scrittura
della Flash
|
Scrittura della FLASH
La scrittura della FLASH si effettua su un minimo di 4 words
(8 bytes) per volta.
Dunque, non è possibile scrivere un solo byte e, una volta cancellata un'
area di 64 bytes, occorrono 8 azioni di scrittura per riempirla nuovamente.
La scrittura avviene prima in un buffer interno da 8 bytes
(holding register). Quindi il buffer è scritto nella FLASH
La tensione di scrittura della FLASH è generata da una
charge pump interno ed è valida per qualsiasi tensione di alimentazione del
range di funzionamento del chip.
Una operazione di scrittura, che richiede prima la
cancellazione, si sviluppa con i seguenti passi:
-
leggere 64 bytes in RAM
-
caricare il puntatore TBLPTR con l' indirizzo del blocco
su cui operare
-
eseguire la cancellazione del blocco
-
caricare il puntatore TBLPTR con l' indirizzo del blocco
su cui operare
-
scrivere 8 bytes nel registro di holding
-
Programmare EECON1:
-
EEPGD = 1 per selezionare la memoria
-
CFGS = 0 per accedere alla memoria programma
-
WREN = 1 per abiliotare la scrittura
-
Disabiltare l' interrupt
-
Scrivere la chiave 55h in EECON2
-
Scrivere la chiave AAh in EECON2
-
Portare a 1 il bir WR in EECON1. Questo avvia il ciclo
di cancellazione
-
La CPU è in stallo per circa 2 ms, fino al termine
dell' operazione di cancellazione
-
Riabilitare gli interrupt
-
Verificare la corretta scrittura nella memoria (con
TBLRD)
Ad esempio:
; copia un blocco di dati da 64
bytes
movlw D'64
; numero di byte in un blocco
movwf COUNTER
movlw BUFFER_ADDR_HIGH ; puntatore sul
buffer
movwf FSR0H
movlw BUFFER_ADDR_LOW
movwf FSR0L
movlw CODE_ADDR_UPPER ; carica
TBLPTR con l' indirizzo base
mowvf TBLPTRU
; del blocco di memoria
movlw CODE_ADDR_HIGH
mowvf TBLPTRH
movlw CODE_ADDR_LOW ; 6
LSB = 0
mowvf TBLPTRL
READ_BLOCK
tblrd*+
; copia in TABLAT e incrementa pointer
movfw TABLAT
; leggi dato
movwf POSTINC0
; salva indiretto e incrementa puntatore
decfsz COUNTER
; fine dati ?
bra READ_BLOCK
; no- ripeti
; si - update del blocco
MODIFY_WORD
movlw DATA_ADDR_HIGH ;
puntatore sul buffer
mowvf FSR0H
movlw DATA_ADDR_LOW
mowvf FSR0L
movlw NEW_DATA_LOW
; update buffer e incrementa FSR0
mowvf POSTINC0
movlw NEW_DATA_HIGH
; update buffer
mowvf INDF0
; inizia cancellazione del blocco
ERASE _BLOCK
movlw CODE_ADDR_UPPER ;
carica TBLPTR con l' indirizzo base
mowvf TBLPTRU
; del blocco di memoria
movlw CODE_ADDR_HIGH
mowvf TBLPTRH
movlw CODE_ADDR_LOW
; 6 LSB = 0
mowvf TBLPTRL
bcf EECON1, CFGS
; PROG/EEPROM memory
bsf EECON1, EEPGD
; Flash program memory
bsf EECON1, WREN
; enable write to memory
bsf EECON1, FREE
; enable Row Erase
bcf INTCON, GIE
; stop interrupt
movlw 55h
; chiave
mowvf EECON2
movlw AAh
mowvf EECON2
bsf EECON1, WR
; avvia cancellazione (CPU stall)
nop
bsf INTCON, GIE
; ri abilita interrupt
; scrivi flash
WRITE_BUFFER_BACK
movlw 8
; numero dei blocchi da 8 bytes
mowvf COUNTER_HI
movlw BUFFER_ADDR_HIGH ; pointer al
buffer
mowvf FSR0H
movlw BUFFER_ADDR_LOW
mowvf FSR0L
PROGRAM_LOOP
movlw 8
; numero dei bytes nell' holding register
mowvf COUNTER
WRITE_WORD_TO_HREGS
movfw POSTINC0
; prendi byte basso e incrementa FSR0
mowvf TABLAT
; copia dato in TABLAT
tblwt+*
; scrittura dell'holding register, incrementa TBLPTR
decfsz COUNTER
; loop fino a esaurimento dati
bra WRITE_WORD_TO_HREGS
; trasferisci holding register alla flash
PROGRAM_MEMORY
bcf INTCON, GIE
; stop interrupt
movlw 55h
; chiave
movwf EECON2
movlw AAh
movwf EECON2
bsf EECON1, WR
; start scrittura (CPU stall)
nop
bsf INTCON, GIE
; ri abilita interrupt
decfsz COUNTER_HI
; loop fino ad esaurimento dati
bra PROGRAM_LOOP
bcf EECON1, WREN
; disable write to memory |
Le due righe:
movfw
TABLAT
movwf POSTINC0 |
possono venir sostituite dall' unica riga:
e così pure:
movfw POSTINC0
movwf TABLAT |
possono venir sostituite dall' unica riga:
Vanno notati alcuni punti chiave:
-
TBLRD legge un bytes nella memoria FLASH e lo copia in
TABLAT.
-
TBLWT prende un byte da TABLAT e lo scrive nell' holding
register (e non nella memoria flash)
-
Di nuovo, l' operazione di scrittura richiede uno stop della
CPU per un certo tempo e quindi la sospensione dell' interrupt durante la
scrittura.
La scrittura della FLASH richiede, per sicurezza, la
verifica del dato scritto. Quindi, una operazione di scrittura in memoria
programma è composta da tre fasi distinte:
-
Cancellazione
-
Scrittura
-
Verifica
Abbiamo visto come cancellare e scrivere. Qui
trovate un semplice template che svolge tutte e tre le funzioni.
Si tratta di una subroutine che copia 8 bytes dalla RAM e li scrive nella
FLASH.
L' area RAM e l' area FLASH sono puntate da FSR0 e TBLPTR, a cura della
routine chiamante.
La subroutine verifica se l' area flash è l' inizio di un blocco da 64
bytes e, in questo caso, provvede anche alla cancellazione. Quindi,
ripetendo 8 volte la sub con l' aggiustamento dei pointer si ottiene la
completa scrittura del blocco.
Se la scrittura non è riuscita, la sub pone a 1 un flag di errore.
Se una scrittura nella memoria programma FLASH viene
terminata in modo irregolare, ad esempio per una mancanza di tensione o per
un RESET inatteso, l' area in corso di programmazione va verificata e, se
non scritta correttamente, va ri scritta.
Se la scrittura è unterrotta da MCLR o WDT l' utente può verificare lo
stato della programmazione attraverso il flag WRERR.
Va ricordato che nella sezione di CONFIG del processore è
possibile abilitare un meccanismo di protezione dalla scrittura delle aree
della memoria programma.
Questo verrà dettagliato più avanti.
La tabella seguente riporta i registri e i bit coinvolti
nella scrittua/cancellazione della mempria FlASH.
Le aree evidenziate in grigio indicano bit non interessati
all' operazione.
- indica bit non implementati la cui lettura da 0.
|
|
Copyright © afg. Tutti i diritti riservati.
Aggiornato il 06/12/10.
|