/******************************************************************************* TEST medi50 Dec 23 ******************************************************************************/ #include "sdk_config.h" #include #include "app_error.h" #include "boards.h" #include "nrf_fstorage.h" #include "nrf_soc.h" #include "nrf_strerror.h" #include "sdk_config.h" #include "nrf_fstorage_sd.h" #include "nrf_delay.h" #include "ble_gap.h" #include "fds.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "fstorage.h" #include "nrf_pwr_mgmt.h" #include "main.h" #include "debug_print.h" /* File ID and Key used for the configuration record. */ #define CONFIG_FILE (0x8010) #define CONFIG_REC_KEY (0x7010) #define CONFIG_MAGIC_NUMBER_VALUE (0x20231226) config_data_t m_config; extern bool go_device_power_off; extern bool go_sleep_mode_enter; extern bool go_NVIC_SystemReset; /* Flag to check fds initialization. */ static bool volatile m_fds_initialized; bool fds_flag_write = false; /* A record containing dummy configuration data. */ static fds_record_t const m_dummy_record = { .file_id = CONFIG_FILE, .key = CONFIG_REC_KEY, .data.p_data = (void const *)&m_config, /* The length of a record is always expressed in 4-byte units (words). */ .data.length_words = (sizeof(m_config) + 3) / sizeof(uint32_t), }; int8_t reset_status_dflt = 99; uint8_t static_passkey_dflt[6] = "123456"; void fds_default_value_set(void) { /* HW Number - empty (set via BLE command) */ memset(m_config.hw_no, 0, 12); /* Serial Number - default from FIRMWARE_SERIAL_NO */ memset(m_config.serial_no, 0, 12); memcpy(m_config.serial_no, "VB026030000", 11); /* Static Passkey */ memcpy(m_config.static_passkey, static_passkey_dflt, 6); /* Bond data delete */ m_config.bond_data_delete = 1; /* Reset status */ m_config.reset_status = reset_status_dflt; /* Measurement parameters */ m_config.pd_adc_cnt = 8; m_config.pd_delay_us = 8000; } static volatile uint8_t fds_last_evt = 0xFF; static void fds_evt_handler( fds_evt_t const *p_evt ) { fds_last_evt = p_evt->id; switch( p_evt->id ) { case FDS_EVT_INIT: if( p_evt->result == NRF_SUCCESS ) { m_fds_initialized = true; } break; case FDS_EVT_WRITE: { fds_flag_write = false; } break; case FDS_EVT_UPDATE: { fds_flag_write = false; if(go_device_power_off == true) { /* After flash writing completed, System Power Off */ device_power_off(); } if(go_sleep_mode_enter == true) { /* After flash writing completed, System go to Sleep Mode */ sleep_mode_enter(); } if(go_NVIC_SystemReset == true) { /* After flash writing completed, System Reset */ DBG_PRINTF("Off FDS_EVENT\r\n"); NVIC_SystemReset(); } } break; case FDS_EVT_DEL_RECORD: break; case FDS_EVT_DEL_FILE: break; case FDS_EVT_GC: break; default: break; } } /**@brief Wait for fds to initialize. */ static void wait_for_fds_ready( void ) { uint32_t timeout = 0; while( !m_fds_initialized ) { nrf_pwr_mgmt_run(); nrf_delay_ms(1); timeout++; if (timeout > 3000) { /* 3 second timeout */ DBG_PRINTF("[FDS] TIMEOUT!\r\n"); break; } } } void config_load( void ) { ret_code_t rc; fds_record_desc_t desc = { 0 }; fds_find_token_t tok = { 0 }; uint8_t cfg_retry = 0; cfg_load_start: memset((char *)&desc, 0, sizeof(desc)); memset((char *)&tok, 0, sizeof(tok)); rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok); DBG_PRINTF("[FDS] find rc=%u\r\n", rc); /* FDS may not be fully ready yet - retry before writing defaults */ if (rc != NRF_SUCCESS && cfg_retry < 10) { cfg_retry++; DBG_PRINTF("[FDS] retry %u/10\r\n", cfg_retry); nrf_delay_ms(100); goto cfg_load_start; } if( rc == NRF_SUCCESS ) { /* 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); if (rc != NRF_SUCCESS) { /* CRC error or corrupt record - delete and use defaults */ DBG_PRINTF("[FDS] open ERR=%u, deleting\r\n", rc); (void)fds_record_delete(&desc); fds_gc(); fds_default_value_set(); goto cfg_load_write_new; } /* Copy the configuration from flash into m_config. */ memcpy(&m_config, config.p_data, sizeof(config_data_t)); /* Close the record when done reading. */ rc = fds_record_close(&desc); APP_ERROR_CHECK(rc); DBG_PRINTF("[FDS] magic=0x%08X (expect 0x%08X)\r\n", m_config.magic_number, CONFIG_MAGIC_NUMBER_VALUE); if( m_config.magic_number != (uint32_t)CONFIG_MAGIC_NUMBER_VALUE ) { // first init DBG_PRINTF("[FDS] FORMAT! overwriting with defaults\r\n"); rc = fds_record_delete(&desc); APP_ERROR_CHECK(rc); m_config.magic_number = CONFIG_MAGIC_NUMBER_VALUE; // default.... fds_default_value_set(); /* Write the updated record to flash. */ rc = fds_record_update(&desc, &m_dummy_record); if( (rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH) ) { rc = fds_gc(); APP_ERROR_CHECK(rc); } else { APP_ERROR_CHECK(rc); } goto cfg_load_start; } DBG_PRINTF("[FDS] Loaded OK\r\n"); } else { cfg_load_write_new: DBG_PRINTF("[FDS] New - writing defaults\r\n"); /* System config not found (or corrupt); write a new one. */ m_config.magic_number = CONFIG_MAGIC_NUMBER_VALUE; // default.... fds_default_value_set(); fds_flag_write = true; rc = fds_record_write(&desc, &m_dummy_record); if (rc != NRF_SUCCESS) { DBG_PRINTF("[FDS] Write ERR=%u\r\n", rc); fds_flag_write = false; } while( fds_flag_write ) { nrf_pwr_mgmt_run(); } if( (rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH) ) { rc = fds_gc(); APP_ERROR_CHECK(rc); } else { APP_ERROR_CHECK(rc); } NRF_LOG_FLUSH(); goto cfg_load_start; } } void config_save( void ) { ret_code_t rc; fds_record_desc_t desc = { 0 }; fds_find_token_t tok = { 0 }; DBG_PRINTF("[CFG_SAVE] start\r\n"); /* Wait for any previous FDS operation to complete */ if (fds_flag_write) { uint32_t wait_cnt = 0; DBG_PRINTF("[CFG_SAVE] waiting for prev FDS op...\r\n"); while (fds_flag_write && wait_cnt < 3000) { nrf_pwr_mgmt_run(); nrf_delay_ms(1); wait_cnt++; } if (fds_flag_write) { DBG_PRINTF("[CFG_SAVE] TIMEOUT! forcing flag clear\r\n"); fds_flag_write = false; } } if( m_config.magic_number != (uint32_t)CONFIG_MAGIC_NUMBER_VALUE ) { m_config.magic_number = CONFIG_MAGIC_NUMBER_VALUE; } memset((char *)&desc, 0, sizeof(desc)); memset((char *)&tok, 0, sizeof(tok)); rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok); DBG_PRINTF("[CFG_SAVE] find rc=%u\r\n", rc); if( rc == NRF_SUCCESS ) { fds_flag_write = true; rc = fds_record_update(&desc, &m_dummy_record); DBG_PRINTF("[CFG_SAVE] update rc=%u\r\n", rc); if( rc == FDS_ERR_NO_SPACE_IN_FLASH ) { fds_flag_write = false; rc = fds_gc(); DBG_PRINTF("[CFG_SAVE] gc rc=%u, retry\r\n", rc); fds_flag_write = true; rc = fds_record_update(&desc, &m_dummy_record); DBG_PRINTF("[CFG_SAVE] retry rc=%u\r\n", rc); } if( rc != NRF_SUCCESS ) { DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc); fds_flag_write = false; } } else { DBG_PRINTF("[CFG_SAVE] not found, writing new\r\n"); fds_flag_write = true; rc = fds_record_write(&desc, &m_dummy_record); DBG_PRINTF("[CFG_SAVE] write rc=%u\r\n", rc); if( rc != NRF_SUCCESS ) { DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc); fds_flag_write = false; } } DBG_PRINTF("[CFG_SAVE] done\r\n"); } void fs_set_value(void) { config_load(); } void fs_storage_init(void) { ret_code_t rc; /* Register first to receive an event when initialization is complete. */ rc = fds_register(fds_evt_handler); APP_ERROR_CHECK(rc); rc = fds_init(); APP_ERROR_CHECK(rc); /* Wait for fds to initialize. */ wait_for_fds_ready(); fds_stat_t stat = { 0 }; rc = fds_stat(&stat); APP_ERROR_CHECK(rc); DBG_PRINTF("[FDS] OK\r\n"); }