주석 정리
This commit is contained in:
+11
-5
@@ -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,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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user