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.