The sequence of events for programming an erased single word of internal program memory location are as follows:
; 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