diff --git a/src/command/handlers/cmd_piezo.c b/src/command/handlers/cmd_piezo.c index 74fe490..a90ce48 100644 --- a/src/command/handlers/cmd_piezo.c +++ b/src/command/handlers/cmd_piezo.c @@ -353,8 +353,6 @@ int cmd_mpc(const uint8_t *data, uint8_t data_len) cmd_get_data_u16_be(data, data_len, 1, &freq_option); cmd_get_data_u16_be(data, data_len, 2, &piezo_ch); - ARG_UNUSED(freq_option); - if ((cycles < 3U) || (cycles > 7U)) { cmd_send_response_u16("rpc:", 2); @@ -380,8 +378,7 @@ int cmd_mpc(const uint8_t *data, uint8_t data_len) return 1; } - // 현재 2.1MHz 고정 - piezo_burst_sw((uint8_t)cycles); + piezo_burst_sw_freq((uint8_t)freq_option, cycles); piezo_power_off(); power_button_suspend(false); @@ -411,8 +408,6 @@ int cmd_mec(const uint8_t *data, uint8_t data_len) cmd_get_data_u16_be(data, data_len, 4, &averaging); cmd_get_data_u16_be(data, data_len, 5, &piezo_ch); - ARG_UNUSED(freq_option); - if (num_samples > PIEZO_MEASURE_MAX_SAMPLES) { num_samples = PIEZO_MEASURE_MAX_SAMPLES; @@ -432,7 +427,7 @@ int cmd_mec(const uint8_t *data, uint8_t data_len) int status = piezo_measure_start_session(); if (status == ECHO_STATUS_OK) { - status = piezo_measure_single_capture((uint8_t)cycles, delay_us, num_samples, averaging, (uint8_t)(piezo_ch % PIEZO_NUM_CHANNELS)); + status = piezo_measure_single_capture((uint8_t)freq_option, cycles, delay_us, num_samples, averaging, (uint8_t)(piezo_ch % PIEZO_NUM_CHANNELS)); } if (status == ECHO_STATUS_OK) diff --git a/src/drivers/piezo/piezo.c b/src/drivers/piezo/piezo.c index c5d3900..474856d 100644 --- a/src/drivers/piezo/piezo.c +++ b/src/drivers/piezo/piezo.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -23,7 +24,7 @@ #define MUX_SEL0_NODE DT_NODELABEL(mux_sel0) #define MUX_SEL1_NODE DT_NODELABEL(mux_sel1) -/* 피에조 전원/구동 GPIO */ +/* Piezo 전원/구동 GPIO */ static const struct gpio_dt_spec piezo_pwr = GPIO_DT_SPEC_GET(PIEZO_PWR_NODE, gpios); static const struct gpio_dt_spec piezo_pe = GPIO_DT_SPEC_GET(PIEZO_PE_NODE, gpios); static const struct gpio_dt_spec piezo_p_out = GPIO_DT_SPEC_GET(PIEZO_P_OUT_NODE, gpios); @@ -36,7 +37,7 @@ static const struct gpio_dt_spec mux_en_b = GPIO_DT_SPEC_GET(MUX_EN_B_NODE, g static const struct gpio_dt_spec mux_sel0 = GPIO_DT_SPEC_GET(MUX_SEL0_NODE, gpios); static const struct gpio_dt_spec mux_sel1 = GPIO_DT_SPEC_GET(MUX_SEL1_NODE, gpios); -/* MUX 제어 상태 */ +/* MUX 제어 핀 */ struct mux_state { uint8_t en_a; uint8_t en_b; @@ -44,7 +45,7 @@ struct mux_state { uint8_t sel1; }; -/* 채널별 MUX EN/SEL 조합 */ +/* MUX EN/SEL 조합 */ static const struct mux_state mux_map[PIEZO_NUM_CHANNELS] = { {1, 0, 0, 0}, {1, 0, 1, 0}, @@ -56,58 +57,32 @@ static const struct mux_state mux_map[PIEZO_NUM_CHANNELS] = { static bool piezo_initialized; -/* 빠른 GPIO 제어용 절대 핀 */ +/* 빠른 GPIO ?�어???��? ?�?*/ static uint32_t piezo_pe_abs; static uint32_t piezo_p_out_abs; static uint32_t piezo_n_out_abs; static uint32_t piezo_dmp_abs; -/* 포트 OUT 직접 갱신용 비트 마스크 */ +/* PE, P OUT, N OUT, DMP 비트 마스크 */ static uint32_t piezo_pe_mask; static uint32_t piezo_p_out_mask; static uint32_t piezo_n_out_mask; static uint32_t piezo_dmp_mask; -/* 포트 포함 절대 핀 번호 */ +/* GPIO 포트를 포함한 nRF 절대 핀 번호 계산 */ static uint32_t gpio_abs_pin(const struct gpio_dt_spec *spec) { uint32_t port = (spec->port == DEVICE_DT_GET(DT_NODELABEL(gpio1))) ? 1U : 0U; return NRF_GPIO_PIN_MAP(port, spec->pin); } -/* 버스트 타이밍용 1사이클 지연 */ +/* BURST 타이밍용 1 사이클 지연(1 burst_nop = 15.625 ns) */ static inline void burst_nop(void) { __asm__ volatile("nop"); } -/* 짧은 반주기 보정 지연 */ -static inline void nop_delay_9(void) -{ - burst_nop(); burst_nop(); burst_nop(); - burst_nop(); burst_nop(); burst_nop(); - burst_nop(); burst_nop(); burst_nop(); -} - -/* 긴 반주기 보정 지연 */ -static inline void nop_delay_14(void) -{ - burst_nop(); burst_nop(); burst_nop(); burst_nop(); - burst_nop(); burst_nop(); burst_nop(); burst_nop(); - burst_nop(); burst_nop(); burst_nop(); burst_nop(); - burst_nop(); burst_nop(); -} - -/* 댐핑 펄스 폭 지연 */ -static inline void nop_delay_32(void) -{ - for (int i = 0; i < 32; i++) - { - burst_nop(); - } -} - -/* 출력/MUX 안전 대기 상태 */ +/* 출력/MUX 핀 초기 상태 */ static void piezo_drive_idle(void) { nrf_gpio_pin_clear(piezo_pe_abs); @@ -123,7 +98,6 @@ static void piezo_drive_idle(void) int piezo_init(void) { - // 중복 초기화 방지 if (piezo_initialized) { return 0; @@ -138,7 +112,6 @@ int piezo_init(void) for (size_t i = 0; i < ARRAY_SIZE(pins); i++) { - // GPIO 포트 준비 확인 if (!device_is_ready(pins[i]->port)) { DBG_PRINTF("[PIEZO] GPIO device not ready (%d)\r\n", (int)i); @@ -154,7 +127,6 @@ int piezo_init(void) } } - // 직접 제어용 핀/마스크 캐시 piezo_pe_abs = gpio_abs_pin(&piezo_pe); piezo_p_out_abs = gpio_abs_pin(&piezo_p_out); piezo_n_out_abs = gpio_abs_pin(&piezo_n_out); @@ -172,25 +144,21 @@ int piezo_init(void) void piezo_power_on(void) { - // 필요 시 자동 초기화 if (!piezo_initialized && piezo_init() != 0) { return; } - // 피에조 전원 인가 gpio_pin_set_dt(&piezo_pwr, 1); } void piezo_power_off(void) { - // 필요 시 자동 초기화 if (!piezo_initialized && piezo_init() != 0) { return; } - // 출력 정지 후 전원 차단 piezo_drive_idle(); gpio_pin_set_dt(&piezo_pwr, 0); } @@ -198,7 +166,6 @@ void piezo_power_off(void) /* Piezo 채널 선택 */ int piezo_select_channel(uint8_t channel) { - // 필요 시 자동 초기화 if (!piezo_initialized) { int err = piezo_init(); @@ -220,24 +187,24 @@ int piezo_select_channel(uint8_t channel) gpio_pin_set_dt(&mux_sel0, mux_map[channel].sel0); gpio_pin_set_dt(&mux_sel1, mux_map[channel].sel1); - // MUX 안정화 대기 + // MUX 안정화 딜레이 k_busy_wait(PIEZO_MUX_SETTLE_US); return 0; } -/* Piezo Burst Switching : 현재는 2.1MHz 고정, 1.8~2.2MHz 추가 예정 */ -void piezo_burst_sw(uint8_t cycles) +/* Piezo Burst Switching : 1.8~2.3MHz */ +void piezo_burst_sw_freq(uint8_t freq, uint8_t cycles) { - // 초기화/횟수 검사 + // 초기 상태 검사 if (!piezo_initialized || cycles == 0U) { return; } - // 타이밍 흔들림 방지 + // 인터럽트 lock unsigned int key = irq_lock(); - // P1 비제어 핀 상태 보존 + // P1 상태 설정 uint32_t saved_p1_out = NRF_P1->OUT; uint32_t p1_ctrl_mask = piezo_p_out_mask | piezo_n_out_mask | piezo_dmp_mask; uint32_t p1_all_low = saved_p1_out & ~p1_ctrl_mask; @@ -245,27 +212,180 @@ void piezo_burst_sw(uint8_t cycles) uint32_t p1_p_low_n_high = p1_all_low | piezo_n_out_mask; uint32_t p1_dmp_high = p1_all_low | piezo_dmp_mask; - // 구동 Enable 전 초기 Low 정렬 + // 초기 상태 all Low NRF_P0->OUTCLR = piezo_pe_mask; NRF_P1->OUT = p1_all_low; NRF_P0->OUTSET = piezo_pe_mask; // PE High - for (uint8_t i = 0; i < cycles; i++) - { - // P High / N Low - NRF_P1->OUT = p1_p_high_n_low; - nop_delay_14(); + // PE High ~ P High 사이 딜레이(첫 TX pulse 밀림 방지, 약 1.5 us) + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); - // P Low / N High - NRF_P1->OUT = p1_p_low_n_high; - nop_delay_9(); + // 주파수별 분기(P, N) + switch (freq) + { + case PIEZO_FREQ_1_8MHZ: // 1.8 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 17 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); + + // P Low / N High = 12 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + } + break; + + case PIEZO_FREQ_1_9MHZ: // 1.9 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 16 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + + // P Low / N High = 11 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); + } + break; + + case PIEZO_FREQ_2_0MHZ: // 2.0 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 16 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + + // P Low / N High = 10 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); + } + break; + + case PIEZO_FREQ_2_1MHZ: // 2.1 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 14 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); + + // P Low / N High =9 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); + } + break; + + case PIEZO_FREQ_2_2MHZ: // 2.2 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 13 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); + + // P Low / N High = 8 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + } + break; + + default: // 2.3 MHz + for (uint8_t i = 0U; i < cycles; i++) + { + // P High / N Low = 12 + NRF_P1->OUT = p1_p_high_n_low; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + + // P Low / N High = 7 + NRF_P1->OUT = p1_p_low_n_high; + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); + } + break; } - // 잔류 전하 방전 - NRF_P1->OUT = p1_dmp_high; - nop_delay_32(); // DMP High 폭 + NRF_P1->OUT = p1_all_low; + + // dmp - 잔류 전하 방전(약 2 us) + NRF_P1->OUT = p1_dmp_high; // DMP High + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); + burst_nop(); burst_nop(); burst_nop(); burst_nop(); - // 출력 Low 복귀 NRF_P1->OUT = p1_all_low; NRF_P0->OUTCLR = piezo_pe_mask; // PE Low irq_unlock(key); diff --git a/src/drivers/piezo/piezo.h b/src/drivers/piezo/piezo.h index 83de4fb..4a9b07b 100644 --- a/src/drivers/piezo/piezo.h +++ b/src/drivers/piezo/piezo.h @@ -14,10 +14,17 @@ #define PIEZO_POWER_STABILIZE_MS 3 #define PIEZO_BURST_TO_ADC_DELAY_US 10 +#define PIEZO_FREQ_1_8MHZ 0U +#define PIEZO_FREQ_1_9MHZ 1U +#define PIEZO_FREQ_2_0MHZ 2U +#define PIEZO_FREQ_2_1MHZ 3U +#define PIEZO_FREQ_2_2MHZ 4U +#define PIEZO_FREQ_2_3MHZ 5U + int piezo_init(void); void piezo_power_on(void); void piezo_power_off(void); int piezo_select_channel(uint8_t channel); -void piezo_burst_sw(uint8_t cycles); +void piezo_burst_sw_freq(uint8_t freq, uint8_t cycles); #endif /* PIEZO_H__ */ diff --git a/src/measurement/piezo_measure.c b/src/measurement/piezo_measure.c index 9796da8..6c10410 100644 --- a/src/measurement/piezo_measure.c +++ b/src/measurement/piezo_measure.c @@ -10,14 +10,23 @@ #include "app_nvs.h" #include "debug_print.h" +/* burst 주파수 */ +#define PIEZO_CFG_FREQ_1_8MHZ 0 +#define PIEZO_CFG_FREQ_1_9MHZ 1 +#define PIEZO_CFG_FREQ_2_0MHZ 2 +#define PIEZO_CFG_FREQ_2_1MHZ 3 +#define PIEZO_CFG_FREQ_2_2MHZ 4 +#define PIEZO_CFG_FREQ_2_3MHZ 5 + /* 앱에서 저장/변경 가능한 piezo 측정 기본값 */ -#define PIEZO_CFG_FREQ_DEFAULT 1 +#define PIEZO_CFG_FREQ_DEFAULT PIEZO_CFG_FREQ_2_1MHZ #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_FREQ_MAX PIEZO_CFG_FREQ_2_3MHZ #define PIEZO_CFG_AVG_MAX 10 #define PIEZO_CFG_SAMPLES_MIN 80 #define PIEZO_CFG_SAMPLES_MAX 117 @@ -60,27 +69,27 @@ bool piezo_config_validate(const piezo_config_t *cfg) return false; } - if (cfg->freq != PIEZO_CFG_FREQ_DEFAULT) + if (cfg->freq > PIEZO_CFG_FREQ_MAX) // 주파수 : 1.8 MHz (00 00) ~ 2.3 MHz (00 05) 범위에서만 동작하도록 제한 { return false; } - if ((cfg->cycles < 3U) || (cfg->cycles > 7U)) + if ((cfg->cycles < 3U) || (cfg->cycles > 7U)) // burst cycles : 3 ~ 7 범위만 허용 { return false; } - if ((cfg->avg == 0U) || (cfg->avg > PIEZO_CFG_AVG_MAX)) + if ((cfg->avg == 0U) || (cfg->avg > PIEZO_CFG_AVG_MAX)) // averaging : 1 ~ 10 범위만 허용 { return false; } - if (cfg->delay_us > PIEZO_CFG_DELAY_MAX_US) + if (cfg->delay_us > PIEZO_CFG_DELAY_MAX_US) // burst-to-capture delay : 0 ~ 50 us 범위만 허용 { return false; } - if ((cfg->samples < PIEZO_CFG_SAMPLES_MIN) || (cfg->samples > PIEZO_CFG_SAMPLES_MAX)) + if ((cfg->samples < PIEZO_CFG_SAMPLES_MIN) || (cfg->samples > PIEZO_CFG_SAMPLES_MAX)) // sample count : 80 ~ 117 범위만 허용 { return false; } @@ -148,8 +157,6 @@ const uint16_t *piezo_measure_single_buffer(void) */ int piezo_measure_start_session(void) { - DBG_PRINTF("[SWEEP] piezo session start\r\n"); - int err = piezo_init(); if (err) { @@ -185,7 +192,12 @@ int piezo_measure_start_session(void) int piezo_measure_sweep(void) { const piezo_config_t *cfg = piezo_config_get(); + + uint8_t freq = cfg->freq; + uint8_t cycles = cfg->cycles; uint16_t capture_delay_us = cfg->delay_us; + uint16_t samples = cfg->samples; + uint8_t avg = cfg->avg; // 너무 짧은 delay가 들어오면 burst 직후 ADC capture가 겹치므로 최소 delay 보장 if (capture_delay_us < PIEZO_BURST_TO_ADC_DELAY_US) @@ -193,9 +205,11 @@ int piezo_measure_sweep(void) capture_delay_us = PIEZO_BURST_TO_ADC_DELAY_US; } + DBG_PRINTF("[SWEEP] freq=0x%04X cycles=%u avg=%u delay_us=%u samples=%u\r\n", cfg->freq, cfg->cycles, cfg->avg, cfg->delay_us, cfg->samples); + for (uint8_t ch = 0; ch < PIEZO_NUM_CHANNELS; ch++) { - DBG_PRINTF("[SWEEP] ch=%d start\r\n", ch); + //DBG_PRINTF("[SWEEP] ch=%d start\r\n", ch); // MUX 채널 선택 int err = piezo_select_channel(ch); @@ -215,16 +229,24 @@ int piezo_measure_sweep(void) return ECHO_STATUS_CAPTURE; } - if (ch == 0U) // 채널 0 시작 전에만 dummy burst 수행 TESTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + if (ch == 0U) // 채널 0 시작 전에만 dummy burst + ADC capture 수행 { // Dummy burst - ADC caputre는 수행하지 않음 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); + // 실제 측정 신호 흔들림 방지를 위해 dummy 측정에도 IRQ 잠금 적용 + unsigned int key = irq_lock(); + + // burst + delay + capture + piezo_burst_sw_freq(freq, cycles); // 주파수 옵션 있는 burst 함수 + k_busy_wait(capture_delay_us); + err = echo_adc_capture(echo_capture, samples); + + // IRQ 잠금 해제 + irq_unlock(key); + if (err) { DBG_PRINTF("[ECHO] dummy capture fail ch=%d dummy=%d err=%d\r\n", ch, dummy, err); @@ -239,7 +261,7 @@ int piezo_measure_sweep(void) // 여기부터 실제 평균에 들어갈 capture memset(echo_accum, 0, sizeof(echo_accum)); - for (uint16_t avg = 0; avg < cfg->avg; avg++) + for (uint16_t a = 0; a < avg; a++) { k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US); @@ -247,35 +269,36 @@ int piezo_measure_sweep(void) unsigned int key = irq_lock(); // burst + delay + capture - piezo_burst_sw((uint8_t)cfg->cycles); + piezo_burst_sw_freq(freq, cycles); // 주파수 옵션 있는 burst 함수 k_busy_wait(capture_delay_us); - err = echo_adc_capture(echo_capture, cfg->samples); + err = echo_adc_capture(echo_capture, samples); // IRQ 잠금 해제 irq_unlock(key); + if (err) { - DBG_PRINTF("[ECHO] capture fail ch=%d avg=%d err=%d\r\n", ch, avg, err); + DBG_PRINTF("[ECHO] capture fail ch=%d avg=%d err=%d\r\n", ch, a, err); return ECHO_STATUS_CAPTURE; } // 같은 sample index끼리 누적 - for (uint16_t i = 0; i < cfg->samples; i++) + for (uint16_t i = 0; i < samples; i++) { echo_accum[i] += echo_capture[i]; } } // 채널별 최종 평균 파형 저장 - 이후 cmd handler가 reb: 패킷으로 전송 - for (uint16_t i = 0; i < cfg->samples; i++) + for (uint16_t i = 0; i < samples; i++) { - piezo_channels[ch][i] = (uint16_t)(echo_accum[i] / cfg->avg); + piezo_channels[ch][i] = (uint16_t)(echo_accum[i] / avg); } - DBG_PRINTF("[SWEEP] ch=%d done\r\n", ch); + //DBG_PRINTF("[SWEEP] ch=%d done\r\n", ch); } - DBG_PRINTF("[SWEEP] done\r\n"); + //DBG_PRINTF("[SWEEP] done\r\n"); return ECHO_STATUS_OK; } @@ -284,7 +307,7 @@ int piezo_measure_sweep(void) * 단일 채널 burst + echo capture * mec? 디버그/테스트 명령에서 사용하며, 결과는 echo_capture에 평균 저장 */ -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_single_capture(uint8_t freq, uint8_t cycles, uint16_t delay_us, uint16_t num_samples, uint16_t averaging, uint8_t channel) { if (channel >= PIEZO_NUM_CHANNELS) { @@ -320,7 +343,7 @@ int piezo_measure_single_capture(uint8_t cycles, uint16_t delay_us, uint16_t num for (uint8_t dummy = 0; dummy < PIEZO_DUMMY_CAPTURE_COUNT; dummy++) { k_busy_wait(PIEZO_AVG_INTER_BURST_GAP_US); - piezo_burst_sw(cycles); + piezo_burst_sw_freq(freq, cycles); k_busy_wait(delay_us); err = echo_adc_capture(echo_capture, num_samples); @@ -343,11 +366,13 @@ int piezo_measure_single_capture(uint8_t cycles, uint16_t delay_us, uint16_t num } unsigned int key = irq_lock(); - piezo_burst_sw(cycles); - k_busy_wait(delay_us); + piezo_burst_sw_freq(freq, cycles); + k_busy_wait(delay_us); err = echo_adc_capture(echo_capture, num_samples); + irq_unlock(key); + if (err) { return ECHO_STATUS_CAPTURE; @@ -414,8 +439,11 @@ int piezo_measure_adc_only_capture(uint16_t num_samples, uint16_t averaging, uin // burst가 없으므로 ADC capture 자체의 간섭만 줄이기 위해 짧게 IRQ를 잠금 unsigned int key = irq_lock(); + err = echo_adc_capture(echo_capture, num_samples); + irq_unlock(key); + if (err) { return ECHO_STATUS_CAPTURE; diff --git a/src/measurement/piezo_measure.h b/src/measurement/piezo_measure.h index c3b0e66..7a44281 100644 --- a/src/measurement/piezo_measure.h +++ b/src/measurement/piezo_measure.h @@ -38,14 +38,8 @@ 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); +int piezo_measure_single_capture(uint8_t freq, 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);