/******************************************************************************* 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 "measurements.h" #include "main.h" #include "power/power_ctrl.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), }; /* 공장 입력 항목 1 */ /* 공장 입력 항목 2 */ //char serial_number_dflt[12] = "2025AAMAY0FF"; //uint16_t pd_delay_us = 0; //int8_t reset_status=0; //uint32_t pd_adc_calibration_dflt_PD0[M_LED_NUM] = // {1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000, /* PD01 */ //}; //uint32_t pd_adc_calibration_dflt_PD1[M_LED_NUM] = // {1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000, /* PD1 */ //}; //uint32_t pd_adc_calibration_dflt_PD2[M_LED_NUM] = // {1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000,1000, 1000, 1000, 1000, 1000, 1000, /* MOD1 */ //}; ///* 공장 입력 항목 5 */ //uint32_t dark_noise_for_pd_dflt[PD_NUM] = /*PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, PD16, PD17, PD18, PD19, PD20, */ // {1111, 1111}; /* 공장 입력 항목 8 */ //int8_t pd_adc_cnt_dflt = 8; /* 8, 16, 24, 32 */ int8_t reset_status_dflt =99; /* 공장 입력 항목 9 */ //uint16_t led_delay_us_dflt = 8000; /* 0 ~ 65535 */ /* 공장 입력 항목 10 */ //uint16_t pd_delay_us_dflt = 8000; /* 0 ~ 65535 */ /* Static Passkey default */ uint8_t static_passkey_dflt[6] = "123456"; // //uint16_t led_power_dp_dflt[48] = { // //NULL, 42, 29, 41, 31, 28, 28, 42, 28, 39, 29, 27, 27, 42, 29, 40, 30, 28, 28, 40, 27, 38, 28, 25, 22 // 25,25,25,18,19,24,24,25,25,18,19,25,23,25,25,18,19,24,24,25,25,19,20,25,24,25,25,25,18,19,24,24,25,25,18,19,25,23,25,25,18,19,24,24,25,25,19,20 //}; void fds_default_value_set(void) { /* HW Number - empty (set via BLE command) */ memset(m_config.hw_no, 0, 12); /* Serial Number */ memcpy(m_config.serial_no, "2025AAAAT001", 12); /* 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 */ printf("Off FDS_ENVET\r\n"); NVIC_SystemReset(); //0112 } } 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 */ 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"); /* Skip if a previous FDS operation is still in progress (non-blocking) */ if (fds_flag_write) { DBG_PRINTF("[CFG_SAVE] busy, skipped\r\n"); return; } 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); /* Debug: show what we're about to save */ { char tmp[13] = {0}; memcpy(tmp, m_config.hw_no, 12); DBG_PRINTF("[CFG_SAVE] hw='%s'\r\n", tmp); memcpy(tmp, m_config.serial_no, 12); DBG_PRINTF("[CFG_SAVE] sn='%s'\r\n", tmp); } 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); printf("[FDS] OK\r\n"); }