PFM Word Write Sequence

The sequence of events for programming an erased single word of internal program memory location are as follows:

  1. 1.Set NVMADR with the target word address.
  2. 2.Load NVMDAT with desired word.
  3. 3.Disable interrupts.
  4. 4.Execute the word/byte write sequence (see example below).
  5. 5.The GO bit is set as last step in the unlock sequence.
  6. 6.The CPU will stall for the duration of the write (about 50 μs using internal timer).
  7. 7.Re-enable interrupts.
  8. 8.Verify the memory (word read).

Writing a Word of Program Flash Memory

; Code sequence to program one erased word of PFM
; Target address is in WORD_ADDR_UPPER:WORD_ADDR_HIGH:WORD_ADDR_LOW
; Target data is in WORD_HIGH_BYTE:WORD_LOW_BYTE
; Calling routine should check WREG for the following error codes:
;
;    0x00 = Successful modification
;    0x01 = Read error 
;    0x03 = Write error 
;
WORD_WRITE:
        MOVF    WORD_ADDR_UPPER, W  ; load NVMADR with the target
        MOVWF   NVMADRU             ; address of the word
        MOVF    WORD_ADDR_HIGH, W
        MOVWF   NVMADRH
        MOVF    WORD_ADDR_LOW, W
        MOVWF   NVMADRL
        MOVF    WORD_HIGH_BYTE, W   ; load NVMDAT with desired
        MOVWF   NVMDATH             ; word
        MOVF    WORD_LOW_BYTE, W
        MOVWF   NVMDATL
        BCF     INTCON0, GIE        ; disable interrupts
        MOVLW   0x03                ; write word command
        MOVWF   NVMCON1             ; set command
PROGRAM_WORD:
; ----- Required Sequence -----       
        MOVLW   0x55
        MOVWF   NVMLOCK             ; first unlock byte = 0x55
        MOVLW   0xAA
        MOVWF   NVMLOCK             ; second unlock byte = 0xAA
        BSF     NVMCON0, GO         ; start word programming (CPU stall)
; ------------------------------        
        BTFSC   NVMCON1, WRERR      ; Verify no error occurred during write
        BRA     NVM_WRERR           ; return write error code
VERIFY_WORD:
        CLRF    NVMCON1             ; NVM read command
        BSF     NVMCON0, GO         ; retrieve byte
        MOVF    WORD_HIGH_BYTE, W   ; Verify high byte
        CPFSEQ  NVMDATH

        BRA     NVM_RDERR           ; not equal - return error code
        MOVF    WORD_LOW_BYTE, W    ; Verify low byte
        CPFSEQ  NVMDATL

        BRA     NVM_RDERR           ; not equal - return error code
        CLRF    WREG,F              ; return with no error
        BRA     NVM_EXIT
NVM_RDERR:
        MOVLW   0x01                ; Read error fault code
        BRA     NVM_EXIT
NVM_WRERR:
        MOVLW   0x03                ; Write error fault code
NVM_EXIT:
        CLRF   NVMCON1              ; disable NVM writes
        BSF    INTCON0, GIE         ; re-enable interrupts
        RETURN