• AVR Freaks

Hot!PIC16F NVM problem

Author
Geoff
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2011/05/07 19:05:12
  • Location: Melbourne Australia
  • Status: offline
2018/10/22 20:04:54 (permalink)
0

PIC16F NVM problem

MPLABX 5.5
PIC16f15313
mpasmx 5.81
PICKit 3  
 
As part of a larger project I need to use non volatile memory. The attached file, I think, is the bare basics to test the NVM operation. It does not appear to be working. I have written a couple of code lines at org 300h to see if they are replaced. Using debug, I halt on the nop after the 'call nvm_write' but there is no change to prog memory 300. I am not saving the row first because I will always be modifying only the first 2 locations. Thanks in advance for any assistance.
 


                    list p=16f15313 ; list directive to define processor

#include <F:\PICs\PICLock\PICLock.X\p16f15313.inc> ; processor specific variable definitions

                    errorlevel -302 ; suppress message 302s fromlist file
                    errorlevel -306 ; suppress message 306s fromlist file

; program configuration register

; CONFIG1
; __config 0xD7DC
 __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT1 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_OFF
; CONFIG2
; __config 0xE73F
 __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_OFF & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_OFF
; CONFIG3
; __config 0xC080
 __CONFIG _CONFIG3, _WDTCPS_WDTCPS_0 & _WDTE_OFF & _WDTCWS_WDTCWS_0 & _WDTCCS_LFINTOSC
; CONFIG4
; __config 0xFFFF
 __CONFIG _CONFIG4, _BBSIZE_BB512 & _BBEN_OFF & _SAFEN_OFF & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_ON
; CONFIG5
; __config 0xFFFF
 __CONFIG _CONFIG5, _CP_OFF


;;/============================================================================

;/ Data storage for nvm row data - 64 bytes

data2: udata 0x0a0

nvm_code res 1
nvm_length res 0x3f

;/============================================================================

; all banks ram (71 to 7e)

data3: udata_shr ; starts at 070

loopcount res 1

addrh res 1
addrl res 1

;/============================================================================
;/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;/============================================================================
                    org 0x000 ; processor reset vector
                    goto initialise ; go to beginning of program
;/============================================================================
;/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;/============================================================================

                    org 0x020

;/============================================================================
initialise:
;/============================================================================
    
;/ Disable Modules
    
      banksel pmd0
      movlw b'01000011'
      movwf pmd0
      
      movlw b'10000010'
      movwf pmd1
      
      movlw b'01100111'
      movwf pmd2
      
      movlw b'00111111'
      movwf pmd3
      
      movlw b'00011110'
      movwf pmd4
      
      movlw b'01010001'
      movwf pmd5

;/============================================================================

;/ PortA

                    banksel ansela
                    clrf ansela ; All digital I/O

                    banksel trisa
                    clrf trisa
      bsf trisa,2

                    banksel wpua
                    clrf wpua
      bsf wpua,2 ; Weak Pullup on RA2

                    banksel porta
                    clrf porta

                    banksel lata
                    clrf lata
      
;/============================================================================

;/ Clear RAM 0x0a0 64 bytes

                    bankisel nvm_code
                    movlw nvm_code
                    movwf fsr1

                    movlw 0x40
                    movwf loopcount
loop2:
                    clrf indf1
                    incf fsr1,f

                    decfsz loopcount,f
                    goto loop2

;/============================================================================

;/ Clear All banks RAM
      
      clrf addrh
      clrf addrl

      clrf nvmadr
      clrf nvmcon1
      clrf nvmcon2
      clrf nvmdat
      
      
;/============================================================================
;/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;/============================================================================

mainloop:

      banksel porta
      btfsc porta,2
      goto mainloop
      
      call gjc
      
      nop
      
      goto mainloop

gjc:
      
;/ Erase and write to NVM
      movlw b'00000000'
      movwf addrl
      movlw b'00000011'
      movwf addrh
      
      call nvm_erase
      
      banksel nvm_code
      movlw d'255'
      movwf nvm_code
      movlw d'8'
      movwf nvm_length
      
      
      
      call nvm_write
      
      
      nop
      
      
      return
      
      
;/============================================================================
nvm_erase:
;/============================================================================
    
      banksel nvmadrl
      movfw addrl
      movwf nvmadrl ; Load lower 8 bits of erase address boundary
      movfw addrh
      movwf nvmadrh ; Load upper 6 bits of erase address boundary
      bcf nvmcon1,nvmregs ; Choose PFM memory area
      bsf nvmcon1,free ; Specify an erase operation
      bsf nvmcon1,wren ; Enable writes
      ; -------------------------------REQUIRED UNLOCK SEQUENCE:------------------------------
      bcf intcon,gie ; Disable interrupts during unlock sequence
      
      banksel nvmcon2
      movlw 0x55 ; Load 55h to get ready for unlock sequence
      movwf nvmcon2 ; First step is to load 55h into nvmCON2
      movlw 0xaa ; Second step is to load AAh into W
      movwf nvmcon2 ; Third step is to load AAh into nvmCON2
      bsf nvmcon1,wr ; Final step is to set WR bit
      bsf intcon,gie ; Re-enable interrupts, erase is complete
      ; --------------------------------------------------------------------------------------
      bcf nvmcon1,wren ; Disable writes

      return
      
;/============================================================================
nvm_write:
;/============================================================================

; This write routine assumes the following:
; 1. 64 bytes of data are loaded, starting at the address in nvm_code
; 2. Each word of data to be written is made up of two adjacent bytes in nvm_code,
; stored in little endian format
; 3. A valid starting address (the least significant bits = 00000) is loaded in ADDRH:ADDRL
; 4. ADDRH and ADDRL are located in common RAM (locations 0x70 - 0x7F)
; 5. nvm interrupts are not taken into account


      
;/ Write nvm - char_str at 0x0300
      
      
      
      banksel nvmadrh
      movfw addrh
      movwf nvmadrh ; Load initial address
      movfw addrl
      movwf nvmadrl
      
      banksel nvm_code
      movlw low nvm_code ; Load initial data address
      movwf fsr0l
      movlw high nvm_code
      movwf fsr0h
      
      banksel nvmcon1
      bcf nvmcon1,nvmregs ; Set Program Flash Memory as write location
      bsf nvmcon1,wren ; Enable writes
      bsf nvmcon1,lwlo ; Load only write latches

loop3:
      moviw fsr0++
      movwf nvmdatl ; Load first data byte
      moviw fsr0++
      movwf nvmdath ; Load second data byte
      movfw nvmadrl
      xorlw 0x1f ; Check if lower bits of address are 00000
      andlw 0x1f ; and if on last of 32 addresses
      btfsc status,z ; Last of 32 words?
      goto start_write ; If so, go write latches into memory
      call unlock_seq ; If not, go load latch
      incf nvmadrl,f ; Increment address
      goto loop3
start_write:
      bcf nvmcon1,lwlo ; Latch writes complete, now write memory
      call unlock_seq ; Perform required unlock sequence
      bcf nvmcon1,wren ; Disable writes
unlock_seq:
      ; -------------------------------REQUIRED UNLOCK SEQUENCE:------------------------------
      bcf intcon,gie ; Disable interrupts
      movlw 0x55
      movwf nvmcon2 ; Begin unlock sequence
      movlw 0xaa
      movwf nvmcon2
      bsf nvmcon1,wr
; bsf intcon,gie ; Unlock sequence complete, re-enable interrupts
      ; --------------------------------------------------------------------------------------

      return
      
      
      

;/============================================================================
;/============================================================================
;/============================================================================

;/ nvm

; org 300h
;
;;/============================================================================
; retlw d'1'
; retlw d'2'
;/============================================================================

     end

#1

2 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9998
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: PIC16F NVM problem 2018/10/22 20:15:40 (permalink)
    +1 (1)
    geoffc
    Using debug, I halt on the nop after the 'call nvm_write' but there is no change to prog memory 300.

    The memory view in MPLABX is NOT a live view.
    You must to a manual read operation to see any changes.
     

    Nearly there...
    #2
    Geoff
    Starting Member
    • Total Posts : 42
    • Reward points : 0
    • Joined: 2011/05/07 19:05:12
    • Location: Melbourne Australia
    • Status: offline
    Re: PIC16F NVM problem 2018/10/22 23:46:14 (permalink)
    0
    fixed. Thanks
    #3
    Jump to:
    © 2019 APG vNext Commercial Version 4.5