From c98d9ae14e2602f7112257eba1fc06c2d6dc9479 Mon Sep 17 00:00:00 2001 From: jhchun Date: Thu, 16 Apr 2026 01:28:11 +0900 Subject: [PATCH] =?UTF-8?q?parser=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 파서 인프라/커맨드 핸들러로 분리 - 커맨드 핸들러는 기기 제어/기기 정보/센서/Piezo로 분리 --- .../command/cmd_common.h | 94 ++ .../ble_app_bladder_patch/command/cmd_table.c | 64 + .../ble_app_bladder_patch/command/cmd_table.h | 12 + .../command/{util => }/dr_util.c | 8 + .../command/{util => }/dr_util.h | 8 +- .../command/handlers/cmd_device.c | 169 +++ .../command/handlers/cmd_device.h | 17 + .../command/handlers/cmd_info.c | 164 ++ .../command/handlers/cmd_info.h | 18 + .../command/handlers/cmd_piezo.c | 305 ++++ .../command/handlers/cmd_piezo.h | 18 + .../command/handlers/cmd_sensor.c | 138 ++ .../command/handlers/cmd_sensor.h | 19 + .../ble_app_bladder_patch/command/parser.c | 1342 ++--------------- .../ble_app_bladder_patch/command/parser.h | 71 +- .../ble_app_bladder_patch/main.c | 2 + .../ble_app_bladder_patch_s140.uvoptx | 348 +++-- .../ble_app_bladder_patch_s140.uvprojx | 82 +- 18 files changed, 1469 insertions(+), 1410 deletions(-) create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/cmd_common.h create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.c create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.h rename project/ble_peripheral/ble_app_bladder_patch/command/{util => }/dr_util.c (85%) rename project/ble_peripheral/ble_app_bladder_patch/command/{util => }/dr_util.h (58%) create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.c create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.h create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.c create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.h create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.c create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.h create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.c create mode 100644 project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.h diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/cmd_common.h b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_common.h new file mode 100644 index 0000000..7dc3276 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_common.h @@ -0,0 +1,94 @@ +/*============================================================================== + * cmd_common.h - Shared header for command handlers + * + * Bundles every include / extern declaration / macro used in common across + * the cmd_*.c modules. A handler module only needs this header plus its own + * area-specific driver headers. + *============================================================================*/ +#ifndef CMD_COMMON_H +#define CMD_COMMON_H + +#include "parser.h" +#include +#include +#include +#include + +#include "nrf_gpio.h" +#include "nrf_delay.h" +#include "debug_print.h" +#include "dr_util.h" +#include "main.h" +#include "app_timer.h" +#include "fstorage.h" /* config_data_t */ + +/*------------------------------------------------------------------------------ + * BLE transmission / formatting (defined in main.c) + *----------------------------------------------------------------------------*/ +extern uint8_t ble_bin_buffer[]; +extern void single_format_data(uint8_t *buffer, const char *tag, uint16_t value); +extern void ascii_format_data(uint8_t *buffer, const char *tag, const char *ascii, size_t length); +extern void format_data(uint8_t *buffer, const char *tag, const uint16_t *data_array, size_t length); +extern void dr_binary_tx_safe(const uint8_t *buffer, uint16_t length); /* length: word count */ +extern void dr_sd_delay_ms(uint32_t ms); +extern volatile bool data_tx_in_progress; + +/*------------------------------------------------------------------------------ + * Device state / flags + *----------------------------------------------------------------------------*/ +extern volatile bool processing; +extern bool device_status; +extern bool con_single; +extern bool lock_check; +extern uint8_t resetCount; + +/*------------------------------------------------------------------------------ + * Measurement functions (defined elsewhere) + *----------------------------------------------------------------------------*/ +extern void battery_level_meas(void); +extern void pressure_all_level_meas(void); +extern void tmp235_voltage_level_meas(void); +extern int imu_read_direct(void); +extern void battery_timer_stop(void); +extern void main_timer_start(void); +extern void hw_i2c_init_once(void); + +/*------------------------------------------------------------------------------ + * info4 mode sensor cache (used to assemble the rbb: response in mbb?) + *----------------------------------------------------------------------------*/ +extern bool info4; +extern bool ble_got_new_data; +extern bool go_batt; +extern bool motion_data_once; +extern bool motion_raw_data_enabled; +extern volatile uint16_t info_batt; +extern volatile uint16_t info_temp; +extern volatile uint16_t info_imu[6]; +extern volatile bool tmp235_saadc_done; +extern volatile bool battery_saadc_done; + +/*------------------------------------------------------------------------------ + * Device identifiers / passkey (FDS-backed) + *----------------------------------------------------------------------------*/ +extern char SERIAL_NO[12]; +extern char HW_NO[12]; +extern char m_static_passkey[6]; +extern uint32_t m_life_cycle; + +/*------------------------------------------------------------------------------ + * Power / reset / bonding control + *----------------------------------------------------------------------------*/ +extern bool go_device_power_off; +extern bool go_NVIC_SystemReset; +extern bool bond_data_delete; +extern uint8_t m_reset_status; +extern void config_save(void); +extern config_data_t m_config; + +/*------------------------------------------------------------------------------ + * AGC gain switch (P0.20) + *----------------------------------------------------------------------------*/ +#define GAIN_SW_PIN NRF_GPIO_PIN_MAP(0, 20) +#define AGC_GAIN_SW(x) do { if(x) nrf_gpio_pin_set(GAIN_SW_PIN); else nrf_gpio_pin_clear(GAIN_SW_PIN); } while(0) + +#endif /* CMD_COMMON_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.c b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.c new file mode 100644 index 0000000..46d377b --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.c @@ -0,0 +1,64 @@ +/*============================================================================== + * cmd_table.c - Command table definition + * + * This file is the only linkage point between parser.c and the cmd_*.c + * handler modules. It pulls in every cmd_*.h to gather handler prototypes, + * builds the CmdEntry array, and injects the table into the parser via + * dr_parser_init() inside cmd_table_init(). + * + * Adding a new command: + * 1) Implement the handler in the appropriate cmd_*.c + * 2) Add the prototype to the matching cmd_*.h + * 3) Append { "tag?", true, Cmd_xxx } to m_cmd_table[] below + *============================================================================*/ + +#include "parser.h" +#include "cmd_table.h" +#include "cmd_device.h" +#include "cmd_info.h" +#include "cmd_sensor.h" +#include "cmd_piezo.h" + +static const CmdEntry m_cmd_table[] = { + /* A. Device state control */ + { "msq?", true, Cmd_msq }, + { "mss?", true, Cmd_mss }, +#if FEATURE_SECURE_CONNECTION + { "msr?", true, Cmd_msr }, +#endif + { "cmd?", true, Cmd_cmd }, + + /* B. Device information */ + { "mfv?", true, Cmd_mfv }, + { "mid?", true, Cmd_mid }, + { "mwh?", true, Cmd_mwh }, + { "mws?", true, Cmd_mws }, + { "mrh?", true, Cmd_mrh }, + { "mrs?", true, Cmd_mrs }, + { "mpz?", true, Cmd_mpz }, + { "mqz?", true, Cmd_mqz }, + + /* C. Sensor measurement */ + { "msn?", true, Cmd_msn }, + { "mso?", true, Cmd_mso }, + { "msp?", true, Cmd_msp }, + { "msi?", true, Cmd_msi }, + + /* D. Piezo ultrasound */ + { "mpa?", true, Cmd_mpa }, + { "mpb?", true, Cmd_mpb }, + { "mpc?", true, Cmd_mpc }, + { "mec?", true, Cmd_mec }, + { "maa?", true, Cmd_maa }, + { "mbb?", true, Cmd_mbb }, + { "mcf?", true, Cmd_mcf }, + { "mcs?", true, Cmd_mcs }, + + /* E. LED control (handler in cmd_device.c) */ + { "mls?", true, Cmd_mls }, +}; + +void cmd_table_init(void) +{ + dr_parser_init(m_cmd_table, sizeof(m_cmd_table) / sizeof(m_cmd_table[0])); +} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.h b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.h new file mode 100644 index 0000000..d142e2b --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/cmd_table.h @@ -0,0 +1,12 @@ +/*============================================================================== + * cmd_table.h - Command table registration entry point + * + * main.c calls cmd_table_init() at boot to inject the command table into + * the parser. + *============================================================================*/ +#ifndef CMD_TABLE_H +#define CMD_TABLE_H + +void cmd_table_init(void); + +#endif /* CMD_TABLE_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.c b/project/ble_peripheral/ble_app_bladder_patch/command/dr_util.c similarity index 85% rename from project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.c rename to project/ble_peripheral/ble_app_bladder_patch/command/dr_util.c index db94283..10fac91 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.c +++ b/project/ble_peripheral/ble_app_bladder_patch/command/dr_util.c @@ -1,3 +1,11 @@ +/*============================================================================== + * dr_util.c - BLE response formatting helpers + * + * Convenience wrappers used by command handlers to assemble and transmit + * short BLE responses. Each helper prepends a 4-char TAG and writes the + * supplied uint16 values in Big-Endian order. + *============================================================================*/ + #include "dr_util.h" #include "parser.h" diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.h b/project/ble_peripheral/ble_app_bladder_patch/command/dr_util.h similarity index 58% rename from project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.h rename to project/ble_peripheral/ble_app_bladder_patch/command/dr_util.h index 5ebec64..5e984f0 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/command/util/dr_util.h +++ b/project/ble_peripheral/ble_app_bladder_patch/command/dr_util.h @@ -1,3 +1,6 @@ +/*============================================================================== + * dr_util.h - BLE response helper API + *============================================================================*/ #ifndef DR_UTIL_H #define DR_UTIL_H @@ -8,11 +11,10 @@ void dr_ble_return_2(const char *tag, uint16_t v1, uint16_t v2); void dr_ble_return_3(const char *tag, uint16_t v1, uint16_t v2, uint16_t v3); void dr_ble_return_3_be(const char *tag, uint16_t v1, uint16_t v2, uint16_t v3); -/* Piezo dedicated BLE return - uses separate buffer to avoid conflicts */ +/* Piezo dedicated BLE return - uses a separate buffer to avoid conflicts. */ void dr_ble_return_piezo_1(const char *tag, uint16_t value); -/* BLE debug output - sends "dbg:" + point_id + value */ +/* BLE debug output - sends "dbg:" + point_id + value. */ void dr_ble_debug(uint16_t point_id, uint16_t value); #endif /* DR_UTIL_H */ - diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.c b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.c new file mode 100644 index 0000000..f50e502 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.c @@ -0,0 +1,169 @@ +/*============================================================================== + * cmd_device.c - Device state control handlers + * + * A. msq? -> rsq: device power OFF + * B. mss? -> rss: device soft reset + * C. msr? -> rsr: BLE bond delete + reset (FEATURE_SECURE_CONNECTION) + * D. cmd? -> rmd: direct GPIO pin control (debug / test only) + * E. mls? -> rls: set LED state + *============================================================================*/ + +#include "cmd_common.h" +#include "cmd_device.h" +#include "fstorage.h" +#include "led_control.h" + +/*============================================================================== + * msq? -> rsq: Device power OFF + * + * Request: [TAG 4B "msq?"] [val 2B BE] [CRC 2B] + * Response: [TAG 4B "rsq:"] [val 2B BE] [CRC 2B] + * + * Sends BLE response first; the actual power-off is performed from the main + * loop. Powering off immediately would prevent the response from reaching + * the host, so a flag + timer pattern is used instead. + *============================================================================*/ +int Cmd_msq(const ParsedCmd *cmd) +{ + uint16_t val = 0; + dr_get_u16(cmd, 0, &val); + if (g_plat.log) + { + g_plat.log("[Cmd_msq] Power off val=%u\r\n", val); + } + single_format_data(ble_bin_buffer, "rsq:", val); + dr_binary_tx_safe(ble_bin_buffer, 2); + go_device_power_off = true; + main_timer_start(); + return 1; +} + +/*============================================================================== + * mss? -> rss: Device soft reset + * + * Request: [TAG 4B "mss?"] [val 2B BE] [CRC 2B] + * Response: [TAG 4B "rss:"] [val 2B BE] [CRC 2B] + * + * Resets without erasing bond information. Reset status code is persisted + * to FDS so the boot path can identify the cause. + *============================================================================*/ +int Cmd_mss(const ParsedCmd *cmd) +{ + uint16_t val = 0; + dr_get_u16(cmd, 0, &val); + single_format_data(ble_bin_buffer, "rss:", val); + dr_binary_tx_safe(ble_bin_buffer, 2); + + m_reset_status = 2; + m_config.reset_status = m_reset_status; + config_save(); + nrf_delay_ms(5); + go_NVIC_SystemReset = true; + main_timer_start(); + return 1; +} + +/*============================================================================== + * msr? -> rsr: Delete BLE bonding info + system reset + * + * Request: [TAG 4B "msr?"] [val 2B BE] [CRC 2B] + * Response: [TAG 4B "rsr:"] [val 2B BE] [CRC 2B] + * + * 1. Send BLE response + * 2. Persist bond-delete flag and reset status to FDS + * 3. Wait 5 ms for FDS write completion + * 4. Set NVIC system reset flag + *============================================================================*/ +#if FEATURE_SECURE_CONNECTION +int Cmd_msr(const ParsedCmd *cmd) +{ + uint16_t val = 0; + dr_get_u16(cmd, 0, &val); + single_format_data(ble_bin_buffer, "rsr:", val); + dr_binary_tx_safe(ble_bin_buffer, 2); + + bond_data_delete = true; + m_config.bond_data_delete = (uint8_t)bond_data_delete; + m_reset_status = 2; + m_config.reset_status = m_reset_status; + config_save(); + nrf_delay_ms(5); + go_NVIC_SystemReset = true; + main_timer_start(); + return 1; +} +#endif + +/*============================================================================== + * cmd? -> rmd: Direct GPIO pin control (debug / test) + * + * Request: [TAG 4B "cmd?"] [port 2B BE] [pin 2B BE] [state 2B BE] [CRC 2B] + * Response: [TAG 4B "rmd:"] [port 2B BE] [pin 2B BE] [state 2B BE] [CRC 2B] + * Error: rmd: + 0 (insufficient data) + * + * port : GPIO port (0 or 1) + * pin : pin number (0..31) + * state: 1=HIGH, 0=LOW + * + * Misuse can damage hardware - intended for debug only. + *============================================================================*/ +int Cmd_cmd(const ParsedCmd *cmd) +{ + uint16_t v1, v2, v3; + uint32_t pin_number; + + if (cmd->data_len < 6) + { + dr_ble_return_1("rmd:", 0); + return 1; + } + + if (!dr_get_u16(cmd, 0, &v1)) v1 = 0; + if (!dr_get_u16(cmd, 1, &v2)) v2 = 0; + if (!dr_get_u16(cmd, 2, &v3)) v3 = 0; + + pin_number = NRF_GPIO_PIN_MAP(v1, v2); + nrf_gpio_cfg_output(pin_number); + + if (v3 == 1) + { + nrf_gpio_pin_set(pin_number); + } + else + { + nrf_gpio_pin_clear(pin_number); + } + + dr_ble_return_3("rmd:", v1, v2, v3); + return 1; +} + +/*============================================================================== + * mls? -> rls: Set LED state (app -> device) + * + * Request: [TAG 4B "mls?"] [state 2B BE] [CRC 2B] + * state: led_state_t enum value + * 0=OFF, 4=DETACH_WARNING, 5=ALIGN_SEARCHING, 6=ALIGN_COMPLETE + * Response: [TAG 4B "rls:"] [state 2B] [CRC 2B] + * Error: rls: + 0xFFFF (insufficient data) + * rls: + 0xFFFE (state out of range) + *============================================================================*/ +int Cmd_mls(const ParsedCmd *cmd) +{ + if (cmd->data_len < 2) { + dr_ble_return_1("rls:", 0xFFFF); + return 1; + } + + uint16_t state; + dr_get_u16(cmd, 0, &state); + + if (state > LED_STATE_ERROR) { + dr_ble_return_1("rls:", 0xFFFE); + return 1; + } + + led_set_state((led_state_t)state); + dr_ble_return_1("rls:", state); + return 1; +} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.h b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.h new file mode 100644 index 0000000..ae7dff3 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_device.h @@ -0,0 +1,17 @@ +/*============================================================================== + * cmd_device.h - Device state control handlers (power / reset / GPIO / LED) + *============================================================================*/ +#ifndef CMD_DEVICE_H +#define CMD_DEVICE_H + +#include "parser.h" + +int Cmd_msq(const ParsedCmd *cmd); /* msq? -> rsq: device power OFF */ +int Cmd_mss(const ParsedCmd *cmd); /* mss? -> rss: device soft reset */ +#if FEATURE_SECURE_CONNECTION +int Cmd_msr(const ParsedCmd *cmd); /* msr? -> rsr: bond delete + reset */ +#endif +int Cmd_cmd(const ParsedCmd *cmd); /* cmd? -> rmd: direct GPIO control */ +int Cmd_mls(const ParsedCmd *cmd); /* mls? -> rls: set LED state */ + +#endif /* CMD_DEVICE_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.c b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.c new file mode 100644 index 0000000..d4d671f --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.c @@ -0,0 +1,164 @@ +/*============================================================================== + * cmd_info.c - Device information read/write handlers + * + * Commands that read or write FDS-persisted data: firmware version, hardware version, serial number, BLE passkey. + * Typically written once at the factory and read back later for identification. + *============================================================================*/ + +#include "cmd_common.h" +#include "cmd_info.h" +#include "fstorage.h" + +/*============================================================================== + * mfv? -> rfv: Read firmware version + * + * Request: [TAG 4B "mfv?"] [CRC 2B] + * Response: [TAG 4B "rfv:"] [FW_VER 12B ASCII] [CRC 2B] + *============================================================================*/ +int Cmd_mfv(const ParsedCmd *cmd) +{ + (void)cmd; + ascii_format_data(ble_bin_buffer, "rfv:", FIRMWARE_VERSION, 12); + dr_binary_tx_safe(ble_bin_buffer, 8); /* 16 bytes = 8 words */ + return 1; +} + +/*============================================================================== + * mid? -> rid: Read HW number + serial number + FW version together + * + * Request: [TAG 4B "mid?"] [CRC 2B] + * Response: [TAG 4B "rid:"] [HW 12B] [SN 12B] [FW 12B] [CRC 2B] + *============================================================================*/ +int Cmd_mid(const ParsedCmd *cmd) +{ + uint8_t *buf = ble_bin_buffer; + (void)cmd; + + memcpy(HW_NO, m_config.hw_no, 12); + memcpy(SERIAL_NO, m_config.serial_no, 12); + + buf[0] = 'r'; buf[1] = 'i'; buf[2] = 'd'; buf[3] = ':'; + memcpy(&buf[4], HW_NO, 12); + memcpy(&buf[16], SERIAL_NO, 12); + memcpy(&buf[28], FIRMWARE_VERSION, 12); + + dr_binary_tx_safe(buf, 20); /* 40 bytes = 20 words */ + return 1; +} + +/*============================================================================== + * mwh? -> rwh: Write HW number to FDS + * + * Request: [TAG 4B "mwh?"] [HW 12B ASCII] [CRC 2B] + * Response: [TAG 4B "rwh:"] [HW 12B ASCII] [CRC 2B] + * Error: rwh: + 0xFFFF (insufficient data) + *============================================================================*/ +int Cmd_mwh(const ParsedCmd *cmd) +{ + char buf[13]; + + if (cmd->data_len < 12) { + dr_ble_return_1("rwh:", 0xFFFF); + return 1; + } + + dr_get_ascii(cmd, 0, buf, 12); + memcpy(HW_NO, buf, 12); + memcpy(m_config.hw_no, buf, 12); + config_save(); + + ascii_format_data(ble_bin_buffer, "rwh:", buf, 12); + dr_binary_tx_safe(ble_bin_buffer, 8); + return 1; +} + +/*============================================================================== + * mws? -> rws: Write serial number to FDS + * + * Request: [TAG 4B "mws?"] [SN 12B ASCII] [CRC 2B] + * Response: [TAG 4B "rws:"] [SN 12B ASCII] [CRC 2B] + * Error: rws: + 0xFFFF (insufficient data) + *============================================================================*/ +int Cmd_mws(const ParsedCmd *cmd) +{ + char buf[13]; + + if (cmd->data_len < 12) { + dr_ble_return_1("rws:", 0xFFFF); + return 1; + } + + dr_get_ascii(cmd, 0, buf, 12); + memcpy(SERIAL_NO, buf, 12); + memcpy(m_config.serial_no, buf, 12); + config_save(); + + ascii_format_data(ble_bin_buffer, "rws:", buf, 12); + dr_binary_tx_safe(ble_bin_buffer, 8); + return 1; +} + +/*============================================================================== + * mrh? -> rrh: Read HW number from FDS + * + * Request: [TAG 4B "mrh?"] [CRC 2B] + * Response: [TAG 4B "rrh:"] [HW 12B ASCII] [CRC 2B] + *============================================================================*/ +int Cmd_mrh(const ParsedCmd *cmd) +{ + (void)cmd; + memcpy(HW_NO, m_config.hw_no, 12); + ascii_format_data(ble_bin_buffer, "rrh:", HW_NO, 12); + dr_binary_tx_safe(ble_bin_buffer, 8); + return 1; +} + +/*============================================================================== + * mrs? -> rrs: Read serial number from FDS + * + * Request: [TAG 4B "mrs?"] [CRC 2B] + * Response: [TAG 4B "rrs:"] [SN 12B ASCII] [CRC 2B] + *============================================================================*/ +int Cmd_mrs(const ParsedCmd *cmd) +{ + (void)cmd; + memcpy(SERIAL_NO, m_config.serial_no, 12); + ascii_format_data(ble_bin_buffer, "rrs:", SERIAL_NO, 12); + dr_binary_tx_safe(ble_bin_buffer, 8); + return 1; +} + +/*============================================================================== + * mpz? -> rpz: Write BLE passkey to FDS + * + * Request: [TAG 4B "mpz?"] [passkey 6B ASCII] [CRC 2B] + * Response: [TAG 4B "rpz:"] [passkey 6B ASCII] [CRC 2B] + *============================================================================*/ +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(); + + ascii_format_data(ble_bin_buffer, "rpz:", passkey, 6); + dr_binary_tx_safe(ble_bin_buffer, 5); + return 1; +} + +/*============================================================================== + * mqz? -> rqz: Read BLE passkey from FDS + * + * Request: [TAG 4B "mqz?"] [CRC 2B] + * Response: [TAG 4B "rqz:"] [passkey 6B ASCII] [CRC 2B] + *============================================================================*/ +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; +} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.h b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.h new file mode 100644 index 0000000..8fd161d --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_info.h @@ -0,0 +1,18 @@ +/*============================================================================== + * cmd_info.h - Device information read/write handlers + *============================================================================*/ +#ifndef CMD_INFO_H +#define CMD_INFO_H + +#include "parser.h" + +int Cmd_mfv(const ParsedCmd *cmd); /* mfv? -> rfv: read firmware version */ +int Cmd_mid(const ParsedCmd *cmd); /* mid? -> rid: read HW + SN + FW together */ +int Cmd_mwh(const ParsedCmd *cmd); /* mwh? -> rwh: write HW number */ +int Cmd_mws(const ParsedCmd *cmd); /* mws? -> rws: write serial number */ +int Cmd_mrh(const ParsedCmd *cmd); /* mrh? -> rrh: read HW number */ +int Cmd_mrs(const ParsedCmd *cmd); /* mrs? -> rrs: read serial number */ +int Cmd_mpz(const ParsedCmd *cmd); /* mpz? -> rpz: write BLE passkey */ +int Cmd_mqz(const ParsedCmd *cmd); /* mqz? -> rqz: read BLE passkey */ + +#endif /* CMD_INFO_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.c b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.c new file mode 100644 index 0000000..5aba363 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.c @@ -0,0 +1,305 @@ +/*============================================================================== + * cmd_piezo.c - Piezo ultrasound measurement handlers + * + * mpa? -> rpa: TX/RX power ON + * mpb? -> rpb: TX/RX power OFF + * mpc? -> rpc: burst generation (test) + * mec? -> reb:+raa: single-channel burst + echo capture + * maa? -> reb:+raa: 6-channel asynchronous capture + * mbb? -> rbb:+reb:+raa: bulk sensor measurement + 6-channel capture + * mcf? -> rcf: read piezo parameters + * mcs? -> rcs: write piezo parameters + *============================================================================*/ + +#include "cmd_common.h" +#include "cmd_piezo.h" +#include "cmd_sensor.h" /* all_sensors() */ +#include "dr_piezo.h" +#include "dr_adc121s051.h" + +/*============================================================================== + * mpa? -> rpa: Enable piezo TX/RX circuit + * + * Request: [TAG 4B "mpa?"] [CRC 2B] + * Response: [TAG 4B "rpa:"] [1 2B] [CRC 2B] + * + * Must be called before mec? / maa?. + *============================================================================*/ +int Cmd_mpa(const ParsedCmd *cmd) +{ + (void)cmd; + dr_piezo_power_on(); + + if (g_plat.tx_bin) { + single_format_data(ble_bin_buffer, "rpa:", 1); + dr_binary_tx_safe(ble_bin_buffer, 3); + } + return 1; +} + +/*============================================================================== + * mpb? -> rpb: Disable piezo TX/RX circuit + * + * Request: [TAG 4B "mpb?"] [CRC 2B] + * Response: [TAG 4B "rpb:"] [1 2B] [CRC 2B] + * + * Power saving once measurement is complete. + *============================================================================*/ +int Cmd_mpb(const ParsedCmd *cmd) +{ + (void)cmd; + dr_piezo_power_off(); + + if (g_plat.tx_bin) { + single_format_data(ble_bin_buffer, "rpb:", 1); + dr_binary_tx_safe(ble_bin_buffer, 3); + } + return 1; +} + +/*============================================================================== + * mpc? -> rpc: Piezo burst generation (test / debug) + * + * Request: [TAG 4B "mpc?"] [cycles 2B] [freq_option 2B] [piezo_ch 2B] [CRC 2B] + * cycles : 3..7 (default 5) + * freq_option : 0=1.8MHz, 1=2.1MHz(default), 2=2.0MHz, 3=1.7MHz, 4=2.2MHz + * piezo_ch : 0..7 + * Response: [TAG 4B "rpc:"] [cycles 2B] [CRC 2B] + * Error: rpc: + 2 (cycles out of range) + * + * Generates the burst only - no echo capture. + *============================================================================*/ +int Cmd_mpc(const ParsedCmd *cmd) +{ + uint16_t cycles = 5; + uint16_t freq_option = 1; + uint16_t piezo_ch = 0; + + (void)dr_get_u16(cmd, 0, &cycles); + (void)dr_get_u16(cmd, 1, &freq_option); + (void)dr_get_u16(cmd, 2, &piezo_ch); + + if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; + + if (cycles < 3 || cycles > 7) { + dr_ble_return_1("rpc:", 2); + return 1; + } + + dr_piezo_select_channel((uint8_t)piezo_ch); + + switch (freq_option) { + case 0: dr_piezo_burst_sw_18mhz((uint8_t)cycles); break; + case 2: dr_piezo_burst_sw_20mhz((uint8_t)cycles); break; + case 3: dr_piezo_burst_sw_17mhz((uint8_t)cycles); break; + case 4: dr_piezo_burst_sw_22mhz((uint8_t)cycles); break; + case 1: + default: dr_piezo_burst_sw((uint8_t)cycles); break; + } + + dr_ble_return_1("rpc:", (uint8_t)cycles); + return 1; +} + +/*============================================================================== + * mec? -> reb:+raa: Piezo burst + echo capture (16-bit raw) + * + * Request: [TAG 4B "mec?"] [freq 2B] [delay_us 2B] [num_samples 2B] + * [cycles 2B] [averaging 2B] [piezo_ch 2B] [CRC 2B] + * Response: reb: [num_samples 2B] [raw_data up to 238B] (red: follow-up if needed) + * raa: [status 2B] + * Error: rer: + (0xEE00|err) + num_samples + * + * Sends raw 16-bit ADC values directly. Suited for short-range (~25cm). + *============================================================================*/ +int Cmd_mec(const ParsedCmd *cmd) +{ + uint16_t freq_option = 0; + uint16_t delay_us = 20; + uint16_t num_samples = 140; + uint16_t cycles = 5; + uint16_t averaging = 1; + uint16_t piezo_ch = 0; + + if (!dr_piezo_is_power_on()) { + dr_piezo_power_on(); + } + + (void)dr_get_u16(cmd, 0, &freq_option); + (void)dr_get_u16(cmd, 1, &delay_us); + (void)dr_get_u16(cmd, 2, &num_samples); + (void)dr_get_u16(cmd, 3, &cycles); + (void)dr_get_u16(cmd, 4, &averaging); + (void)dr_get_u16(cmd, 5, &piezo_ch); + + if (averaging == 0) averaging = 1; + if (averaging > 1000) averaging = 1000; + if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; + + dr_adc_err_t err = dr_adc_burst_capture_transmit( + (uint8_t)freq_option, delay_us, num_samples, (uint8_t)cycles, + (uint16_t)averaging, (uint8_t)piezo_ch, ble_bin_buffer, 0); + + if (err != DR_ADC_OK) { + dr_ble_return_2("rer:", 0xEE00 | (uint16_t)err, num_samples); + } + + dr_piezo_power_off(); + return 1; +} + +/*============================================================================== + * maa? -> reb:+raa: 6-channel asynchronous full capture + * + * Request: [TAG 4B "maa?"] [CRC 2B] + * Response: per channel reb: [num_samples 2B] [raw_data...] + * final raa: [status 2B] + * Error: raa: + 0xFFFE (previous capture in progress) + * raa: + (0xFF00|err) (start failed) + * + * Asynchronous state machine - the BLE_NUS_EVT_TX_RDY callback drives the + * follow-up packet transmissions. Parameters are loaded from m_config (FDS). + *============================================================================*/ +int Cmd_maa(const ParsedCmd *cmd) +{ + dr_adc_err_t err; + (void)cmd; + + if (maa_async_is_busy()) { + dr_ble_return_1("raa:", 0xFFFE); + return 1; + } + + if (!dr_piezo_is_power_on()) { + dr_piezo_power_on(); + } + + err = maa_async_start( + m_config.piezo_freq_option, + m_config.piezo_delay_us, + m_config.piezo_num_samples, + m_config.piezo_cycles, + m_config.piezo_averaging, + ble_bin_buffer + ); + + if (err != DR_ADC_OK) { + if (g_plat.log) g_plat.log("[Cmd_maa] start failed err=%d\r\n", err); + single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err)); + dr_binary_tx_safe(ble_bin_buffer, 3); + dr_piezo_power_off(); + return 1; + } + + return 1; +} + +/*============================================================================== + * mbb? -> rbb:+reb:+raa: Bulk sensor measurement + 6-channel full capture + * + * Request: [TAG 4B "mbb?"] [CRC 2B] + * Response: rbb: [batt 2B] [IMU 12B] [temp 2B] + * reb: [num_samples 2B] [raw_data...] (per channel) + * raa: [status 2B] + * Error: raa: + 0xFFFE (previous capture in progress) + * raa: + (0xFF00|err) (start failed) + * + * 1) all_sensors() measures battery / IMU / temperature and emits rbb: + * 2) Starts 6-channel capture in pre-capture-all mode + *============================================================================*/ +int Cmd_mbb(const ParsedCmd *cmd) +{ + dr_adc_err_t err; + (void)cmd; + + all_sensors(); + + if (maa_async_is_busy()) { + dr_ble_return_1("raa:", 0xFFFE); + return 1; + } + + maa_async_set_pre_capture_all(true); + + err = maa_async_start( + m_config.piezo_freq_option, + m_config.piezo_delay_us, + m_config.piezo_num_samples, + m_config.piezo_cycles, + m_config.piezo_averaging, + ble_bin_buffer + ); + + if (err != DR_ADC_OK) { + if (g_plat.log) g_plat.log("[Cmd_mbb] start failed err=%d\r\n", err); + single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err)); + dr_binary_tx_safe(ble_bin_buffer, 3); + dr_piezo_power_off(); + return 1; + } + + return 1; +} + +/*============================================================================== + * mcf? -> rcf: Read piezo parameters from FDS + * + * Request: [TAG 4B "mcf?"] [CRC 2B] + * Response: [TAG 4B "rcf:"] [freq 2B] [cycles 2B] [avg 2B] + * [delay_us 2B] [num_samples 2B] [CRC 2B] + *============================================================================*/ +int Cmd_mcf(const ParsedCmd *cmd) +{ + (void)cmd; + + uint8_t *buf = ble_bin_buffer; + buf[0] = 'r'; buf[1] = 'c'; buf[2] = 'f'; buf[3] = ':'; + buf[4] = 0; buf[5] = m_config.piezo_freq_option; + buf[6] = 0; buf[7] = m_config.piezo_cycles; + buf[8] = (uint8_t)(m_config.piezo_averaging >> 8); buf[9] = (uint8_t)(m_config.piezo_averaging & 0xFF); + buf[10] = (uint8_t)(m_config.piezo_delay_us >> 8); buf[11] = (uint8_t)(m_config.piezo_delay_us & 0xFF); + buf[12] = (uint8_t)(m_config.piezo_num_samples >> 8); buf[13] = (uint8_t)(m_config.piezo_num_samples & 0xFF); + dr_binary_tx_safe(buf, 7); /* 14 bytes = 7 words */ + return 1; +} + +/*============================================================================== + * mcs? -> rcs: Write piezo parameters to FDS + * + * Request: [TAG 4B "mcs?"] [freq 2B] [cycles 2B] [avg 2B] + * [delay_us 2B] [num_samples 2B] [CRC 2B] + * Response: [TAG 4B "rcs:"] [stored 5 values] [CRC 2B] + * Error: rcs: + 0xFFFF (insufficient data) + *============================================================================*/ +int Cmd_mcs(const ParsedCmd *cmd) +{ + if (cmd->data_len < 10) { + if (g_plat.log) g_plat.log("[Cmd_mcs] missing params (data_len=%u)\r\n", cmd->data_len); + dr_ble_return_1("rcs:", 0xFFFF); + return 1; + } + + uint16_t freq, cycles, averaging, delay_us, num_samples; + dr_get_u16(cmd, 0, &freq); + dr_get_u16(cmd, 1, &cycles); + dr_get_u16(cmd, 2, &averaging); + dr_get_u16(cmd, 3, &delay_us); + dr_get_u16(cmd, 4, &num_samples); + + m_config.piezo_freq_option = (uint8_t)freq; + m_config.piezo_cycles = (uint8_t)cycles; + m_config.piezo_averaging = averaging; + m_config.piezo_delay_us = delay_us; + m_config.piezo_num_samples = num_samples; + config_save(); + + uint8_t *buf = ble_bin_buffer; + buf[0] = 'r'; buf[1] = 'c'; buf[2] = 's'; buf[3] = ':'; + buf[4] = 0; buf[5] = m_config.piezo_freq_option; + buf[6] = 0; buf[7] = m_config.piezo_cycles; + buf[8] = (uint8_t)(m_config.piezo_averaging >> 8); buf[9] = (uint8_t)(m_config.piezo_averaging & 0xFF); + buf[10] = (uint8_t)(m_config.piezo_delay_us >> 8); buf[11] = (uint8_t)(m_config.piezo_delay_us & 0xFF); + buf[12] = (uint8_t)(m_config.piezo_num_samples >> 8); buf[13] = (uint8_t)(m_config.piezo_num_samples & 0xFF); + dr_binary_tx_safe(buf, 7); + return 1; +} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.h b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.h new file mode 100644 index 0000000..9830a79 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_piezo.h @@ -0,0 +1,18 @@ +/*============================================================================== + * cmd_piezo.h - Piezo ultrasound measurement handlers + *============================================================================*/ +#ifndef CMD_PIEZO_H +#define CMD_PIEZO_H + +#include "parser.h" + +int Cmd_mpa(const ParsedCmd *cmd); /* mpa? -> rpa: TX/RX power ON */ +int Cmd_mpb(const ParsedCmd *cmd); /* mpb? -> rpb: TX/RX power OFF */ +int Cmd_mpc(const ParsedCmd *cmd); /* mpc? -> rpc: burst generation */ +int Cmd_mec(const ParsedCmd *cmd); /* mec? -> reb:+raa: single-channel capture */ +int Cmd_maa(const ParsedCmd *cmd); /* maa? -> reb:+raa: 6-channel async capture */ +int Cmd_mbb(const ParsedCmd *cmd); /* mbb? -> rbb:+reb:+raa: sensors + capture */ +int Cmd_mcf(const ParsedCmd *cmd); /* mcf? -> rcf: read piezo parameters */ +int Cmd_mcs(const ParsedCmd *cmd); /* mcs? -> rcs: write piezo parameters */ + +#endif /* CMD_PIEZO_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.c b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.c new file mode 100644 index 0000000..1a4136a --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.c @@ -0,0 +1,138 @@ +/*============================================================================== + * cmd_sensor.c - Sensor measurement handlers + * + * msn? -> rsn: battery ADC measurement + * mso? -> rso: TMP235 temperature reading + * msp? -> rsp: IMU 6-axis single read + * msi? -> rsi: IMU motion streaming start + * all_sensors() bulk-measurement helper used by the mbb? handler + *============================================================================*/ + +#include "cmd_common.h" +#include "cmd_sensor.h" +#include "dr_piezo.h" + +/*============================================================================== + * msn? -> rsn: Battery level ADC measurement + * + * Request: [TAG 4B "msn?"] [CRC 2B] + * Response: rsn: + battery voltage in mV (sent from battery_saadc.c callback) + *============================================================================*/ +int Cmd_msn(const ParsedCmd *cmd) +{ + (void)cmd; + battery_level_meas(); + return 1; +} + +/*============================================================================== + * mso? -> rso: TMP235-Q1 temperature sensor measurement + * + * Request: [TAG 4B "mso?"] [CRC 2B] + * Response: rso: + temperature (sent from tmp235_q1.c callback) + *============================================================================*/ +int Cmd_mso(const ParsedCmd *cmd) +{ + (void)cmd; + tmp235_voltage_level_meas(); + return 1; +} + +/*============================================================================== + * msp? -> rsp: IMU 6-axis single read + * + * Request: [TAG 4B "msp?"] [CRC 2B] + * Response: rsp: + accel(xyz) + gyro(xyz) (transmitted inside imu_read_direct) + * + * Reads IMU registers directly over I2C and transmits over BLE. Synchronous. + *============================================================================*/ +int Cmd_msp(const ParsedCmd *cmd) +{ + (void)cmd; + hw_i2c_init_once(); + imu_read_direct(); + return 1; +} + +/*============================================================================== + * msi? -> rsi: IMU motion sensor streaming start + * + * Request: [TAG 4B "msi?"] [mode 1B] [CRC 2B] + * mode = 'c': continuous (repeats on timer) + * else : single shot (one read then auto stop) + * Response: rsi: + IMU data (sent from main timer callback) + *============================================================================*/ +int Cmd_msi(const ParsedCmd *cmd) +{ + hw_i2c_init_once(); + + motion_raw_data_enabled = true; + ble_got_new_data = false; + + if (cmd->data_len > 0 && (char)cmd->data[0] == 'c') { + motion_data_once = false; + } else { + motion_data_once = true; + } + + main_timer_start(); + return 1; +} + +/*============================================================================== + * all_sensors() - Bulk-measurement helper for the mbb? handler + * + * Stores sensor values into globals via info4 mode, then transmits them as a + * single rbb: packet. SAADC measurements run asynchronously (callback), so + * dr_sd_delay_ms() is used to wait for completion. + * + * Order: battery -> IMU -> (Piezo TX/RX ON) -> temperature + * Response: rbb: [batt 2B] [IMU 6x2B] [temp 2B] = 20 bytes = 10 words + *============================================================================*/ +void all_sensors(void) +{ + uint8_t *buf; + uint32_t timeout_cnt; + + info4 = true; + + /* 1. Battery voltage -> info_batt */ + battery_saadc_done = false; + battery_level_meas(); + for (timeout_cnt = 0; !battery_saadc_done && timeout_cnt < 100; timeout_cnt++) { + dr_sd_delay_ms(1); + } + + /* 2. IMU 6-axis single read -> info_imu[6] */ + hw_i2c_init_once(); + imu_read_direct(); + + /* 3. Temperature -> info_temp (TMP235 needs Piezo TX/RX power) */ + if (!dr_piezo_is_power_on()) { + dr_piezo_power_on(); + } + + tmp235_saadc_done = false; + tmp235_voltage_level_meas(); + for (timeout_cnt = 0; !tmp235_saadc_done && timeout_cnt < 100; timeout_cnt++) { + dr_sd_delay_ms(1); + } + + info4 = false; + + /* Assemble and transmit the rbb: packet */ + buf = ble_bin_buffer; + buf[0] = 'r'; buf[1] = 'b'; buf[2] = 'b'; buf[3] = ':'; + buf[4] = (uint8_t)(info_batt >> 8); + buf[5] = (uint8_t)(info_batt & 0xFF); + + for (int i = 0; i < 6; i++) { + buf[6 + i * 2] = (uint8_t)(info_imu[i] >> 8); + buf[6 + i * 2 + 1] = (uint8_t)(info_imu[i] & 0xFF); + } + + buf[18] = (uint8_t)(info_temp >> 8); + buf[19] = (uint8_t)(info_temp & 0xFF); + + dr_binary_tx_safe(buf, 10); /* 20 bytes = 10 words */ +} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.h b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.h new file mode 100644 index 0000000..5c9c0d3 --- /dev/null +++ b/project/ble_peripheral/ble_app_bladder_patch/command/handlers/cmd_sensor.h @@ -0,0 +1,19 @@ +/*============================================================================== + * cmd_sensor.h - Sensor measurement handlers (battery / temperature / IMU) + *============================================================================*/ +#ifndef CMD_SENSOR_H +#define CMD_SENSOR_H + +#include "parser.h" + +int Cmd_msn(const ParsedCmd *cmd); /* msn? -> rsn: battery ADC measurement */ +int Cmd_mso(const ParsedCmd *cmd); /* mso? -> rso: TMP235 temperature reading */ +int Cmd_msp(const ParsedCmd *cmd); /* msp? -> rsp: IMU 6-axis single read */ +int Cmd_msi(const ParsedCmd *cmd); /* msi? -> rsi: IMU streaming start */ + +/* Helper for the mbb? handler: sequentially measures battery / IMU / + * temperature, then emits a single rbb: response. Called from + * Cmd_mbb() in cmd_piezo.c. */ +void all_sensors(void); + +#endif /* CMD_SENSOR_H */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/parser.c b/project/ble_peripheral/ble_app_bladder_patch/command/parser.c index 39221e0..b050d8a 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/command/parser.c +++ b/project/ble_peripheral/ble_app_bladder_patch/command/parser.c @@ -1,156 +1,53 @@ -/* - * 2025-12-08 power loop bug fix - * 2025-12-07 msn, mta, mqq - * 2025-12-04 by Charles KWON - * parser.c : Common parser + command table + handlers - * - Firmware/PC shared - * - Hardware-dependent parts left as TODO - * - Added CRC16 validation support +/*============================================================================== + * parser.c - BLE command parser / dispatcher * - * [파일 개요] - * BLE(Bluetooth Low Energy)를 통해 수신된 바이너리 명령 패킷을 파싱하고, 명령 테이블에서 해당 핸들러를 찾아 실행하는 공통 파서 모듈 + * Common module that parses binary command packets received over BLE and + * dispatches them to the appropriate handler from the command table. * - * 패킷 구조: [TAG 4바이트] [데이터 N바이트] [CRC16 2바이트(선택)] - * - TAG: 4글자 ASCII 명령 식별자 (예: "mta?", "mec?") - * - 데이터: Big-Endian uint16 또는 ASCII 문자열 - * - CRC16: g_plat.crc_check가 true일 때 패킷 끝 2바이트(Little-Endian)로 무결성 검증 + * Key point: this file does not know which Cmd_* functions exist. + * cmd_table.c injects the table pointer at boot via dr_parser_init(). * - * 동작 흐름: - * 1) dr_cmd_parser() → 외부에서 호출하는 진입점 - * 2) dr_parse_cmd() → CRC 검증 + TAG/데이터 분리 - * 3) dr_cmd_dispatch() → 명령 테이블(g_cmd_table) 순회하여 핸들러 호출 - * 4) Cmd_xxx() → 각 명령별 하드웨어 제어 및 BLE 응답 전송 - */ + * Packet layout: [TAG 4B] [data N] [CRC16 2B (optional)] + * - TAG : 4-char ASCII identifier (e.g. "mid?") + * - data : Big-Endian uint16 or ASCII + * - CRC16: present when g_plat.crc_check is true; trailing 2 bytes (LE) + * + * Flow: + * 1) dr_cmd_parser() - external entry point + * 2) dr_parse_cmd() - length / CRC verification + TAG/data split + * 3) dr_cmd_dispatch() - walks the command table -> calls handler + * + * Error responses (all formatted as [err_tag 4B] [echo cmd_tag 4B] = 8 bytes): + * - rxs: Too short (< 4B, or < 7B with CRC enabled) + * - rxc: CRC fail + * - rxd: Disabled command + * - rxn: NULL handler + * - rxx: Unknown command + *============================================================================*/ #include "parser.h" #include -#include "nrf_gpio.h" -#include "debug_print.h" -#include "nrf_delay.h" -#include "dr_piezo.h" -#include "dr_util.h" -#include "main.h" -#include "dr_adc121s051.h" -#include "led_control.h" -#include "app_timer.h" -/*============================================================================== - * 외부 함수 선언부 - * - 다른 모듈(센서, BLE, 디바이스 제어 등)에서 정의된 함수들의 프로토타입 - *============================================================================*/ - -/* 센서 측정 함수 */ -extern void battery_level_meas(void); /* 배터리 잔량 ADC 측정 */ -extern void pressure_all_level_meas(void); /* 압력 센서 1,2 동시 측정 */ -extern void tmp235_voltage_level_meas(void); /* TMP235 온도 센서 전압 측정 */ - -/* 디바이스 전원/상태 제어 함수 */ -extern int device_activated(void); /* 디바이스 활성화 (센서 전원 ON) → 0:성공 */ -extern int device_sleep_mode(void); /* 슬립 모드 진입 (저전력) → 0:성공 */ - -/* 에러 처리 */ -extern void param_error(const char *cmd); /* 파라미터 오류 시 BLE로 에러 응답 전송 */ - -/* BLE 바이너리 전송 함수 */ -extern void single_format_data(uint8_t *buffer, const char *tag, uint16_t value); /* TAG(4바이트) + uint16 값(2바이트)을 buffer에 포맷팅 */ -extern void ascii_format_data(uint8_t *buffer, const char *tag, const char *ascii, size_t len); /* TAG(4바이트) + ASCII 문자열을 buffer에 포맷팅 */ -extern void dr_binary_tx_safe(const uint8_t *buffer, uint16_t length); /* BLE NUS를 통해 바이너리 데이터 전송 (length는 워드 단위) */ -extern volatile bool data_tx_in_progress; /* BLE TX 진행 중 플래그 */ -extern void dr_sd_delay_ms(uint32_t ms); /* SoftDevice 호환 딜레이 (BLE 스택 이벤트 처리 허용) */ - -/* FDS(Flash Data Storage) 설정 관련 */ -#include "fstorage.h" -extern char SERIAL_NO[12]; /* 시리얼 넘버 (12자 ASCII, FDS에 저장) */ -extern char HW_NO[12]; /* 하드웨어 넘버 (12자 ASCII, FDS에 저장) */ -extern char m_static_passkey[6]; /* BLE 정적 패스키 (6자리 숫자 문자열) */ -extern uint32_t m_life_cycle; /* 디바이스 수명 카운터 (FDS에 영구 저장) */ -extern void format_data(uint8_t *buffer, const char *tag, const uint16_t *data_array, size_t length); /* TAG + uint16 배열을 buffer에 포맷팅 (가변 길이 응답용) */ - - -/*============================================================================== - * 외부 변수 선언부 - * - main.c 등 다른 모듈에서 정의된 전역 변수 참조 - *============================================================================*/ - -extern volatile bool processing; /* true: 측정 진행 중 (중복 명령 방지 플래그) */ -extern bool device_status; /* true: 디바이스 활성화 상태 (센서 전원 ON) */ -extern uint8_t resetCount; /* 통신 타임아웃 카운터 (리셋 감지용) */ -extern uint8_t ble_bin_buffer[]; /* BLE 바이너리 전송 버퍼 (공용) */ - -extern bool con_single; /* 단일 연결 모드 플래그 */ -extern bool lock_check; /* 보안 잠금 상태 플래그 */ - - -extern bool info4; /* true: 센서값을 전역 변수에 저장 (BLE 전송 안 함) */ -extern bool ble_got_new_data; /* true: BLE로 새 데이터 수신됨 (처리 대기) */ -extern bool go_batt; /* true: 배터리 측정 요청 플래그 */ -extern bool motion_data_once; /* true: IMU 1회 측정, false: 연속 측정 */ -extern bool motion_raw_data_enabled;/* true: IMU 원시 데이터 전송 활성화 */ -extern int imu_read_direct(void); /* IMU 레지스터 직접 읽기 + BLE 전송 */ - -/* info4 모드 센서값 저장 변수 (mbb? rbb: 패킷 조립용) */ -extern volatile uint16_t info_batt; /* 배터리 전압 (mV) */ -extern volatile uint16_t info_temp; /* 온도 (°C x 100) */ -extern volatile uint16_t info_imu[6]; /* IMU 6축 (accel XYZ + gyro XYZ) */ -extern volatile bool tmp235_saadc_done; /* TMP235 SAADC 콜백 완료 플래그 */ -extern volatile bool battery_saadc_done; /* 배터리 SAADC 콜백 완료 플래그 */ - -extern void pressure_all_level_meas(void); /* 압력 센서 전체 측정 */ -extern void battery_timer_stop(void); /* 배터리 타이머 중지 */ -extern void main_timer_start(void); /* 메인 타이머 시작 (주기적 측정 트리거) */ -extern void hw_i2c_init_once(void); /* IMU용 I2C 버스 초기화 (최초 1회) */ - -/* 전원/리셋/본딩 제어 플래그 */ -extern bool go_device_power_off; /* true → 메인 루프에서 전원 OFF 실행 */ -extern bool go_NVIC_SystemReset; /* true → 메인 루프에서 시스템 리셋 실행 */ -extern bool bond_data_delete; /* true → 리셋 시 BLE 본딩 정보 삭제 */ -extern uint8_t m_reset_status; /* 리셋 상태 코드 (FDS에 저장, 부팅 시 참조) */ -extern void config_save(void); /* 설정값을 FDS(Flash)에 저장 */ -extern config_data_t m_config; /* 전체 설정 구조체 (FDS 저장 대상) */ - -/* AGC(자동 이득 제어) 게인 스위치 매크로 - * - P0.20 핀으로 아날로그 수신 회로의 게인을 HIGH/LOW 전환 - * - measurements.h의 매크로를 여기서도 사용하기 위해 재정의 */ -#include "nrf_gpio.h" -#define GAIN_SW_PIN NRF_GPIO_PIN_MAP(0, 20) -#define AGC_GAIN_SW(x) do { if(x) nrf_gpio_pin_set(GAIN_SW_PIN); else nrf_gpio_pin_clear(GAIN_SW_PIN); } while(0) - - -/* ---- 피에조 관련 제어 함수 ---- */ -extern void dr_piezo_power_on( void ); /* 피에조 회로 전원 ON (TX/RX 보드) */ -extern void dr_piezo_power_off( void ); /* 피에조 회로 전원 OFF */ -extern bool dr_piezo_is_power_on( void ); /* 피에조 전원 상태 확인 */ -extern void dr_piezo_burst_sw(uint8_t cycles); /* 2.1MHz 버스트 펄스 발생 (기본 주파수) */ -extern void dr_piezo_burst_sw_18mhz(uint8_t cycles); /* 1.8MHz 버스트 펄스 발생 */ -extern void dr_piezo_burst_sw_20mhz(uint8_t cycles); /* 2.0MHz 버스트 펄스 발생 */ -extern void dr_piezo_burst_sw_17mhz(uint8_t cycles); /* 1.7MHz 버스트 펄스 발생 */ - - -/* ---- 전역 변수 정의 (헤더에서 extern 선언) ---- */ +/*------------------------------------------------------------------------------ + * Globals (declared extern in header) + *----------------------------------------------------------------------------*/ dr_platform_if_t g_plat = { 0, 0, 0 }; - /* 플랫폼 인터페이스 구조체: - * .tx_bin = BLE 바이너리 전송 함수 포인터 - * .log = 디버그 로그 출력 함수 포인터 - * .crc_check = CRC16 검증 활성화 여부 */ bool g_log_enable = false; - /* 디버그 로그 전역 활성화 플래그 (g_plat.log와 함께 사용) */ -/* ---- 내부 상수/구조체 정의 ---- */ -#define DR_MAX_DATA 128 /* TAG 이후 데이터의 최대 바이트 수 */ +/*------------------------------------------------------------------------------ + * Internal state - command table pointer injected via dr_parser_init() + *----------------------------------------------------------------------------*/ +static const CmdEntry *m_cmd_table = NULL; +static uint16_t m_cmd_count = 0; -/* 파싱된 명령 구조체 - 수신 패킷을 TAG와 데이터로 분리한 결과 */ -typedef struct { - char tag[5]; /* 명령 TAG 문자열 (예: "sta?") 4글자 + '\0' */ - uint8_t data[DR_MAX_DATA]; /* TAG 뒤의 원시 데이터 바이트 배열 */ - uint8_t data_len; /* data[]의 유효 길이 (바이트) */ -} ParsedCmd; +/*============================================================================== + * Internal utilities (static) + *============================================================================*/ -/* ---- 내부 유틸리티 함수 ---- */ - -/* 수신 버퍼의 처음 4바이트를 TAG 문자열로 복사 (널 종료 포함) */ +/* Copy first 4 bytes of buffer into a null-terminated TAG string. */ static void dr_copy_tag(const uint8_t *buf, char *tag_out) { tag_out[0] = (char)buf[0]; @@ -160,7 +57,7 @@ static void dr_copy_tag(const uint8_t *buf, char *tag_out) tag_out[4] = '\0'; } -/* TAG 4글자 비교 (memcmp 대신 바이트 단위 비교로 최적화) */ +/* Compare two 4-char TAGs (byte-by-byte, faster than memcmp here). */ static bool dr_tag_eq(const char *tag, const char *key4) { return (tag[0] == key4[0] && @@ -169,119 +66,92 @@ static bool dr_tag_eq(const char *tag, const char *key4) tag[3] == key4[3]); } -/* 파싱된 명령 데이터에서 uint16 값 추출 (Big-Endian) - * - * word_index: 추출할 워드 인덱스 (0번째 = data[0..1], 1번째 = data[2..3], ...) - * out: 추출된 uint16 값 저장 포인터 - * 반환값: true=성공, false=데이터 부족 - * - * 패킷 데이터는 빅엔디안: data[pos]=상위바이트, data[pos+1]=하위바이트 */ -static bool dr_get_u16(const ParsedCmd *cmd, uint8_t word_index, uint16_t *out) + +/*============================================================================== + * Public utilities - used by handlers + *============================================================================*/ + +bool dr_get_u16(const ParsedCmd *cmd, uint8_t word_index, uint16_t *out) { uint8_t pos = (uint8_t)(word_index * 2); if (cmd->data_len < (uint8_t)(pos + 2)) { - return false; /* 데이터 길이 부족 → 기본값 유지 */ + return false; } - - /* Big Endian 조합: data[pos]=상위, data[pos+1]=하위 */ *out = (uint16_t)((uint16_t)cmd->data[pos] << 8) | (uint16_t)cmd->data[pos + 1]; - return true; } -/* ASCII 문자열 추출: data[offset] ~ data[offset+max_len-1] → 널 종료 문자열 - * - * 시리얼번호, HW번호, 패스키 등 FDS에 저장할 텍스트 데이터를 추출할 때 사용 - * offset: data[] 내 시작 위치 - * out: 추출된 문자열 저장 버퍼 (max_len+1 이상 크기 필요) - * max_len: 최대 추출 길이 (바이트) - */ -static void dr_get_ascii(const ParsedCmd *cmd, uint8_t offset, char *out, uint8_t max_len) +void dr_get_ascii(const ParsedCmd *cmd, uint8_t offset, char *out, uint8_t max_len) { uint8_t i; uint8_t remain; - /* 오프셋이 데이터 범위를 초과하면 빈 문자열 반환 */ - if (offset >= cmd->data_len) - { + if (offset >= cmd->data_len) { out[0] = '\0'; return; } - /* 실제 복사 가능한 길이 계산 (남은 데이터 vs 최대 길이 중 작은 값) */ remain = (uint8_t)(cmd->data_len - offset); - if (remain > max_len) - { + if (remain > max_len) { remain = max_len; } - for (i = 0; i < remain; i++) - { + for (i = 0; i < remain; i++) { out[i] = (char)cmd->data[offset + i]; } - out[remain] = '\0'; /* 널 종료 보장 */ + out[remain] = '\0'; } -/* ---- CRC16 무결성 검증 함수 ---- */ -/* CRC16 계산 - Nordic SDK의 crc16_compute와 동일한 알고리즘 (CRC-CCITT 변형) - * - * p_data: 계산 대상 데이터 포인터 - * size: 데이터 길이 (바이트) - * p_crc: 초기 CRC 값 (NULL이면 0xFFFF로 시작) - * 반환값: 계산된 CRC16 값 - */ -static uint16_t dr_crc16_compute(const uint8_t *p_data, uint32_t size, const uint16_t *p_crc) +/*============================================================================== + * CRC16 (Nordic SDK CRC-CCITT variant) + *============================================================================*/ + +uint16_t dr_crc16_compute(const uint8_t *p_data, uint32_t size, const uint16_t *p_crc) { uint32_t i; uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc; - for (i = 0; i < size; i++) - { - crc = (uint8_t)(crc >> 8) | (crc << 8); /* 상위/하위 바이트 교환 */ - crc ^= p_data[i]; /* 데이터 바이트 XOR */ - crc ^= (uint8_t)(crc & 0xFF) >> 4; /* 다항식 연산 1 */ - crc ^= (crc << 8) << 4; /* 다항식 연산 2 */ - crc ^= ((crc & 0xFF) << 4) << 1; /* 다항식 연산 3 */ + for (i = 0; i < size; i++) { + crc = (uint8_t)(crc >> 8) | (crc << 8); + crc ^= p_data[i]; + crc ^= (uint8_t)(crc & 0xFF) >> 4; + crc ^= (crc << 8) << 4; + crc ^= ((crc & 0xFF) << 4) << 1; } - return crc; } -/* CRC16 검증: 데이터에 대해 계산한 CRC와 기대값 비교 */ static bool dr_crc16_check(const uint8_t *p_data, uint32_t data_len, uint16_t expected_crc) { - uint16_t computed_crc = dr_crc16_compute(p_data, data_len, NULL); - return (computed_crc == expected_crc); + return (dr_crc16_compute(p_data, data_len, NULL) == expected_crc); } -/* 패킷 단위 CRC16 검증 - * 패킷 구조: [데이터 N바이트] + [CRC16 2바이트(Little-Endian)] - * 마지막 2바이트를 CRC 기대값으로 추출하여, 나머지 데이터의 CRC와 비교 */ +/* Extract trailing 2 bytes (Little-Endian) as expected CRC and verify. */ static bool dr_crc16_check_packet(const uint8_t *packet, uint32_t packet_len) { uint16_t expected_crc; uint32_t data_len; - if (packet_len < 2) - { - return false; /* 최소 CRC 2바이트도 없으면 실패 */ + if (packet_len < 2) { + return false; } - data_len = packet_len - 2; /* CRC를 제외한 실제 데이터 길이 */ - - /* 패킷 끝 2바이트에서 CRC 추출 (Little-Endian: 하위바이트 먼저) */ + data_len = packet_len - 2; expected_crc = (uint16_t)packet[packet_len - 2] | ((uint16_t)packet[packet_len - 1] << 8); return dr_crc16_check(packet, data_len, expected_crc); } -/* ---- 에러 응답 헬퍼 ---- - * 패킷: [err_tag 4B] [cmd_tag 에코 4B] = 8바이트 = 4워드 - * CRC16은 tx_bin 레이어에서 자동 부가 - */ + +/*============================================================================== + * Error response helper + * + * Packet: [err_tag 4B] [echo cmd_tag 4B] = 8 bytes = 4 words + * CRC16 is appended automatically by the tx_bin layer. + *============================================================================*/ static void dr_send_error(const char *err_tag, const char *cmd_tag) { if (g_plat.tx_bin) { @@ -292,20 +162,17 @@ static void dr_send_error(const char *err_tag, const char *cmd_tag) } } -/* ---- 수신 버퍼 → ParsedCmd 구조체 변환 ---- */ -/* 수신된 원시 바이트 버퍼를 파싱하여 TAG와 데이터를 분리 +/*============================================================================== + * Packet parser - raw buffer -> ParsedCmd * - * buffer: 수신 패킷 [TAG(4)] [DATA(N)] [CRC16(2, 선택)] - * length: 전체 패킷 길이 - * out: 파싱 결과 저장 구조체 - * 반환값: true=파싱 성공, false=CRC 실패 또는 패킷 길이 부족 - */ + * Error responses (rxs: / rxc:) are emitted directly from this function. + *============================================================================*/ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out) { uint8_t data_len; - /* TAG 4바이트조차 수신되지 않음 → rxs: + "????" (TAG 특정 불가) */ + /* Less than 4 bytes -> TAG cannot be identified */ if (length < 4) { dr_send_error("rxs:", "????"); if (g_plat.log && g_log_enable) { @@ -314,12 +181,11 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out) return false; } - /* TAG 먼저 추출 (에러 응답 에코에 사용) */ + /* Extract TAG first (used in error echoes below) */ dr_copy_tag(buffer, out->tag); - /* CRC 검증이 활성화된 경우 패킷 무결성 확인 */ - if (g_plat.crc_check) - { + /* CRC verification */ + if (g_plat.crc_check) { if (length < 7) { dr_send_error("rxs:", out->tag); if (g_plat.log && g_log_enable) { @@ -328,8 +194,7 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out) return false; } - if (!dr_crc16_check_packet(buffer, length)) - { + if (!dr_crc16_check_packet(buffer, length)) { dr_send_error("rxc:", out->tag); if (g_plat.log && g_log_enable) { g_plat.log("[parser] CRC mismatch '%s' -> rxc:\r\n", out->tag); @@ -337,14 +202,12 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out) return false; } - data_len = (uint8_t)(length - 4 - 2); /* TAG(4) + CRC(2) 제외 */ + data_len = (uint8_t)(length - 4 - 2); /* strip TAG and CRC */ } - else - { - data_len = (uint8_t)(length - 4); /* TAG(4) 제외 */ + else { + data_len = (uint8_t)(length - 4); } - /* 최대 길이 클램프 */ if (data_len > DR_MAX_DATA) { data_len = DR_MAX_DATA; } @@ -357,167 +220,35 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out) return true; } -/*============================================================================== - * BLE 명령어 - * - * A. 디바이스 상태 제어 - * - 전원 OFF (msq? / rsq:) - * - 재부팅 (mss? / rss:) - * - 본딩 정보 삭제 및 재부팅 (msr? / rsr:) : 확인 필요 - * - GPIO 제어(핀 테스트용, cmd? / rmd:) - * - * B. 디바이스 정보 읽기, 쓰기 - * - 하드웨어 버전 읽기 (mrh? / rrh:) - * - 하드웨어 버전 쓰기 (mwh? / rwh:) - * - 시리얼 넘버 읽기 (mrs? / rrs:) - * - 시리얼 넘버 쓰기 (mws? / rws:) - * - 펌웨어 버전 읽기 (mfv? / rfv:) - * - 패스키 읽기 (mqz? / rqz:) : 필요 유무 검토(암호화 혹은 삭제) - * - 패스키 쓰기 (mpz? / rpz:) - * - * C. 각종 센서 측정 - * - 배터리 전압 측정 (msn? / rsn:) - test용 - * - IMU 단발 측정 (msp? / rsp:) : 동기 - test용 - * - IMU 연속 스트리밍 (msi? / rsi:) : 비동기(타이머) 1초 주기, 확인 필요 - test용 - * - 온도 측정 (mso? / rso:) - test용 - * - * D. Piezo 초음파 측정 - * - TX/RX 전원 활성화 (mpa? / rpa:) - test용 - * - TX/RX 전원 비활성화 (mpb? / rpb:) - test용 - * - 단일 채널 Burst (mpc? / rpc:) - test용 - * - 단일 채널 Burst + ADC -> echo capture (mec? / reb: merged -> raa:) : TX/RX Active -> 응답 -> TX/RX Sleep - * - 모든 채널 Burst + ADC -> echo capture (maa? / reb: merged -> raa:) : TX/RX Active -> 응답 -> TX/RX Sleep - * - 모든 채널 Burst + ADC -> echo capture (mbb? / reb: merged -> raa:) + 각종 센서 측정(배터리, IMU, 온도) : TX/RX Active -> 응답 -> TX/RX Sleep - * - * 삭제 명령어 - * - 디바이스 활성화/슬립 : TX 전원 활성화/비활성화와 동일 기능 - * - 디바이스 상태 조회 - * - 디바이스 준비 확인 - * - 수명 카운터(life cycle) 읽기 및 쓰기 - * - 압력 센서 측정 : 센서 미탑재 - * - 단일 채널 ADC - *============================================================================*/ /*============================================================================== - * 핸들러 함수 프로토타입 선언 - * - 반환값: 1=성공, 0=실패/비활성 - * - 각 핸들러는 BLE 응답 전송까지 담당 - *============================================================================*/ - -/* A. 디바이스 상태 제어 */ -static int Cmd_msq(const ParsedCmd *cmd); /* msq? 디바이스 전원 OFF */ -static int Cmd_mss(const ParsedCmd *cmd); /* mss? 디바이스 재부팅 */ -#if FEATURE_SECURE_CONNECTION -static int Cmd_msr(const ParsedCmd *cmd); /* msr? 본딩 삭제 + 디바이스 재부팅 */ -#endif -static int Cmd_cmd(const ParsedCmd *cmd); /* cmd? GPIO 핀 테스트 (HIGH/LOW 제어) */ - -/* B. 디바이스 정보 읽기, 쓰기 */ -static int Cmd_mwh(const ParsedCmd *cmd); /* mwh? HW 넘버 FDS에 쓰기 */ -static int Cmd_mws(const ParsedCmd *cmd); /* mws? 시리얼 넘버 FDS에 쓰기 */ -static int Cmd_mrh(const ParsedCmd *cmd); /* mrh? HW 넘버 FDS에서 읽기 */ -static int Cmd_mrs(const ParsedCmd *cmd); /* mrs? 시리얼 넘버 FDS에서 읽기 */ -static int Cmd_mfv(const ParsedCmd *cmd); /* mfv? 펌웨어 버전 읽기 */ -static int Cmd_mid(const ParsedCmd *cmd); /* mid? HW 넘버 + 시리얼 넘버 + FW 버전 일괄 읽기 */ -static int Cmd_mpz(const ParsedCmd *cmd); /* mpz? BLE 패스키 FDS에 쓰기 */ -static int Cmd_mqz(const ParsedCmd *cmd); /* mqz? BLE 패스키 FDS에서 읽기 */ - -/* C. 각종 센서 측정 */ -static int Cmd_msn(const ParsedCmd *cmd); /* msn? 배터리 잔량 측정 */ -static int Cmd_mso(const ParsedCmd *cmd); /* mso? TMP235 온도 센서 측정 */ -static int Cmd_msp(const ParsedCmd *cmd); /* msp? IMU 6축 원시 데이터 (단발) */ -static int Cmd_msi(const ParsedCmd *cmd); /* msi? IMU 모션 센서 스트리밍 (타이머 기반) */ - -/* D. Piezo 초음파 측정 */ -static int Cmd_mpa(const ParsedCmd *cmd); /* mpa? 피에조 TX/RX 회로 활성화 (전원 ON) */ -static int Cmd_mpb(const ParsedCmd *cmd); /* mpb? 피에조 TX/RX 회로 비활성화 (전원 OFF) */ -static int Cmd_mpc(const ParsedCmd *cmd); /* mpc? 피에조 버스트 발생 (주파수/사이클 제어) */ -static int Cmd_mec(const ParsedCmd *cmd); /* mec? 피에조 버스트 + 에코 캡처 (16비트 원시) */ -static int Cmd_maa(const ParsedCmd *cmd); /* maa? 6채널 전체 캡처 (비동기 전송) */ -static int Cmd_mbb(const ParsedCmd *cmd); /* mbb? 6채널 캡처 + 센서 측정 (배터리 + 온도 + IMU) */ -static int Cmd_mcf(const ParsedCmd *cmd); /* mcf? 피에조 파라미터 읽기 (FDS) */ -static int Cmd_mcs(const ParsedCmd *cmd); /* mcs? 피에조 파라미터 쓰기 (FDS) */ - -/* E. LED 제어 */ -static int Cmd_mls(const ParsedCmd *cmd); /* mls? LED 상태 설정 (앱 → 기기) */ - - -/* ---- 명령 테이블 ---- */ - -/* 명령 엔트리 구조체: TAG 문자열 + 활성화 여부 + 핸들러 함수 포인터 */ -typedef struct { - char tag[5]; /* 명령 TAG (예: "sta?") - 4글자 + NULL */ - bool enabled; /* false면 핸들러가 호출되지 않음 (비활성 명령) */ - int (*handler)(const ParsedCmd *cmd); /* 핸들러 함수 포인터 (1=성공, 0=실패) */ -} CmdEntry; - -/* 전체 명령 테이블 - 수신된 TAG와 순차 비교하여 일치하는 핸들러 호출 */ -static CmdEntry g_cmd_table[] = { - /* A. 디바이스 상태 제어 */ - { "msq?", true, Cmd_msq }, - { "mss?", true, Cmd_mss }, -#if FEATURE_SECURE_CONNECTION - { "msr?", true, Cmd_msr }, -#endif - { "cmd?", true, Cmd_cmd }, - - /* C. 디바이스 정보 읽기, 쓰기 */ - { "mwh?", true, Cmd_mwh }, - { "mws?", true, Cmd_mws }, - { "mrh?", true, Cmd_mrh }, - { "mrs?", true, Cmd_mrs }, - { "mpz?", true, Cmd_mpz }, - { "mqz?", true, Cmd_mqz }, - { "mfv?", true, Cmd_mfv }, - { "mid?", true, Cmd_mid }, - - /* D. 각종 센서 측정 */ - { "msn?", true, Cmd_msn }, - { "mso?", true, Cmd_mso }, - { "msp?", true, Cmd_msp }, - { "msi?", true, Cmd_msi }, - - /* E. Piezo 초음파 측정 */ - { "mpa?", true, Cmd_mpa }, - { "mpb?", true, Cmd_mpb }, - { "mpc?", true, Cmd_mpc }, - { "mec?", true, Cmd_mec }, - { "maa?", true, Cmd_maa }, - { "mbb?", true, Cmd_mbb }, - { "mcf?", true, Cmd_mcf }, - { "mcs?", true, Cmd_mcs }, - - /* F. LED 제어 */ - { "mls?", true, Cmd_mls }, -}; - -/* 명령 테이블 엔트리 수 (컴파일 타임 계산) */ -static const uint16_t g_cmd_count = - (uint16_t)(sizeof(g_cmd_table) / sizeof(g_cmd_table[0])); - -/* ---- 명령 디스패처 ---- - * 파싱된 TAG를 소문자로 변환 후, 명령 테이블을 순회하여 일치하는 핸들러 호출 + * Command dispatcher * - * 반환값: 핸들러의 반환값 (1=성공), 매칭 실패 또는 비활성 명령이면 0 - */ + * Lower-cases the parsed TAG and walks the command table to find a matching + * handler. Emits the matching error response on miss / disabled / NULL handler. + *============================================================================*/ static int dr_cmd_dispatch(const ParsedCmd *cmd) { uint16_t i; char tag_lower[5]; - /* 수신된 TAG를 소문자로 변환 (대소문자 구분 없이 명령 매칭) */ + if (m_cmd_table == NULL) { + dr_send_error("rxn:", cmd->tag); + if (g_plat.log) g_plat.log("[parser] table not initialized -> rxn:\n"); + return 0; + } + + /* Case-insensitive matching */ for (i = 0; i < 4 && cmd->tag[i]; i++) { tag_lower[i] = (cmd->tag[i] >= 'A' && cmd->tag[i] <= 'Z') ? (cmd->tag[i] + 32) : cmd->tag[i]; } tag_lower[i] = '\0'; - /* 명령 테이블 순차 검색 */ - for (i = 0; i < g_cmd_count; i++) { - if (dr_tag_eq(tag_lower, g_cmd_table[i].tag)) { + for (i = 0; i < m_cmd_count; i++) { + if (dr_tag_eq(tag_lower, m_cmd_table[i].tag)) { - /* 비활성화된 명령 → rxd: 응답 */ - if (!g_cmd_table[i].enabled) { + if (!m_cmd_table[i].enabled) { dr_send_error("rxd:", cmd->tag); if (g_plat.log && g_log_enable) { g_plat.log("Command '%s' disabled -> rxd:\n", cmd->tag); @@ -525,8 +256,7 @@ static int dr_cmd_dispatch(const ParsedCmd *cmd) return 0; } - /* NULL 핸들러 가드 → rxn: 응답 */ - if (g_cmd_table[i].handler == NULL) { + if (m_cmd_table[i].handler == NULL) { dr_send_error("rxn:", cmd->tag); if (g_plat.log) { g_plat.log("[parser] NULL handler for '%s' -> rxn:\n", cmd->tag); @@ -534,12 +264,11 @@ static int dr_cmd_dispatch(const ParsedCmd *cmd) return 0; } - /* 매칭된 핸들러 호출 */ - return g_cmd_table[i].handler(cmd); + return m_cmd_table[i].handler(cmd); } } - /* 테이블에 없는 TAG → rxx: 응답 */ + /* TAG not found in table */ dr_send_error("rxx:", cmd->tag); if (g_plat.log && g_log_enable) { g_plat.log("Unknown TAG '%s' -> rxx:\n", cmd->tag); @@ -547,872 +276,33 @@ static int dr_cmd_dispatch(const ParsedCmd *cmd) return 0; } + /*============================================================================== - * 메인 파서 진입점 - 외부 모듈(BLE 수신 콜백 등)에서 호출 - * - * buf: 수신된 BLE 패킷 원시 바이트 - * len: 패킷 길이 - * 반환값: - * 1 = 명령 처리 성공 - * 0 = 알 수 없는 TAG 또는 비활성 명령 - * -1 = CRC 실패 또는 파싱 실패 → 호출자가 레거시 파서로 위임 가능 + * Public API *============================================================================*/ +/* Called by cmd_table.c at boot to inject the command table. */ +void dr_parser_init(const CmdEntry *table, uint16_t count) +{ + m_cmd_table = table; + m_cmd_count = count; +} + +/* Entry point - called from BLE NUS / UART receive callbacks. + * + * Returns: + * 1 = command processed successfully + * 0 = unknown TAG / disabled command (error response already sent) + * -1 = parse failure (rxs: / rxc: error response already sent) + */ int dr_cmd_parser(const uint8_t *buf, uint8_t len) { ParsedCmd cmd; - /* 패킷 파싱 (CRC 검증 포함) - 에러 응답은 dr_parse_cmd 내부에서 전송 */ if (!dr_parse_cmd(buf, len, &cmd)) { if (g_plat.log) g_plat.log("[PARSER] PARSE FAIL\r\n"); return -1; } - /* 수신 명령어 종류 확인용 로그 */ - //if (g_plat.log) g_plat.log("[PARSER] tag=%s\r\n", cmd.tag); - - /* 파싱 성공 → 명령 테이블에서 핸들러를 찾아 실행 */ return dr_cmd_dispatch(&cmd); } - -/*============================================================================== - * 각 명령 핸들러 구현부 - *============================================================================*/ - -/* msn? - 배터리 잔량 ADC 측정 - * 응답: battery_level_meas() 내부에서 BLE 전송 처리 */ -static int Cmd_msn(const ParsedCmd *cmd) -{ - (void)cmd; - battery_level_meas(); /* ADC로 배터리 전압 측정 → BLE 응답 전송 */ - return 1; -} - -/* mso? - TMP235-Q1 온도 센서 전압 측정 - * SAADC로 TMP235 출력 전압을 측정하여 BLE로 응답 - * 응답은 tmp235_q1.c의 콜백에서 자동 전송 */ -static int Cmd_mso(const ParsedCmd *cmd) -{ - (void)cmd; - tmp235_voltage_level_meas(); - return 1; -} - -/* msi? - IMU 모션 센서 원시 데이터 읽기 - * - * 파라미터: data[0]='c'이면 연속 측정, 그 외 단발 측정 - * 단발 모드: 1회 측정 후 자동 중지 - * 연속 모드: 타이머 주기마다 반복 측정 (별도 중지 명령 필요) - * - * 동작: I2C 초기화 → 플래그 설정 → 메인 타이머 시작 - */ -static int Cmd_msi(const ParsedCmd *cmd) -{ - /* IMU용 I2C 버스 초기화 (최초 호출 시 1회만 실행) */ - hw_i2c_init_once(); - - motion_raw_data_enabled = true; /* IMU 원시 데이터 전송 활성화 */ - ble_got_new_data = false; - - /* 'c' = 연속(continuous) 모드, 그 외 = 단발(single shot) 모드 */ - if (cmd->data_len > 0 && (char)cmd->data[0] == 'c') { - motion_data_once = false; /* 연속 측정 */ - } else { - motion_data_once = true; /* 1회 측정 후 자동 중지 */ - } - - main_timer_start(); /* 타이머 콜백에서 IMU 데이터 읽기 + BLE 전송 */ - - return 1; -} - -/*============================================================================== - * J. 전원/리셋/버전/보안 핸들러 - *============================================================================*/ - -/* msq? - 디바이스 전원 OFF - * - * BLE 응답("rsq:") 전송 후 → 메인 루프에서 실제 전원 OFF 수행 - * 즉시 전원을 끄면 BLE 응답이 전달되지 않으므로, 플래그+타이머 방식 사용 - */ -static int Cmd_msq(const ParsedCmd *cmd) -{ - uint16_t val = 0; - dr_get_u16(cmd, 0, &val); - if (g_plat.log) g_plat.log("[Cmd_msq] Power off val=%u\r\n", val); - single_format_data(ble_bin_buffer, "rsq:", val); - dr_binary_tx_safe(ble_bin_buffer, 2); - go_device_power_off = true; /* 메인 루프에서 전원 OFF 실행 예약 */ - main_timer_start(); /* 타이머 콜백에서 전원 OFF 처리 */ - return 1; -} - -/* msr? - BLE 본딩 정보 삭제 + 시스템 리셋 - * - * 동작 순서: - * 1. BLE 응답("rsr:") 전송 - * 2. 본딩 삭제 플래그 + 리셋 상태를 FDS에 저장 - * 3. 5ms 딜레이 (FDS 쓰기 완료 대기) - * 4. NVIC 시스템 리셋 플래그 설정 → 타이머에서 리셋 실행 - */ -#if FEATURE_SECURE_CONNECTION -static int Cmd_msr(const ParsedCmd *cmd) -{ - uint16_t val = 0; - dr_get_u16(cmd, 0, &val); - //if (g_plat.log) g_plat.log("[Cmd_msr] Bond delete + reset val=%u\r\n", val); - single_format_data(ble_bin_buffer, "rsr:", val); - dr_binary_tx_safe(ble_bin_buffer, 2); - - /* 본딩 삭제 + 리셋 상태를 설정에 저장 (재부팅 후에도 유지) */ - bond_data_delete = true; - m_config.bond_data_delete = (uint8_t)bond_data_delete; - m_reset_status = 2; /* 리셋 상태 코드 2 = 본딩 삭제 리셋 */ - m_config.reset_status = m_reset_status; - config_save(); /* FDS에 설정 영구 저장 */ - nrf_delay_ms(5); /* Flash 쓰기 완료 대기 */ - go_NVIC_SystemReset = true; /* 시스템 리셋 예약 */ - main_timer_start(); - return 1; -} -#endif - -/* mss? - 디바이스 소프트 리셋 (리부팅) - * - * msr?과 유사하지만 본딩 정보는 삭제하지 않음 - * 리셋 상태 코드를 FDS에 저장하여 부팅 시 리셋 원인 확인 가능 =======> val 파라미터 확인 - */ -static int Cmd_mss(const ParsedCmd *cmd) -{ - uint16_t val = 0; - dr_get_u16(cmd, 0, &val); - //if (g_plat.log) g_plat.log("[Cmd_mss] Device reset val=%u\r\n", val); - single_format_data(ble_bin_buffer, "rss:", val); - dr_binary_tx_safe(ble_bin_buffer, 2); - - m_reset_status = 2; - m_config.reset_status = m_reset_status; - config_save(); - nrf_delay_ms(5); - go_NVIC_SystemReset = true; - main_timer_start(); - return 1; -} - -/* mfv? - 펌웨어 버전 읽기 - * - * 응답: "rfv:" + 12자 ASCII 버전 문자열 (DR_DEVICE_VERSION) - * 구 명령 ssv?에서 mfv?로 변경 (26.03.13) - */ -static int Cmd_mfv(const ParsedCmd *cmd) -{ - (void)cmd; - ascii_format_data(ble_bin_buffer, "rfv:", FIRMWARE_VERSION, 12); - dr_binary_tx_safe(ble_bin_buffer, 8); /* 4(TAG) + 12(버전) = 16바이트 = 8워드 */ - return 1; -} - -/* mid? - HW 넘버 + 시리얼 넘버 + FW 버전 일괄 읽기 - * - * 응답: "rid:" + HW_NO(12) + SERIAL_NO(12) + FIRMWARE_VERSION(12) = 40바이트 = 20워드 - */ -static int Cmd_mid(const ParsedCmd *cmd) -{ - uint8_t *buf = ble_bin_buffer; - (void)cmd; - - memcpy(HW_NO, m_config.hw_no, 12); - memcpy(SERIAL_NO, m_config.serial_no, 12); - - buf[0] = 'r'; buf[1] = 'i'; buf[2] = 'd'; buf[3] = ':'; - memcpy(&buf[4], HW_NO, 12); - memcpy(&buf[16], SERIAL_NO, 12); - memcpy(&buf[28], FIRMWARE_VERSION, 12); - - dr_binary_tx_safe(buf, 20); /* 40바이트 = 20워드 */ - return 1; -} - - -/* mpa? - 피에조 초음파 TX/RX 회로 활성화 - * - * 동작: 피에조 전원 ON → 시스템 초기화 (DAC, MUX, ADC 설정) - * 응답: "rpa:" + 1 (성공) - * 주의: mec?/mdc?/maa? 실행 전에 반드시 먼저 호출해야 함 - */ -static int Cmd_mpa(const ParsedCmd *cmd) -{ - (void)cmd; - - dr_piezo_power_on(); /* 부팅 시 init 완료, 전원만 ON */ - - if (g_plat.tx_bin) - { - single_format_data(ble_bin_buffer, "rpa:", 1); - dr_binary_tx_safe(ble_bin_buffer, 3); - } - - return 1; -} - -/* mpb? - 피에조 초음파 TX/RX 회로 비활성화 (전원 OFF) - * - * 측정 완료 후 전력 소모 절감을 위해 호출 - * 응답: "rpb:" + 1 (성공) - */ -static int Cmd_mpb(const ParsedCmd *cmd) -{ - (void)cmd; - - dr_piezo_power_off(); /* 피에조 보드 전원 OFF */ - - if (g_plat.tx_bin) { - single_format_data(ble_bin_buffer, "rpb:", 1); - dr_binary_tx_safe(ble_bin_buffer, 3); - } - - return 1; -} - - -/** - * @brief mpc? - 피에조 버스트 발생 명령 (주파수/사이클/채널 선택) - * - * 초음파 트랜스듀서에 지정된 주파수와 사이클 수로 버스트 펄스를 발생시킴 - * 에코 캡처 없이 버스트만 발생 (테스트/디버그용) - * - * 파라미터 (Big-Endian uint16 x 3): - * word 0: cycles (3~7, 기본값=5) - 버스트 펄스 사이클 수 - * word 1: freq_option (기본값=1) - 주파수 선택 - * 0=1.8MHz, 1=2.1MHz(기본), 2=2.0MHz, 3=1.7MHz, 4=2.2MHz - * word 2: piezo_ch (0~7, 기본값=0) - 피에조 채널 선택 - * - * 응답: "rpc:" + cycles (성공), "rpc:" + 2 (범위 초과 에러) - * - * 사용 예시 (Harbour에서): - * mpc?0x05,0x00,0x01,0x00 → 5사이클 @ 2.1MHz - * mpc?0x05,0x00,0x00,0x00 → 5사이클 @ 1.8MHz - * mpc?0x07,0x00,0x02,0x00 → 7사이클 @ 2.0MHz - */ -static int Cmd_mpc(const ParsedCmd *cmd) -{ - uint16_t cycles = 5; /* 기본 5사이클 */ - uint16_t freq_option = 1; /* 기본 2.1MHz (0=1.8, 1=2.1, 2=2.0, 3=1.7, 4=2.2) */ - uint16_t piezo_ch = 0; /* 기본 채널 0 (0~7) */ - - /* 파라미터 추출 (데이터 부족 시 기본값 유지) */ - (void)dr_get_u16(cmd, 0, &cycles); /* word 0: 사이클 수 */ - (void)dr_get_u16(cmd, 1, &freq_option); /* word 1: 주파수 옵션 */ - (void)dr_get_u16(cmd, 2, &piezo_ch); /* word 2: 피에조 채널 */ - - /* 채널 범위 검증: 초과 시 0으로 리셋 */ - if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; - - /* 사이클 범위 검증: 3~7 유효 */ - if (cycles < 3 || cycles > 7) - { - dr_ble_return_1("rpc:", 2); /* 에러 응답: 범위 초과 */ - return 1; - } - - /* MUX로 피에조 채널 선택 (0~7번 트랜스듀서 중 하나) */ - dr_piezo_select_channel((uint8_t)piezo_ch); - - /* 선택된 주파수로 버스트 펄스 발생 */ - switch (freq_option) - { - case 0: dr_piezo_burst_sw_18mhz((uint8_t)cycles); break; /* 1.8MHz */ - case 2: dr_piezo_burst_sw_20mhz((uint8_t)cycles); break; /* 2.0MHz */ - case 3: dr_piezo_burst_sw_17mhz((uint8_t)cycles); break; /* 1.7MHz */ - case 4: dr_piezo_burst_sw_22mhz((uint8_t)cycles); break; /* 2.2MHz */ - /*case 9: dr_piezo_burst_sw_19mhz((uint8_t)cycles); break;*/ /* 1.9MHz (미사용) */ - case 1: - default: dr_piezo_burst_sw((uint8_t)cycles); break; /* 2.1MHz (기본) */ - } - - /* 성공 응답: "rpc:" + 실행된 사이클 수 */ - dr_ble_return_1("rpc:", (uint8_t)cycles); - - return 1; -} - - -/** - * @brief mec? - 피에조 버스트 + 에코 캡처 (16비트 원시 데이터, 무압축) - * - * 12비트 압축(mdc?)과 달리 ADC 원시 16비트 값을 그대로 전송 - * 샘플 수가 적은 근거리 측정(~25cm)에 적합 - * - * 파라미터 (Big-Endian uint16 x 6): - * word 0: freq_option (기본=0) - 주파수 선택 (0=1.8MHz, 1=2.1MHz, ...) - * word 1: delay_us (기본=20) - 버스트 후 ADC 시작 지연 (us) - * word 2: num_samples (기본=140) - ADC 샘플 수 (140샘플 ≒ 20cm 거리) - * word 3: cycles (기본=5) - 버스트 사이클 수 (3~7) - * word 4: averaging (기본=1) - 평균화 횟수 (1~1000, 노이즈 저감용) - * word 5: piezo_ch (기본=0) - 피에조 채널 (0~7) - * - * 응답 패킷 형식 (reb+red merged protocol): - * 첫 패킷 ("reb:"): num_samples(2) + raw_data(up to 238B = 119샘플) - * 연속 패킷 ("red:"): pkt_idx(2) + raw_data(up to 238B) — 119샘플 초과 시만 - * 완료 패킷 ("raa:"): status(2) - * - * 100샘플 기준: reb: 1패킷(206B)으로 완료 - */ -static int Cmd_mec(const ParsedCmd *cmd) -{ - uint16_t freq_option = 0; /* 기본 1.8MHz */ - uint16_t delay_us = 20; /* 기본 20us 딜레이 */ - uint16_t num_samples = 140; /* 기본 100샘플 */ - uint16_t cycles = 5; /* 기본 5사이클 (유효: 3~7) */ - uint16_t averaging = 1; /* 기본 1 (평균화 없음), 최대 1000 */ - uint16_t piezo_ch = 0; /* 기본 채널 0 (유효: 0~7) */ - - /* 피에조 전원이 꺼져 있으면 켜기 */ - if (!dr_piezo_is_power_on()) - { - //if (g_plat.log) g_plat.log("[Cmd_mec] TX/RX Sleep -> Active\r\n"); - dr_piezo_power_on(); - } - - /* 6개 파라미터 순서대로 추출 (데이터 부족 시 기본값 유지) */ - (void)dr_get_u16(cmd, 0, &freq_option); /* word 0: 주파수 옵션 */ - (void)dr_get_u16(cmd, 1, &delay_us); /* word 1: 버스트→ADC 딜레이 */ - (void)dr_get_u16(cmd, 2, &num_samples); /* word 2: ADC 샘플 수 */ - (void)dr_get_u16(cmd, 3, &cycles); /* word 3: 버스트 사이클 */ - (void)dr_get_u16(cmd, 4, &averaging); /* word 4: 평균화 횟수 */ - (void)dr_get_u16(cmd, 5, &piezo_ch); /* word 5: 피에조 채널 */ - - /* 평균화 횟수 범위 검증: 1~1000 */ - if (averaging == 0) averaging = 1; - if (averaging > 1000) averaging = 1000; - - /* 피에조 채널 범위 검증 */ - if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; - - /* - if (g_plat.log && g_log_enable) { - const char *freq_str = (freq_option == 0) ? "1.8MHz" : - (freq_option == 1) ? "2.1MHz" : - (freq_option == 2) ? "2.0MHz" : - (freq_option == 3) ? "1.7MHz" : - (freq_option == 4) ? "2.2MHz" : - (freq_option == 9) ? "1.9MHz" : "unknown"; - g_plat.log("[Parameter] freq=%u (%s), delay=%uus, samples=%u, cycles=%u, avg=%u, piezo=%u\r\n", - freq_option, freq_str, delay_us, num_samples, cycles, averaging, piezo_ch); - } - */ - - /* 통합 버스트+캡처+전송 함수 호출 */ - dr_adc_err_t err = dr_adc_burst_capture_transmit( - (uint8_t)freq_option, delay_us, num_samples, (uint8_t)cycles, - (uint16_t)averaging, (uint8_t)piezo_ch, ble_bin_buffer, 0); - - /* 에러 발생 시 에러 코드 + 요청 샘플 수 응답 */ - if (err != DR_ADC_OK) { - dr_ble_return_2("rer:", 0xEE00 | (uint16_t)err, num_samples); - } - - /* raw 데이터 덤프 - if (g_plat.log && g_log_enable) { - g_plat.log("[Cmd_mec] result=%d\r\n", err); - - const uint16_t *buf = dr_adc_get_echo_buffer(); - g_plat.log("[mec] CH%u raw (%u samples):\r\n", piezo_ch, num_samples); - for (uint16_t i = 0; i < num_samples; i++) { - g_plat.log("%u ", buf[i]); - if ((i + 1) % 16 == 0) g_plat.log("\r\n"); - } - if (num_samples % 16 != 0) g_plat.log("\r\n"); - }*/ - - /* 측정 완료 후 Piezo TX/RX Sleep */ - dr_piezo_power_off(); - - return 1; -} - - -/* cmd? - GPIO 핀 직접 제어 (디버그/테스트용) - * - * 파라미터 (Big-Endian uint16 x 3, 총 6바이트): - * v1: GPIO 포트 번호 (0 또는 1, nRF52는 2개 포트) - * v2: GPIO 핀 번호 (0~31) - * v3: 출력 상태 (1=HIGH, 0=LOW) - * - * 동작: 지정된 핀을 출력 모드로 설정 후 HIGH/LOW 제어 - * 응답: "rmd:" + v1(포트) + v2(핀) + v3(상태) - 에코 확인 - * - * 주의: 잘못된 핀 제어 시 하드웨어 손상 가능 - 디버그용으로만 사용 - */ -static int Cmd_cmd(const ParsedCmd *cmd) -{ - uint16_t v1, v2, v3; - uint32_t pin_number; - - /* 최소 6바이트(3 워드) 필요 */ - if (cmd->data_len < 6) { - dr_ble_return_1("rmd:", 0); /* 데이터 부족 에러 */ - return 1; - } - - if (!dr_get_u16(cmd, 0, &v1)) v1 = 0; /* 포트 (0~1) */ - if (!dr_get_u16(cmd, 1, &v2)) v2 = 0; /* 핀 (0~31) */ - if (!dr_get_u16(cmd, 2, &v3)) v3 = 0; /* 상태 (1=HIGH, 0=LOW) */ - - /* nRF52 GPIO 핀 번호 계산: port * 32 + pin */ - pin_number = NRF_GPIO_PIN_MAP(v1, v2); - - /* 핀을 출력 모드로 설정 */ - nrf_gpio_cfg_output(pin_number); - - /* HIGH 또는 LOW 출력 */ - if (v3 == 1) { - nrf_gpio_pin_set(pin_number); /* HIGH 출력 */ - } else { - nrf_gpio_pin_clear(pin_number); /* LOW 출력 */ - } - - /* 응답: 포트, 핀, 상태 에코 */ - dr_ble_return_3("rmd:", v1, v2, v3); - - return 1; -} - - -/** - * @brief maa? - 4채널 전체 캡처 명령 (비동기 버전) - * - * 4개 피에조 채널(CH0~CH3)을 순차적으로 버스트+캡처하고 BLE로 전송 - * 블로킹 방식 대신 비동기 상태 머신으로 구현하여 BLE 스택 안정성 확보 - * - * 파라미터: mode (uint16, word 0) - * mode=0: 16비트 원시 데이터 비동기 전송 (유일하게 지원) - * - * 비동기 아키텍처: - * - maa_async_start()가 CH0 캡처 시작 및 헤더 전송 - * - BLE_NUS_EVT_TX_RDY 콜백이 나머지 데이터/채널 전송 구동 - * - 블로킹 없음 → SoftDevice 이벤트 정상 처리 - * - BLE TX 버퍼 오버플로우로 인한 펌웨어 브릭 방지 - * - * 고정 파라미터 (하드코딩): - * 주파수 = 1.8MHz, 딜레이 = 10us, 샘플 수 = 140 - * 사이클 = 7, 평균화 = 5회 - * - * 응답 형식 (reb+red merged protocol): - * 각 채널마다: - * reb: [샘플수(2)] [raw_data...] — 119샘플 이하면 단일 패킷 - * red: [패킷순번(2)] [데이터...] — 119샘플 초과 시만 - * 전체 완료: - * raa: [상태(2)] - */ -/* 피에조 캡처 파라미터: FDS(m_config)에서 로드, 앱에서 변경 가능 */ - -static int Cmd_maa(const ParsedCmd *cmd) -{ - dr_adc_err_t err; - - /* 이전 캡처가 진행 중인지 확인 (비동기이므로 중복 실행 방지) */ - if (maa_async_is_busy()) - { - dr_ble_return_1("raa:", 0xFFFE); /* 처리 중(Busy) 에러 */ - return 1; - } - - /* Piezo TX/RX 전원: OFF일 경우 ON → maa_async_start()에서 캡처 완료 후 OFF */ - if (!dr_piezo_is_power_on()) - { - //if (g_plat.log) g_plat.log("[Cmd_maa] TX/RX Sleep -> Active\r\n"); - dr_piezo_power_on(); - } - - /*======================================================================= - * 비동기 6채널 캡처 시작 - * - maa_async_start(): CH0 캡처 실행 + 첫 헤더 패킷 전송 - * - 이후 패킷은 BLE_NUS_EVT_TX_RDY 콜백에서 자동 전송 - *=======================================================================*/ - err = maa_async_start( - m_config.piezo_freq_option, - m_config.piezo_delay_us, - m_config.piezo_num_samples, - m_config.piezo_cycles, - m_config.piezo_averaging, - ble_bin_buffer - ); - - if (err != DR_ADC_OK) - { - /* 시작 실패 → 에러 응답 전송 (앱 타임아웃 방지) */ - if (g_plat.log) g_plat.log("[Cmd_maa] start failed err=%d\r\n", err); - single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err)); - dr_binary_tx_safe(ble_bin_buffer, 3); - dr_piezo_power_off(); - return 1; - } - - return 1; -} - - -/** - * @brief mbb? 비동기 캡처 완료 후 콜백 - 센서 측정 체인 실행 - * - * raa: 전송 + 피에조 전원 OFF 이후 호출 - * info4 모드로 센서값을 전역 변수에 저장한 뒤, rbb: 패킷으로 일괄 전송 - * SAADC 측정은 비동기(콜백)이므로 dr_sd_delay_ms()로 완료 대기 - * - * 순서: 배터리 → IMU → (Piezo TX/RX ON) → 온도 - * 응답: rbb: [배터리mV(2)] [IMU 6축(12)] [온도°Cx100(2)] = 20바이트 - */ -static void all_sensors(void) -{ - uint8_t *buf; - uint32_t timeout_cnt; - - info4 = true; /* 센서값을 전역 변수에 저장 (BLE 전송 안 함) */ - - /* 1. 배터리 전압 측정 → info_batt에 저장 */ - battery_saadc_done = false; - battery_level_meas(); - for (timeout_cnt = 0; !battery_saadc_done && timeout_cnt < 100; timeout_cnt++) - { - dr_sd_delay_ms(1); /* 콜백 오면 즉시 탈출, 최대 100ms */ - } - - /* 2. IMU 6축 단발 읽기 → info_imu[6]에 저장 */ - hw_i2c_init_once(); - imu_read_direct(); - - /* 3. 온도 측정 → info_temp에 저장 (TMP235는 Piezo TX/RX 전원 필요) */ - if (!dr_piezo_is_power_on()) - { - dr_piezo_power_on(); - } - - tmp235_saadc_done = false; - tmp235_voltage_level_meas(); - - for (timeout_cnt = 0; !tmp235_saadc_done && timeout_cnt < 100; timeout_cnt++) - { - dr_sd_delay_ms(1); /* 콜백 오면 즉시 탈출, 최대 100ms, 타임아웃 시 이전 값 또는 쓰레기값.. */ - } - - info4 = false; - - /* rbb: 패킷 조립 및 전송 : [TAG 4B] [배터리 2B] [IMU 12B] [온도 2B] = 20바이트 = 10워드 */ - buf = ble_bin_buffer; - - buf[0] = 'r'; buf[1] = 'b'; buf[2] = 'b'; buf[3] = ':'; - buf[4] = (uint8_t)(info_batt >> 8); - buf[5] = (uint8_t)(info_batt & 0xFF); - - for (int i = 0; i < 6; i++) - { - buf[6 + i * 2] = (uint8_t)(info_imu[i] >> 8); - buf[6 + i * 2 + 1] = (uint8_t)(info_imu[i] & 0xFF); - } - - buf[18] = (uint8_t)(info_temp >> 8); - buf[19] = (uint8_t)(info_temp & 0xFF); - - dr_binary_tx_safe(buf, 10); /* 20바이트 = 10워드 */ - - /* 배터리, IMU, 온도 확인용 로그 */ - //if (g_plat.log) g_plat.log("-------------------------------------------------------------------------------------\r\n[Battery] %u\r\n[IMU] %d,%d,%d,%d,%d,%d\r\n[Temperature] %u\r\n\r\n", info_batt, (int16_t)info_imu[0], (int16_t)info_imu[1], (int16_t)info_imu[2], - //(int16_t)info_imu[3], (int16_t)info_imu[4], (int16_t)info_imu[5], info_temp); -} - - -/** - * @brief mbb? - 6채널 전체 캡처 + 센서 측정 (배터리/온도/IMU) - * - * 센서 측정(rbb:) → 6채널 비동기 캡처(reb: merged) → raa: → TX/RX OFF - * - * 응답 흐름: - * 1) 센서 측정: rbb: [배터리(2) + IMU 6축(12) + 온도(2)] - * 2) 각 채널: reb: [샘플수(2) + raw_data] (100샘플이면 단일 패킷) - * 3) 캡처 완료: raa: [상태] - */ - -static int Cmd_mbb(const ParsedCmd *cmd) -{ - dr_adc_err_t err; - - all_sensors(); /* 배터리, IMU, 온도 센서 먼저 측정 */ - - if (maa_async_is_busy()) - { - dr_ble_return_1("raa:", 0xFFFE); - return 1; - } - - /* 측정 파라미터 확인용 로그 - if (g_plat.log) g_plat.log("[Parameter] freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n\r\n", - m_config.piezo_freq_option, m_config.piezo_cycles, - m_config.piezo_averaging, m_config.piezo_delay_us, - m_config.piezo_num_samples);*/ - - /* 전채널 선캡처 모드: 모든 채널 캡처 완료 후 BLE 전송하도록 */ - maa_async_set_pre_capture_all(true); - - /* 비동기 6채널 캡처 시작 (FDS m_config 파라미터 사용) */ - err = maa_async_start( - m_config.piezo_freq_option, - m_config.piezo_delay_us, - m_config.piezo_num_samples, - m_config.piezo_cycles, - m_config.piezo_averaging, - ble_bin_buffer - ); - - if (err != DR_ADC_OK) - { - if (g_plat.log) g_plat.log("[Cmd_mbb] start failed err=%d\r\n", err); - single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err)); - dr_binary_tx_safe(ble_bin_buffer, 3); - dr_piezo_power_off(); - return 1; - } - - return 1; -} - - -/** - * @brief mcf? - 피에조 파라미터 읽기 (FDS) - * - * 응답: rcf: [freq(2)] [cycles(2)] [avg(2)] [delay_us(2)] [num_samples(2)] = 14바이트 = 7워드 - */ -static int Cmd_mcf(const ParsedCmd *cmd) -{ - (void)cmd; - - uint8_t *buf = ble_bin_buffer; - buf[0] = 'r'; buf[1] = 'c'; buf[2] = 'f'; buf[3] = ':'; - buf[4] = 0; buf[5] = m_config.piezo_freq_option; - buf[6] = 0; buf[7] = m_config.piezo_cycles; - buf[8] = (uint8_t)(m_config.piezo_averaging >> 8); buf[9] = (uint8_t)(m_config.piezo_averaging & 0xFF); - buf[10] = (uint8_t)(m_config.piezo_delay_us >> 8); buf[11] = (uint8_t)(m_config.piezo_delay_us & 0xFF); - buf[12] = (uint8_t)(m_config.piezo_num_samples >> 8); buf[13] = (uint8_t)(m_config.piezo_num_samples & 0xFF); - dr_binary_tx_safe(buf, 7); /* 14바이트 = 7워드 */ - - return 1; -} - - -/** - * @brief mcs? - 피에조 파라미터 쓰기 (FDS) - * - * 파라미터: [freq(2)] [cycles(2)] [avg(2)] [delay_us(2)] [num_samples(2)] = 10바이트 - * 응답: rcs: [저장된 5개 값] = 14바이트 = 7워드 - */ -static int Cmd_mcs(const ParsedCmd *cmd) -{ - if (cmd->data_len < 10) - { - if (g_plat.log) g_plat.log("[Cmd_mcs] missing params (data_len=%u)\r\n", cmd->data_len); - dr_ble_return_1("rcs:", 0xFFFF); - return 1; - } - - uint16_t freq, cycles, averaging, delay_us, num_samples; - dr_get_u16(cmd, 0, &freq); - dr_get_u16(cmd, 1, &cycles); - dr_get_u16(cmd, 2, &averaging); - dr_get_u16(cmd, 3, &delay_us); - dr_get_u16(cmd, 4, &num_samples); - - m_config.piezo_freq_option = (uint8_t)freq; - m_config.piezo_cycles = (uint8_t)cycles; - m_config.piezo_averaging = averaging; - m_config.piezo_delay_us = delay_us; - m_config.piezo_num_samples = num_samples; - config_save(); - - /* - if (g_plat.log) g_plat.log("[Cmd_mcs] saved: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n", - m_config.piezo_freq_option, m_config.piezo_cycles, - m_config.piezo_averaging, m_config.piezo_delay_us, - m_config.piezo_num_samples); - */ - - uint8_t *buf = ble_bin_buffer; - buf[0] = 'r'; buf[1] = 'c'; buf[2] = 's'; buf[3] = ':'; - buf[4] = 0; buf[5] = m_config.piezo_freq_option; - buf[6] = 0; buf[7] = m_config.piezo_cycles; - buf[8] = (uint8_t)(m_config.piezo_averaging >> 8); buf[9] = (uint8_t)(m_config.piezo_averaging & 0xFF); - buf[10] = (uint8_t)(m_config.piezo_delay_us >> 8); buf[11] = (uint8_t)(m_config.piezo_delay_us & 0xFF); - buf[12] = (uint8_t)(m_config.piezo_num_samples >> 8); buf[13] = (uint8_t)(m_config.piezo_num_samples & 0xFF); - dr_binary_tx_safe(buf, 7); /* 14바이트 = 7워드 */ - - return 1; -} - - -/** - * @brief mls? - LED 상태 설정 (앱 → 기기) - * - * 파라미터: [state(2)] - led_state_t enum 값 - * 0: OFF, 4: DETACH_WARNING, 5: ALIGN_SEARCHING, 6: ALIGN_COMPLETE - * 응답: rls: [state(2)] - 에코 - */ -static int Cmd_mls(const ParsedCmd *cmd) -{ - if (cmd->data_len < 2) { - dr_ble_return_1("rls:", 0xFFFF); - return 1; - } - - uint16_t state; - dr_get_u16(cmd, 0, &state); - - if (state > LED_STATE_ERROR) { - dr_ble_return_1("rls:", 0xFFFE); - return 1; - } - - led_set_state((led_state_t)state); - dr_ble_return_1("rls:", state); - - return 1; -} - - -/*============================================================================== - * 설정: HW/시리얼 넘버 FDS 읽기/쓰기 - * - * FDS(Flash Data Storage)에 디바이스 식별 정보를 영구 저장 - * 제조 시 공장에서 한 번 기록하고, 이후 읽기로 확인 - *============================================================================*/ - -/* mwh? - HW 넘버 FDS에 쓰기 - * - * 데이터: 12바이트 ASCII HW 넘버 (예: "VB2025A00001") - * 응답: "rwh:" + 저장된 HW 넘버 에코 - */ -static int Cmd_mwh(const ParsedCmd *cmd) -{ - char buf[13]; - - /* 최소 12바이트 데이터 필요 */ - if (cmd->data_len < 12) - { - dr_ble_return_1("rwh:", 0xFFFF); /* 데이터 부족 에러 */ - return 1; - } - - /* ASCII 추출 → 전역 변수 + 설정 구조체에 복사 → FDS 저장 */ - dr_get_ascii(cmd, 0, buf, 12); - memcpy(HW_NO, buf, 12); - memcpy(m_config.hw_no, buf, 12); - config_save(); /* FDS(Flash Memory)에 저장 */ - - ascii_format_data(ble_bin_buffer, "rwh:", buf, 12); - dr_binary_tx_safe(ble_bin_buffer, 8); - return 1; -} - -/* mws? - 시리얼 넘버 FDS에 쓰기 - * - * 데이터: 12바이트 ASCII 시리얼 넘버 - * 응답: "rws:" + 저장된 시리얼 넘버 에코 - */ -static int Cmd_mws(const ParsedCmd *cmd) -{ - char buf[13]; - - if (cmd->data_len < 12) { - dr_ble_return_1("rws:", 0xFFFF); /* 데이터 부족 에러 */ - return 1; - } - - dr_get_ascii(cmd, 0, buf, 12); - memcpy(SERIAL_NO, buf, 12); - memcpy(m_config.serial_no, buf, 12); - config_save(); /* FDS(Flash Memory)에 저장 */ - - ascii_format_data(ble_bin_buffer, "rws:", buf, 12); - dr_binary_tx_safe(ble_bin_buffer, 8); - return 1; -} - -/* mrh? - HW 넘버 FDS에서 읽기 - * FDS의 설정 구조체에서 HW 넘버를 읽어 BLE로 응답 */ -static int Cmd_mrh(const ParsedCmd *cmd) -{ - (void)cmd; - memcpy(HW_NO, m_config.hw_no, 12); /* FDS 설정 → 전역 변수 동기화 */ - ascii_format_data(ble_bin_buffer, "rrh:", HW_NO, 12); - dr_binary_tx_safe(ble_bin_buffer, 8); /* 4(TAG) + 12(HW넘버) = 16바이트 = 8워드 */ - return 1; -} - -/* mrs? - 시리얼 넘버 FDS에서 읽기 */ -static int Cmd_mrs(const ParsedCmd *cmd) -{ - (void)cmd; - memcpy(SERIAL_NO, m_config.serial_no, 12); /* FDS 설정 → 전역 변수 동기화 */ - ascii_format_data(ble_bin_buffer, "rrs:", SERIAL_NO, 12); - dr_binary_tx_safe(ble_bin_buffer, 8); - return 1; -} - - -/*============================================================================== - * 패스키: BLE 페어링 시 사용하는 6자리 숫자 (예: "123456") - *============================================================================*/ - -/* mpz? - BLE 패스키 FDS에 쓰기 - * 패킷: mpz? + ASCII 6자리 패스키 (예: "654321") - * 응답: rpz: + 저장된 패스키 에코 (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(); /* FDS(Flash Memory)에 저장 */ - - ascii_format_data(ble_bin_buffer, "rpz:", passkey, 6); - dr_binary_tx_safe(ble_bin_buffer, 5); - return 1; -} - -/* mqz? - BLE 패스키 FDS에서 읽기 - * 패킷: 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; -} - -/*============================================================================== - * IMU: 6축 원시 데이터 (단발 읽기) - *============================================================================*/ - -/* msp? - IMU 가속도(xyz) + 자이로(xyz) 원시 데이터 단발 읽기 - * - * I2C로 IMU 레지스터를 직접 읽어 BLE로 전송 - * 타이머/인터럽트 없이 즉시 실행 (동기 방식) - * - * 응답: rsp: + 6 x uint16_t - * [accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z] - */ -static int Cmd_msp(const ParsedCmd *cmd) -{ - (void)cmd; - - hw_i2c_init_once(); /* I2C 버스 초기화 (최초 1회) */ - - /* IMU 레지스터 직접 읽기 - 타이머, DRDY 인터럽트, 콜백 없이 동기 실행 */ - int rc = imu_read_direct(); - - return 1; -} diff --git a/project/ble_peripheral/ble_app_bladder_patch/command/parser.h b/project/ble_peripheral/ble_app_bladder_patch/command/parser.h index 507e81d..458e904 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/command/parser.h +++ b/project/ble_peripheral/ble_app_bladder_patch/command/parser.h @@ -1,24 +1,75 @@ -/* parser.h */ +/*============================================================================== + * parser.h - BLE command parser public API + * + * Parser infrastructure (parsing/CRC/dispatch) and command handlers are + * decoupled: + * - Parser: parser.c (defines the functions here) + * - Handlers: handlers/cmd_device.c / cmd_info.c / ... + * - Table: cmd_table.c (injected via cmd_table_init) + * + * Boot sequence: main.c calls cmd_table_init() -> dr_parser_init() to inject + * the command table pointer into the parser. + *============================================================================*/ #ifndef PARSER_H #define PARSER_H #include #include -/* Platform-dependent function pointer set */ +/* Maximum payload length (excludes TAG) */ +#define DR_MAX_DATA 128 + +/*------------------------------------------------------------------------------ + * Platform interface + *----------------------------------------------------------------------------*/ typedef struct { void (*log)(const char *fmt, ...); - void (*tx_bin)(const uint8_t *buf, uint16_t len); - bool crc_check; + void (*tx_bin)(const uint8_t *buf, uint16_t len); /* len: word (uint16) count */ + bool crc_check; } dr_platform_if_t; - -/* Global interface & log flag */ extern dr_platform_if_t g_plat; -extern bool g_log_enable; +extern bool g_log_enable; -/* Main parser entry point */ -int dr_cmd_parser(const uint8_t *buf, uint8_t len); +/*------------------------------------------------------------------------------ + * Parsed command - input passed to handlers + *----------------------------------------------------------------------------*/ +typedef struct { + char tag[5]; /* Command TAG (e.g. "mid?") + '\0' */ + uint8_t data[DR_MAX_DATA]; /* Payload bytes following the TAG */ + uint8_t data_len; /* Valid length of data[] */ +} ParsedCmd; + +/*------------------------------------------------------------------------------ + * Command table entry - defined in cmd_table.c + *----------------------------------------------------------------------------*/ +typedef struct { + char tag[5]; /* TAG: 4 chars + '\0' */ + bool enabled; /* false -> rxd: response */ + int (*handler)(const ParsedCmd *cmd); /* 1=success, 0=failure */ +} CmdEntry; + +/*------------------------------------------------------------------------------ + * Parser API + *----------------------------------------------------------------------------*/ + +/* Inject command table (called once at boot). */ +void dr_parser_init(const CmdEntry *table, uint16_t count); + +/* Entry point: invoked from BLE NUS / UART receive callbacks. */ +int dr_cmd_parser(const uint8_t *buf, uint8_t len); + +/*------------------------------------------------------------------------------ + * Public utilities for handlers + *----------------------------------------------------------------------------*/ + +/* Extract Big-Endian uint16. Returns false if not enough data. */ +bool dr_get_u16(const ParsedCmd *cmd, uint8_t word_index, uint16_t *out); + +/* Extract null-terminated ASCII string. out must hold at least max_len+1. */ +void dr_get_ascii(const ParsedCmd *cmd, uint8_t offset, char *out, uint8_t max_len); + +/* CRC16 (Nordic SDK CRC-CCITT variant). p_crc=NULL -> initial 0xFFFF. */ +uint16_t dr_crc16_compute(const uint8_t *p_data, uint32_t size, const uint16_t *p_crc); #endif /* PARSER_H */ - diff --git a/project/ble_peripheral/ble_app_bladder_patch/main.c b/project/ble_peripheral/ble_app_bladder_patch/main.c index 217d0d9..a38ea54 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/main.c +++ b/project/ble_peripheral/ble_app_bladder_patch/main.c @@ -111,6 +111,7 @@ /* ── 암호화/명령 파서/디버그 ── */ #include "nrf_crypto.h" /* nRF 암호화 라이브러리 (AES 등) */ #include "parser.h" /* 새 바이너리 명령 파서 (dr_cmd_parser) */ +#include "cmd_table.h" /* 명령 테이블 등록 (cmd_table_init) */ #include "debug_print.h" /* 디버그 출력 매크로 (DBG_PRINTF) */ #include "fstorage.h" /* Flash Storage 래퍼 (FDS 초기화/저장/로드) */ #include "dr_piezo.h" /* 피에조 초음파 드라이버 */ @@ -1840,6 +1841,7 @@ int main(void) g_plat.tx_bin = dr_binary_tx_safe; g_plat.crc_check = true; g_log_enable = true; + cmd_table_init(); /* 명령 테이블을 파서에 주입 */ dr_piezo_init(); DBG_PRINTF(" parser/piezo OK\r\n"); diff --git a/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvoptx b/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvoptx index 75b8859..64a0e3a 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvoptx +++ b/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvoptx @@ -1339,20 +1339,20 @@ 0 0 0 - ..\..\..\command\util\dr_util.c - dr_util.c + ..\..\..\measurement\adc121s051\dr_adc121s051.c + dr_adc121s051.c 0 0 1 17 - 5 + 1 0 0 0 - ..\..\..\command\util\dr_util.h - dr_util.h + ..\..\..\system\led\led_control.c + led_control.c 0 0 @@ -1363,8 +1363,8 @@ 0 0 0 - ..\..\..\measurement\adc121s051\dr_adc121s051.c - dr_adc121s051.c + ..\..\..\command\dr_util.c + dr_util.c 0 0 @@ -1375,8 +1375,56 @@ 0 0 0 - ..\..\..\system\led\led_control.c - led_control.c + ..\..\..\command\cmd_table.c + cmd_table.c + 0 + 0 + + + 1 + 20 + 1 + 0 + 0 + 0 + ..\..\..\command\handlers\cmd_device.c + cmd_device.c + 0 + 0 + + + 1 + 21 + 1 + 0 + 0 + 0 + ..\..\..\command\handlers\cmd_info.c + cmd_info.c + 0 + 0 + + + 1 + 22 + 1 + 0 + 0 + 0 + ..\..\..\command\handlers\cmd_piezo.c + cmd_piezo.c + 0 + 0 + + + 1 + 23 + 1 + 0 + 0 + 0 + ..\..\..\command\handlers\cmd_sensor.c + cmd_sensor.c 0 0 @@ -1390,7 +1438,7 @@ 0 2 - 20 + 24 1 0 0 @@ -1410,7 +1458,7 @@ 0 3 - 21 + 25 1 0 0 @@ -1422,7 +1470,7 @@ 3 - 22 + 26 1 0 0 @@ -1442,7 +1490,7 @@ 0 4 - 23 + 27 1 0 0 @@ -1462,7 +1510,7 @@ 0 5 - 24 + 28 1 0 0 @@ -1474,7 +1522,7 @@ 5 - 25 + 29 1 0 0 @@ -1486,7 +1534,7 @@ 5 - 26 + 30 1 0 0 @@ -1498,7 +1546,7 @@ 5 - 27 + 31 1 0 0 @@ -1510,7 +1558,7 @@ 5 - 28 + 32 1 0 0 @@ -1522,7 +1570,7 @@ 5 - 29 + 33 1 0 0 @@ -1534,7 +1582,7 @@ 5 - 30 + 34 1 0 0 @@ -1546,7 +1594,7 @@ 5 - 31 + 35 1 0 0 @@ -1558,7 +1606,7 @@ 5 - 32 + 36 1 0 0 @@ -1570,7 +1618,7 @@ 5 - 33 + 37 1 0 0 @@ -1582,7 +1630,7 @@ 5 - 34 + 38 1 0 0 @@ -1594,7 +1642,7 @@ 5 - 35 + 39 1 0 0 @@ -1606,7 +1654,7 @@ 5 - 36 + 40 1 0 0 @@ -1618,7 +1666,7 @@ 5 - 37 + 41 1 0 0 @@ -1630,7 +1678,7 @@ 5 - 38 + 42 1 0 0 @@ -1642,7 +1690,7 @@ 5 - 39 + 43 1 0 0 @@ -1654,7 +1702,7 @@ 5 - 40 + 44 1 0 0 @@ -1666,7 +1714,7 @@ 5 - 41 + 45 1 0 0 @@ -1678,7 +1726,7 @@ 5 - 42 + 46 1 0 0 @@ -1690,7 +1738,7 @@ 5 - 43 + 47 1 0 0 @@ -1710,7 +1758,7 @@ 0 6 - 44 + 48 1 0 0 @@ -1730,7 +1778,7 @@ 0 7 - 45 + 49 1 0 0 @@ -1742,7 +1790,7 @@ 7 - 46 + 50 1 0 0 @@ -1754,7 +1802,7 @@ 7 - 47 + 51 1 0 0 @@ -1766,7 +1814,7 @@ 7 - 48 + 52 1 0 0 @@ -1778,7 +1826,7 @@ 7 - 49 + 53 1 0 0 @@ -1790,7 +1838,7 @@ 7 - 50 + 54 1 0 0 @@ -1802,7 +1850,7 @@ 7 - 51 + 55 1 0 0 @@ -1814,7 +1862,7 @@ 7 - 52 + 56 1 0 0 @@ -1826,7 +1874,7 @@ 7 - 53 + 57 1 0 0 @@ -1838,7 +1886,7 @@ 7 - 54 + 58 1 0 0 @@ -1850,7 +1898,7 @@ 7 - 55 + 59 1 0 0 @@ -1862,7 +1910,7 @@ 7 - 56 + 60 1 0 0 @@ -1874,7 +1922,7 @@ 7 - 57 + 61 1 0 0 @@ -1886,7 +1934,7 @@ 7 - 58 + 62 1 0 0 @@ -1898,7 +1946,7 @@ 7 - 59 + 63 1 0 0 @@ -1910,7 +1958,7 @@ 7 - 60 + 64 1 0 0 @@ -1922,7 +1970,7 @@ 7 - 61 + 65 1 0 0 @@ -1934,7 +1982,7 @@ 7 - 62 + 66 1 0 0 @@ -1946,7 +1994,7 @@ 7 - 63 + 67 1 0 0 @@ -1958,7 +2006,7 @@ 7 - 64 + 68 5 0 0 @@ -1978,7 +2026,7 @@ 0 8 - 65 + 69 1 0 0 @@ -1990,7 +2038,7 @@ 8 - 66 + 70 1 0 0 @@ -2002,7 +2050,7 @@ 8 - 67 + 71 1 0 0 @@ -2014,7 +2062,7 @@ 8 - 68 + 72 1 0 0 @@ -2026,7 +2074,7 @@ 8 - 69 + 73 1 0 0 @@ -2038,7 +2086,7 @@ 8 - 70 + 74 1 0 0 @@ -2050,7 +2098,7 @@ 8 - 71 + 75 1 0 0 @@ -2062,7 +2110,7 @@ 8 - 72 + 76 1 0 0 @@ -2074,7 +2122,7 @@ 8 - 73 + 77 1 0 0 @@ -2086,7 +2134,7 @@ 8 - 74 + 78 1 0 0 @@ -2098,7 +2146,7 @@ 8 - 75 + 79 1 0 0 @@ -2110,7 +2158,7 @@ 8 - 76 + 80 1 0 0 @@ -2122,7 +2170,7 @@ 8 - 77 + 81 1 0 0 @@ -2134,7 +2182,7 @@ 8 - 78 + 82 1 0 0 @@ -2146,7 +2194,7 @@ 8 - 79 + 83 1 0 0 @@ -2158,7 +2206,7 @@ 8 - 80 + 84 1 0 0 @@ -2170,7 +2218,7 @@ 8 - 81 + 85 1 0 0 @@ -2182,7 +2230,7 @@ 8 - 82 + 86 1 0 0 @@ -2194,7 +2242,7 @@ 8 - 83 + 87 1 0 0 @@ -2206,7 +2254,7 @@ 8 - 84 + 88 1 0 0 @@ -2218,7 +2266,7 @@ 8 - 85 + 89 1 0 0 @@ -2230,7 +2278,7 @@ 8 - 86 + 90 1 0 0 @@ -2242,7 +2290,7 @@ 8 - 87 + 91 1 0 0 @@ -2254,7 +2302,7 @@ 8 - 88 + 92 1 0 0 @@ -2266,7 +2314,7 @@ 8 - 89 + 93 1 0 0 @@ -2278,7 +2326,7 @@ 8 - 90 + 94 1 0 0 @@ -2290,7 +2338,7 @@ 8 - 91 + 95 1 0 0 @@ -2302,7 +2350,7 @@ 8 - 92 + 96 1 0 0 @@ -2314,7 +2362,7 @@ 8 - 93 + 97 1 0 0 @@ -2334,7 +2382,7 @@ 0 9 - 94 + 98 1 0 0 @@ -2346,7 +2394,7 @@ 9 - 95 + 99 1 0 0 @@ -2358,7 +2406,7 @@ 9 - 96 + 100 1 0 0 @@ -2370,7 +2418,7 @@ 9 - 97 + 101 1 0 0 @@ -2382,7 +2430,7 @@ 9 - 98 + 102 1 0 0 @@ -2402,7 +2450,7 @@ 0 10 - 99 + 103 1 0 0 @@ -2414,7 +2462,7 @@ 10 - 100 + 104 1 0 0 @@ -2426,7 +2474,7 @@ 10 - 101 + 105 1 0 0 @@ -2446,7 +2494,7 @@ 0 11 - 102 + 106 1 0 0 @@ -2458,7 +2506,7 @@ 11 - 103 + 107 1 0 0 @@ -2470,7 +2518,7 @@ 11 - 104 + 108 1 0 0 @@ -2490,7 +2538,7 @@ 0 12 - 105 + 109 1 0 0 @@ -2502,7 +2550,7 @@ 12 - 106 + 110 1 0 0 @@ -2514,7 +2562,7 @@ 12 - 107 + 111 1 0 0 @@ -2526,7 +2574,7 @@ 12 - 108 + 112 1 0 0 @@ -2546,7 +2594,7 @@ 0 13 - 109 + 113 1 0 0 @@ -2558,7 +2606,7 @@ 13 - 110 + 114 1 0 0 @@ -2570,7 +2618,7 @@ 13 - 111 + 115 1 0 0 @@ -2582,7 +2630,7 @@ 13 - 112 + 116 1 0 0 @@ -2594,7 +2642,7 @@ 13 - 113 + 117 1 0 0 @@ -2606,7 +2654,7 @@ 13 - 114 + 118 1 0 0 @@ -2618,7 +2666,7 @@ 13 - 115 + 119 1 0 0 @@ -2630,7 +2678,7 @@ 13 - 116 + 120 1 0 0 @@ -2642,7 +2690,7 @@ 13 - 117 + 121 1 0 0 @@ -2654,7 +2702,7 @@ 13 - 118 + 122 1 0 0 @@ -2666,7 +2714,7 @@ 13 - 119 + 123 1 0 0 @@ -2678,7 +2726,7 @@ 13 - 120 + 124 1 0 0 @@ -2690,7 +2738,7 @@ 13 - 121 + 125 1 0 0 @@ -2702,7 +2750,7 @@ 13 - 122 + 126 1 0 0 @@ -2722,7 +2770,7 @@ 0 14 - 123 + 127 1 0 0 @@ -2734,7 +2782,7 @@ 14 - 124 + 128 1 0 0 @@ -2746,7 +2794,7 @@ 14 - 125 + 129 1 0 0 @@ -2758,7 +2806,7 @@ 14 - 126 + 130 1 0 0 @@ -2770,7 +2818,7 @@ 14 - 127 + 131 1 0 0 @@ -2782,7 +2830,7 @@ 14 - 128 + 132 1 0 0 @@ -2794,7 +2842,7 @@ 14 - 129 + 133 1 0 0 @@ -2806,7 +2854,7 @@ 14 - 130 + 134 1 0 0 @@ -2818,7 +2866,7 @@ 14 - 131 + 135 1 0 0 @@ -2830,7 +2878,7 @@ 14 - 132 + 136 1 0 0 @@ -2842,7 +2890,7 @@ 14 - 133 + 137 1 0 0 @@ -2854,7 +2902,7 @@ 14 - 134 + 138 1 0 0 @@ -2866,7 +2914,7 @@ 14 - 135 + 139 1 0 0 @@ -2886,7 +2934,7 @@ 0 15 - 136 + 140 1 0 0 @@ -2898,7 +2946,7 @@ 15 - 137 + 141 1 0 0 @@ -2910,7 +2958,7 @@ 15 - 138 + 142 1 0 0 @@ -2922,7 +2970,7 @@ 15 - 139 + 143 1 0 0 @@ -2934,7 +2982,7 @@ 15 - 140 + 144 1 0 0 @@ -2946,7 +2994,7 @@ 15 - 141 + 145 1 0 0 @@ -2958,7 +3006,7 @@ 15 - 142 + 146 1 0 0 @@ -2978,7 +3026,7 @@ 0 16 - 143 + 147 1 0 0 @@ -2990,7 +3038,7 @@ 16 - 144 + 148 1 0 0 @@ -3002,7 +3050,7 @@ 16 - 145 + 149 1 0 0 @@ -3022,7 +3070,7 @@ 0 17 - 146 + 150 4 0 0 @@ -3042,7 +3090,7 @@ 0 18 - 147 + 151 1 0 0 @@ -3054,7 +3102,7 @@ 18 - 148 + 152 1 0 0 @@ -3066,7 +3114,7 @@ 18 - 149 + 153 1 0 0 @@ -3086,7 +3134,7 @@ 0 19 - 150 + 154 4 0 0 @@ -3106,7 +3154,7 @@ 0 20 - 151 + 155 1 0 0 @@ -3118,7 +3166,7 @@ 20 - 152 + 156 1 0 0 @@ -3130,7 +3178,7 @@ 20 - 153 + 157 1 0 0 @@ -3142,7 +3190,7 @@ 20 - 154 + 158 1 0 0 @@ -3154,7 +3202,7 @@ 20 - 155 + 159 1 0 0 @@ -3166,7 +3214,7 @@ 20 - 156 + 160 1 0 0 @@ -3178,7 +3226,7 @@ 20 - 157 + 161 1 0 0 @@ -3190,7 +3238,7 @@ 20 - 158 + 162 1 0 0 @@ -3202,7 +3250,7 @@ 20 - 159 + 163 1 0 0 @@ -3214,7 +3262,7 @@ 20 - 160 + 164 1 0 0 diff --git a/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvprojx b/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvprojx index 584f964..2135989 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvprojx +++ b/project/ble_peripheral/ble_app_bladder_patch/pca10056/s140/arm5_no_packs/ble_app_bladder_patch_s140.uvprojx @@ -339,7 +339,7 @@ --reduce_paths --diag_suppress 188 APP_TIMER_V2 APP_TIMER_V2_RTC1_ENABLED BOARD_PCA10056 FLOAT_ABI_HARD NRF52840_XXAA NRF_SD_BLE_API_VERSION=7 S140 SOFTDEVICE_PRESENT __HEAP_SIZE=8192 __STACK_SIZE=8192 NRF_DFU_SVCI_ENABLED NRF_DFU_TRANSPORT_BLE=1 ICM42670P CONFIG_NFCT_PINS_AS_GPIOS MBEDTLS_CONFIG_FILE=<nrf_crypto_mbedtls_config.h> NRF_APP_VERSION=0x00000001 NRF_APP_VERSION_ADDR=0x1D000 NRF_CRYPTO_MAX_INSTANCE_COUN=1 - ..\..\..\config;..\..\..\..\..\..\components;..\..\..\..\..\..\components\ble\ble_advertising;..\..\..\..\..\..\components\ble\ble_dtm;..\..\..\..\..\..\components\ble\ble_link_ctx_manager;..\..\..\..\..\..\components\ble\ble_racp;..\..\..\..\..\..\components\ble\ble_services\ble_ancs_c;..\..\..\..\..\..\components\ble\ble_services\ble_ans_c;..\..\..\..\..\..\components\ble\ble_services\ble_bas;..\..\..\..\..\..\components\ble\ble_services\ble_bas_c;..\..\..\..\..\..\components\ble\ble_services\ble_cscs;..\..\..\..\..\..\components\ble\ble_services\ble_cts_c;..\..\..\..\..\..\components\ble\ble_services\ble_dfu;..\..\..\..\..\..\components\ble\ble_services\ble_dis;..\..\..\..\..\..\components\ble\ble_services\ble_gls;..\..\..\..\..\..\components\ble\ble_services\ble_hids;..\..\..\..\..\..\components\ble\ble_services\ble_hrs;..\..\..\..\..\..\components\ble\ble_services\ble_hrs_c;..\..\..\..\..\..\components\ble\ble_services\ble_hts;..\..\..\..\..\..\components\ble\ble_services\ble_ias;..\..\..\..\..\..\components\ble\ble_services\ble_ias_c;..\..\..\..\..\..\components\ble\ble_services\ble_lbs;..\..\..\..\..\..\components\ble\ble_services\ble_lbs_c;..\..\..\..\..\..\components\ble\ble_services\ble_lls;..\..\..\..\..\..\components\ble\ble_services\ble_nus;..\..\..\..\..\..\components\ble\ble_services\ble_nus_c;..\..\..\..\..\..\components\ble\ble_services\ble_rscs;..\..\..\..\..\..\components\ble\ble_services\ble_rscs_c;..\..\..\..\..\..\components\ble\ble_services\ble_tps;..\..\..\..\..\..\components\ble\common;..\..\..\..\..\..\components\ble\nrf_ble_gatt;..\..\..\..\..\..\components\ble\nrf_ble_qwr;..\..\..\..\..\..\components\ble\peer_manager;..\..\..\..\..\..\components\boards;..\..\..\..\..\..\components\libraries\atomic;..\..\..\..\..\..\components\libraries\atomic_fifo;..\..\..\..\..\..\components\libraries\atomic_flags;..\..\..\..\..\..\components\libraries\balloc;..\..\..\..\..\..\components\libraries\bootloader\ble_dfu;..\..\..\..\..\..\components\libraries\bsp;..\..\..\..\..\..\components\libraries\button;..\..\..\..\..\..\components\libraries\cli;..\..\..\..\..\..\components\libraries\crc16;..\..\..\..\..\..\components\libraries\crc32;..\..\..\..\..\..\components\libraries\crypto;..\..\..\..\..\..\components\libraries\csense;..\..\..\..\..\..\components\libraries\csense_drv;..\..\..\..\..\..\components\libraries\delay;..\..\..\..\..\..\components\libraries\ecc;..\..\..\..\..\..\components\libraries\experimental_section_vars;..\..\..\..\..\..\components\libraries\experimental_task_manager;..\..\..\..\..\..\components\libraries\fds;..\..\..\..\..\..\components\libraries\fifo;..\..\..\..\..\..\components\libraries\fstorage;..\..\..\..\..\..\components\libraries\gfx;..\..\..\..\..\..\components\libraries\gpiote;..\..\..\..\..\..\components\libraries\hardfault;..\..\..\..\..\..\components\libraries\hci;..\..\..\..\..\..\components\libraries\led_softblink;..\..\..\..\..\..\components\libraries\log;..\..\..\..\..\..\components\libraries\log\src;..\..\..\..\..\..\components\libraries\low_power_pwm;..\..\..\..\..\..\components\libraries\mem_manager;..\..\..\..\..\..\components\libraries\memobj;..\..\..\..\..\..\components\libraries\mpu;..\..\..\..\..\..\components\libraries\mutex;..\..\..\..\..\..\components\libraries\pwm;..\..\..\..\..\..\components\libraries\pwr_mgmt;..\..\..\..\..\..\components\libraries\queue;..\..\..\..\..\..\components\libraries\ringbuf;..\..\..\..\..\..\components\libraries\scheduler;..\..\..\..\..\..\components\libraries\sdcard;..\..\..\..\..\..\components\libraries\slip;..\..\..\..\..\..\components\libraries\sortlist;..\..\..\..\..\..\components\libraries\spi_mngr;..\..\..\..\..\..\components\libraries\stack_guard;..\..\..\..\..\..\components\libraries\strerror;..\..\..\..\..\..\components\libraries\svc;..\..\..\..\..\..\components\libraries\timer;..\..\..\..\..\..\components\libraries\twi_mngr;..\..\..\..\..\..\components\libraries\twi_sensor;..\..\..\..\..\..\components\libraries\uart;..\..\..\..\..\..\components\libraries\usbd;..\..\..\..\..\..\components\libraries\usbd\class\audio;..\..\..\..\..\..\components\libraries\usbd\class\cdc;..\..\..\..\..\..\components\libraries\usbd\class\cdc\acm;..\..\..\..\..\..\components\libraries\usbd\class\hid;..\..\..\..\..\..\components\libraries\usbd\class\hid\generic;..\..\..\..\..\..\components\libraries\usbd\class\hid\kbd;..\..\..\..\..\..\components\libraries\usbd\class\hid\mouse;..\..\..\..\..\..\components\libraries\usbd\class\msc;..\..\..\..\..\..\components\libraries\util;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\ac_rec_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\ble_oob_advdata_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\le_oob_rec_parser;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ac_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_oob_advdata;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_pair_lib;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_pair_msg;..\..\..\..\..\..\components\nfc\ndef\connection_handover\common;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ep_oob_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\hs_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\le_oob_rec;..\..\..\..\..\..\components\nfc\ndef\generic\message;..\..\..\..\..\..\components\nfc\ndef\generic\record;..\..\..\..\..\..\components\nfc\ndef\launchapp;..\..\..\..\..\..\components\nfc\ndef\parser\message;..\..\..\..\..\..\components\nfc\ndef\parser\record;..\..\..\..\..\..\components\nfc\ndef\text;..\..\..\..\..\..\components\nfc\ndef\uri;..\..\..\..\..\..\components\nfc\platform;..\..\..\..\..\..\components\nfc\t2t_lib;..\..\..\..\..\..\components\nfc\t2t_parser;..\..\..\..\..\..\components\nfc\t4t_lib;..\..\..\..\..\..\components\nfc\t4t_parser\apdu;..\..\..\..\..\..\components\nfc\t4t_parser\cc_file;..\..\..\..\..\..\components\nfc\t4t_parser\hl_detection_procedure;..\..\..\..\..\..\components\nfc\t4t_parser\tlv;..\..\..\..\..\..\components\softdevice\common;..\..\..\..\..\..\components\softdevice\s140\headers;..\..\..\..\..\..\components\softdevice\s140\headers\nrf52;..\..\..\..\..\..\external\fprintf;..\..\..\..\..\..\external\segger_rtt;..\..\..\..\..\..\external\utf_converter;..\..\..\..\..\..\integration\nrfx;..\..\..\..\..\..\integration\nrfx\legacy;..\..\..\..\..\..\modules\nrfx;..\..\..\..\..\..\modules\nrfx\drivers\include;..\..\..\..\..\..\modules\nrfx\hal;..\config;..\..\..\..\ble_app_bladder_patch;..\..\..\..\..\..\components\libraries\bootloader\dfu;..\..\..\..\..\..\components\libraries\bootloader;..\..\..\..\..\..\modules\nrfx\drivers\src;..\..\..\measurement\imu;..\..\..\measurement\imu\Invn;..\..\..\measurement\imu\Invn\EmbUtils;..\..\..\measurement\imu\Invn\imu;..\..\..\measurement\imu\Invn\lib_agm;..\..\..\measurement\imu\Invn\lib_agm\invn\common;..\..\..\measurement\imu\Invn\lib_agm\test_vector;..\..\..\..\..\..\integration\nrfx\legacy;..\..\..\measurement\imu\app_raw;..\..\..\..\..\..\components\libraries\crypto\backend\cc310;..\..\..\..\..\..\components\libraries\crypto\backend\cc310_bl;..\..\..\..\..\..\components\libraries\crypto\backend\cifra;..\..\..\..\..\..\components\libraries\crypto\backend\mbedtls;..\..\..\..\..\..\components\libraries\crypto\backend\micro_ecc;..\..\..\..\..\..\components\libraries\crypto\backend\nrf_hw;..\..\..\..\..\..\components\libraries\crypto\backend\nrf_sw;..\..\..\..\..\..\components\libraries\crypto\backend\oberon;..\..\..\..\..\..\components\libraries\crypto\backend\optiga;..\..\..\..\..\..\external\nrf_cc310\include;..\..\..\..\..\..\external\mbedtls\include;..\..\..\..\..\..\external\nrf_oberon;..\..\..\..\..\..\external\nrf_oberon\include;..\..\..\..\..\..\external\nrf_tls\mbedtls\nrf_crypto\config;..\..\..\..\..\..\components\libraries\stack_info;..\..\..\system\security;..\..\..\command;..\..\..\measurement\piezo;..\..\..\command\util;..\..\..\measurement\adc121s051;..\..\..\measurement\battery;..\..\..\measurement\temperature;..\..\..\system\led;..\..\..\system\power;..\..\..\hal\i2c;..\..\..\hal\fds;..\..\..\system + ..\..\..\config;..\..\..\..\..\..\components;..\..\..\..\..\..\components\ble\ble_advertising;..\..\..\..\..\..\components\ble\ble_dtm;..\..\..\..\..\..\components\ble\ble_link_ctx_manager;..\..\..\..\..\..\components\ble\ble_racp;..\..\..\..\..\..\components\ble\ble_services\ble_ancs_c;..\..\..\..\..\..\components\ble\ble_services\ble_ans_c;..\..\..\..\..\..\components\ble\ble_services\ble_bas;..\..\..\..\..\..\components\ble\ble_services\ble_bas_c;..\..\..\..\..\..\components\ble\ble_services\ble_cscs;..\..\..\..\..\..\components\ble\ble_services\ble_cts_c;..\..\..\..\..\..\components\ble\ble_services\ble_dfu;..\..\..\..\..\..\components\ble\ble_services\ble_dis;..\..\..\..\..\..\components\ble\ble_services\ble_gls;..\..\..\..\..\..\components\ble\ble_services\ble_hids;..\..\..\..\..\..\components\ble\ble_services\ble_hrs;..\..\..\..\..\..\components\ble\ble_services\ble_hrs_c;..\..\..\..\..\..\components\ble\ble_services\ble_hts;..\..\..\..\..\..\components\ble\ble_services\ble_ias;..\..\..\..\..\..\components\ble\ble_services\ble_ias_c;..\..\..\..\..\..\components\ble\ble_services\ble_lbs;..\..\..\..\..\..\components\ble\ble_services\ble_lbs_c;..\..\..\..\..\..\components\ble\ble_services\ble_lls;..\..\..\..\..\..\components\ble\ble_services\ble_nus;..\..\..\..\..\..\components\ble\ble_services\ble_nus_c;..\..\..\..\..\..\components\ble\ble_services\ble_rscs;..\..\..\..\..\..\components\ble\ble_services\ble_rscs_c;..\..\..\..\..\..\components\ble\ble_services\ble_tps;..\..\..\..\..\..\components\ble\common;..\..\..\..\..\..\components\ble\nrf_ble_gatt;..\..\..\..\..\..\components\ble\nrf_ble_qwr;..\..\..\..\..\..\components\ble\peer_manager;..\..\..\..\..\..\components\boards;..\..\..\..\..\..\components\libraries\atomic;..\..\..\..\..\..\components\libraries\atomic_fifo;..\..\..\..\..\..\components\libraries\atomic_flags;..\..\..\..\..\..\components\libraries\balloc;..\..\..\..\..\..\components\libraries\bootloader\ble_dfu;..\..\..\..\..\..\components\libraries\bsp;..\..\..\..\..\..\components\libraries\button;..\..\..\..\..\..\components\libraries\cli;..\..\..\..\..\..\components\libraries\crc16;..\..\..\..\..\..\components\libraries\crc32;..\..\..\..\..\..\components\libraries\crypto;..\..\..\..\..\..\components\libraries\csense;..\..\..\..\..\..\components\libraries\csense_drv;..\..\..\..\..\..\components\libraries\delay;..\..\..\..\..\..\components\libraries\ecc;..\..\..\..\..\..\components\libraries\experimental_section_vars;..\..\..\..\..\..\components\libraries\experimental_task_manager;..\..\..\..\..\..\components\libraries\fds;..\..\..\..\..\..\components\libraries\fifo;..\..\..\..\..\..\components\libraries\fstorage;..\..\..\..\..\..\components\libraries\gfx;..\..\..\..\..\..\components\libraries\gpiote;..\..\..\..\..\..\components\libraries\hardfault;..\..\..\..\..\..\components\libraries\hci;..\..\..\..\..\..\components\libraries\led_softblink;..\..\..\..\..\..\components\libraries\log;..\..\..\..\..\..\components\libraries\log\src;..\..\..\..\..\..\components\libraries\low_power_pwm;..\..\..\..\..\..\components\libraries\mem_manager;..\..\..\..\..\..\components\libraries\memobj;..\..\..\..\..\..\components\libraries\mpu;..\..\..\..\..\..\components\libraries\mutex;..\..\..\..\..\..\components\libraries\pwm;..\..\..\..\..\..\components\libraries\pwr_mgmt;..\..\..\..\..\..\components\libraries\queue;..\..\..\..\..\..\components\libraries\ringbuf;..\..\..\..\..\..\components\libraries\scheduler;..\..\..\..\..\..\components\libraries\sdcard;..\..\..\..\..\..\components\libraries\slip;..\..\..\..\..\..\components\libraries\sortlist;..\..\..\..\..\..\components\libraries\spi_mngr;..\..\..\..\..\..\components\libraries\stack_guard;..\..\..\..\..\..\components\libraries\strerror;..\..\..\..\..\..\components\libraries\svc;..\..\..\..\..\..\components\libraries\timer;..\..\..\..\..\..\components\libraries\twi_mngr;..\..\..\..\..\..\components\libraries\twi_sensor;..\..\..\..\..\..\components\libraries\uart;..\..\..\..\..\..\components\libraries\usbd;..\..\..\..\..\..\components\libraries\usbd\class\audio;..\..\..\..\..\..\components\libraries\usbd\class\cdc;..\..\..\..\..\..\components\libraries\usbd\class\cdc\acm;..\..\..\..\..\..\components\libraries\usbd\class\hid;..\..\..\..\..\..\components\libraries\usbd\class\hid\generic;..\..\..\..\..\..\components\libraries\usbd\class\hid\kbd;..\..\..\..\..\..\components\libraries\usbd\class\hid\mouse;..\..\..\..\..\..\components\libraries\usbd\class\msc;..\..\..\..\..\..\components\libraries\util;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\ac_rec_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\ble_oob_advdata_parser;..\..\..\..\..\..\components\nfc\ndef\conn_hand_parser\le_oob_rec_parser;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ac_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_oob_advdata;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_pair_lib;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ble_pair_msg;..\..\..\..\..\..\components\nfc\ndef\connection_handover\common;..\..\..\..\..\..\components\nfc\ndef\connection_handover\ep_oob_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\hs_rec;..\..\..\..\..\..\components\nfc\ndef\connection_handover\le_oob_rec;..\..\..\..\..\..\components\nfc\ndef\generic\message;..\..\..\..\..\..\components\nfc\ndef\generic\record;..\..\..\..\..\..\components\nfc\ndef\launchapp;..\..\..\..\..\..\components\nfc\ndef\parser\message;..\..\..\..\..\..\components\nfc\ndef\parser\record;..\..\..\..\..\..\components\nfc\ndef\text;..\..\..\..\..\..\components\nfc\ndef\uri;..\..\..\..\..\..\components\nfc\platform;..\..\..\..\..\..\components\nfc\t2t_lib;..\..\..\..\..\..\components\nfc\t2t_parser;..\..\..\..\..\..\components\nfc\t4t_lib;..\..\..\..\..\..\components\nfc\t4t_parser\apdu;..\..\..\..\..\..\components\nfc\t4t_parser\cc_file;..\..\..\..\..\..\components\nfc\t4t_parser\hl_detection_procedure;..\..\..\..\..\..\components\nfc\t4t_parser\tlv;..\..\..\..\..\..\components\softdevice\common;..\..\..\..\..\..\components\softdevice\s140\headers;..\..\..\..\..\..\components\softdevice\s140\headers\nrf52;..\..\..\..\..\..\external\fprintf;..\..\..\..\..\..\external\segger_rtt;..\..\..\..\..\..\external\utf_converter;..\..\..\..\..\..\integration\nrfx;..\..\..\..\..\..\integration\nrfx\legacy;..\..\..\..\..\..\modules\nrfx;..\..\..\..\..\..\modules\nrfx\drivers\include;..\..\..\..\..\..\modules\nrfx\hal;..\config;..\..\..\..\ble_app_bladder_patch;..\..\..\..\..\..\components\libraries\bootloader\dfu;..\..\..\..\..\..\components\libraries\bootloader;..\..\..\..\..\..\modules\nrfx\drivers\src;..\..\..\measurement\imu;..\..\..\measurement\imu\Invn;..\..\..\measurement\imu\Invn\EmbUtils;..\..\..\measurement\imu\Invn\imu;..\..\..\measurement\imu\Invn\lib_agm;..\..\..\measurement\imu\Invn\lib_agm\invn\common;..\..\..\measurement\imu\Invn\lib_agm\test_vector;..\..\..\..\..\..\integration\nrfx\legacy;..\..\..\measurement\imu\app_raw;..\..\..\..\..\..\components\libraries\crypto\backend\cc310;..\..\..\..\..\..\components\libraries\crypto\backend\cc310_bl;..\..\..\..\..\..\components\libraries\crypto\backend\cifra;..\..\..\..\..\..\components\libraries\crypto\backend\mbedtls;..\..\..\..\..\..\components\libraries\crypto\backend\micro_ecc;..\..\..\..\..\..\components\libraries\crypto\backend\nrf_hw;..\..\..\..\..\..\components\libraries\crypto\backend\nrf_sw;..\..\..\..\..\..\components\libraries\crypto\backend\oberon;..\..\..\..\..\..\components\libraries\crypto\backend\optiga;..\..\..\..\..\..\external\nrf_cc310\include;..\..\..\..\..\..\external\mbedtls\include;..\..\..\..\..\..\external\nrf_oberon;..\..\..\..\..\..\external\nrf_oberon\include;..\..\..\..\..\..\external\nrf_tls\mbedtls\nrf_crypto\config;..\..\..\..\..\..\components\libraries\stack_info;..\..\..\system\security;..\..\..\command;..\..\..\measurement\piezo;..\..\..\command\util;..\..\..\measurement\adc121s051;..\..\..\measurement\battery;..\..\..\measurement\temperature;..\..\..\system\led;..\..\..\system\power;..\..\..\hal\i2c;..\..\..\hal\fds;..\..\..\system;..\..\..\command\handlers @@ -458,16 +458,6 @@ 5 ..\..\..\measurement\piezo\dr_piezo.h - - dr_util.c - 1 - ..\..\..\command\util\dr_util.c - - - dr_util.h - 5 - ..\..\..\command\util\dr_util.h - dr_adc121s051.c 1 @@ -478,6 +468,36 @@ 1 ..\..\..\system\led\led_control.c + + dr_util.c + 1 + ..\..\..\command\dr_util.c + + + cmd_table.c + 1 + ..\..\..\command\cmd_table.c + + + cmd_device.c + 1 + ..\..\..\command\handlers\cmd_device.c + + + cmd_info.c + 1 + ..\..\..\command\handlers\cmd_info.c + + + cmd_piezo.c + 1 + ..\..\..\command\handlers\cmd_piezo.c + + + cmd_sensor.c + 1 + ..\..\..\command\handlers\cmd_sensor.c + @@ -4646,16 +4666,6 @@ 5 ..\..\..\measurement\piezo\dr_piezo.h - - dr_util.c - 1 - ..\..\..\command\util\dr_util.c - - - dr_util.h - 5 - ..\..\..\command\util\dr_util.h - dr_adc121s051.c 1 @@ -4666,6 +4676,36 @@ 1 ..\..\..\system\led\led_control.c + + dr_util.c + 1 + ..\..\..\command\dr_util.c + + + cmd_table.c + 1 + ..\..\..\command\cmd_table.c + + + cmd_device.c + 1 + ..\..\..\command\handlers\cmd_device.c + + + cmd_info.c + 1 + ..\..\..\command\handlers\cmd_info.c + + + cmd_piezo.c + 1 + ..\..\..\command\handlers\cmd_piezo.c + + + cmd_sensor.c + 1 + ..\..\..\command\handlers\cmd_sensor.c +