NRF_NVMC->CONFIG hangs on setting NRF_NVMC_MODE_WRITE in Zephyr (without Softdevice)

I am using the Zephyr NVS Settings module. In some cases this happens: I try to save a value with `settings_save_one()`, which internally calls `nvs_write()`.
I debugged it down to `nrf_nvmc_mode_set()`, which is trying to set the `NRF_NVMC->CONFIG` register to `NRF_NVMC_MODE_WRITE`.
But it keeps hanging there.

NCS 2.1.4
Zephyr 3.1.99
Custom Board with nRF52832

Enabled features:
- PWM
- ADC (SAADC)
- ESB Shockburst
- NVS Settings
- UART
- CONFIG_PM=y
- CONFIG_MPU_ALLOW_FLASH_WRITE=y
- CONFIG_DEBUG=y


Things that I have tried/checked:
  • There is no softdevice in the flash
  • I am not using BLE (but ESB Shockburst, maybe this is a problem?)
  • Settings partition is at 0x7c000 (0x4000 size), `CONFIG_SETTINGS_NVS_SECTOR_COUNT=2`
  • I call it on the main thread not in an ISR
  • Zephyr workers and other threads are still running
  • Application is not overlapping (size is around 0x489F0)

I have added some debug prints to the SDK to trace down the spot where it fails. See the logs at the bottom.
This is the code snippet where it fails:
The "Finished" is never printed

---------------
nrf_nvmc_mode_set(NRF_NVMC, NRF_NVMC_MODE_WRITE);

// ...

NRF_STATIC_INLINE void nrf_nvmc_mode_set(NRF_NVMC_Type *p_reg,
                                         nrf_nvmc_mode_t mode)
{
    printk("BPROT CONFIG0: 0x%08x\n", NRF_BPROT->CONFIG0);
    printk("BPROT CONFIG1: 0x%08x\n", NRF_BPROT->CONFIG1);
    printk("NRF_NVMC->READY: 0x%08x\n", NRF_NVMC->READY);

    printk("FICR FLASH: %lu kB\n", NRF_FICR->INFO.FLASH);
    printk("FICR RAM: %lu kB\n", NRF_FICR->INFO.RAM);

    unsigned int key = irq_lock();
    printk("nrf_nvmc_mode_set: Set mode %d\n", mode);

    p_reg->CONFIG = (uint32_t)mode;
    irq_unlock(key);
    printk("nrf_nvmc_mode_set: Finished\n");
}




nvs_write: Enter while #1
nvs_write: Exit while #1
nvs_write: Enter while #2
nvs_write: Enter nvs_flash_wrt_entry
nvs_flash_wrt_entry: Writing entry id 49153 at offset 8 len 4
nvs_flash_wrt_entry: Writing data at 8
nvs_flash_al_wrt: Writing 4 bytes at 7c008
soc_flash_nrf: write addr 0x0007c008 len 4
write_op: context 0x20005190
write_op: Enter write 4-byte aligned data
write_op: Write 4 bytes at flash addr 0x0007c008 from data addr 0x20001efc
nvmc_word_write: addr 0x0007c008, value 0x0000001e
nvmc_write_mode_set: Set write mode
BPROT CONFIG0: 0x00000000
BPROT CONFIG1: 0x00000000
NRF_NVMC->READY: 0x00000001
FICR FLASH: 512 kB
FICR RAM: 64 kB
nrf_nvmc_mode_set: Set mode 1



Parents
  • Today I found out that it works when I change the IRQ setup for my ADC. But this is not feasible for my project. I still don't get how this can be related to the NVMC deadlock...

    // This works for the NVMC
    IRQ_DIRECT_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_saadc_irq_handler, 0);
    
    // This is what my project requires but it has the deadlock problem
    IRQ_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_saadc_irq_handler, 0, 0);
    

Reply
  • Today I found out that it works when I change the IRQ setup for my ADC. But this is not feasible for my project. I still don't get how this can be related to the NVMC deadlock...

    // This works for the NVMC
    IRQ_DIRECT_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_saadc_irq_handler, 0);
    
    // This is what my project requires but it has the deadlock problem
    IRQ_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_saadc_irq_handler, 0, 0);
    

Children
No Data
Related