parser 분리

- 파서 인프라/커맨드 핸들러로 분리
- 커맨드 핸들러는 기기 제어/기기 정보/센서/Piezo로 분리
This commit is contained in:
2026-04-16 01:28:11 +09:00
parent c11ce4ec3e
commit c98d9ae14e
18 changed files with 1469 additions and 1410 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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 */
}

View File

@@ -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 */