<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/34262/system-reset-after-uicr-erase-and-write-leads-to-system-off</link><description>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. 
 
 2nd 
 
 
 The first implementation was not allowing me to</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 02 Feb 2021 12:12:21 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/34262/system-reset-after-uicr-erase-and-write-leads-to-system-off" /><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/292457?ContentTypeID=1</link><pubDate>Tue, 02 Feb 2021 12:12:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5f426b43-90a6-4289-a275-609be1c279dd</guid><dc:creator>Jason</dc:creator><description>&lt;p&gt;Hi, I know this is old... But I think there&amp;#39;s a bug on line 13 where it says i &amp;lt; sizeof(uicr_buffer). this is i &amp;lt; 236&lt;/p&gt;
&lt;p&gt;It should say&amp;nbsp;&lt;/p&gt;
&lt;p&gt;for(int i = 0; i&amp;lt;(sizeof(uicr_buffer) / &lt;span&gt;sizeof(uicr_buffer[0]))&lt;/span&gt;; i++)&lt;/p&gt;
&lt;p&gt;or just&amp;nbsp;for(int i = 0; i&amp;lt;59; i++)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I changed the code to this (My code increments a reboot counter in CUSTOMER[0] every reboot, whereas yours was updating the bootloader address)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void    increment_reboot_count()  
{ 
//Must be done before SoftDevice init
//This code modified from https://devzone.nordicsemi.com/f/nordic-q-a/34262/system-reset-after-uicr-erase-and-write-leads-to-system-off

    static uint32_t temp_uicr_NRFFW[sizeof(NRF_UICR-&amp;gt;NRFFW) / sizeof (NRF_UICR-&amp;gt;NRFFW[0])] = {0x00000000};
    static uint32_t temp_uicr_NRFHW[sizeof(NRF_UICR-&amp;gt;NRFHW) / sizeof (NRF_UICR-&amp;gt;NRFHW[0])] = {0x00000000};
    static uint32_t temp_uicr_CUSTOMER[sizeof(NRF_UICR-&amp;gt;CUSTOMER) / sizeof (NRF_UICR-&amp;gt;CUSTOMER[0])] = {0x00000000};

    static uint32_t temp_pselreset_0        = 0x00000000;
    static uint32_t temp_pselreset_1        = 0x00000000;
    static uint32_t temp_approtect          = 0x00000000;
    static uint32_t temp_nfcpins            = 0x00000000;

    CRITICAL_REGION_ENTER();

    //Read everything into temp buffers prior to erase
    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_NRFFW) / sizeof(temp_uicr_NRFFW[0])); i++)
    {
      temp_uicr_NRFFW[i] = NRF_UICR-&amp;gt;NRFFW[i];
      while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}

    }

    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_NRFHW) / sizeof(temp_uicr_NRFHW[0])); i++)
    {
      temp_uicr_NRFHW[i] = NRF_UICR-&amp;gt;NRFHW[i];
      while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
    }

    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_CUSTOMER) / sizeof(temp_uicr_CUSTOMER[0])); i++)
    {
      temp_uicr_CUSTOMER[i] = NRF_UICR-&amp;gt;CUSTOMER[i];
      while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
    }
  
    temp_pselreset_0 = NRF_UICR-&amp;gt;PSELRESET[0];
    temp_pselreset_1 = NRF_UICR-&amp;gt;PSELRESET[1];
    temp_approtect   = NRF_UICR-&amp;gt;APPROTECT;
    temp_nfcpins     = NRF_UICR-&amp;gt;NFCPINS;
    
    //increment my variable
    reboot_count = temp_uicr_CUSTOMER[0] + 1;
    temp_uicr_CUSTOMER[0] = reboot_count;

    // Enable Erase mode
    NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Een &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos; //0x02; 
    while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
    
    // Erase the UICR registers
    NRF_NVMC-&amp;gt;ERASEUICR = NVMC_ERASEUICR_ERASEUICR_Erase &amp;lt;&amp;lt; NVMC_ERASEUICR_ERASEUICR_Pos; //0x00000001;
    while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
    
    // Enable WRITE mode
    NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Wen &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos; //0x01;
    while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
    

    //Write everything back
    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_NRFFW) / sizeof(temp_uicr_NRFFW[0])); i++)
    {
      if (temp_uicr_NRFFW[i] != 0xFFFFFFFF)
      {
        //printf(&amp;quot;writing temp_uicr_NRFFW[%d] = %x\n&amp;quot;, i, temp_uicr_NRFFW[i]);
        NRF_UICR-&amp;gt;NRFFW[i] = temp_uicr_NRFFW[i];
        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
      }
    }

    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_NRFHW) / sizeof(temp_uicr_NRFHW[0])); i++)
    {
      if (temp_uicr_NRFHW[i] != 0xFFFFFFFF)
      {
        //printf(&amp;quot;writing temp_uicr_NRFHW[%d] = %x\n&amp;quot;, i, temp_uicr_NRFHW[i]);
        NRF_UICR-&amp;gt;NRFHW[i] = temp_uicr_NRFHW[i];
        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
      }
    }

    for (int i = 0; i &amp;lt; (sizeof(temp_uicr_CUSTOMER) / sizeof(temp_uicr_CUSTOMER[0])); i++)
    {
      if (temp_uicr_CUSTOMER[i] != 0xFFFFFFFF)
      {
        //printf(&amp;quot;writing temp_uicr_CUSTOMER[%d] = %x\n&amp;quot;, i, temp_uicr_CUSTOMER[i]);
        NRF_UICR-&amp;gt;CUSTOMER[i] = temp_uicr_CUSTOMER[i];
        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
      }
    }
  
    NRF_UICR-&amp;gt;PSELRESET[0] = temp_pselreset_0; 
    NRF_UICR-&amp;gt;PSELRESET[1] = temp_pselreset_1; 
    NRF_UICR-&amp;gt;APPROTECT    = temp_approtect; 
    NRF_UICR-&amp;gt;NFCPINS      = temp_nfcpins;


    CRITICAL_REGION_EXIT();
}

&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/283919?ContentTypeID=1</link><pubDate>Tue, 08 Dec 2020 21:55:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:218294f2-9cc2-49f9-847a-9abf16e4df9f</guid><dc:creator>yuval</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Why did you save &amp;amp; restore UICR content from 0x10001014 and not from 0x10001000 ?!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/132851?ContentTypeID=1</link><pubDate>Wed, 23 May 2018 02:17:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:99fbd8a6-6a72-49f6-8d0d-d77ef918bbcf</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Be aware of &lt;em&gt;nWRITE&lt;/em&gt;. The UICR register is part of the Flash memory, and it must not be repeatedly written (max 181 times) as it would be by an indiscriminate register write in user code on every reset. The Nordic SystemInit() checks the value before writing when using the defines to avoid repeated writes. This also means - for example - that the NFC pins can not be easily repeatedly switched between NFC mode and I/O port mode.&lt;/p&gt;
&lt;p&gt;I quote:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;11.3 Writing to user information configuration registers (UICR)&lt;/em&gt;&lt;br /&gt;&lt;em&gt;User information configuration registers (UICR) are written in the same way as Flash. After UICR has been&amp;nbsp;&lt;/em&gt;&lt;em&gt;written, the new UICR configuration will only take effect after a reset.&lt;/em&gt;&lt;br /&gt;&lt;em&gt;UICR can only be written nWRITE number of times before an erase must be performed using ERASEUICR or&amp;nbsp;&lt;/em&gt;&lt;em&gt;ERASEALL.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;nWRITE,BLOCK Amount of writes allowed in a block between erase 181&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/132631?ContentTypeID=1</link><pubDate>Tue, 22 May 2018 06:12:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98304c31-c9f1-4b8b-bb71-f43f768bed01</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;Happy to help!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/132401?ContentTypeID=1</link><pubDate>Thu, 17 May 2018 10:43:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:32b7431c-f2f4-448c-afe9-a1c23f5a7b9b</guid><dc:creator>Prashant Singh</dc:creator><description>&lt;p&gt;Thanks, Bjorn.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: System Reset after UICR Erase and write leads to System Off.</title><link>https://devzone.nordicsemi.com/thread/131879?ContentTypeID=1</link><pubDate>Mon, 14 May 2018 12:52:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e9ebbc74-28fa-4500-a76e-01caa9e7fb7b</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;Hi Prasant,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;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 &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/18199/dfu---updating-from-legacy-sdk-v11-0-0-bootloader-to-secure-sdk-v12-x-0-bootloader"&gt;this&lt;/a&gt;&amp;nbsp;question. You should be able to reuse that.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;+        // 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&amp;lt;sizeof(uicr_buffer); i++)
+        {
+            uicr_buffer[i] = *(uint32_t *)uicr_address; 
+            while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
+            // Set UICR address to the next register
+            uicr_address += 0x04;
+        }
+      
+        pselreset_0 = NRF_UICR-&amp;gt;PSELRESET[0];
+        pselreset_1 = NRF_UICR-&amp;gt;PSELRESET[1];
+        approtect   = NRF_UICR-&amp;gt;APPROTECT;
+        nfcpins     = NRF_UICR-&amp;gt;NFCPINS;
+        
+        //Modify the Bootloader start address  to correspond to the new bootloader
+        uicr_buffer[0] = 0x00078000;
+       
+        // Enable Erase mode
+        NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Een &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos; //0x02; 
+        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
+        
+        // Erase the UICR registers
+        NRF_NVMC-&amp;gt;ERASEUICR = NVMC_ERASEUICR_ERASEUICR_Erase &amp;lt;&amp;lt; NVMC_ERASEUICR_ERASEUICR_Pos; //0x00000001;
+        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
+       
+        // Enable WRITE mode
+        NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Wen &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos; //0x01;
+        while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
+   
+        // Write the modified UICR content back to the UICR registers 
+        uicr_address = 0x10001014;
+        for(int j = 0; j&amp;lt;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-&amp;gt;READY == NVMC_READY_READY_Busy){}                
+            }
+            // Set UICR address to the next register
+            uicr_address += 0x04;  
+        }
+
+        NRF_UICR-&amp;gt;PSELRESET[0]  = pselreset_0;
+        NRF_UICR-&amp;gt;PSELRESET[1]  = pselreset_1;
+        NRF_UICR-&amp;gt;APPROTECT     = approtect;
+        NRF_UICR-&amp;gt;NFCPINS       = nfcpins;
+
+        CRITICAL_REGION_EXIT();&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>