parser 분리
- 파서 인프라/커맨드 핸들러로 분리 - 커맨드 핸들러는 기기 제어/기기 정보/센서/Piezo로 분리
This commit is contained in:
@@ -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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#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 */
|
||||
@@ -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]));
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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"
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user