Tutorials - PIC18 by Data Sheet

 

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:

  1. leggere 64 bytes in RAM

  2. caricare il puntatore TBLPTR con l' indirizzo del blocco su cui operare

  3. eseguire la cancellazione del blocco

  4. caricare il puntatore TBLPTR con l' indirizzo del blocco su cui operare

  5. scrivere 8 bytes nel registro di holding

  6. Programmare EECON1:

    • EEPGD = 1 per selezionare la memoria

    • CFGS = 0 per accedere alla memoria programma

    • WREN = 1 per abiliotare la scrittura

  7. Disabiltare l' interrupt

  8. Scrivere la chiave 55h in EECON2

  9. Scrivere la chiave AAh in EECON2

  10. Portare a 1 il bir WR in EECON1. Questo avvia il ciclo di cancellazione

  11. La CPU è in stallo per circa 2 ms, fino al termine dell' operazione di cancellazione

  12. Riabilitare gli interrupt

  13. 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: 

   movff  POSTINC0, TABLAT

e così pure: 

   movfw  POSTINC0
   movwf 
TABLAT 

possono venir sostituite dall' unica riga: 

   movff  TABLAT, POSTINC0

Vanno notati alcuni punti chiave:

  1. TBLRD legge un bytes nella memoria FLASH e lo copia in TABLAT.

  2. TBLWT prende un byte da TABLAT e lo scrive nell' holding register (e non nella memoria flash)

  3. 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:

  1. Cancellazione

  2. Scrittura

  3. 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.