piezo_measure 파일 분리

- parser.c: BLE 커맨드 파싱/측정 함수 호출/응담 패킷 생성 및 전송
- piezo.c: Piezo 관련 GPIO 제어
- piezo_measure.c: 실제 측정 시퀀스
This commit is contained in:
2026-06-30 15:38:32 +09:00
parent 3207caa3bf
commit 9b042dfef2
5 changed files with 455 additions and 385 deletions
+376
View File
@@ -0,0 +1,376 @@
/*******************************************************************************
* @file piezo_measure.c
* @brief Piezo echo measurement sequencing
******************************************************************************/
#include <zephyr/kernel.h>
#include <errno.h>
#include <string.h>
#include "piezo_measure.h"
#include "app_nvs.h"
#include "debug_print.h"
#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
#define PIEZO_CFG_DELAY_MAX_US 50
#define PIEZO_POST_SELECT_SETTLE_US 500
#define PIEZO_AVG_INTER_BURST_GAP_US 500
#define PIEZO_DUMMY_CAPTURE_COUNT 5
static uint16_t piezo_channels[PIEZO_NUM_CHANNELS][PIEZO_MEASURE_MAX_SAMPLES];
static uint16_t echo_capture[PIEZO_MEASURE_MAX_SAMPLES];
static uint32_t echo_accum[PIEZO_MEASURE_MAX_SAMPLES];
static piezo_config_t g_piezo_config = {
.freq = PIEZO_CFG_FREQ_DEFAULT,
.cycles = PIEZO_CFG_CYCLES_DEFAULT,
.avg = PIEZO_CFG_AVG_DEFAULT,
.delay_us = PIEZO_CFG_DELAY_DEFAULT,
.samples = PIEZO_CFG_SAMPLES_DEFAULT,
};
bool piezo_config_validate(const piezo_config_t *cfg)
{
if (cfg == NULL)
{
return false;
}
if (cfg->freq != PIEZO_CFG_FREQ_DEFAULT)
{
return false;
}
if ((cfg->cycles < 3U) || (cfg->cycles > 7U))
{
return false;
}
if ((cfg->avg == 0U) || (cfg->avg > PIEZO_CFG_AVG_MAX))
{
return false;
}
if (cfg->delay_us > PIEZO_CFG_DELAY_MAX_US)
{
return false;
}
if ((cfg->samples < PIEZO_CFG_SAMPLES_MIN) ||
(cfg->samples > PIEZO_CFG_SAMPLES_MAX))
{
return false;
}
return true;
}
const piezo_config_t *piezo_config_get(void)
{
return &g_piezo_config;
}
int piezo_config_init(void)
{
int err = app_nvs_init(&g_piezo_config, piezo_config_validate, NULL);
if (err)
{
return err;
}
return 0;
}
int piezo_config_set(const piezo_config_t *cfg)
{
if (!piezo_config_validate(cfg))
{
return -EINVAL;
}
g_piezo_config = *cfg;
return app_nvs_save_piezo(&g_piezo_config);
}
const uint16_t *piezo_measure_channel_buffer(uint8_t channel)
{
if (channel >= PIEZO_NUM_CHANNELS)
{
return NULL;
}
return piezo_channels[channel];
}
const uint16_t *piezo_measure_single_buffer(void)
{
return echo_capture;
}
int piezo_measure_start_session(void)
{
DBG_PRINTF("[MBB] piezo session start\r\n");
int err = piezo_init();
if (err)
{
DBG_PRINTF("[PIEZO] init fail err=%d\r\n", err);
return ECHO_STATUS_PIEZO;
}
piezo_power_on();
k_msleep(PIEZO_POWER_STABILIZE_MS);
err = echo_adc_init();
if (err)
{
DBG_PRINTF("[ECHO] init fail err=%d\r\n", err);
return ECHO_STATUS_ADC_INIT;
}
err = echo_adc_wake();
if (err)
{
DBG_PRINTF("[ECHO] wake fail err=%d\r\n", err);
return ECHO_STATUS_ADC_INIT;
}
DBG_PRINTF("[MBB] piezo session ready\r\n");
return ECHO_STATUS_OK;
}
int piezo_measure_sweep(void)
{
const piezo_config_t *cfg = piezo_config_get();
uint16_t capture_delay_us = cfg->delay_us;
if (capture_delay_us < PIEZO_BURST_TO_ADC_DELAY_US)
{
capture_delay_us = PIEZO_BURST_TO_ADC_DELAY_US;
}
for (uint8_t ch = 0; ch < PIEZO_NUM_CHANNELS; ch++)
{
DBG_PRINTF("[MBB] sweep ch=%d start\r\n", ch);
int err = piezo_select_channel(ch);
if (err)
{
DBG_PRINTF("[PIEZO] mux fail ch=%d err=%d\r\n", ch, err);
return ECHO_STATUS_MUX;
}
k_busy_wait(PIEZO_POST_SELECT_SETTLE_US);
err = echo_adc_wake();
if (err)
{
DBG_PRINTF("[ECHO] dummy read fail ch=%d err=%d\r\n", ch, err);
return ECHO_STATUS_CAPTURE;
}
for (uint8_t dummy = 0; dummy < PIEZO_DUMMY_CAPTURE_COUNT; dummy++)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
piezo_burst_sw((uint8_t)cfg->cycles);
k_busy_wait(capture_delay_us);
err = echo_adc_capture(echo_capture, cfg->samples);
if (err)
{
DBG_PRINTF("[ECHO] dummy capture fail ch=%d dummy=%d err=%d\r\n", ch, dummy, err);
return ECHO_STATUS_CAPTURE;
}
}
memset(echo_accum, 0, sizeof(echo_accum));
for (uint16_t avg = 0; avg < cfg->avg; avg++)
{
if (avg > 0U)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
}
unsigned int key = irq_lock();
piezo_burst_sw((uint8_t)cfg->cycles);
k_busy_wait(capture_delay_us);
err = echo_adc_capture(echo_capture, cfg->samples);
irq_unlock(key);
if (err)
{
DBG_PRINTF("[ECHO] capture fail ch=%d avg=%d err=%d\r\n", ch, avg, err);
return ECHO_STATUS_CAPTURE;
}
for (uint16_t i = 0; i < cfg->samples; i++)
{
echo_accum[i] += echo_capture[i];
}
}
for (uint16_t i = 0; i < cfg->samples; i++)
{
piezo_channels[ch][i] = (uint16_t)(echo_accum[i] / cfg->avg);
}
DBG_PRINTF("[MBB] sweep ch=%d done\r\n", ch);
}
DBG_PRINTF("[MBB] sweep done\r\n");
return ECHO_STATUS_OK;
}
int piezo_measure_single_capture(uint8_t cycles,
uint16_t delay_us,
uint16_t num_samples,
uint16_t averaging,
uint8_t channel)
{
if (channel >= PIEZO_NUM_CHANNELS)
{
return ECHO_STATUS_MUX;
}
if ((num_samples == 0U) || (num_samples > PIEZO_MEASURE_MAX_SAMPLES))
{
return ECHO_STATUS_CAPTURE;
}
if (averaging == 0U)
{
averaging = 1U;
}
int err = piezo_select_channel(channel);
if (err)
{
return ECHO_STATUS_MUX;
}
k_busy_wait(PIEZO_POST_SELECT_SETTLE_US);
err = echo_adc_wake();
if (err)
{
return ECHO_STATUS_CAPTURE;
}
for (uint8_t dummy = 0; dummy < PIEZO_DUMMY_CAPTURE_COUNT; dummy++)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
piezo_burst_sw(cycles);
k_busy_wait(delay_us);
err = echo_adc_capture(echo_capture, num_samples);
if (err)
{
return ECHO_STATUS_CAPTURE;
}
}
memset(echo_accum, 0, sizeof(echo_accum));
for (uint16_t avg = 0; avg < averaging; avg++)
{
if (avg > 0U)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
}
unsigned int key = irq_lock();
piezo_burst_sw(cycles);
k_busy_wait(delay_us);
err = echo_adc_capture(echo_capture, num_samples);
irq_unlock(key);
if (err)
{
return ECHO_STATUS_CAPTURE;
}
for (uint16_t i = 0; i < num_samples; i++)
{
echo_accum[i] += echo_capture[i];
}
}
for (uint16_t i = 0; i < num_samples; i++)
{
echo_capture[i] = (uint16_t)(echo_accum[i] / averaging);
}
return ECHO_STATUS_OK;
}
int piezo_measure_adc_only_capture(uint16_t num_samples,
uint16_t averaging,
uint8_t channel)
{
if (channel >= PIEZO_NUM_CHANNELS)
{
return ECHO_STATUS_MUX;
}
if ((num_samples == 0U) || (num_samples > PIEZO_MEASURE_MAX_SAMPLES))
{
return ECHO_STATUS_CAPTURE;
}
if (averaging == 0U)
{
averaging = 1U;
}
int err = piezo_select_channel(channel);
if (err)
{
return ECHO_STATUS_MUX;
}
k_busy_wait(PIEZO_POST_SELECT_SETTLE_US);
err = echo_adc_wake();
if (err)
{
return ECHO_STATUS_CAPTURE;
}
memset(echo_accum, 0, sizeof(echo_accum));
for (uint16_t avg = 0; avg < averaging; avg++)
{
if (avg > 0U)
{
k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US);
}
unsigned int key = irq_lock();
err = echo_adc_capture(echo_capture, num_samples);
irq_unlock(key);
if (err)
{
return ECHO_STATUS_CAPTURE;
}
for (uint16_t i = 0; i < num_samples; i++)
{
echo_accum[i] += echo_capture[i];
}
}
for (uint16_t i = 0; i < num_samples; i++)
{
echo_capture[i] = (uint16_t)(echo_accum[i] / averaging);
}
return ECHO_STATUS_OK;
}
+53
View File
@@ -0,0 +1,53 @@
/*******************************************************************************
* @file piezo_measure.h
* @brief Piezo echo measurement sequencing
******************************************************************************/
#ifndef PIEZO_MEASURE_H__
#define PIEZO_MEASURE_H__
#include <stdbool.h>
#include <stdint.h>
#include "echo_adc.h"
#include "piezo.h"
#define PIEZO_MEASURE_MAX_SAMPLES ECHO_ADC_MAX_SAMPLES
#define ECHO_STATUS_OK 0x0000
#define ECHO_STATUS_PIEZO 0x0001
#define ECHO_STATUS_ADC_INIT 0x0002
#define ECHO_STATUS_MUX 0x0003
#define ECHO_STATUS_CAPTURE 0x0004
#define ECHO_STATUS_BATT 0x0005
#define ECHO_STATUS_IMU 0x0006
#define ECHO_STATUS_TEMP 0x0007
typedef struct
{
uint16_t freq;
uint16_t cycles;
uint16_t avg;
uint16_t delay_us;
uint16_t samples;
} piezo_config_t;
int piezo_config_init(void);
bool piezo_config_validate(const piezo_config_t *cfg);
const piezo_config_t *piezo_config_get(void);
int piezo_config_set(const piezo_config_t *cfg);
int piezo_measure_start_session(void);
int piezo_measure_sweep(void);
int piezo_measure_single_capture(uint8_t cycles,
uint16_t delay_us,
uint16_t num_samples,
uint16_t averaging,
uint8_t channel);
int piezo_measure_adc_only_capture(uint16_t num_samples,
uint16_t averaging,
uint8_t channel);
const uint16_t *piezo_measure_channel_buffer(uint8_t channel);
const uint16_t *piezo_measure_single_buffer(void);
#endif /* PIEZO_MEASURE_H__ */