<?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>Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/78990/recover-from-a-sd_softdevice_disable</link><description>When writing to flash it is MUCH easier to perform the write if SoftDevice is disabled. If it is not, one has to wait for an event to continue writing. ON the Nordic platforms, that is very complicated as one already has code for fragmented notifications</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 06 Sep 2021 12:28:28 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/78990/recover-from-a-sd_softdevice_disable" /><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/328198?ContentTypeID=1</link><pubDate>Mon, 06 Sep 2021 12:28:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6f0658f2-3114-451a-9502-d85f47441d40</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Good to hear you got things working that way &lt;span class="emoticon" data-url="https://devzone.nordicsemi.com/cfs-file/__key/system/emoji/1f642.svg" title="Slight smile"&gt;&amp;#x1f642;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327914?ContentTypeID=1</link><pubDate>Fri, 03 Sep 2021 08:23:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e79b25c6-8583-4e75-acc5-64b7ce3d71b4</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;THanks - but in the in I took your advice. I crammed all those BTLE init methods and service table setup methods and stuffed them in a single function and call that function instead of the system reset. It works and I skip doing some free()s and calloc()s!&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now I have a very short main().&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327906?ContentTypeID=1</link><pubDate>Fri, 03 Sep 2021 07:50:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ec74ac21-4711-40e7-8713-78fe7f30d4dc</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you want to check what is happening after reset before the main function is invoked you can have a look at the ses_startup files, and the system_nrf52840.c file.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327773?ContentTypeID=1</link><pubDate>Thu, 02 Sep 2021 11:33:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:70dbcd59-8b73-4915-8035-0628a51d1a74</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;IN my case most of the main is dedicated to initializing the Bluetooth, and its not that long because I have one service with two characteristics, so a reset didn&amp;#39;t look like much was happening. I could easily make main a 10 line program or something of that size by calling a setup Bluetooth method.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327740?ContentTypeID=1</link><pubDate>Thu, 02 Sep 2021 09:29:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a8fee480-a3f9-4131-8f4b-14f37b7e1d94</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;As you say there is quite a lot that happens during a reset, and doing this&amp;nbsp;unnecessarily will increase the runtime and power consumption of your application. For instance various startup code is run, a lot of RAM variables will be initialized, and if you are using some kind of bootloader you will also run through that.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Personally I think that the way many of our examples are set up, with hundreds of lines of BLE related code in main.c, is not the best way to set up a project. By abstracting this into its own c file you make the main file much more clean, and if you ever need to change anything BLE related in your project you immediately know where to go.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Some of our more complex software deliveries, such as the mouse/keyboard reference examples, are set up this way. Below I added the main function for the desktop mouse as an example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/**@brief Application main function.
 */
int main(void)
{   
    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
    modules_init();
    gzll_keep_alive_init();
    buffer_init();
    misc_io_init();
    
    // Enter main loop
    for (;;)
    {   
        app_sched_execute();
        m_pwr_mgmt_run();
    }
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327577?ContentTypeID=1</link><pubDate>Wed, 01 Sep 2021 11:28:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:12681601-0523-44bb-80f1-701b28b97721</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;I was thinking about doing that but basically realized that would be about 90% of my main function.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;int main(void)
{
    ret_code_t err_code;
    unsigned char cccds[2];
    bool result;
    m_adv_handle = 0;
    queue = initializeQueue(10);
    if (queue == NULL)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not allocate memory for the message queue. Quitting&amp;quot;);
        return 0;
    }
    ghs_abort = false;
    send_live_data = false;
    first_cont_sent = false;
    numberOfStoredMsmtGroups = 0;
    global_send.continuous_stage = CONT_NONE;

    // Initialize.
    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_LOG_DEBUG(&amp;quot;Main start GHS&amp;quot;);

    // Allocate memory for the security keys
    allocateMemoryForSecurityKeys(&amp;amp;keys);
    sec_params_init();
    timers_init();

    memset(&amp;amp;m_sccd_ghs_cp_handle, 0, sizeof(m_sccd_ghs_cp_handle));
    memset(&amp;amp;m_sccd_ghs_response_handle, 0, sizeof(m_sccd_ghs_response_handle));

    memset(cccds, 0, noOfCccds);
    loadKeysFromFlash(&amp;amp;keys, &amp;amp;saveDataBuffer, &amp;amp;saveDataLength, cccds, &amp;amp;noOfCccds);
    memcpy(cccdSet, cccds, noOfCccds);  // destination, source, length


    buttons_leds_init();

    gpiote_init_new();

//================================= All stuff fof softdevice init
    // This also provides the callback method to receive events.
    ble_stack_init();
    sd_mutex_new(&amp;amp;p_mutex);
    sd_mutex_new(&amp;amp;q_mutex);

    // Set device address
    ble_gap_addr_t addrStruct;
    addrStruct.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    memcpy(addrStruct.addr, getBtAddress(), 6);  // destination, source, length
    err_code = sd_ble_gap_addr_set(&amp;amp;addrStruct);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not set the Bluetooth Address. Error code %d&amp;quot;, err_code);
        APP_ERROR_CHECK(err_code);
    }
    configureSpecializations();

    // Sets max and min connection intervals, slave latency, and the GAP characteristic entries
    // for the friendly name and appearance.
    gap_params_init();
    // Creates the advertisement and scan response data arrays
    err_code = advertisement_ghs_set(&amp;amp;m_adv_handle);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not configure the advertisements&amp;quot;);
        APP_ERROR_CHECK(err_code);
    }
    // ===================================== Create the GHS service
    err_code = createPrimaryService(&amp;amp;m_sccd_ghs_service_handle, BTLE_SCCD_GHS_SERVICE);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not create GHS service&amp;quot;);
        APP_ERROR_CHECK(err_code);
    }
    // Create the GHS control point characteristic
    err_code = createStandardCharacteristic(m_sccd_ghs_service_handle,
        &amp;amp;m_sccd_ghs_cp_handle,
        BTLE_SCCD_GHS_CP_CHAR,
        true,   // Has CCCD
        true,   // This will cause indicate instead of notify if CCCD is set to true
        0,
        NULL,
        false,
        (ble_gap_conn_sec_mode_t) {1, 1},   // [CCCD write is open]
        (ble_gap_conn_sec_mode_t) {0, 0},   // Reading characteristic value is forbidden
        (ble_gap_conn_sec_mode_t) {1, 1});  // [Writing characteristic is open]
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not create GHS control point characteristic&amp;quot;);
        APP_ERROR_CHECK(err_code);
    }
    // ===================================== Create the GHS response characteristic
    err_code = createStandardCharacteristic(m_sccd_ghs_service_handle,
        &amp;amp;m_sccd_ghs_response_handle,
        BTLE_SCCD_GHS_RESPONSE_CHAR,
        true,   // Has CCCD
        false,  // This will cause indicate instead of notify if CCCD is set to true
        0,
        NULL,
        false,
        (ble_gap_conn_sec_mode_t)
        {
            1, 1
        },
        // CCCD write is open
        (ble_gap_conn_sec_mode_t)
        {
            0, 0
        },
            // Reading characteristic value is forbidden
        (ble_gap_conn_sec_mode_t)
        {
            1, 1
        });  // Writing characteristic is open
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG(&amp;quot;Could not create GHS response characteristic&amp;quot;);
        APP_ERROR_CHECK(err_code);
    }
    // Not sure about this yet. I think it allows one to put up a fight to argue 
    // over connection parameters and sets up responses to connection parameter
    // change requests.
    //conn_params_init();
//=============================== End of SoftDevice init???
    // Start execution.
    err_code = app_timer_start(m_app_dummy_timer_id, CMD_SENSOR_TIME, NULL);
    APP_ERROR_CHECK(err_code);
    elapsedTimeStart = app_timer_cnt_get();
    #if (USES_TIMESTAMP == 1)
        if (sTimeInfo-&amp;gt;timeFlagsSupport == 1)
        {
            sGhsTime-&amp;gt;epoch = (unsigned long long)elapsedTimeStart;
        }
        else if(sTimeInfo-&amp;gt;timeFlagsSupport &amp;gt; 1)
        {
            epoch = GHS_TIME_EPOCH_DEFAULT;
            sGhsTime-&amp;gt;epoch = (unsigned long long)elapsedTimeStart + epoch;
        }
    #endif
    NRF_LOG_INFO(&amp;quot;GHS Start at time %u!\r&amp;quot;, getTicks());
    #if (USE_DK == 0)
        bring_up_adver();
    #endif
    // Since we don&amp;#39;t have continuous power we cannot maintain a real time clock between power cycles
    // So each power cycle will be treated as a factory reset where we start a new wall clock time
    // of a facory reset value. We will then create stored measurements with a button push and use our
    // tick counter to add to this factory reset time
    //=============================================================================== Start GHS Pulse OX
    // Enter main loop.
    main_loop();
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If I understand how much that would be it looks like all the code between my doft device init start comment and soft device init end comment. I suppose there is a lot of stuff that happens on a system reset that I don&amp;#39;t see so even though 90 % of my main function would be the softdevice init and setup of all the BTLE stuff it would still be more efficient.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327524?ContentTypeID=1</link><pubDate>Wed, 01 Sep 2021 06:50:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:94d20d97-bf2a-44fd-bfae-933ac5bf9a58</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;All the SoftDevice init will need to be repeated, yes, but a full system reset is not really necessary.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I would recommend designing some kind of Bluetooth handler/manager module that takes care of all the SoftDevice init steps, allowing you to initialize the SoftDevice from a single call to this module in the rest of your code.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This will speed up the process of disabling, writing to flash, re-enabling the SoftDevice compared to doing a full system reset.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327359?ContentTypeID=1</link><pubDate>Tue, 31 Aug 2021 08:57:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:29aac4b0-a752-4e17-a942-5a0bb60a0c37</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Yes it did. And I guess the answer to the actual posted question (should I ever need to do it) is that I basically have to start from scratch. In other words, the best option after the disabled soft device call is to do a system reset and reinitialize everything, the bt stack, the services and characteristics, advertisement, etc.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327311?ContentTypeID=1</link><pubDate>Tue, 31 Aug 2021 05:18:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d29c0d19-239c-4b21-948d-46226e158925</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I agree this could be described better in the dongle documentation.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Since the chip is exactly the same any difference has to be down to the internal flash content, or to the difference in external hardware (missing LED&amp;#39;s, buttons, external memory chip, debugger etc).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Hopefully moving the flash content will solve your issue &lt;span class="emoticon" data-url="https://devzone.nordicsemi.com/cfs-file/__key/system/emoji/1f642.svg" title="Slight smile"&gt;&amp;#x1f642;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327132?ContentTypeID=1</link><pubDate>Mon, 30 Aug 2021 08:39:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0e626427-369a-491c-ab20-ec4761667ac2</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;I ended up posting a separate issue dedicated to just this. And of course I wrote to the same areas. I followed the example provided in the SDK. There is no indication anywhere in the documentation that I stumbled upon to suggest that the pages alluded to in the example would cause problems. There needs to be clear documentation somewhere in the nRF52840 Dongle &amp;#39;how-to&amp;#39; that there is this critical difference between the DK and the dongle. It has caused me problems for months...but it took a long time to finally identify the problem as being the flash write. It generated issues that on face value appeared to have nothing to do with the flash write (since once cannot debug the dongle).&lt;/p&gt;
&lt;p&gt;PS. I still have not validated yet that it is the problem. I will drop down 3 pages and see if that works.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327120?ContentTypeID=1</link><pubDate>Mon, 30 Aug 2021 07:46:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bd7d5ee6-d891-44e9-9146-adef307fef6f</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I read the other case, and the possibility that you are writing to the same page that the bootloader is using for its settings could explain the issues you are seeing on the dongle.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I suggest you continue the discussion there, since that case has more of the background.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327030?ContentTypeID=1</link><pubDate>Fri, 27 Aug 2021 15:07:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bdcd4c75-9966-4eaa-b661-9c317b40bce0</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;I have come a lot further on this. The reason that the NVIC_SystemReset() was not working had nothing to do with that method. The problem is the flash write itself. On the dongle, the flash write kills the application and the dongle dies. It needs a power cycle to restart. If I remove the flash write, everything works the same on the Dongle as the DK.&lt;/p&gt;
&lt;p&gt;The flash write is here (note that it works fine on the DK and I have tested it by writing data to the flash and reading it back right after. Well, at least on the DK it works fine - the code is below.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void saveKeysToFlash(ble_gap_sec_keyset_t* keys,
    unsigned char **saveDataBuffer, unsigned short int *saveDataLength,
    bool* cccdSet, unsigned short* noOfCccds)
{
    int i;
//        char buffer[1024];
    unsigned char *keysDataBuffer = NULL;
    ret_code_t err_code;

    uint32_t pg_size = NRF_FICR-&amp;gt;CODEPAGESIZE;
    uint32_t pg_num  = NRF_FICR-&amp;gt;CODESIZE - 1;  // Use last page in flash
    uint32_t *addr;
    NRF_LOG_DEBUG(&amp;quot;Saving data to flash.&amp;quot;);

    int size = sizeof(nameKey) +
               sizeof(ble_gap_enc_key_t) +      // should be a fixed length even if no pairing was done
               sizeof(ble_gap_id_key_t) +       // should be a fixed length even if no pairing was done so no IRK
               sizeof(ble_gap_enc_key_t) +
               sizeof(ble_gap_id_key_t) +
               sizeof(unsigned short) +         // Number of CCCDs
               sizeof(bool) * (*noOfCccds) +    // CCCD set
               sizeof(unsigned short) +         // Savedata length
               ((*saveDataBuffer != NULL) ? *saveDataLength * sizeof(unsigned char) : 0);
    // The writes are done in 4-byte hunks so we have to even out the length
    size = 4 + ((size &amp;gt;&amp;gt; 2) &amp;lt;&amp;lt; 2);  // Here we round up to the nearest 4-byte size so it is evenly divisible by 4
    NRF_LOG_DEBUG(&amp;quot;Size of data to write %u.&amp;quot;, size);
    keysDataBuffer = calloc(1, size);
    
    // Now load all the data we want to save into this buffer
    uint8_t *ptr = keysDataBuffer;
    memcpy(ptr, nameKey, sizeof(nameKey));          // Load identifier
    ptr = ptr + sizeof(nameKey);
    memcpy(ptr, keys-&amp;gt;keys_own.p_enc_key, sizeof(ble_gap_enc_key_t)); // load our LTK
    ptr = ptr + sizeof(ble_gap_enc_key_t);
    memcpy(ptr, keys-&amp;gt;keys_own.p_id_key, sizeof(ble_gap_id_key_t));   // load our LTK id
    ptr = ptr + sizeof(ble_gap_id_key_t);
    memcpy(ptr, keys-&amp;gt;keys_peer.p_enc_key, sizeof(ble_gap_enc_key_t)); // load peer LTK
    ptr = ptr + sizeof(ble_gap_enc_key_t);
    memcpy(ptr, keys-&amp;gt;keys_peer.p_id_key, sizeof(ble_gap_id_key_t));   // load peer LTK id
    ptr = ptr + sizeof(ble_gap_id_key_t);
    memcpy(ptr, noOfCccds, sizeof(unsigned short));             // Load number of CCCDs
    ptr = ptr + sizeof(unsigned short);
    memcpy(ptr, cccdSet, sizeof(unsigned char) * (*noOfCccds)); // Load the cccdSet[]
    ptr = ptr + sizeof(unsigned char) * (*noOfCccds);
    memcpy(ptr, saveDataLength, sizeof(unsigned short));        // Load saveDataLength
    ptr = ptr + sizeof(unsigned short);
    if (*saveDataBuffer != NULL)
    {
        memcpy(ptr, *saveDataBuffer, *saveDataLength * sizeof(unsigned char));   // Load the saveDataBuffer
        ptr = ptr + *saveDataLength * sizeof(unsigned char);
    }

//    memset(buffer, 0 , 1024);
//    NRF_LOG_DEBUG(&amp;quot;Full set of data being written %s&amp;quot;, (uint32_t)byteToHex(keysDataBuffer, buffer, &amp;quot; &amp;quot;, size));
//    NRF_LOG_FLUSH();

    // Now we have to write the data in hunks into flash
    // Each page is 1024 bytes, and a write is in 4-byte hunks
    // So we will find the number of 1024 byte pages to write,
    // and then the number of 4-byte hunks left over.

    // Disable soft device so we don&amp;#39;t have to deal with events which would make this write PAINFULLY complicated to implement
    //sd_softdevice_disable();
    nrf_sdh_disable_request();
    // Buffer to write to flash. Need to write it in four-byte hunks
    uint32_t *ptr32 = (uint32_t *)keysDataBuffer;
    while (true)
    {
        // Where to write
        addr = (uint32_t *)(pg_size * pg_num);
        // Erase page:
        while(true)
        {
            err_code = sd_flash_page_erase(pg_num);
            if (err_code == NRF_SUCCESS)
            {
                break;
            }
            if (err_code != NRF_ERROR_BUSY)
            {
                NRF_LOG_DEBUG(&amp;quot;Erasing data returned error %u.&amp;quot;, err_code);
                APP_ERROR_CHECK(err_code);      // Program dies
            }
        }

        i = (size &amp;gt;= pg_size) ? (pg_size &amp;gt;&amp;gt; 2) : // Do as many write that will fill the page, eg if pg size = 1024, then 256 writes
                                (size &amp;gt;&amp;gt; 2);     // All fits in one page, so divide size by four
        NRF_LOG_DEBUG(&amp;quot;Number of 4-byte hunks to write %u.&amp;quot;, i);
        while(true)
        {
            err_code = sd_flash_write(addr,     // Pointer to start of flash location to be written.
                                      ptr32,    // Pointer to buffer with data to be written.
                                      i);       // Number of 32-bit words to write. Maximum size is the number of words in one
                                                // flash page. See the device&amp;#39;s Product Specification for details (pg size I assume).
            if (err_code == NRF_SUCCESS)
            {
                break;
            }
            if (err_code != NRF_ERROR_BUSY)
            {
                NRF_LOG_DEBUG(&amp;quot;Writing data returned error %u.&amp;quot;, err_code);
                APP_ERROR_CHECK(err_code);      // Program dies
            }
        }
        size = size - pg_size;  // Subtract a page size from the total size
        if (size &amp;lt;= 0)          // if zero or less, all data has been written
        {
            NRF_LOG_DEBUG(&amp;quot;Flash written&amp;quot;);
            break;
        }
        pg_num++;   // TODO we are on last page, so have to hope everything fits in one page. Still have not figured out how to get
                    // to the start of the first free page available.
        ptr32 = (uint32_t *)(keysDataBuffer + pg_size);
    }
    free(keysDataBuffer);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The flash write is to save pairing/bonding info. I happen to have a test app&amp;nbsp; (RGT Cycle) that connects and if it receives no measurements it disconnects only to reconnect if I advertise. One the DK, I go through endless cycles of this.&lt;/p&gt;
&lt;p&gt;On the dongle, the app dies in the flash write (which happens on the disconnect).&lt;/p&gt;
&lt;p&gt;I have gone to the point of returning in the above code just before the while loop that does the writes. Works okay on both platforms if I return &lt;strong&gt;before&lt;/strong&gt; attempting&amp;nbsp;any flash operations.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If I try just the first erase operation, the app dies on the dongle. So its pretty clear its the first attempt to do the erase that kills the app. That is as far as I have come.&lt;/p&gt;
&lt;p&gt;In the end if I have to do a flash write, I will call the NVIC_SystemReset(), and if I don&amp;#39;t, I will skip the reset and just start advertising. Works great on the DK but if the flash write is needed the dongle dies.&lt;/p&gt;
&lt;p&gt;That is where I am at now. A lot of background is here:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/78993/sd_softdevice_is_enabled-returns-false-but-then-nrf_sdh_enable_request-returns-error-8-softdevice-already-enabled"&gt;devzone.nordicsemi.com/.../sd_softdevice_is_enabled-returns-false-but-then-nrf_sdh_enable_request-returns-error-8-softdevice-already-enabled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wondering if I should simply open up a new issue about the flash writes on the dongle vs the DK&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Recover from a sd_softdevice_disable()</title><link>https://devzone.nordicsemi.com/thread/327028?ContentTypeID=1</link><pubDate>Fri, 27 Aug 2021 14:51:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0a123129-fbcf-437f-9512-0aa18ec3796d</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
[quote user=""]When writing to flash it is MUCH easier to perform the write if SoftDevice is disabled. If it is not, one has to wait for an event to continue writing. ON the Nordic platforms, that is very complicated as one already has code for fragmented notifications handling asynchronous waits.[/quote]
&lt;p&gt;Both the SoftDevice and the SDK is event based, and&amp;nbsp;to handle this you could for instance set up some kind of state machine to handle larger operations that require multiple &amp;#39;call some function -&amp;gt; wait for an event&amp;#39; type operations.&lt;/p&gt;
&lt;p&gt;Then this can run in parallel with whatever else the application is doing, and once the state machine gets to the end of its operation it can signal this to the rest of the system.&amp;nbsp;&lt;/p&gt;
[quote user=""]The only &amp;#39;wait&amp;#39; one can perform that is not a CPU busy loop is through&amp;nbsp;sd_app_evt_wait().[/quote]
&lt;p&gt;If you mean a blocking wait then I guess this is true. Unless some RTOS is used on top of the SoftDevice there is no concept of multi-threading, and blocking wait calls are not recommended.&amp;nbsp;&lt;/p&gt;
[quote user=""]That approach has worked fine on the DKs but as soon as I invoke that&amp;nbsp;NVIC_SystemReset() on an nRF52840 dongle, it no longer works. [/quote]
&lt;p&gt;I assume the factory USB bootloader is present on the dongle?&lt;/p&gt;
&lt;p&gt;I have to check this with the DFU experts, but it is possible that the bootloader is causing some issue here.&amp;nbsp;&lt;/p&gt;
[quote user=""]Since&amp;nbsp;NVIC_SystemReset() does not work, how do I recover from an sd_softdevice_disable? What does that disable? The documentation suggests EVERYTHING. Have I lost my service tables? Do I have to re-initialize the BLE stack? How many of the startup &amp;#39;init&amp;#39; methods do I need to call?[/quote]
&lt;p&gt;Disabling the SoftDevice disables everything, yes. All peripherals are released back to the application, and all the memory previously used by the SoftDevice is also available (except for the 8 first bytes of memory in the SoftDevice region).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In other words you have to call all the same functions, starting with the &lt;span&gt;sd_softdevice_enable(..) call, and all the subsequent GAP/GATT initialization functions.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In other words I would strongly suggest trying to handle the flash writes through the SoftDevice instead. As long as the SoftDevice is not doing anything else&amp;nbsp;you should be able to finish the writes almost as quick, unless you issue a lot of small writes.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards&lt;br /&gt;Torbjørn&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>