From e0a504b96934f64d003b086ebfba33566a35a0df Mon Sep 17 00:00:00 2001 From: jhchun Date: Mon, 16 Mar 2026 17:58:17 +0900 Subject: [PATCH] =?UTF-8?q?cmd=5Fparse.c=EC=97=90=EC=84=9C=20parser.c?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=ED=95=A9=20=EC=A4=80=EB=B9=84:=20spz=3F?= =?UTF-8?q?=20/=20sqz=3F=20/=20sxz=3F=20/=20syz=3F=20->=20mpz=3F=20/=20mqz?= =?UTF-8?q?=3F=20/=20mxz=3F=20/=20myz=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- pc_firm/parser.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/pc_firm/parser.c b/pc_firm/parser.c index c87bebf..a70343e 100644 --- a/pc_firm/parser.c +++ b/pc_firm/parser.c @@ -46,6 +46,9 @@ extern void dr_sd_delay_ms(uint32_t ms); /* Softdevice-friendly delay */ #include "fstorage.h" extern char SERIAL_NO[12]; extern char HW_NO[12]; +extern char m_static_passkey[6]; +extern uint32_t m_life_cycle; +extern void format_data(uint8_t *buffer, const char *tag, const uint16_t *data_array, size_t length); /* FW Version - must match cmd_parse.c DEVICE_VERSION */ #define DR_DEVICE_VERSION "FW25LIT2B102" @@ -298,7 +301,7 @@ static int Cmd_sss(const ParsedCmd *cmd); static int Cmd_sst(const ParsedCmd *cmd); static int Cmd_mfv(const ParsedCmd *cmd); -/////////////////////* PIEZO *///////////////////// +/* ------------------ Piezo ------------------ */ static int Cmd_msp(const ParsedCmd *cmd); /* IMU 6-axis raw data (single shot) */ @@ -311,11 +314,18 @@ static int Cmd_maa(const ParsedCmd *cmd); /* Piezo Burst + ADC all channel capt static int Cmd_cmd(const ParsedCmd *cmd); /* Pin Test (High / Low) */ +/* ------------------ FDS ------------------ */ + static int Cmd_mwh(const ParsedCmd *cmd); /* Write HW Number to FDS */ static int Cmd_mws(const ParsedCmd *cmd); /* Write Serial Number to FDS */ static int Cmd_mrh(const ParsedCmd *cmd); /* Read HW Number from FDS */ static int Cmd_mrs(const ParsedCmd *cmd); /* Read Serial Number from FDS */ +static int Cmd_mpz(const ParsedCmd *cmd); /* Write Passkey to FDS */ +static int Cmd_mqz(const ParsedCmd *cmd); /* Read Passkey from FDS */ +static int Cmd_mxz(const ParsedCmd *cmd); /* Write Life Cycle to FDS */ +static int Cmd_myz(const ParsedCmd *cmd); /* Read Life Cycle from FDS */ + /* ---- Command Table ---- */ typedef struct { @@ -344,6 +354,12 @@ static CmdEntry g_cmd_table[] = { { "mrh?", true, Cmd_mrh }, { "mrs?", true, Cmd_mrs }, + /* Config: Passkey / Life Cycle (FDS) */ + { "mpz?", true, Cmd_mpz }, /* 패스키 쓰기 (spz? → mpz?) */ + { "mqz?", true, Cmd_mqz }, /* 패스키 읽기 (sqz? → mqz?) */ + { "mxz?", true, Cmd_mxz }, /* life_cycle 쓰기 (sxz? → mxz?) */ + { "myz?", true, Cmd_myz }, /* life_cycle 읽기 (syz? → myz?) */ + /* A. Device Status */ { "mta?", true, Cmd_mta }, { "sta?", true, Cmd_sta }, @@ -1349,6 +1365,84 @@ static int Cmd_mrs(const ParsedCmd *cmd) } +/*============================================================================== + * Passkey / Life Cycle (FDS) + *============================================================================*/ + +/* mpz? - 패스키 쓰기 (spz? → mpz?) + * 패킷: mpz? + ASCII 6자리 패스키 + * 응답: rpz: + ASCII 6바이트 + */ +static int Cmd_mpz(const ParsedCmd *cmd) +{ + char passkey[7] = {0}; + dr_get_ascii(cmd, 0, passkey, 6); + + memcpy(m_static_passkey, passkey, 6); + memcpy(m_config.static_passkey, m_static_passkey, 6); + config_save(); + + if (g_plat.log) g_plat.log("[mpz] Passkey saved: %.6s\r\n", m_static_passkey); + + ascii_format_data(ble_bin_buffer, "rpz:", passkey, 6); + dr_binary_tx_safe(ble_bin_buffer, 5); + return 1; +} + +/* mqz? - 패스키 읽기 (sqz? → mqz?) + * 패킷: mqz? (데이터 없음) + * 응답: rqz: + ASCII 6바이트 + */ +static int Cmd_mqz(const ParsedCmd *cmd) +{ + (void)cmd; + memcpy(m_static_passkey, m_config.static_passkey, 6); + + ascii_format_data(ble_bin_buffer, "rqz:", m_static_passkey, 6); + dr_binary_tx_safe(ble_bin_buffer, 5); + return 1; +} + +/* mxz? - life_cycle 쓰기 (sxz? → mxz?) + * 패킷: mxz? + uint16 x 2 (상위16비트, 하위16비트) + * 응답: rxz: + uint16 x 2 + */ +static int Cmd_mxz(const ParsedCmd *cmd) +{ + uint16_t hi = 0, lo = 0; + dr_get_u16(cmd, 0, &hi); + dr_get_u16(cmd, 1, &lo); + + m_life_cycle = ((uint32_t)hi << 16) | (uint32_t)lo; + m_config.life_cycle = m_life_cycle; + config_save(); + + if (g_plat.log) g_plat.log("[mxz] life_cycle=%u saved\r\n", m_life_cycle); + + uint16_t result[2] = { hi, lo }; + format_data(ble_bin_buffer, "rxz:", result, 2); + dr_binary_tx_safe(ble_bin_buffer, 4); + return 1; +} + +/* myz? - life_cycle 읽기 (syz? → myz?) + * 패킷: myz? (데이터 없음) + * 응답: ryz: + uint16 x 2 + */ +static int Cmd_myz(const ParsedCmd *cmd) +{ + (void)cmd; + m_life_cycle = m_config.life_cycle; + + uint16_t result[2]; + result[0] = (uint16_t)(m_life_cycle >> 16); + result[1] = (uint16_t)(m_life_cycle & 0xFFFF); + + format_data(ble_bin_buffer, "ryz:", result, 2); + dr_binary_tx_safe(ble_bin_buffer, 4); + return 1; +} + /*============================================================================== * IMU: 6-axis raw data (single shot) *============================================================================*/