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

System Reset after UICR Erase and write leads to System Off.

Hello,

I am using a custom board NRF52382, Softdevice 132_v2.0, SDK 11. Two power supply options are given, battery and USB.

I tried to rewrite UICR register with two implementation
 
    1st.

    uint32_t err_code = sd_softdevice_disable();
	APP_ERROR_CHECK(err_code);
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
	nrf_delay_ms(100);
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	nrf_delay_ms(100);
	*(uint32_t *)0x100010E4 = var_register[0] ;
	*(uint32_t *)0x100010E8 = var_register[1] ;
	*(uint32_t *)0x100010EC = var_register[2] ;
	*(uint32_t *)0x100010F0 = var_register[3] ;
	nrf_delay_ms(100);
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	NVIC_SystemReset();

 2nd

uint32_t err_code = sd_softdevice_disable();
	APP_ERROR_CHECK(err_code);
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos;
	nrf_delay_ms(100);
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	NRF_NVMC->ERASEUICR = 1;
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	nrf_delay_ms(100);
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
	nrf_delay_ms(100);
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	nrf_delay_ms(100);
	*(uint32_t *)0x100010E4 = var_register[0] ;
	*(uint32_t *)0x100010E8 = var_register[1] ;
	*(uint32_t *)0x100010EC = var_register[2] ;
	*(uint32_t *)0x100010F0 = var_register[3] ;
	nrf_delay_ms(100);
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
	NVIC_SystemReset();

 The first implementation was not allowing me to rewrite UICR register either some corrupted data or previously stored data were coming.

In the Second implementation, I first erased UICR register then rewrite those register, it works fine for me. 

ISSUE). With the Second implementation, System is not resetting it is going in power off. Only possible way to do a reset is plug in USB, not working on battery independently and also causing problems if I try to do the soft reset.

I then have to erase the chip, program hex with DFU bootloader and do a firmware update over the air to see a soft reset is working.

This just explains that either soft device is forgetting that bootloader is present or erasing UICR register is erasing bootloader.
I tried to check also NRFFW register which is showing value 0xFFFFFFFF, in both scenarios.

From the first implementation, everything works fine but not rewrite of UICR register.

Need some explanation and how to move forward.

Thanks,

Parents
  • Hi Prasant, 

    if you are modifying the UICR registers at run-time then you have to read out all the UICR registers, store the content in a local variable, erase the UICR registers, modify the registers you want to change and then write the values back to the UICR registers. I have attached code below that I made for modifying the bootloader address at run-time, see this question. You should be able to reuse that. 

    +        // Storage buffers and variables to hold the UICR register content
    +        static uint32_t uicr_buffer[59]    = {0x00000000};
    +        static uint32_t pselreset_0        = 0x00000000;
    +        static uint32_t pselreset_1        = 0x00000000;
    +        static uint32_t approtect          = 0x00000000;
    +        static uint32_t nfcpins            = 0x00000000;
    +
    +        CRITICAL_REGION_ENTER();
    +      
    +        // Read and buffer UICR register content prior to erase
    +        uint32_t uicr_address = 0x10001014;
    + 
    +        for(int i = 0; i<sizeof(uicr_buffer); i++)
    +        {
    +            uicr_buffer[i] = *(uint32_t *)uicr_address; 
    +            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    +            // Set UICR address to the next register
    +            uicr_address += 0x04;
    +        }
    +      
    +        pselreset_0 = NRF_UICR->PSELRESET[0];
    +        pselreset_1 = NRF_UICR->PSELRESET[1];
    +        approtect   = NRF_UICR->APPROTECT;
    +        nfcpins     = NRF_UICR->NFCPINS;
    +        
    +        //Modify the Bootloader start address  to correspond to the new bootloader
    +        uicr_buffer[0] = 0x00078000;
    +       
    +        // Enable Erase mode
    +        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos; //0x02; 
    +        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    +        
    +        // Erase the UICR registers
    +        NRF_NVMC->ERASEUICR = NVMC_ERASEUICR_ERASEUICR_Erase << NVMC_ERASEUICR_ERASEUICR_Pos; //0x00000001;
    +        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    +       
    +        // Enable WRITE mode
    +        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; //0x01;
    +        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    +   
    +        // Write the modified UICR content back to the UICR registers 
    +        uicr_address = 0x10001014;
    +        for(int j = 0; j<sizeof(uicr_buffer); j++)
    +        {
    +            // Skip writing to registers that were 0xFFFFFFFF before the UICR register were erased. 
    +            if(uicr_buffer[j] != 0xFFFFFFFF)
    +            {
    +                *(uint32_t *)uicr_address = uicr_buffer[j];
    +                // Wait untill the NVMC peripheral has finished writting to the UICR register
    +                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}                
    +            }
    +            // Set UICR address to the next register
    +            uicr_address += 0x04;  
    +        }
    +
    +        NRF_UICR->PSELRESET[0]  = pselreset_0;
    +        NRF_UICR->PSELRESET[1]  = pselreset_1;
    +        NRF_UICR->APPROTECT     = approtect;
    +        NRF_UICR->NFCPINS       = nfcpins;
    +
    +        CRITICAL_REGION_EXIT();

Reply Children
No Data
Related