This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can't change ERASEPROTECT.DISABLE value

If I write a value to ERASEPROTECT.DISABLE -- which itself works, as I'm fully able to perform the mass erase by writing the same value using the debugger -- I can't seem to write a new value to the register during the same boot. It presumably isn't flash-based, since it needs to be written each boot. Is this specifically being prevented by the core? Is there a way to "reset" the value and write a new one, assuming ERASEPROTECT.LOCK hasn't been set?

Parents
  • Hello, 

    I've found the following in modules\hal\nordic\nrfx\mdk\nrf9160.h

    /**
      * @brief CTRLAPPERI_ERASEPROTECT [ERASEPROTECT] (Unspecified)
      */
    typedef struct {
      __IOM uint32_t  LOCK;                         /*!< (@ 0x00000000) Lock register ERASEPROTECT.DISABLE from being
                                                                        written until next reset                                   */
      __IOM uint32_t  DISABLE;                      /*!< (@ 0x00000004) Disable ERASEPROTECT and perform ERASEALL                  */
    } CTRLAPPERI_ERASEPROTECT_Type;                 /*!< Size = 8 (0x8)    

    Kind regards,
    Øyvind

  • Looks like DISABLE is being read as zero, even after writing to it (which I've verified is working, since I can write from the debugger to trigger the mass erase). The register description in the datasheet indicates it should be read/write.

    So, clearly there's some under-the-hood handling of this register in the core that makes it act a little differently than other registers. This isn't any kind of a show-stopper, but it doesn't seem to behave the way I'd expect it to having read the datasheet.

  • Ahh, it appears there is an entire section I didn't know about in the NVMC section of the datasheet about specific steps to enable Non-Secure erase operations when Secure access is blocked. Hopefully all of this is my fault!

    Although the debugger should have access to these registers, since there are Non-Secure sets for them, so I would hope nrfjprog would already be setting these up if needed.

  • So, looks like we weren't setting NVMC to Non-Secure-accessible in the peripheral permission registers, which was preventing the debugger from using those registers at all. I found that, if I allow Non-Secure access to them and didn't use ERASEPROTECT, I could set SECUREAPPROTECT and the debugger could still do its nrfjprog --recover process. But, if I turn ERASEPROTECT back on, nrfjprog will no longer do anything, including --program <file> --sectorerase, since it doesn't like that "readback protection" is on.

    Since we don't want to allow anyone to erase our UICR and our Secure flash, we have to use ERASEPROTECT. Both 10.7.0 and 10.9.0 will not do the --sectorerase operation nor a manual --erasepage operation. Do you know what the "readback protection" is conditioned on? Is it something that could be bypassed in order to still do the page erase/flash write operations? I would think with NVMC now being Non-Secure-accessible this should work from the debugger.

  • Thanks for the feedback! This is valuable information that I will forward to our R&D team to verify behavior. 

    Investigating some more around the ERASEPROTECT, I found the following from modules\hal\nordic\nrfx\mdk\nrf9160_bitfields.h

    /* Register: CTRLAPPERI_ERASEPROTECT_LOCK */
    /* Description: Lock register ERASEPROTECT.DISABLE from being written until next reset */
    
    /* Bit 0 : Lock register ERASEPROTECT.DISABLE from being written until next reset */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos (0UL) /*!< Position of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Msk (0x1UL << CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos) /*!< Bit mask of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Unlocked (0UL) /*!< Register ERASEPROTECT.DISABLE is writeable */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Locked (1UL) /*!< Register ERASEPROTECT.DISABLE is read-only */
    
    /* Register: CTRLAPPERI_ERASEPROTECT_DISABLE */
    /* Description: Disable ERASEPROTECT and perform ERASEALL */
    
    /* Bits 31..0 : The ERASEALL sequence will be initiated if value of KEY fields are non-zero and KEY fields match on both CPU and debugger side */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos (0UL) /*!< Position of KEY field. */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Msk (0xFFFFFFFFUL << CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos) /*!< Bit mask of KEY field. */
     

    erik.johnson said:
    Ahh, it appears there is an entire section I didn't know about in the NVMC section of the datasheet about specific steps to enable Non-Secure erase operations when Secure access is blocked. Hopefully all of this is my fault!

     I assume it was the nAN41 you found? The NVMC field (along with APPROTECT and SECUREAPPOTECT) is described in the application note nAN41 - nRF9160 Production Programming under Troubleshooting, and the chapter Enabling device protection.

    Will get back to you with more information as soon as I know more.

  • Hopefully someone will have some more ideas on how to get the nrfjprog programming working.

    As for the NVMC fields, I was mostly just talking about NVMC->CONFIGNS and how the NVMC peripheral hadn't been set to Non-Secure (in the SPU->PERIPHID[n].PERM registers). Like I said before, though, even after setting the permission to Non-Secure nrfjprog still isn't working.

    Looking at nAN41, it seems like nrfjprog/a debugger should be fully capable of programming the Non-Secure flash using the DAP. I'm definitely not experienced enough with debuggers to be able to quickly put together a custom DAP script to accomplish the programming, so I'll wait to hear what the Nordic team has to say.

    Thanks!

  • Hi Erik, 

    Our system architecture group reports that you are correct, and that this a Write Once register. Currently no fix available unfortunately. 

    Kind regards,
    Øyvind

Reply Children
Related