How to remove the nRF9160's erase protection.

Hello everyone,

I'm working on a project with nRF9160 and I used to this code to test the erase protection. But I found that the value of the "ERASEPROTECT->DISABLE" register does not match.

#include <zephyr.h>

void main(void)
{
    NRF_NVMC->CONFIG = ( (NVMC_CONFIG_WEN_Wen | NVMC_CONFIG_WEN_Een) << NVMC_CONFIG_WEN_Pos);
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
    { }


    NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK = 0x00000000;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
    { }

    NRF_UICR->APPROTECT = 0x00000000;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
    { }

    NRF_UICR->ERASEPROTECT = 0x00000000;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
    { }

    NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0xDEADBEEF;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
    { }

    printk("Before Write Key.\n");
    printk("ERASEPROTECT     Addr	 0x%X\n", &NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
    printk("ERASEPROTECT          0x%X\n",  NRF_UICR->ERASEPROTECT);
    printk("ERASEPROTECT.LOCK    0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
    printk("ERASEPROTECT.DISABLE 0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE);

    uint32_t count = 0;

    while (1)
    {
        k_msleep(1000);
        printk("Count:: %u\r\n", count++);
    }
} /* main */

Command to build this code:

$ west build -b nrf9160dk_nrf9160 .

My result on UART terminal.

*** Booting Zephyr OS build v3.0.99-ncs1 ***

Begin Unlock.
Before Write Key.
ERASEPROTECT Addr 0x50006500
ERASEPROTECT 0x0
ERASEPROTECT.LOCK 0x0
ERASEPROTECT.DISABLE 0x0

And then I try to write the value to "ERASEPROTECT->DISABLE" as the same c-code using this script.

setPassword.txt

SWDSelect
SWDWriteDP 1 0x50000000  
SWDWriteDP 2 0x04000010  
SWDWriteAP 3 0xDEADBEEF

sleep 10000
SWDWriteDP 1 0x50000000  
SWDWriteDP 2 0x04000000  
SWDWriteAP 0 0x00000001
SWDReadAP 0
SWDReadAP 0
sleep 5000
SWDWriteAP 0 0x00000000
SWDReadAP 0
SWDReadAP 0
sleep 1000

exit

Command to run script

$ JLinkExe -Commandfile setPassword.jlink 

The result:

SEGGER J-Link Commander V7.80c (Compiled Sep 27 2022 16:06:19)
DLL version V7.80c, compiled Sep 27 2022 16:05:56
J-Link Command File read successfully.
Processing script file...
J-Link>SWDSelect
J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link Ultra V5-1 compiled Sep 22 2022 14:54:27
Hardware version: V5.10
J-Link uptime (since boot): 0d 00h 13m 13s
S/N: 505101964
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
USB speed mode: High speed (480 MBit/s)
VTref=3.270V
Select SWD by sending SWD switching sequence.
Found SWD-DP with ID 0x6BA02477
J-Link>SWDWriteDP 1 0x50000000
Write DP register 1 = 0x50000000
J-Link>SWDWriteDP 2 0x04000010
Write DP register 2 = 0x04000010
J-Link>SWDWriteAP 3 0xDEADBEEF
Write AP register 3 = 0xDEADBEEF
J-Link>sleep 10000
Sleep(10000)
J-Link>SWDWriteDP 1 0x50000000
Write DP register 1 = 0x50000000
J-Link>SWDWriteDP 2 0x04000000
Write DP register 2 = 0x04000000
J-Link>SWDWriteAP 0 0x00000001
Write AP register 0 = 0x00000001
J-Link>SWDReadAP 0
Read AP register 0 = 0x00000000
J-Link>SWDReadAP 0
Read AP register 0 = 0x00000001
J-Link>sleep 5000
Sleep(5000)
J-Link>SWDWriteAP 0 0x00000000
Write AP register 0 = 0x00000000
J-Link>SWDReadAP 0
Read AP register 0 = 0x00000001
J-Link>SWDReadAP 0
Read AP register 0 = 0x00000000
J-Link>sleep 1000
Sleep(1000)
J-Link>exit

Script processing completed.

I found my board can't disable erase protection and I can't recover it.

Helpful hints Exactly what is happening?

Best regards

Wasan

Parents
  • Hi All,

    When I remove some line in my code as below. My device is working.

    Test base on:

    SDK 2.1.2

    MCU nRF9160

     

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <drivers/gpio.h>
    
    #define GPIO_DEV     gpio0 /**< The gpio blank name. */
    #define BUTTON_A_PIN 12    /**< Pin number of factory button. */
    #define BUTTON_B_PIN 18    /**< Pin number of factory button. */
    
    static const struct device *gpio_dev;
    
    void main(void)
    {
        const uint32_t key = 0xDEADBEEF;
    
        gpio_dev = DEVICE_DT_GET(DT_NODELABEL(GPIO_DEV));
        if (gpio_dev == NULL)
        {
            LOG_ERR("Could not get GPIO Module.");
            return -EIO;
        }
    
        gpio_pin_configure(gpio_dev, BUTTON_A_PIN, GPIO_INPUT);
        gpio_pin_configure(gpio_dev, BUTTON_B_PIN, GPIO_INPUT);
    
        NRF_NVMC->CONFIG = ( (NVMC_CONFIG_WEN_Wen  ) << NVMC_CONFIG_WEN_Pos);
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->APPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->ERASEPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->SECUREAPPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
    
        NRF_NVMC->CONFIG = ( (NVMC_CONFIG_WEN_Ren  ) << NVMC_CONFIG_WEN_Pos);
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        /**
         * @brief When unuse unlock feature in this boot.
         *
         */
        // NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK = 0x00000001;
        // while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        // { }
    
        printk("Before Write Key.\n");
        printk("ERASEPROTECT     Addr	 0x%X\n", &NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
        printk("ERASEPROTECT          0x%X\n",  NRF_UICR->ERASEPROTECT);
        printk("ERASEPROTECT.LOCK    0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
        printk("ERASEPROTECT.DISABLE 0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE);
        uint32_t count = 0;
    
        k_msleep(1000);
        while (1)
        {
            if (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
            {
                k_msleep(100);
                if (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
                {
                    printk("Unlock with Key A:0x%x\r\n", count++);
    
                    NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0xDEADBEEF;
                    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
                    { }
    
                    while (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
                    {
                        k_msleep(1);
                    }
                }
            }
    
    
            if (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
            {
                k_msleep(100);
                if (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
                {
                    printk("Unlock with Key B:0x%x\r\n", count++);
    
                    NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0x00000000;
                    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
                    { }
    
                    while (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
                    {
                        k_msleep(1);
                    }
                }
            }
    
            k_msleep(1);
        }
    } /* main */
    

    Command to build this code:

    $ west build -b nrf9160dk_nrf9160 .
    Scrip file > setPassword.jlink
    SWDSelect
    SWDWriteDP 1 0x50000000  
    SWDWriteDP 2 0x04000010  
    SWDWriteAP 3 0xDEADBEEF
    
    sleep 10000
    SWDWriteDP 1 0x50000000  
    SWDWriteDP 2 0x04000000  
    SWDWriteAP 0 0x00000001
    SWDReadAP 0
    SWDReadAP 0
    sleep 5000
    SWDWriteAP 0 0x00000000
    SWDReadAP 0
    SWDReadAP 0
    sleep 1000
    
    exit
    
    
    Command to run script
    $ JLinkExe -Commandfile setPassword.jlink 
    Noted:
    1. The device can't  disable erase protection when set the register NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0x00000000;  
    2. Please use the "nrfjprog --recover" command to test the nRF91's erase protection that has been disabled.
    Best regards
    Wasan
Reply
  • Hi All,

    When I remove some line in my code as below. My device is working.

    Test base on:

    SDK 2.1.2

    MCU nRF9160

     

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <drivers/gpio.h>
    
    #define GPIO_DEV     gpio0 /**< The gpio blank name. */
    #define BUTTON_A_PIN 12    /**< Pin number of factory button. */
    #define BUTTON_B_PIN 18    /**< Pin number of factory button. */
    
    static const struct device *gpio_dev;
    
    void main(void)
    {
        const uint32_t key = 0xDEADBEEF;
    
        gpio_dev = DEVICE_DT_GET(DT_NODELABEL(GPIO_DEV));
        if (gpio_dev == NULL)
        {
            LOG_ERR("Could not get GPIO Module.");
            return -EIO;
        }
    
        gpio_pin_configure(gpio_dev, BUTTON_A_PIN, GPIO_INPUT);
        gpio_pin_configure(gpio_dev, BUTTON_B_PIN, GPIO_INPUT);
    
        NRF_NVMC->CONFIG = ( (NVMC_CONFIG_WEN_Wen  ) << NVMC_CONFIG_WEN_Pos);
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->APPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->ERASEPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        NRF_UICR->SECUREAPPROTECT = 0x00000000;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
    
        NRF_NVMC->CONFIG = ( (NVMC_CONFIG_WEN_Ren  ) << NVMC_CONFIG_WEN_Pos);
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        { }
    
        /**
         * @brief When unuse unlock feature in this boot.
         *
         */
        // NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK = 0x00000001;
        // while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        // { }
    
        printk("Before Write Key.\n");
        printk("ERASEPROTECT     Addr	 0x%X\n", &NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
        printk("ERASEPROTECT          0x%X\n",  NRF_UICR->ERASEPROTECT);
        printk("ERASEPROTECT.LOCK    0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK);
        printk("ERASEPROTECT.DISABLE 0x%X\n",   NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE);
        uint32_t count = 0;
    
        k_msleep(1000);
        while (1)
        {
            if (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
            {
                k_msleep(100);
                if (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
                {
                    printk("Unlock with Key A:0x%x\r\n", count++);
    
                    NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0xDEADBEEF;
                    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
                    { }
    
                    while (0 == gpio_pin_get(gpio_dev, BUTTON_A_PIN))
                    {
                        k_msleep(1);
                    }
                }
            }
    
    
            if (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
            {
                k_msleep(100);
                if (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
                {
                    printk("Unlock with Key B:0x%x\r\n", count++);
    
                    NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0x00000000;
                    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
                    { }
    
                    while (0 == gpio_pin_get(gpio_dev, BUTTON_B_PIN))
                    {
                        k_msleep(1);
                    }
                }
            }
    
            k_msleep(1);
        }
    } /* main */
    

    Command to build this code:

    $ west build -b nrf9160dk_nrf9160 .
    Scrip file > setPassword.jlink
    SWDSelect
    SWDWriteDP 1 0x50000000  
    SWDWriteDP 2 0x04000010  
    SWDWriteAP 3 0xDEADBEEF
    
    sleep 10000
    SWDWriteDP 1 0x50000000  
    SWDWriteDP 2 0x04000000  
    SWDWriteAP 0 0x00000001
    SWDReadAP 0
    SWDReadAP 0
    sleep 5000
    SWDWriteAP 0 0x00000000
    SWDReadAP 0
    SWDReadAP 0
    sleep 1000
    
    exit
    
    
    Command to run script
    $ JLinkExe -Commandfile setPassword.jlink 
    Noted:
    1. The device can't  disable erase protection when set the register NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = 0x00000000;  
    2. Please use the "nrfjprog --recover" command to test the nRF91's erase protection that has been disabled.
    Best regards
    Wasan
Children
No Data
Related