Hello,
I need help regarding flash memory read on nRF52840 device, SDk16, SD=340.
I have using the fds libarary for memory read/write in my code for many years now. However, after changing the softdevice from S140 to S340 started causing issues with reading the flash after writing. The same code is used in both cases, for S140 it works fine but for S340, upon memory read after a power cycle, the device crashes and becomes unresponsive.
Is there something changed with this SD? Is there anybody else facing same problem?
Im attaching the fds if that helps.
Thanks.
#include <stdint.h>
#include <string.h>
#include "nrf.h"
#include "nordic_common.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#else
#include "nrf_drv_clock.h"
#endif
#include "fds.h"
#include "app_timer.h"
#include "app_error.h"
#include "nrf_cli.h"
#include "fds_driver.h"
#include "nrf_delay.h"
//#define NRF_LOG_MODULE_NAME app
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "Services/scr_service.h"
#include "Services/dev_service.h"
#include "globals.h"
/* A tag identifying the SoftDevice BLE configuration. */
#define APP_BLE_CONN_CFG_TAG 1
// FOr Hotshot
#define FDS_SUCCESS NRF_SUCCESS
uint16_t script_total_length = 0;
uint64_t last_log_index = 0;
/* Array to map FDS return values to strings. */
char const * fds_err_str[] =
{
"FDS_SUCCESS",
"FDS_ERR_OPERATION_TIMEOUT",
"FDS_ERR_NOT_INITIALIZED",
"FDS_ERR_UNALIGNED_ADDR",
"FDS_ERR_INVALID_ARG",
"FDS_ERR_NULL_ARG",
"FDS_ERR_NO_OPEN_RECORDS",
"FDS_ERR_NO_SPACE_IN_FLASH",
"FDS_ERR_NO_SPACE_IN_QUEUES",
"FDS_ERR_RECORD_TOO_LARGE",
"FDS_ERR_NOT_FOUND",
"FDS_ERR_NO_PAGES",
"FDS_ERR_USER_LIMIT_REACHED",
"FDS_ERR_CRC_CHECK_FAILED",
"FDS_ERR_BUSY",
"FDS_ERR_INTERNAL",
};
/* Array to map FDS events to strings. */
static char const * fds_evt_str[] =
{
"FDS_EVT_INIT",
"FDS_EVT_WRITE",
"FDS_EVT_UPDATE",
"FDS_EVT_DEL_RECORD",
"FDS_EVT_DEL_FILE",
"FDS_EVT_GC",
};
static rgb_values_t rgb_dummy_cfg =
{
.red = 0x0,
.green = 0x0,
.blue = 0x0,
.ant_address = 0x0,
// .ant_rf_freq = 0x0,
// .ant_dev_type = 0x0,
};
static data_values_t data_dummy_cfg =
{
.time_stamp = 0x0,
};
static show_script_t scr_dummy_cfg =
{
.script = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123",
};
static ant_bytes_t ant_dummy_cfg =
{
.data = "01",
};
#ifdef INTERNAL_LOG_ENABLED
static log_value_t log_dummy_cfg =
{
.log_table = "",
};
#endif
static fds_record_t const rgb_dummy_record =
{
.file_id = RGB_FILE_ID,
.key = RGB_REC_KEY,
.data.p_data = &rgb_dummy_cfg,
.data.length_words = (sizeof(&rgb_dummy_cfg) + 3) / sizeof(uint32_t),
//.data.p_data = sizeof(&rgb_dummy_cfg),
};
static fds_record_t const data_dummy_record =
{
.file_id = DATA_FILE_ID,
.key = DATA_REC_KEY,
.data.p_data = &data_dummy_cfg,
.data.length_words = (sizeof(&data_dummy_cfg) + 3) / sizeof(uint32_t),
//.data.p_data = sizeof(&rgb_dummy_cfg),
};
#ifdef INTERNAL_LOG_ENABLED
static fds_record_t const log_dummy_record =
{
.file_id = LOG_FILE_ID,
.key = LOG_REC_KEY,
.data.p_data = &log_dummy_cfg,
.data.length_words = LOG_DATA_SIZE/4, //(sizeof(&log_dummy_cfg) + 3) / sizeof(uint32_t),
//.data.p_data = sizeof(&rgb_dummy_cfg),
};
#endif
static fds_record_t const scr_dummy_record =
{
.file_id = SCR_FILE_ID,
.key = SCR_REC_KEY,
.data.p_data = &scr_dummy_cfg,
.data.length_words = SCRIPT_LENGTH/4, //(sizeof(&scr_dummy_cfg) + 3) / sizeof(uint32_t),
//.data.p_data = sizeof(&rgb_dummy_cfg),
};
static fds_record_t const ant_dummy_record =
{
.file_id = ANT_FILE_ID,
.key = ANT_REC_KEY,
.data.p_data = &ant_dummy_cfg,
.data.length_words = (sizeof(&ant_dummy_cfg) + 3) / sizeof(uint32_t),
//.data.p_data = sizeof(&rgb_dummy_cfg),
};
/* Keep track of the progress of a delete_all operation. */
static struct
{
bool delete_next; //!< Delete next record.
bool pending; //!< Waiting for an fds FDS_EVT_DEL_RECORD event, to delete the next record.
} m_delete_all;
/* Flag to check fds initialization. */
static bool volatile m_fds_initialized;
static void fds_evt_handler(fds_evt_t const * p_evt)
{
NRF_LOG_GREEN("Event: %s received (%s)",
fds_evt_str[p_evt->id],
fds_err_str[p_evt->result]);
switch (p_evt->id)
{
case FDS_EVT_INIT:
if (p_evt->result == FDS_SUCCESS)
{
m_fds_initialized = true;
}
break;
case FDS_EVT_WRITE:
{
if (p_evt->result == FDS_SUCCESS)
{
NRF_LOG_INFO("Record ID:\t0x%04x", p_evt->write.record_id);
NRF_LOG_INFO("File ID:\t0x%04x", p_evt->write.file_id);
NRF_LOG_INFO("Record key:\t0x%04x", p_evt->write.record_key);
}
} break;
case FDS_EVT_DEL_RECORD:
{
if (p_evt->result == FDS_SUCCESS)
{
NRF_LOG_INFO("Record ID:\t0x%04x", p_evt->del.record_id);
NRF_LOG_INFO("File ID:\t0x%04x", p_evt->del.file_id);
NRF_LOG_INFO("Record key:\t0x%04x", p_evt->del.record_key);
}
m_delete_all.pending = false;
} break;
default:
break;
}
}
bool record_delete_next(void)
{
fds_find_token_t tok = {0};
fds_record_desc_t desc = {0};
if (fds_record_iterate(&desc, &tok) == FDS_SUCCESS)
{
ret_code_t rc = fds_record_delete(&desc);
if (rc != FDS_SUCCESS)
{
return false;
}
return true;
}
else
{
/* No records left to delete. */
return false;
}
}
/**@brief Begin deleting all records, one by one. */
void delete_all_begin(void)
{
m_delete_all.delete_next = true;
}
/**@brief Process a delete all command.
*
* Delete records, one by one, until no records are left.
*/
void delete_all_process(void)
{
if ( m_delete_all.delete_next
& !m_delete_all.pending)
{
NRF_LOG_INFO("Deleting next record.");
m_delete_all.delete_next = record_delete_next();
if (!m_delete_all.delete_next)
{
NRF_LOG_CYAN("No records left to delete.");
}
}
}
/**@brief Sleep until an event is received. */
static void power_manage(void)
{
#ifdef SOFTDEVICE_PRESENT
(void) sd_app_evt_wait();
#else
__WFE();
#endif
}
/**@brief Wait for fds to initialize. */
static void wait_for_fds_ready(void)
{
while (!m_fds_initialized)
{
power_manage();
}
}
void fdsm_init(){
ret_code_t rc;
uint32_t *data;
(void) fds_register(fds_evt_handler);
NRF_LOG_INFO("Initializing fds...");
rc = fds_init();
APP_ERROR_CHECK(rc);
/* Wait for fds to initialize. */
wait_for_fds_ready();
// Call garbage collector
NRF_LOG_INFO("Running garbage collector...");
rc = fds_gc();
if (rc == FDS_SUCCESS){
NRF_LOG_INFO("Garbage collection complete");
}
// Delete files and records
//rc = fds_file_delete(SCR_FILE_ID);
//rc = fds_file_delete(RGB_FILE_ID);
//nrf_delay_ms(10);
NRF_LOG_INFO("Reading flash usage statistics...");
fds_stat_t stat = {0};
rc = fds_stat(&stat);
APP_ERROR_CHECK(rc);
NRF_LOG_INFO("Found %d valid records.", stat.valid_records);
NRF_LOG_INFO("Found %d dirty records (ready to be garbage collected).", stat.dirty_records);
//nrf_delay_ms(10);
}
void record_read_rgb(uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *ant_address/*, uint8_t *ant_rf_freq, uint8_t *ant_dev_type*/){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
uint32_t *data;
//NRF_LOG_INFO("Reading RGB Record...");
wait_for_fds_ready();
// It is required to zero the token before first use. */
memset(&tok, 0x00, sizeof(fds_find_token_t));
rc = fds_record_find(RGB_FILE_ID, RGB_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// RGB record found
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("RGB record found");
#endif
// A config file is in flash. Let's update it.
fds_flash_record_t config = {0};
// Open the record and read its contents.
rc = fds_record_open(&desc, &config);
APP_ERROR_CHECK(rc);
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Found Record ID = %d",desc.record_id);
#endif
// Copy the configuration from flash into m_dummy_cfg.
memcpy(&rgb_dummy_cfg, config.p_data, sizeof(rgb_values_t));
*red = rgb_dummy_cfg.red;
*green = rgb_dummy_cfg.green;
*blue = rgb_dummy_cfg.blue;
*ant_address = rgb_dummy_cfg.ant_address;
// *ant_rf_freq = rgb_dummy_cfg.ant_rf_freq;
// *ant_dev_type = rgb_dummy_cfg.ant_dev_type;
//#ifdef LOG_ENABLED_2
//NRF_LOG_INFO("RGB record values:%X,%X,%X", rgb_dummy_cfg.red, rgb_dummy_cfg.green, rgb_dummy_cfg.blue);
//NRF_LOG_INFO("ANT settings from flash: %X, %X", ant_rf_freq, ant_dev_type);
//#endif
// Close the record when done reading.
rc = fds_record_close(&desc);
APP_ERROR_CHECK(rc);
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("RGB record not found");
}
}
void record_update_rgb(uint8_t red, uint8_t green, uint8_t blue, uint8_t ant_address/*, uint8_t ant_rf_freq, uint8_t ant_dev_type*/){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Updating RGB Record...");
#endif
wait_for_fds_ready();
rc = fds_record_find(RGB_FILE_ID, RGB_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// RGB record found
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("RGB record found");
#endif
rgb_dummy_cfg.red = red;
rgb_dummy_cfg.green = green;
rgb_dummy_cfg.blue = blue;
rgb_dummy_cfg.ant_address = ant_address;
NRF_LOG_INFO("Saving R=%X, G=%X, B=%X, ANT_Addr=%X", rgb_dummy_cfg.red, rgb_dummy_cfg.green, rgb_dummy_cfg.blue, rgb_dummy_cfg.ant_address);
rc = fds_record_update(&desc, &rgb_dummy_record);
//APP_ERROR_CHECK(rc);
if (rc == FDS_SUCCESS){
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("RGB record updated: %X,%X,%X", rgb_dummy_cfg.red, rgb_dummy_cfg.green, rgb_dummy_cfg.blue);
NRF_LOG_INFO("RGB record id: %d", desc.record_id);
#endif
}
else{
NRF_LOG_INFO("Creating new RGB file...");
rc = fds_record_write(&desc, &rgb_dummy_record);
//APP_ERROR_CHECK(rc);
if (rc != FDS_SUCCESS){
NRF_LOG_INFO("Could not save RGB address of the device.");
}
}
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Creating new RGB file...");
rc = fds_record_write(&desc, &rgb_dummy_record);
APP_ERROR_CHECK(rc);
}
}
char * record_read_scr(){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
uint32_t *data;
// Make log entry
#ifdef INTERNAL_LOG_ENABLED
log_data("SLM");
#endif
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Reading Script Record...");
#endif
wait_for_fds_ready();
// It is required to zero the token before first use. */
memset(&tok, 0x00, sizeof(fds_find_token_t));
rc = fds_record_find(SCR_FILE_ID, SCR_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// Script record found
NRF_LOG_INFO("Script record found");
// A config file is in flash. Let's update it.
fds_flash_record_t config = {0};
// Open the record and read its contents.
rc = fds_record_open(&desc, &config);
APP_ERROR_CHECK(rc);
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Found Record ID = %d",desc.record_id);
#endif
// Copy the configuration from flash into m_dummy_cfg.
memcpy(&scr_dummy_cfg, config.p_data, sizeof(show_script_t));
//*script = scr_dummy_cfg.script;
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Script record values:");
NRF_LOG_INFO("p_data:");
NRF_LOG_HEXDUMP_INFO(config.p_data, sizeof(config.p_data));
#endif
NRF_LOG_INFO("Script data read.");
NRF_LOG_INFO("dummy:");
//NRF_LOG_HEXDUMP_INFO(scr_dummy_cfg.script, sizeof(scr_dummy_cfg.script));
// Close the record when done reading.
rc = fds_record_close(&desc);
APP_ERROR_CHECK(rc);
// Calculate length of recored
script_total_length = 0;
for (int i=0; i<121; i++){
// If end of script found, terminate
if (scr_dummy_cfg.script[i] == 0xFF)
break;
script_total_length++;
}
// Read the current script ID
scr_script_id = scr_dummy_cfg.script[script_total_length+1];
NRF_LOG_INFO("Script total length: %d", script_total_length);
NRF_LOG_INFO("Script ID: 0x%2X", scr_script_id);
return scr_dummy_cfg.script;
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Script record not found");
}
}
void record_update_scr(char script[], int len){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
// Make log entry
#ifdef INTERNAL_LOG_ENABLED
log_data("SUP");
#endif
// Call garbage collector before saving script data
NRF_LOG_INFO("Running garbage collector...");
rc = fds_gc();
if (rc == FDS_SUCCESS){
NRF_LOG_INFO("Garbage collection complete");
}
NRF_LOG_INFO("Updating Script Record...");
//NRF_LOG_INFO("Received string:");
//NRF_LOG_HEXDUMP_INFO(script, sizeof(scr_dummy_cfg.script));
//script_id = script[len-1];
//NRF_LOG_INFO("Script ID: %d", script_id);
// copy data into scr_dummy_cfg
//int len = sizeof(scr_dummy_cfg.script);
int i=0;
for (i=0; i<len; i++){
scr_dummy_cfg.script[i] = script[i];
}
for (i=len; i<scr_dummy_record.data.length_words*4; i++){
scr_dummy_cfg.script[i] = 0;
}
NRF_LOG_INFO("Copied/dummy string");
//NRF_LOG_HEXDUMP_INFO(scr_dummy_cfg.script, sizeof(scr_dummy_cfg.script));
NRF_LOG_INFO("Copied/dummy string len: %d", len); //strlen(scr_dummy_cfg.script))
//NRF_LOG_INFO("Record len: %d", scr_dummy_record.data.length_words);
wait_for_fds_ready();
rc = fds_record_find(SCR_FILE_ID, SCR_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// RGB record found
NRF_LOG_INFO("Script record found");
rc = fds_record_update(&desc, &scr_dummy_record);
APP_ERROR_CHECK(rc);
if (rc == FDS_SUCCESS){
NRF_LOG_INFO("Script record updated");
//NRF_LOG_INFO("Script record id: %d", desc.record_id);
}
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Creating new Script file...");
rc = fds_record_write(&desc, &scr_dummy_record);
APP_ERROR_CHECK(rc);
}
}
void record_read_ant(){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
uint32_t *data;
// Make log entry
#ifdef INTERNAL_LOG_ENABLED
log_data("SLM");
#endif
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Reading Script Record...");
#endif
wait_for_fds_ready();
// It is required to zero the token before first use. */
memset(&tok, 0x00, sizeof(fds_find_token_t));
rc = fds_record_find(ANT_FILE_ID, ANT_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// Script record found
NRF_LOG_INFO("Script record found");
// A config file is in flash. Let's update it.
fds_flash_record_t config = {0};
// Open the record and read its contents.
rc = fds_record_open(&desc, &config);
APP_ERROR_CHECK(rc);
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Found Record ID = %d",desc.record_id);
#endif
// Copy the configuration from flash into m_dummy_cfg.
memcpy(&ant_dummy_cfg, config.p_data, sizeof(ant_bytes_t));
//*script = scr_dummy_cfg.script;
// Close the record when done reading.
rc = fds_record_close(&desc);
APP_ERROR_CHECK(rc);
// Read the current script ID
ant_rf_frequency = ant_dummy_cfg.data[0];
ant_channel_id_dev_type = ant_dummy_cfg.data[1];
NRF_LOG_INFO("ANT freq read: %d", ant_rf_frequency);
NRF_LOG_INFO("ANT type read: %d", ant_channel_id_dev_type);
//return scr_dummy_cfg.script;
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("ANT record not found");
}
}
void record_update_ant(char data[2]){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
ant_dummy_cfg.data[0] = data[0];
ant_dummy_cfg.data[1] = data[1];
NRF_LOG_INFO("Copied/dummy string");
//NRF_LOG_INFO("Copied/dummy string for ANT network: %02x, %02x", data[0], data[1]);
NRF_LOG_HEXDUMP_INFO(ant_dummy_cfg.data, sizeof(ant_dummy_cfg.data));
//NRF_LOG_INFO("Copied/dummy string len: %d", len); //strlen(scr_dummy_cfg.script))
//NRF_LOG_INFO("Record len: %d", scr_dummy_record.data.length_words);
wait_for_fds_ready();
rc = fds_record_find(ANT_FILE_ID, ANT_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// RGB record found
NRF_LOG_INFO("ANT record found");
rc = fds_record_update(&desc, &ant_dummy_record);
APP_ERROR_CHECK(rc);
if (rc == FDS_SUCCESS){
NRF_LOG_INFO("ANT record updated");
//NRF_LOG_INFO("Script record id: %d", desc.record_id);
}
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Creating new ANTt file...");
rc = fds_record_write(&desc, &ant_dummy_record);
APP_ERROR_CHECK(rc);
}
}
#ifdef INTERNAL_LOG_ENABLED
char * record_read_log(){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
uint32_t *data;
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Reading Script Record...");
#endif
wait_for_fds_ready();
// It is required to zero the token before first use. */
memset(&tok, 0x00, sizeof(fds_find_token_t));
rc = fds_record_find(LOG_FILE_ID, LOG_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// Script record found
NRF_LOG_INFO("Log record found");
// A config file is in flash. Let's update it.
fds_flash_record_t config = {0};
// Open the record and read its contents.
rc = fds_record_open(&desc, &config);
APP_ERROR_CHECK(rc);
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Found Record ID = %d",desc.record_id);
#endif
// Copy the configuration from flash into m_dummy_cfg.
memcpy(&log_dummy_cfg, config.p_data, sizeof(log_value_t));
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Log record values:");
NRF_LOG_INFO("p_data:");
NRF_LOG_HEXDUMP_INFO(config.p_data, sizeof(config.p_data));
#endif
// NRF_LOG_INFO("Log data read.");
// NRF_LOG_INFO("dummy:");
// NRF_LOG_HEXDUMP_INFO(log_dummy_cfg.log_table, sizeof(log_dummy_cfg.log_table));
// Close the record when done reading.
rc = fds_record_close(&desc);
APP_ERROR_CHECK(rc);
last_log_index = strlen(log_dummy_cfg.log_table);
NRF_LOG_INFO("last_log_index:%d", last_log_index);
// // Calculate length of recored
// log_total_length = 0;
// for (int i=0; i<121; i++){
// // If end of script found, terminate
// if (log_dummy_cfg.log_table[i] == 0xFF)
// break;
//
// script_total_length++;
// }
// Read the current script ID
//scr_script_id = scr_dummy_cfg.script[script_total_length+1];
//NRF_LOG_INFO("Script total length: %d", script_total_length);
//NRF_LOG_INFO("Script ID: 0x%2X", scr_script_id);
return log_dummy_cfg.log_table;
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Log record not found");
}
}
void record_update_log(char log_data[], int len){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
NRF_LOG_INFO("Updating LOG Record...");
// copy data into log_dummy_cfg
//int len = sizeof(log_dummy_cfg.log_table);
int i=0;
for (i=0; i<len; i++){
log_dummy_cfg.log_table[i] = log_data[i];
}
for (i=len; i<log_dummy_record.data.length_words*4; i++){
log_dummy_cfg.log_table[i] = 0;
}
// NRF_LOG_INFO("Copied/dummy log");
// NRF_LOG_HEXDUMP_INFO(log_dummy_cfg.log_table, sizeof(log_dummy_cfg.log_table));
// NRF_LOG_INFO("Copied/dummy log len: %d", len); //strlen(scr_dummy_cfg.script))
wait_for_fds_ready();
rc = fds_record_find(LOG_FILE_ID, LOG_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// LOG record found
NRF_LOG_INFO("LOG record found");
rc = fds_record_update(&desc, &log_dummy_record);
APP_ERROR_CHECK(rc);
if (rc == FDS_SUCCESS){
NRF_LOG_INFO("LOG record updated: %X", log_dummy_cfg.log_table);
NRF_LOG_INFO("LOG record id: %d", desc.record_id);
}
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Creating new LOG file...");
rc = fds_record_write(&desc, &log_dummy_record);
APP_ERROR_CHECK(rc);
}
}
#endif
void record_read_data(uint8_t *time_stamp){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
uint32_t *data;
NRF_LOG_INFO("Reading DATA Record...");
wait_for_fds_ready();
// It is required to zero the token before first use. */
memset(&tok, 0x00, sizeof(fds_find_token_t));
rc = fds_record_find(DATA_FILE_ID, DATA_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// DATA record found
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("DATA record found");
#endif
// A config file is in flash. Let's update it.
fds_flash_record_t config = {0};
// Open the record and read its contents.
rc = fds_record_open(&desc, &config);
APP_ERROR_CHECK(rc);
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Found Record ID = %d",desc.record_id);
#endif
// Copy the configuration from flash into m_dummy_cfg.
memcpy(&data_dummy_cfg, config.p_data, sizeof(data_values_t));
*time_stamp = data_dummy_cfg.time_stamp;
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("RGB record values:%X,%X,%X", rgb_dummy_cfg.red, rgb_dummy_cfg.green, rgb_dummy_cfg.blue);
#endif
// Close the record when done reading.
rc = fds_record_close(&desc);
APP_ERROR_CHECK(rc);
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("DATA record not found");
}
}
void record_update_data(uint8_t time_stamp){
ret_code_t rc;
fds_record_desc_t desc = {0};
fds_find_token_t tok = {0};
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("Updating DATA Record...");
#endif
wait_for_fds_ready();
rc = fds_record_find(DATA_FILE_ID, DATA_REC_KEY, &desc, &tok);
if (rc == FDS_SUCCESS){
// RGB record found
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("DATA record found");
#endif
data_dummy_cfg.time_stamp = time_stamp;
rc = fds_record_update(&desc, &data_dummy_record);
APP_ERROR_CHECK(rc);
if (rc == FDS_SUCCESS){
#ifdef LOG_ENABLED_2
NRF_LOG_INFO("RGB record updated: %X,%X,%X", rgb_dummy_cfg.red, rgb_dummy_cfg.green, rgb_dummy_cfg.blue);
NRF_LOG_INFO("RGB record id: %d", desc.record_id);
#endif
}
}
else{
// System config not found; write a new one.
NRF_LOG_INFO("Creating new DATA file...");
rc = fds_record_write(&desc, &data_dummy_record);
APP_ERROR_CHECK(rc);
}
}