initial commit
This commit is contained in:
222
project/ble_peripheral/ble_app_vivaMayo/config/device_config.c
Normal file
222
project/ble_peripheral/ble_app_vivaMayo/config/device_config.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/*******************************************************************************
|
||||
* @file device_config.c
|
||||
* @brief Device Configuration Management
|
||||
* @author Charles KWON <charleskwon@medithings.co.kr>
|
||||
* @date 2025-01-30
|
||||
* @copyright (c) 2025 Medithings Inc. All rights reserved.
|
||||
*
|
||||
* @details EEPROM configuration loading and default values.
|
||||
******************************************************************************/
|
||||
|
||||
#include "device_config.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "debug_print.h"
|
||||
#include "cat_interface.h"
|
||||
#include <cmd_parse.h>
|
||||
#include <string.h>
|
||||
#include "storage/dr_mem.h"
|
||||
#include "fstorage.h"
|
||||
|
||||
/*==============================================================================
|
||||
* GLOBAL VARIABLES
|
||||
*============================================================================*/
|
||||
|
||||
char m_static_passkey[7] = "123456";
|
||||
char SERIAL_NO[16] = "2025VIVAM00001";
|
||||
char HW_NO[12] = "HW00000001";
|
||||
bool bond_data_delete = true;
|
||||
uint8_t m_pd_adc_cnt = 8;
|
||||
uint16_t m_pd_delay_us = 8000;
|
||||
uint32_t m_life_cycle = 0;
|
||||
uint16_t led_pd_dac_v[48];
|
||||
|
||||
/*==============================================================================
|
||||
* VALIDATION FUNCTIONS
|
||||
*============================================================================*/
|
||||
|
||||
bool is_valid_serial_no(const char *serial)
|
||||
{
|
||||
if (serial == NULL) return false;
|
||||
|
||||
/* Check for reasonable serial number format */
|
||||
for (int i = 0; i < 12; i++) {
|
||||
char c = serial[i];
|
||||
if (c == 0) break;
|
||||
if (c == 0xFF) return false; /* Uninitialized EEPROM */
|
||||
if (c < 0x20 || c > 0x7E) return false; /* Non-printable */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_valid_passkey(const char *passkey)
|
||||
{
|
||||
if (passkey == NULL) return false;
|
||||
|
||||
/* Check for 6 digit passkey */
|
||||
for (int i = 0; i < 6; i++) {
|
||||
char c = passkey[i];
|
||||
if (c == 0xFF) return false; /* Uninitialized EEPROM */
|
||||
if (c < '0' || c > '9') return false; /* Not a digit */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* CONFIGURATION LOADING
|
||||
*============================================================================*/
|
||||
|
||||
void load_default_values(void)
|
||||
{
|
||||
/* Default Serial Number */
|
||||
memset(SERIAL_NO, 0, sizeof(SERIAL_NO));
|
||||
memcpy(SERIAL_NO, "2025AAAAT001", 12);
|
||||
|
||||
/* Default Passkey */
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, "123456", 6);
|
||||
|
||||
/* Default measurement parameters */
|
||||
m_pd_delay_us = 8000;
|
||||
m_pd_adc_cnt = 8;
|
||||
|
||||
/* Default state */
|
||||
bond_data_delete = 1;
|
||||
|
||||
/* Default AGC Gain values */
|
||||
for (int i = 0; i < 48; i++) {
|
||||
led_pd_dac_v[i] = 2048;
|
||||
}
|
||||
|
||||
DBG_PRINTF("[CFG] Using default values\r\n");
|
||||
}
|
||||
|
||||
static bool is_valid_hw_no(const char *hw)
|
||||
{
|
||||
if (hw == NULL) return false;
|
||||
/* All 0x00 or 0xFF = uninitialized */
|
||||
bool all_zero = true, all_ff = true;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (hw[i] != 0x00) all_zero = false;
|
||||
if ((uint8_t)hw[i] != 0xFF) all_ff = false;
|
||||
}
|
||||
if (all_zero || all_ff) return false;
|
||||
/* Check printable ASCII */
|
||||
for (int i = 0; i < 12; i++) {
|
||||
char c = hw[i];
|
||||
if (c == 0) break;
|
||||
if (c < 0x20 || c > 0x7E) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void load_device_configuration(void)
|
||||
{
|
||||
extern uint8_t m_reset_status;
|
||||
ret_code_t err_code;
|
||||
|
||||
/* Start with RAM defaults, then override with FDS-saved values below.
|
||||
* dr_memSetDefaults() removed: it was clobbering FDS-loaded m_config,
|
||||
* wiping user-saved data (serial_no, passkey, etc.) on every boot
|
||||
* when hw_no was still all-zeros. */
|
||||
load_default_values();
|
||||
|
||||
/* Show m_config state right after config_load (before dr_memRead) */
|
||||
{
|
||||
char tmp[13] = {0};
|
||||
memcpy(tmp, m_config.serial_no, 12);
|
||||
DBG_PRINTF("[CFG] FDS serial_no='%s'\r\n", tmp);
|
||||
memcpy(tmp, m_config.hw_no, 12);
|
||||
DBG_PRINTF("[CFG] FDS hw_no='%s'\r\n", tmp);
|
||||
}
|
||||
|
||||
/* Read FDS entries (already loaded by config_load() into m_config) */
|
||||
err_code = dr_memRead("serial_no", (uint8_t *)SERIAL_NO, 12);
|
||||
DBG_PRINTF("[CFG] dr_memRead S/N rc=%u valid=%d\r\n", err_code, is_valid_serial_no(SERIAL_NO));
|
||||
DBG_PRINTF("[CFG] S/N hex: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
|
||||
(uint8_t)SERIAL_NO[0], (uint8_t)SERIAL_NO[1], (uint8_t)SERIAL_NO[2], (uint8_t)SERIAL_NO[3],
|
||||
(uint8_t)SERIAL_NO[4], (uint8_t)SERIAL_NO[5], (uint8_t)SERIAL_NO[6], (uint8_t)SERIAL_NO[7],
|
||||
(uint8_t)SERIAL_NO[8], (uint8_t)SERIAL_NO[9], (uint8_t)SERIAL_NO[10], (uint8_t)SERIAL_NO[11]);
|
||||
if (err_code != NRF_SUCCESS || !is_valid_serial_no(SERIAL_NO)) {
|
||||
DBG_PRINTF("[CFG] Invalid S/N - using default\r\n");
|
||||
memset(SERIAL_NO, 0, sizeof(SERIAL_NO));
|
||||
memcpy(SERIAL_NO, "2025AAAAT001", 12);
|
||||
}
|
||||
|
||||
err_code = dr_memRead("passkey", (uint8_t *)m_static_passkey, 6);
|
||||
if (err_code != NRF_SUCCESS || !is_valid_passkey(m_static_passkey)) {
|
||||
DBG_PRINTF("[CFG] Invalid passkey - using default\r\n");
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, "123456", 6);
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t raw = 0;
|
||||
dr_memRead("bond_delete", &raw, 1);
|
||||
bond_data_delete = (raw != 0);
|
||||
}
|
||||
|
||||
dr_memRead("reset_status", &m_reset_status, 1);
|
||||
if (m_reset_status > 2) {
|
||||
DBG_PRINTF("[CFG] Invalid reset_status (%u) - using 1\r\n", m_reset_status);
|
||||
m_reset_status = 1;
|
||||
}
|
||||
|
||||
dr_memRead("pd_adc_cnt", &m_pd_adc_cnt, 1);
|
||||
if (m_pd_adc_cnt == 0 || m_pd_adc_cnt >= 255) {
|
||||
DBG_PRINTF("[CFG] Invalid adc_cnt (%u) - using 8\r\n", m_pd_adc_cnt);
|
||||
m_pd_adc_cnt = 8;
|
||||
}
|
||||
|
||||
dr_memRead("pd_delay", &m_pd_delay_us, 2);
|
||||
if (m_pd_delay_us < 5000 || m_pd_delay_us > 30000) {
|
||||
DBG_PRINTF("[CFG] Invalid pd_delay (%u) - using 8000\r\n", m_pd_delay_us);
|
||||
m_pd_delay_us = 8000;
|
||||
}
|
||||
|
||||
/* W25Q32 entries - NOT read during boot
|
||||
* W25Q32 is not initialized at boot (SPIM + BSP event conflict).
|
||||
* agc_gain and life_cycle use RAM defaults from load_default_values().
|
||||
* Actual W25Q32 values are loaded later when W25Q32 is powered on
|
||||
* (via BLE command or measurement start). */
|
||||
|
||||
DBG_PRINTF("[CFG] Loaded: S/N=%s, delay=%u, cnt=%u, life=%u\r\n",
|
||||
SERIAL_NO, m_pd_delay_us, m_pd_adc_cnt, m_life_cycle);
|
||||
|
||||
/* 3. config_data_t dump (FDS raw) */
|
||||
{
|
||||
char tmp[13] = {0};
|
||||
#define CFG_DLY() nrf_delay_ms(10)
|
||||
|
||||
DBG_PRINTF("[CFG] === config_data_t (FDS) ===\r\n"); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] magic : 0x%08X\r\n", m_config.magic_number); CFG_DLY();
|
||||
|
||||
memcpy(tmp, m_config.hw_no, 12); tmp[12] = 0;
|
||||
DBG_PRINTF("[CFG] hw_no : %s\r\n", tmp); CFG_DLY();
|
||||
|
||||
memcpy(tmp, m_config.serial_no, 12); tmp[12] = 0;
|
||||
DBG_PRINTF("[CFG] serial : %s\r\n", tmp); CFG_DLY();
|
||||
|
||||
DBG_PRINTF("[CFG] passkey : %c%c%c%c%c%c\r\n",
|
||||
m_config.static_passkey[0], m_config.static_passkey[1],
|
||||
m_config.static_passkey[2], m_config.static_passkey[3],
|
||||
m_config.static_passkey[4], m_config.static_passkey[5]); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] bond_del: %u\r\n", m_config.bond_data_delete); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] reset_st: %d\r\n", m_config.reset_status); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] adc_cnt : %u\r\n", m_config.pd_adc_cnt); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] pd_delay: %u\r\n", m_config.pd_delay_us); CFG_DLY();
|
||||
|
||||
/* W25Q32 entries */
|
||||
DBG_PRINTF("[CFG] agc_gain[48]:\r\n"); CFG_DLY();
|
||||
for (int i = 0; i < 48; i += 8) {
|
||||
DBG_PRINTF(" [%2d] %u %u %u %u %u %u %u %u\r\n", i,
|
||||
led_pd_dac_v[i], led_pd_dac_v[i+1],
|
||||
led_pd_dac_v[i+2], led_pd_dac_v[i+3],
|
||||
led_pd_dac_v[i+4], led_pd_dac_v[i+5],
|
||||
led_pd_dac_v[i+6], led_pd_dac_v[i+7]); CFG_DLY();
|
||||
}
|
||||
DBG_PRINTF("[CFG] life : %u\r\n", m_life_cycle); CFG_DLY();
|
||||
DBG_PRINTF("[CFG] ========================\r\n");
|
||||
|
||||
#undef CFG_DLY
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* @file device_config.h
|
||||
* @brief Device Configuration Management
|
||||
* @author Charles KWON <charleskwon@medithings.co.kr>
|
||||
* @date 2025-01-30
|
||||
* @copyright (c) 2025 Medithings Inc. All rights reserved.
|
||||
*
|
||||
* @details EEPROM configuration loading and default values.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef DEVICE_CONFIG_H
|
||||
#define DEVICE_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*==============================================================================
|
||||
* CONSTANTS
|
||||
*============================================================================*/
|
||||
|
||||
#define LED_NUM 24 /* Number of LEDs in system */
|
||||
|
||||
/*==============================================================================
|
||||
* EXTERNAL VARIABLES
|
||||
*============================================================================*/
|
||||
|
||||
extern char m_static_passkey[7];
|
||||
extern char SERIAL_NO[16];
|
||||
extern bool bond_data_delete;
|
||||
extern uint8_t m_pd_adc_cnt;
|
||||
extern uint16_t m_pd_delay_us;
|
||||
extern uint32_t m_life_cycle;
|
||||
extern uint16_t led_pd_dac_v[];
|
||||
|
||||
/*==============================================================================
|
||||
* FUNCTION PROTOTYPES
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Load device configuration from EEPROM
|
||||
*/
|
||||
void load_device_configuration(void);
|
||||
|
||||
/**
|
||||
* @brief Load default configuration values
|
||||
*/
|
||||
void load_default_values(void);
|
||||
|
||||
/**
|
||||
* @brief Validate serial number string
|
||||
* @param serial Serial number string
|
||||
* @return true if valid
|
||||
*/
|
||||
bool is_valid_serial_no(const char *serial);
|
||||
|
||||
/**
|
||||
* @brief Validate passkey string
|
||||
* @param passkey Passkey string
|
||||
* @return true if valid
|
||||
*/
|
||||
bool is_valid_passkey(const char *passkey);
|
||||
|
||||
#endif /* DEVICE_CONFIG_H */
|
||||
Reference in New Issue
Block a user