Hot!dsPIC33EP FlashPageErase causing jump to PC=0x0000

Author
jmadsenee
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/09/13 11:39:18
  • Location: Richmond, VA, USA
  • Status: offline
2018/02/09 08:56:34 (permalink)
0

dsPIC33EP FlashPageErase causing jump to PC=0x0000

Hi All,
 
I have been using the FlashPageErase routine for a few years on various dsPIC33EPxxxx processors and never had any problem.  Currently I am using it in a dsPIC33EP512MU810.  It had been working fine for weeks and then started causing the dsPIC to lock up (I was developing the application during this time, but never touched any of the Flash routines).  I traced the problem to the FlashPageErase routine.  I had been using it exactly as found the Microchip code examples - i.e. CE478. 
/******************************************************************************
  Flash Page Erase
  Erase EIGHT rows (PAGE) of memory
*******************************************************************************/
_FlashPageErase:
    push TBLPAG

    mov w0, TBLPAG ; Init Pointer to page to be erased
    mov w0,NVMADRU ; Init Pointer to row to be erased
    mov w1,NVMADR
    tblwtl w1, [w1]
    
    mov #FLASH_PAGE_ERASE_CODE,w7
    mov w7, NVMCON
    bset w7,#WR;NVMCON,#15
    disi #5 ; Block all interrupt with priority <7 for next 5 instructions
    mov #0x55, W0
    mov W0, NVMKEY
    mov #0xAA, W0
    mov W0, NVMKEY
    mov w7,NVMCON ; Start Program Operation
    nop
    nop


erase_wait:
  btsc NVMCON, #WR
  bra erase_wait

  clr w0

  pop TBLPAG
  return

  nop

If I set a break point in the beginning, stepped through, then pressed run again everything was fine.  If I set a breakpoint at "mov w7,NVMCON," then ran it from there, everything was fine.  If I put the breakpoint at the line before, "mov W0, NVMKEY," the dsPIC would lock up.  I moved my breakpoint back to the "mov w7,NVMCON" line and changed the properties to "Break occurs Count Instructions after Event" and started increasing the number of counts until I had a problem.  Up to 1360 counts it broke on the "btsc NVMCON, #WR" line.  at 1361 counts, it broke on PC = 0x0000. 
 
I modified the routine to be like Example 5-4 in Flash FRM (DS70609D-page 5-11) and did some experimentation:

/******************************************************************************
  Flash Page Erase
  int16 FlashPageErase(uint16 nvmAdru, uint16 nvmAdr);
  Erase 16 rows (PAGE) of memory
*******************************************************************************/
_FlashPageErase:
    push    TBLPAG
;    mov     w0, TBLPAG  ; Init Pointer to page to be erased     
    mov     w0,NVMADRU ; Init Pointer to row to be erased
    mov  w1,NVMADR
    nop
    nop
;    nop
;    tblwtl  w1, [w1]
   
    mov    #FLASH_PAGE_ERASE_CODE,w7
    mov     w7, NVMCON
    bset  w7,#WR;NVMCON,#15
    disi  #6    ; Block all interrupt with priority <7 for next 5 instructions
    mov   #0x55, W0
    mov   W0, NVMKEY
    mov   #0xAA, W0
    mov   W0, NVMKEY 
;    bset  NVMCON,#WR
    mov   w7,NVMCON  ; Start Program Operation
    nop
    nop

erase_wait:    
  btsc    NVMCON, #WR
  bra     erase_wait
  clr  w0
  pop     TBLPAG
  return
  nop

To make a long story short, commenting one of the nops on the 5th, 6th or 7th line makes the routine fail (causing a jump to PC: 0x0000).  Commenting none, two or three of the nops allows the routine to complete.  Obviously those nops don't need to be there, but other combinations of seemingly irrelevant changes causes the same problem. 
 
Does anyone have any idea what is going on? 
 
Thanks in advance for any assistance you can give!
 
John
 
 
 
#1

14 Replies Related Threads

    RISC
    Super Member
    • Total Posts : 4896
    • Reward points : 0
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 09:08:05 (permalink)
    0
    Hi,
    I suggest you look at the code generated by EZbootloader : http://www.microchip.com/EZBL
    this device has 2 flash panels so it is a little more tricky than standard dsPIC33EP devices
    Regards
     
    #2
    NorthGuy
    Super Member
    • Total Posts : 4783
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 13:00:30 (permalink)
    0
    I would suspect a watchdog, or possible some interrupt happening.
     
    To test for interrupts, set the DISI parameter to something around 1500 and see if you can go further than before.
    #3
    jmadsenee
    New Member
    • Total Posts : 22
    • Reward points : 0
    • Joined: 2017/09/13 11:39:18
    • Location: Richmond, VA, USA
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 13:49:13 (permalink)
    0
    Hi RISC,
    Are you suggesting that I generate my code with the bootloader or look at the bootloader code itself?  I don't need to use a bootloader and it looks like there would be a bit of a learning curve.  Since the routine is written in assembly, why would it come out different?
     
    Hi NorthGuy.
    I suspected the WDT first.  It is disabled and RCON shows no interrupt occurring.  Good idea to increase DISI count; I will try it.
     
    The problem seems to be related to the location of the code in memory.  I had been using XC16 V1.24.  It put the code (working version) at 0x36b2.  I upgraded to the latest compiler V1.33.  It put the routine at 0x353c and it fails.  I had v1.32 on my machine; it put the routine at 0x34fc and it fails.  For giggles, I tried forcing the code to a specific location:

     .section *,address(0x5000),code
     .global _FlashPageRead
     .global _FlashPageErase
     .global _FlashPageWrite
     .global _FlashPageModify
     .global _flashWordModify
     .global _flashWordRead

    It worked fine with all 3 compilers.  I changed the address to 0x10000.  Again, worked fine with all 3 compilers.
     
    #4
    jmadsenee
    New Member
    • Total Posts : 22
    • Reward points : 0
    • Joined: 2017/09/13 11:39:18
    • Location: Richmond, VA, USA
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 14:43:49 (permalink)
    0
    Increasing DISI does delay the crash.  If I set a breakpoint, count = 2000, DISI = 6, when it stops, PC = 0.  If I set DISI = 2100, breakpoint count = 2000, it stops at "erase_wait:" as it should. 
     
    If I disable interrupts while erasing/writing flash, I have no problem with any of the 3 compilers (I am no longer forcing an address with ".section *,address(0x5000),code").

     _GIE = 0;
     FlashPageErase(nvram_addru, nvram_addr);
     flashWordModify(nvram_addru, nvram_addr, NONVRAMDATA, nvram_data);
     _GIE = 1;  

    Another thing to note:  when using V1.33 compiler, it is no longer failing during FlashPageErase.  It is failing in flashWordModify. 
    #5
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 15:29:59 (permalink)
    0
    You need two nops.
     
    Put in some check code in case you are erasing the code that is running.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #6
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 15:32:47 (permalink)
    0
    _flash_getpstart:
        mov     #tblpage(protect_start),w1
        mov     #tbloffset(protect_start),w0
        return
     
    _flash_getpend:
        mov     #tblpage(protect_end),w1
        mov     #tbloffset(protect_end),w0
        return


     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #7
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/09 15:39:35 (permalink)
    0
    ;----------------------------------------------------
    .equ arg_OP,    w0

    update_flash:
        mov     arg_OP,NVMCON
        push    SR
        mov     #0x00E0,w0
        ior     SR
        mov     #0x55,w0
        mov     w0,NVMKEY
        mov     #0xAA,w0
        mov     w0,NVMKEY
        bset    NVMCON,#WR
        nop
        nop
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    loop_wait:
        btsc    NVMCON,#WR
        bra     loop_wait
        pop     SR
        return
    protect_end:
    ;----------------------------------------------------

     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #8
    jmadsenee
    New Member
    • Total Posts : 22
    • Reward points : 0
    • Joined: 2017/09/13 11:39:18
    • Location: Richmond, VA, USA
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/12 12:26:53 (permalink)
    0
    Hi Gort2015,
     
    Thanks for all your suggestions!  I appreciate your time. 
     
    The two nops have always been there after setting NVMCON, #WR.  I uploaded the code to a file both right after I downloaded it and after running FlashPageErase and locking up.  Running a compare of the files, the only difference was the page that was erased, so it is definitely not erasing running code.
     
    Trying your suggestion of setting the Interrupt Priority Level = 7 fixed the problem in FlashPageErase when using compiler V1.24, but not with compiler V1.33, because the problem moves to flashWordModify.  Raising the Interrupt Priority Level in place of using DISI 6 in flashWordModify fixes the problem there.  This is similar, but better, than when I set GIE = 0 when running the flash routines.
     
    This all begs the questions:  Why does an interrupt while waiting for NVMCON, #WR to clear cause a jump to 0x0000?  Why does forcing the code to be in a different location cause the problem not to occur?
    #9
    jmadsenee
    New Member
    • Total Posts : 22
    • Reward points : 0
    • Joined: 2017/09/13 11:39:18
    • Location: Richmond, VA, USA
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/12 14:09:15 (permalink)
    0
    Gort2015, why do you do a dummy write:


    erase:
        mov     arg_pDest_H,TBLPAG
        tblwtl  arg_pDest_L,[arg_pDest_L]       ;dummy write
        mov     #FLASH_ERASE_CODE,w0        ;erase one page
        rcall   update_flash
        mov     #FLERROR_OK,w4
        return

    #10
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/12 15:21:10 (permalink)
    0
    I wrote that ages ago but I think it was in the specs. that a dummy write is required.
    Seen that in a few chips.
    This saves the STATUS then stops interrupts.
    push    SR
    mov     #0x00E0,w0
    ior     SR
     
    You should not have interrupts running.  It's all syncronized, it must be free running.
    If you are getting a reset, you could be erasing the code that is actually running that is why is it a good idea to put a guard in place.
    A guard to check the page to be erased does not erase the page containing the executing code.
     
     
    Instant resume interrupts.
    pop     SR

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #11
    NorthGuy
    Super Member
    • Total Posts : 4783
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/12 15:22:54 (permalink)
    0
    Apparently, an interrupt is happening somewhere in the process, possibly trying to execute some code in the flash being erased/written. Find the bad interrupt and disable it, or even disable them all during flash erase/write.
     
    RCON will not indicate interrupts happening in your code - only the final reset cause.
    #12
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/12 15:34:31 (permalink)
    0
    I did post the NVMADRU and NVMADR setup on a similar thread.
     
    Global Interrupt Enable (GIE) needs to be disabled and you should also save the STATUS register.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #13
    jmadsenee
    New Member
    • Total Posts : 22
    • Reward points : 0
    • Joined: 2017/09/13 11:39:18
    • Location: Richmond, VA, USA
    • Status: offline
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/13 07:06:05 (permalink)
    0
    Thanks guys, for all your help.  I followed Gort2015's method of having a separate update_flash routine that would set the Interrupt Priority Level = 7 in SR before setting NVMCON,#WR and then restoring SR after the operation was complete (NVMCON,#WR is cleared).  I put FLASH_PAGE_ERASE_CODE, FLASH_ROW_PROG_CODE, or FLASH_WORD_PROG_CODE in w0 and call the update_flash routine.
     
    There was no code in the page that was being erased; it was just some saved parameters.  I took care to make sure no code could be saved on that page.
    #14
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1913
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: dsPIC33EP FlashPageErase causing jump to PC=0x0000 2018/02/13 07:46:06 (permalink)
    0
    Protection to stop executing code from erasure.
    ;----------------------------------------------------
    .equ arg_pDest_L,   w0
    .equ arg_pDest_H,   w1
    .equ block_start24, w0
    .equ block_start,   w1
    .equ code_start24,  w2
    .equ code_start,    w3
    .equ code_end24,    w4
    .equ code_end,      w5
    .equ block_end24,   w6
    .equ block_end,     w7
    .equ SP,           w15
    ;rtn error,         w4

    protect_start:
    eraseflash:
        ;check block aligned
        mov     #0x3ff,w6
        and     arg_pDest_L,w6,w6
        bra     nz,error_block_align
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;1MB flash not available
        cp      arg_pDest_H,#16
        bra     gtu,error_memory
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;code start
        mov     #tblpage(protect_start),code_start24
        mov     #tbloffset(protect_start),code_start
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;code end
        mov     #tblpage(protect_end),code_end24
        mov     #tbloffset(protect_end),code_end
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;check erase self
        mov     #1024,w6    ;block addr size
        push    w6
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;block end=block_start+512 instructions
        mov     block_start24,block_end24
        add     block_start,[--SP],block_end
        addc    #0,block_end24
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ;block start in code?
        cp      block_start24,code_start24
        cpb     block_start,code_start
        bra     ltu,check_end
        cp      block_start24,code_end24
        cpb     block_start,code_end
        bra     leu,error_code_overwrite
        ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    check_end:
        ;block end in code?
        cp      block_end24,code_start24
        cpb     block_end,code_start
        bra     ltu,erase
        cp      block_end24,code_end24
        cpb     block_end,code_end
        bra     leu,error_code_overwrite
       ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    erase:
        mov     arg_pDest_H,TBLPAG
        tblwtl  arg_pDest_L,[arg_pDest_L]       ;dummy write
        mov     #FLASH_ERASE_CODE,w0        ;erase one page
        rcall   update_flash
        mov     #FLERROR_OK,w4
        return
    ;----------------------------------------------------

    "protect_end:" would appear after any writing code.
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #15
    Jump to:
    © 2018 APG vNext Commercial Version 4.5