Hi!
Working on project based on nRF52810. Everything was fine until I began to work on part to save setting in flash memory.
I've used flash_fds example SDK 16.0 as starting point. I don't use softdevice so I choosed nvmc option.
This is my code to test library functionality:
NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) = { .evt_handler = fstorage_evt_handler, .start_addr = 0x27000, .end_addr = 0x28000, }; static void print_flash_info(nrf_fstorage_t * p_fstorage) { NRF_LOG_INFO("========| flash info |========"); NRF_LOG_INFO("erase unit: \t%d bytes", p_fstorage->p_flash_info->erase_unit); NRF_LOG_INFO("program unit: \t%d bytes", p_fstorage->p_flash_info->program_unit); NRF_LOG_INFO("=============================="); } static uint32_t nrf5_flash_end_addr_get() { uint32_t const bootloader_addr = BOOTLOADER_ADDRESS; uint32_t const page_sz = NRF_FICR->CODEPAGESIZE; uint32_t const code_sz = NRF_FICR->CODESIZE; return (bootloader_addr != 0xFFFFFFFF ? bootloader_addr : (code_sz * page_sz)); } void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage) { /* While fstorage is busy, sleep and wait for an event. */ while (nrf_fstorage_is_busy(p_fstorage)) { } } static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt) { if (p_evt->result != NRF_SUCCESS) { NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation."); return; } switch (p_evt->id) { case NRF_FSTORAGE_EVT_WRITE_RESULT: {NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.", p_evt->len, p_evt->addr);} break; case NRF_FSTORAGE_EVT_ERASE_RESULT: {NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.", p_evt->len, p_evt->addr);} break; default: break; } } void main () { uint32_t err_code; err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); //err_code = radio_init(settings.networkID, radioPacketReceived); //APP_ERROR_CHECK(err_code); err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); app_timer_init(); const app_uart_comm_params_t comm_params = { RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, UART_HWFC, false, NRF_UART_BAUDRATE_9600 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uartErrorHandle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); nrf_gpio_cfg_input(BUTTON_1, NRF_GPIO_PIN_PULLUP); nrf_gpio_pin_write(BUZZER, 0); nrf_gpio_cfg_output(ROW1); nrf_gpio_cfg_output(ROW2); nrf_gpio_cfg_output(ROW3); nrf_gpio_cfg_output(COIN_CTRL); nrf_gpio_cfg_output(BUZZER); nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.mosi_pin = DATA_PIN; spi_config.sck_pin = SCK_PIN; spi_config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY; spi_config.frequency = NRF_DRV_SPI_FREQ_8M; // FLASH PART static uint32_t m_data = 0xBADC0FFE; static char m_hello_world[] = "hello world"; nrf_fstorage_api_t * p_fs_api; p_fs_api = &nrf_fstorage_nvmc; err_code = nrf_fstorage_init(&fstorage, p_fs_api, NULL); APP_ERROR_CHECK(err_code); print_flash_info(&fstorage); (void) nrf5_flash_end_addr_get(); /* Let's write to flash. */ NRF_LOG_INFO("Writing \"%x\" to flash.", m_data); err_code = nrf_fstorage_write(&fstorage, 0x2e000, &m_data, sizeof(m_data), NULL); APP_ERROR_CHECK(err_code); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); NRF_LOG_INFO("Writing \"%s\" to flash.", m_hello_world); err_code = nrf_fstorage_write(&fstorage, 0x2f000, m_hello_world, sizeof(m_hello_world), NULL); APP_ERROR_CHECK(err_code); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); uint8_t arr[20]; err_code = nrf_fstorage_read(&fstorage, 0x2f000, &arr[0], 15); APP_ERROR_CHECK(err_code); wait_for_flash_ready(&fstorage); NRF_LOG_INFO(arr); while (1) {} }
I left initialization code of other peripheral in case if it can interfere with storage. Also product uses ESB radio.
I'm using Segger studio and I added in flash_placement.xml file this lines of code:
<ProgramSection alignment="4" load="Yes" name=".fs_data" /> <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
With debugger I found that program goes into Hard fault at the end of nrf_fstorage_init(&fstorage, p_fs_api, NULL) function.
I don't have any idea why this is happening. Hopefully somebody will give a tip.