Hi,
I have an application which has 2 services and 3 characteristics. I want to keep the value of characteristics when the characteristic value changed. I tried FDS and i can not make it so i tried Flash Storage and it didn't work. I looked all examples and also GitHub but i couln't make it work. Where am I making a mistake? Here is my code of Flash Storage;
My aim is keep the data save when mcu power gone. I am using nrf52840 DK, SoftDevice s140
#define NUM_PAGES 4
#define PAGE_SIZE_WORDS 1024
static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
//static void fstorage_init(void)
//{
NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
/* Set a handler for fstorage events. */
.evt_handler = fstorage_evt_handler,
/* These below are the boundaries of the flash space assigned to this instance of fstorage.
* You must set these manually, even at runtime, before nrf_fstorage_init() is called.
* The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
* last page of flash available to write data. */
.start_addr = 0x3e000,
.end_addr = 0x3ffff,
};
//}
void fstorage_write(void)
{
ret_code_t rc = nrf_fstorage_write(
&fstorage, /* The instance to use. */
0x3F000, /* The address in flash where to store the data. */
&number, /* A pointer to the data. */
sizeof(number), /* Lenght of the data, in bytes. */
NULL /* Optional parameter, backend-dependent. */
);
if (rc == NRF_SUCCESS)
{
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_WRITE_RESULT event
is sent to the callback function registered by the instance. */
}
else
{
/* Handle error.*/
}
}
void fstorage_erase(void)
{
static uint32_t pages_to_erase = 4;
ret_code_t rc = nrf_fstorage_erase(
&fstorage, /* The instance to use. */
0x3F000, /* The address of the flash pages to erase. */
pages_to_erase, /* The number of pages to erase. */
NULL /* Optional parameter, backend-dependent. */
);
if (rc == NRF_SUCCESS)
{
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_ERASE_RESULT event
is sent to the callback function registered by the instance. */
}
else
{
/* Handle error.*/
}
}
void fstorage_read(void)
{
ret_code_t rc = nrf_fstorage_read(
&fstorage, /* The instance to use. */
0x3F000, /* The address in flash where to read data from. */
&number, /* A buffer to copy the data into. */
sizeof(number) /* Lenght of the data, in bytes. */
);
if (rc == NRF_SUCCESS)
{
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_READ_RESULT event
is sent to the callback function registered by the instance.
Once the event is received, it is possible to read the contents of 'number'. */
}
else
{
/* Handle error.*/
}
}
here is my timer;
// This is a timer event handler
static void timer_timeout_handler(void * p_context)
{
// Update temperature characteristic and voltage characteristic value.
//int32_t temperature = 0;
//sd_temp_get(&temperature);
voltage = 0;
voltage = saadc_measure();
if(voltage < 0) //don't let adc value negative
voltage = 0;
our_voltage_characteristic_update(&m_our_service, &voltage);
our_temperature_characteristic_update_2(&m_our_service, &number); //update characteristic value every 100ms
if(button_value == 1) //this condition changes characteristics value
{
nrf_gpio_pin_toggle(LED_4); //code check
number=0x35;
fstorage_erase(); //erase before writing
fstorage_write(); //write the new value
}
}
here is fs event handler;
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;
}
}
and main;
int main(void)
{
bool erase_bonds;
// Initialize.
log_init();
ret_code_t ret;
serial_uart_init();
timers_init();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
saadc_init();
services_init();
advertising_init();
conn_params_init();
peer_manager_init();
// Start execution.
NRF_LOG_INFO("OurCharacteristics tutorial started.");
application_timers_start();
advertising_start(erase_bonds);
nrf_fstorage_init(&fstorage,&nrf_fstorage_sd,NULL);
fstorage_read(); //read the flash value when mcu is restarting after mcu power off
// Enter main loop.