주석 정리

This commit is contained in:
2026-06-30 18:20:39 +09:00
parent a01c0fb01b
commit 822789ff82
5 changed files with 92 additions and 15 deletions
+11 -5
View File
@@ -2,28 +2,34 @@
cmake_minimum_required(VERSION 3.20.0)
macro(app_set_runner_args)
board_runner_args(nrfutil "--erase-mode=ranges")
endmacro()
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(vesiscan)
target_include_directories(app PRIVATE
src
src/command
src/command/handlers
src/ble
src/drivers/battery
src/drivers/echo_adc
src/drivers/led
src/drivers/imu
src/drivers/piezo
src/measurement
)
target_sources(app PRIVATE
src/main.c
src/app_nvs.c
src/parser.c
src/command/parser.c
src/command/cmd_common.c
src/command/cmd_table.c
src/command/handlers/cmd_device.c
src/command/handlers/cmd_info.c
src/command/handlers/cmd_piezo.c
src/command/handlers/cmd_sensor.c
src/power_control.c
src/measurement/piezo_measure.c
src/ble/ble_service.c
src/drivers/battery/battery_adc.c
src/drivers/echo_adc/echo_adc.c
+15 -4
View File
@@ -15,6 +15,9 @@
#include "ble_service.h"
#include "cmd_device.h"
/*
* msq: power off
*/
int cmd_msq(const uint8_t *data, uint8_t data_len)
{
ARG_UNUSED(data);
@@ -31,6 +34,9 @@ int cmd_msq(const uint8_t *data, uint8_t data_len)
return 1;
}
/*
* mss: reboot
*/
int cmd_mss(const uint8_t *data, uint8_t data_len)
{
ARG_UNUSED(data);
@@ -47,6 +53,9 @@ int cmd_mss(const uint8_t *data, uint8_t data_len)
return 1;
}
/*
* msr: clear bond data and reboot
*/
int cmd_msr(const uint8_t *data, uint8_t data_len)
{
uint16_t status = 0x0000;
@@ -62,8 +71,8 @@ int cmd_msr(const uint8_t *data, uint8_t data_len)
}
/*
* 현재 연결의 bond/security 정보를 먼저 지우면 같은 연결에서 rsr: 응답을
* 보낼 수 없음. 응답 전송 완료 후 bond 삭제와 reboot 진행 필요
* 현재 연결의 bond/security 정보를 먼저 지우면 같은 연결에서 rsr: 응답을 보낼 수 없음
* 응답 전송 완료 후 bond 삭제와 reboot 진행 필요
*/
k_msleep(100);
@@ -93,7 +102,9 @@ int cmd_msr(const uint8_t *data, uint8_t data_len)
return 1;
}
/* msp? → IMU 1회 측정 → rsp: + accel XYZ + gyro XYZ (각 int16 빅엔디안) */
/*
* mdf: DFU mode enter
*/
int cmd_mdf(const uint8_t *data, uint8_t data_len)
{
ARG_UNUSED(data);
@@ -101,7 +112,7 @@ int cmd_mdf(const uint8_t *data, uint8_t data_len)
uint16_t status = ble_dfu_advertising_is_enabled() ? 0xFFFF : 0x0000;
/* DFU advertising 전환 중 연결이 끊겨도 전원 래치가 유지되도록 먼저 ON 상태를 확정한다. */
/* DFU advertising 전환 중 연결이 끊겨도 전원 래치가 유지되도록 먼저 ON 상태를 확정 */
device_power_keep_on();
int tx_err = cmd_send_response_u16("rdf:", status);
+1 -3
View File
@@ -76,9 +76,7 @@ int imu_fifo_start(void);
* @param out_count 실제 저장한 샘플 수
* @return 0 성공, 음수 에러
*/
int imu_fifo_read_latest(uint8_t *sample_bytes,
uint16_t max_samples,
uint16_t *out_count);
int imu_fifo_read_latest(uint8_t *sample_bytes, uint16_t max_samples, uint16_t *out_count);
/**
* @brief Return whether IMU FIFO streaming is active.
+3 -3
View File
@@ -246,7 +246,7 @@ void piezo_burst_sw(uint8_t cycles)
/* 구동 Enable 전 초기 Low 정렬 */
NRF_P0->OUTCLR = piezo_pe_mask;
NRF_P1->OUT = p1_all_low;
NRF_P0->OUTSET = piezo_pe_mask;
NRF_P0->OUTSET = piezo_pe_mask; /* PE High */
for (uint8_t i = 0; i < cycles; i++)
{
@@ -261,10 +261,10 @@ void piezo_burst_sw(uint8_t cycles)
/* 잔류 전하 방전 */
NRF_P1->OUT = p1_dmp_high;
nop_delay_32();
nop_delay_32(); /* DMP High 폭 */
/* 출력 Low 복귀 */
NRF_P1->OUT = p1_all_low;
NRF_P0->OUTCLR = piezo_pe_mask;
NRF_P0->OUTCLR = piezo_pe_mask; /* PE Low */
irq_unlock(key);
}
+62
View File
@@ -10,12 +10,14 @@
#include "app_nvs.h"
#include "debug_print.h"
/* 앱에서 저장/변경 가능한 piezo 측정 기본값 */
#define PIEZO_CFG_FREQ_DEFAULT 1
#define PIEZO_CFG_CYCLES_DEFAULT 7
#define PIEZO_CFG_DELAY_DEFAULT 10
#define PIEZO_CFG_SAMPLES_DEFAULT 100
#define PIEZO_CFG_AVG_DEFAULT 3
/* 설정값 검증 범위 */
#define PIEZO_CFG_AVG_MAX 10
#define PIEZO_CFG_SAMPLES_MIN 80
#define PIEZO_CFG_SAMPLES_MAX 117
@@ -24,10 +26,16 @@
#define PIEZO_AVG_INTER_BURST_GAP_US 500
#define PIEZO_DUMMY_CAPTURE_COUNT 5
/* 6채널 sweep 결과 (각 채널의 평균 완료 후 최종만 저장) */
static uint16_t piezo_channels[PIEZO_NUM_CHANNELS][PIEZO_MEASURE_MAX_SAMPLES];
/* 단일 capture 임시 버퍼 (dummy capture와 real capture 모두 이 버퍼 재사용) */
static uint16_t echo_capture[PIEZO_MEASURE_MAX_SAMPLES];
/* 평균 누적 버퍼 (uint16 샘플을 avg 횟수만큼 더하므로 overflow 여유를 위해 uint32) */
static uint32_t echo_accum[PIEZO_MEASURE_MAX_SAMPLES];
/* NVS에서 읽어 오거나 mcs? 명령으로 갱신되는 현재 측정 설정 */
static piezo_config_t g_piezo_config = {
.freq = PIEZO_CFG_FREQ_DEFAULT,
.cycles = PIEZO_CFG_CYCLES_DEFAULT,
@@ -36,6 +44,9 @@ static piezo_config_t g_piezo_config = {
.samples = PIEZO_CFG_SAMPLES_DEFAULT,
};
/*
* 저장/측정에 사용할 piezo 설정값 검증
*/
bool piezo_config_validate(const piezo_config_t *cfg)
{
if (cfg == NULL)
@@ -77,6 +88,9 @@ const piezo_config_t *piezo_config_get(void)
return &g_piezo_config;
}
/*
* 부팅 시 NVS 설정 읽기 (없거나 유효하지 않으면 기본값 유지)
*/
int piezo_config_init(void)
{
int err = app_nvs_init(&g_piezo_config, piezo_config_validate, NULL);
@@ -88,6 +102,9 @@ int piezo_config_init(void)
return 0;
}
/*
* 런타임 설정 변경: RAM 설정을 갱신한 뒤 NVS에도 저장
*/
int piezo_config_set(const piezo_config_t *cfg)
{
if (!piezo_config_validate(cfg))
@@ -99,6 +116,9 @@ int piezo_config_set(const piezo_config_t *cfg)
return app_nvs_save_piezo(&g_piezo_config);
}
/*
* sweep 명령이 끝난 뒤 BLE 응답에서 채널별 결과 버퍼 참조 시 사용
*/
const uint16_t *piezo_measure_channel_buffer(uint8_t channel)
{
if (channel >= PIEZO_NUM_CHANNELS)
@@ -109,11 +129,18 @@ const uint16_t *piezo_measure_channel_buffer(uint8_t channel)
return piezo_channels[channel];
}
/*
* mec?/mad? 같은 단일 채널 명령의 최종 결과 버퍼 반환
*/
const uint16_t *piezo_measure_single_buffer(void)
{
return echo_capture;
}
/*
* piezo 측정 공통 준비 단계
* 전원 인가, piezo GPIO 초기화, echo ADC 초기화/wake를 한 번에 수행
*/
int piezo_measure_start_session(void)
{
DBG_PRINTF("[MBB] piezo session start\r\n");
@@ -146,11 +173,16 @@ int piezo_measure_start_session(void)
return ECHO_STATUS_OK;
}
/*
* 6채널 전체 sweep
* 각 채널마다 dummy capture를 먼저 버린 뒤, cfg->avg회 real capture를 sample index별로 평균
*/
int piezo_measure_sweep(void)
{
const piezo_config_t *cfg = piezo_config_get();
uint16_t capture_delay_us = cfg->delay_us;
/* 너무 짧은 delay가 들어오면 burst 직후 ADC capture가 겹치므로 최소 delay 보장 */
if (capture_delay_us < PIEZO_BURST_TO_ADC_DELAY_US)
{
capture_delay_us = PIEZO_BURST_TO_ADC_DELAY_US;
@@ -160,6 +192,10 @@ int piezo_measure_sweep(void)
{
DBG_PRINTF("[MBB] sweep ch=%d start\r\n", ch);
/*
* MUX 채널 선택
* 드라이버 내부에서 1.3 ms settle을 기다리고, 아래에서 measurement layer settle 0.5 ms를 추가로 기다린다.
*/
int err = piezo_select_channel(ch);
if (err)
{
@@ -169,6 +205,7 @@ int piezo_measure_sweep(void)
k_busy_wait(PIEZO_POST_SELECT_SETTLE_US);
/* ADC dummy read/wake (채널 전환 직후 첫 ADC 접근을 실제 데이터에 섞지 않기 위한 준비 단계) */
err = echo_adc_wake();
if (err)
{
@@ -176,6 +213,10 @@ int piezo_measure_sweep(void)
return ECHO_STATUS_CAPTURE;
}
/*
* Dummy burst + dummy capture
* 결과는 버리고, piezo/mux/ADC 입력의 이전 상태가 real 평균에 섞이지 않도록 함
*/
for (uint8_t dummy = 0; dummy < PIEZO_DUMMY_CAPTURE_COUNT; dummy++)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
@@ -190,6 +231,10 @@ int piezo_measure_sweep(void)
}
}
/* 마지막 dummy capture와 첫 real capture 사이에도 같은 회복 시간을 둔다. */
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
/* 여기부터 실제 평균에 들어갈 capture */
memset(echo_accum, 0, sizeof(echo_accum));
for (uint16_t avg = 0; avg < cfg->avg; avg++)
@@ -199,6 +244,7 @@ int piezo_measure_sweep(void)
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
}
/* burst-to-capture 사이 타이밍 흔들림을 줄이기 위해 real capture 구간만 IRQ를 잠금 */
unsigned int key = irq_lock();
piezo_burst_sw((uint8_t)cfg->cycles);
k_busy_wait(capture_delay_us);
@@ -211,12 +257,14 @@ int piezo_measure_sweep(void)
return ECHO_STATUS_CAPTURE;
}
/* 같은 sample index끼리 누적 */
for (uint16_t i = 0; i < cfg->samples; i++)
{
echo_accum[i] += echo_capture[i];
}
}
/* 채널별 최종 평균 파형 저장 - 이후 cmd handler가 reb: 패킷으로 전송 */
for (uint16_t i = 0; i < cfg->samples; i++)
{
piezo_channels[ch][i] = (uint16_t)(echo_accum[i] / cfg->avg);
@@ -229,6 +277,10 @@ int piezo_measure_sweep(void)
return ECHO_STATUS_OK;
}
/*
* 단일 채널 burst + echo capture
* mec? 디버그/테스트 명령에서 사용하며, 결과는 echo_capture에 평균 저장된다.
*/
int piezo_measure_single_capture(uint8_t cycles,
uint16_t delay_us,
uint16_t num_samples,
@@ -245,6 +297,7 @@ int piezo_measure_single_capture(uint8_t cycles,
return ECHO_STATUS_CAPTURE;
}
/* averaging 0은 명령 파라미터 누락/미지정으로 보고 1회 capture로 보정한다. */
if (averaging == 0U)
{
averaging = 1U;
@@ -264,6 +317,7 @@ int piezo_measure_single_capture(uint8_t cycles,
return ECHO_STATUS_CAPTURE;
}
/* real capture 전에 같은 채널에서 dummy burst/capture를 수행하고 버린다. */
for (uint8_t dummy = 0; dummy < PIEZO_DUMMY_CAPTURE_COUNT; dummy++)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
@@ -277,6 +331,9 @@ int piezo_measure_single_capture(uint8_t cycles,
}
}
/* 마지막 dummy capture와 첫 real capture 사이에도 같은 회복 시간을 둔다. */
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
memset(echo_accum, 0, sizeof(echo_accum));
for (uint16_t avg = 0; avg < averaging; avg++)
@@ -311,6 +368,10 @@ int piezo_measure_single_capture(uint8_t cycles,
return ECHO_STATUS_OK;
}
/*
* 단일 채널 ADC-only capture.
* piezo burst 없이 현재 echo ADC 입력만 평균해서 확인할 때 사용한다.
*/
int piezo_measure_adc_only_capture(uint16_t num_samples,
uint16_t averaging,
uint8_t channel)
@@ -353,6 +414,7 @@ int piezo_measure_adc_only_capture(uint16_t num_samples,
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
}
/* burst가 없으므로 ADC capture 자체의 간섭만 줄이기 위해 짧게 IRQ를 잠근다. */
unsigned int key = irq_lock();
err = echo_adc_capture(echo_capture, num_samples);
irq_unlock(key);