From ce81cd949fe78682d4e7dbb5033f995df213ad64 Mon Sep 17 00:00:00 2001 From: jhChun Date: Wed, 18 Mar 2026 18:20:52 +0900 Subject: [PATCH] =?UTF-8?q?-=20FDS=20=ED=94=BC=EC=97=90=EC=A1=B0=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=EC=B2=B4=20=EB=B3=80=EA=B2=BD=20(pd=5Fadc=5Fcnt/pd=5Fdelay=5Fu?= =?UTF-8?q?s=20=EC=82=AD=EC=A0=9C,=20piezo=205=EA=B0=9C=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80)=20-=20maa/mbb=20=EC=95=B1=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=88=98=EC=8B=A0=20?= =?UTF-8?q?=E2=86=92=20FDS=20=EC=A0=80=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20magic=5Fnumber=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(0x20260319),=20cycles=20=EB=B2=94=EC=9C=84=203~7=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- pc_firm/dr_adc121s051/dr_adc121s051.c | 59 ++++++++++++++----- pc_firm/parser.c | 58 ++++++++++++++---- .../ble_app_bladder_patch/fstorage.c | 27 +++++---- .../ble_app_bladder_patch/fstorage.h | 8 +-- .../ble_app_bladder_patch/main.c | 4 ++ project/ble_peripheral/dr_piezo/dr_piezo.c | 14 ++--- 6 files changed, 120 insertions(+), 50 deletions(-) diff --git a/pc_firm/dr_adc121s051/dr_adc121s051.c b/pc_firm/dr_adc121s051/dr_adc121s051.c index 2aa7361..8ba5d35 100644 --- a/pc_firm/dr_adc121s051/dr_adc121s051.c +++ b/pc_firm/dr_adc121s051/dr_adc121s051.c @@ -56,6 +56,7 @@ extern void dr_piezo_power_off(void); /*============================================================================== * DEBUG CONFIGURATION *============================================================================*/ +#define DEBUG_ADC #ifdef DEBUG_ADC #include "nrf_log.h" #define ADC_LOG(...) NRF_LOG_INFO(__VA_ARGS__) @@ -1330,7 +1331,7 @@ static dr_adc_err_t maa_async_capture_channel(uint8_t ch) if (g_plat.log) g_plat.log("[maa] capturing CH%u\r\n", ch); - return dr_adc_capture_channel_only( + dr_adc_err_t err = dr_adc_capture_channel_only( g_maa_ctx.freq_option, g_maa_ctx.delay_us, g_maa_ctx.num_samples, @@ -1339,6 +1340,23 @@ static dr_adc_err_t maa_async_capture_channel(uint8_t ch) ch, &g_maa_ctx.channels[ch] ); + + /* 캡처 성공 시 원시 데이터 덤프 (10진수) */ + if (err == DR_ADC_OK && g_plat.log) + { + dr_maa_channel_t *c = &g_maa_ctx.channels[ch]; + g_plat.log("[maa] CH%u raw (%u samples):\r\n", ch, c->num_samples); + + for (uint16_t i = 0; i < c->num_samples; i++) + { + g_plat.log("%u ", c->samples[i]); + if ((i + 1) % 16 == 0) g_plat.log("\r\n"); + } + + if (c->num_samples % 16 != 0) g_plat.log("\r\n"); + } + + return err; } /** @@ -1387,9 +1405,10 @@ static bool maa_async_send_data_packet(void) { dr_maa_channel_t *ch = &g_maa_ctx.channels[g_maa_ctx.current_ch]; uint8_t *buf = g_maa_ctx.ble_buffer; - uint16_t total_data_bytes = ch->num_samples * 2; - if (g_maa_ctx.data_offset >= total_data_bytes) { + + if (g_maa_ctx.data_offset >= total_data_bytes) + { return false; /* All data sent */ } @@ -1405,7 +1424,8 @@ static bool maa_async_send_data_packet(void) /* Copy sample data */ uint16_t src_sample_idx = g_maa_ctx.data_offset / 2; uint16_t dst_idx = 6; - for (uint16_t i = 0; i < chunk_size / 2 && src_sample_idx < ch->num_samples; i++, src_sample_idx++) { + for (uint16_t i = 0; i < chunk_size / 2 && src_sample_idx < ch->num_samples; i++, src_sample_idx++) + { uint16_t sample = ch->samples[src_sample_idx]; buf[dst_idx++] = (uint8_t)(sample & 0xFF); buf[dst_idx++] = (uint8_t)(sample >> 8); @@ -1417,8 +1437,7 @@ static bool maa_async_send_data_packet(void) g_maa_ctx.data_offset += chunk_size; g_maa_ctx.current_pkt++; - ADC_LOG("maa_async: CH%u red:%u (%u/%u bytes)", - g_maa_ctx.current_ch, pkt_idx, g_maa_ctx.data_offset, total_data_bytes); + ADC_LOG("maa_async: CH%u red:%u (%u/%u bytes)", g_maa_ctx.current_ch, pkt_idx, g_maa_ctx.data_offset, total_data_bytes); return (g_maa_ctx.data_offset < total_data_bytes); } @@ -1450,7 +1469,8 @@ static void maa_async_send_completion(uint16_t status) ADC_LOG("maa_async: complete, status=0x%04X", status); /* 완료 콜백 호출 (mbb? 등에서 센서 측정 체인 트리거용) */ - if (g_maa_ctx.on_complete_cb) { + if (g_maa_ctx.on_complete_cb) + { void (*cb)(void) = g_maa_ctx.on_complete_cb; g_maa_ctx.on_complete_cb = NULL; /* 1회성: 재호출 방지 */ cb(); @@ -1465,7 +1485,8 @@ dr_adc_err_t maa_async_start(uint8_t freq_option, uint16_t delay_us, uint16_t num_samples, uint8_t cycles, uint16_t averaging, uint8_t *ble_buffer) { - if (g_maa_ctx.state != MAA_ASYNC_IDLE) { + if (g_maa_ctx.state != MAA_ASYNC_IDLE) + { ADC_LOG("maa_async_start: busy"); return DR_ADC_ERR_NOT_INIT; /* Already running */ } @@ -1492,7 +1513,9 @@ dr_adc_err_t maa_async_start(uint8_t freq_option, uint16_t delay_us, /* Capture CH0 */ g_maa_ctx.state = MAA_ASYNC_CAPTURING; dr_adc_err_t err = maa_async_capture_channel(0); - if (err != DR_ADC_OK) { + + if (err != DR_ADC_OK) + { ADC_LOG("maa_async_start: CH0 capture failed (%d)", err); maa_async_send_completion(0xFFF0); return err; @@ -1506,26 +1529,34 @@ dr_adc_err_t maa_async_start(uint8_t freq_option, uint16_t delay_us, bool maa_async_on_tx_ready(void) { - if (g_maa_ctx.state == MAA_ASYNC_IDLE) { + if (g_maa_ctx.state == MAA_ASYNC_IDLE) + { return false; } switch (g_maa_ctx.state) { case MAA_ASYNC_TX_DATA: /* Send next data packet */ - if (!maa_async_send_data_packet()) { + if (!maa_async_send_data_packet()) + { /* Current channel done, move to next */ g_maa_ctx.current_ch++; - if (g_maa_ctx.current_ch >= MAA_NUM_CHANNELS) { + + if (g_maa_ctx.current_ch >= MAA_NUM_CHANNELS) + { /* All channels done */ g_maa_ctx.state = MAA_ASYNC_COMPLETE; maa_async_send_completion(0x0000); return false; - } else { + } + else + { /* Capture next channel */ g_maa_ctx.state = MAA_ASYNC_CAPTURING; dr_adc_err_t err = maa_async_capture_channel(g_maa_ctx.current_ch); - if (err != DR_ADC_OK) { + + if (err != DR_ADC_OK) + { ADC_LOG("maa_async: CH%u capture failed", g_maa_ctx.current_ch); maa_async_send_completion(0xFFF0 | g_maa_ctx.current_ch); return false; diff --git a/pc_firm/parser.c b/pc_firm/parser.c index fbe9ea6..76679fe 100644 --- a/pc_firm/parser.c +++ b/pc_firm/parser.c @@ -976,17 +976,30 @@ static int Cmd_cmd(const ParsedCmd *cmd) static int Cmd_maa(const ParsedCmd *cmd) { - uint16_t mode = 0; dr_adc_err_t err; - /* mode 파라미터 추출 */ - (void)dr_get_u16(cmd, 0, &mode); + /* 파라미터 5개 수신 시 FDS에 저장 — 디버그 중 비활성화 + if (cmd->data_len >= 10) { + 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); - /* mode 검증 - mode 0(비동기 원시)만 지원 */ - if (mode > 0) { - dr_ble_return_1("raa:", 0xFFFF); /* 미지원 모드 에러 */ - return 1; + 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(); + + if (g_plat.log) g_plat.log("[Cmd_maa] params updated: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n", + m_config.piezo_freq_option, m_config.piezo_cycles, + m_config.piezo_averaging, m_config.piezo_delay_us, + m_config.piezo_num_samples); } + */ /* 이전 캡처가 진행 중인지 확인 (비동기이므로 중복 실행 방지) */ if (maa_async_is_busy()) { @@ -1108,16 +1121,30 @@ static void all_sensors(void) */ static int Cmd_mbb(const ParsedCmd *cmd) { - uint16_t mode = 0; dr_adc_err_t err; - (void)dr_get_u16(cmd, 0, &mode); + /* 파라미터 5개 수신 시 FDS에 저장 — 디버그 중 비활성화 + if (cmd->data_len >= 10) { + 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); - if (mode > 0) - { - dr_ble_return_1("raa:", 0xFFFF); - return 1; + 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(); + + if (g_plat.log) g_plat.log("[Cmd_mbb] params updated: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n", + m_config.piezo_freq_option, m_config.piezo_cycles, + m_config.piezo_averaging, m_config.piezo_delay_us, + m_config.piezo_num_samples); } + */ all_sensors(); @@ -1134,6 +1161,11 @@ static int Cmd_mbb(const ParsedCmd *cmd) dr_piezo_system_init(); } + if (g_plat.log) g_plat.log("[Cmd_mbb] freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n", + m_config.piezo_freq_option, m_config.piezo_cycles, + m_config.piezo_averaging, m_config.piezo_delay_us, + m_config.piezo_num_samples); + /* 비동기 6채널 캡처 시작 (m_config 파라미터 사용) */ err = maa_async_start( m_config.piezo_freq_option, diff --git a/project/ble_peripheral/ble_app_bladder_patch/fstorage.c b/project/ble_peripheral/ble_app_bladder_patch/fstorage.c index e58a0ad..322d0a6 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/fstorage.c +++ b/project/ble_peripheral/ble_app_bladder_patch/fstorage.c @@ -12,15 +12,18 @@ * - CONFIG_FILE = 0x8010, CONFIG_REC_KEY = 0x7010 으로 단일 레코드를 관리한다. * * [config_data_t 구조체 필드] - * - magic(4B) : 포맷 확인용 매직 넘버 (MAGIC = 0x20231226) - * - hw_no(12B) : 하드웨어 번호 (BLE 명령으로 설정) - * - serial_no(12B) : 시리얼 번호 (기본값: "VB026030000") - * - passkey(6B) : BLE 페어링용 정적 패스키 - * - bond_delete(1B) : 본딩 데이터 삭제 플래그 - * - reset_status(1B) : 리셋 상태 값 - * - pd_adc_cnt : 포토다이오드 ADC 측정 횟수 - * - pd_delay_us : 포토다이오드 측정 간 지연 시간(us) - * - life_cycle : 장치 사용 횟수 + * - magic(4B) : 포맷 확인용 매직 넘버 (0x20231226 -> 0x20260318(기본값 재생성을 위해 매직넘버 변경)) + * - hw_no(12B) : 하드웨어 버전 (기본값: "") + * - serial_no(12B) : 시리얼 번호 (기본값: "VB026030000") + * - passkey(6B) : BLE 페어링용 정적 패스키(기본값: "123456") + * - bond_data_delete(1B) : 본딩 데이터 삭제 플래그(기본값: 1) + * - reset_status(1B) : 리셋 상태 값(기본값: 99) + * - life_cycle(4B) : 장치 사용 횟수(기본값: 0) + * - piezo_freq_option : Piezo 송신 펄스 주파수(기본값: 1=2.1MHz) + * - piezo_cycles : Piezo 송신 펄스 사이클 수 (기본값: 7) + * - piezo_averaging : Piezo 채널당 반복 측정 횟수 (기본값: 5) + * - piezo_delay_us : Piezo 송신 펄스 출력 후 ADC 시작 시까지 대기시간(us) (기본값: 10) + * - piezo_num_samples : Piezo 측정 ADC 샘플 개수 (기본값: 100) * * [매직 넘버 검증] * - 플래시에서 로드한 데이터의 magic 값이 0x20231226과 일치하는지 확인하여 @@ -63,7 +66,7 @@ #define CONFIG_REC_KEY (0x7010) /* 매직 넘버: 플래시에 저장된 데이터가 유효한 설정인지 판별하는 데 사용 */ -#define CONFIG_MAGIC_NUMBER_VALUE (0x20260318) +#define CONFIG_MAGIC_NUMBER_VALUE (0x20260319) /* 전역 설정 데이터 구조체 인스턴스 */ config_data_t m_config; @@ -98,7 +101,7 @@ uint8_t static_passkey_dflt[6] = "123456"; /* BLE 패스키 기본값 */ * @brief 기본 설정값 초기화 * * m_config 구조체의 각 필드를 공장 초기값으로 설정한다. - * 플래시에 유효한 설정이 없거나 매직 넘버가 불일치할 때 호출된다. + * 플래시에 유효한 설정이 없거나 매직 넘버가 불일치할 때 호출된다.VB0HW0000 */ void fds_default_value_set(void) { @@ -310,7 +313,7 @@ void config_load( void ) } else { - cfg_load_write_new: + cfg_load_write_new: DBG_PRINTF("[FDS] New - writing defaults\r\n"); /* System config not found (or corrupt); write a new one. */ m_config.magic_number = CONFIG_MAGIC_NUMBER_VALUE; diff --git a/project/ble_peripheral/ble_app_bladder_patch/fstorage.h b/project/ble_peripheral/ble_app_bladder_patch/fstorage.h index 2f3100d..9a731db 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/fstorage.h +++ b/project/ble_peripheral/ble_app_bladder_patch/fstorage.h @@ -39,7 +39,7 @@ #pragma pack(1) typedef struct { - uint32_t magic_number; /* 4B - 0x20231226 */ + uint32_t magic_number; /* 4B - 포맷 확인용 매직 넘버 */ char hw_no[12]; /* 12B - HW Version */ char serial_no[12]; /* 12B - Serial Number */ uint8_t static_passkey[6]; /* 6B - BLE Passkey */ @@ -50,9 +50,9 @@ typedef struct /* Piezo 측정 파라미터 - 8B */ uint8_t piezo_freq_option; /* 1B - Frequency : 송신 펄스 주파수 (0=1.8M, 1=2.1M, 2=2.0M, 3=1.7M) */ uint8_t piezo_cycles; /* 1B - Burst Cycle : 송신 펄스 사이클 수 (3~7) */ - uint16_t piezo_averaging; /* 2B - 채널당 반복 측정 횟수 */ - uint16_t piezo_delay_us; /* 2B - 송신 펄스 출력 후 ADC 시작 시까지 대기시간(us) */ - uint16_t piezo_num_samples; /* 2B - 측정 ADC 샘플 개수(80~140) */ + uint16_t piezo_averaging; /* 2B - 평균화 수 : 채널당 반복 측정 횟수 (1~10) */ + uint16_t piezo_delay_us; /* 2B - 대기 시간(Delay) : 송신 펄스 출력 후 ADC 시작 시까지 대기시간 (us) (0~30) */ + uint16_t piezo_num_samples; /* 2B - 측정 ADC 샘플 개수 (80~140) */ } config_data_t; /* Total: 48 bytes - FDS에 저장하는 디바이스 설정 */ extern config_data_t m_config; diff --git a/project/ble_peripheral/ble_app_bladder_patch/main.c b/project/ble_peripheral/ble_app_bladder_patch/main.c index e022181..d71de4d 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/main.c +++ b/project/ble_peripheral/ble_app_bladder_patch/main.c @@ -441,6 +441,10 @@ static void load_flash_config(void) DBG_PRINTF("[CFG] HW=%.12s S/N=%s passkey=%.6s bond=%d rst=%d\r\n", m_config.hw_no, SERIAL_NO, m_static_passkey, bond_data_delete, m_reset_status); + DBG_PRINTF("[CFG] piezo: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n", + m_config.piezo_freq_option, m_config.piezo_cycles, + m_config.piezo_averaging, m_config.piezo_delay_us, + m_config.piezo_num_samples); } /*============================================================================== diff --git a/project/ble_peripheral/dr_piezo/dr_piezo.c b/project/ble_peripheral/dr_piezo/dr_piezo.c index 753fe0f..0e7104e 100644 --- a/project/ble_peripheral/dr_piezo/dr_piezo.c +++ b/project/ble_peripheral/dr_piezo/dr_piezo.c @@ -225,7 +225,7 @@ void dr_piezo_power_on(void) m_power_enabled = true; - DBG_PRINTF("[DR_PIEZO] Power ON: +/-20V ready\r\n"); + DBG_PRINTF("[PIEZO] Power ON: +/-20V ready\r\n"); } /* 피에조 전원 OFF: TX 비활성화 후 DC/DC 컨버터 차단 */ @@ -237,7 +237,7 @@ void dr_piezo_power_off(void) m_power_enabled = false; - DBG_PRINTF("[DR_PIEZO] Power OFF\r\n"); + DBG_PRINTF("[PIEZO] Power OFF\r\n"); } /* 피에조 전원 상태 확인 */ @@ -267,7 +267,7 @@ static void dr_piezo_gpio_init(void) /* Initialize MUX control pins */ dr_piezo_mux_init(); - DBG_PRINTF("[DR_PIEZO] GPIO init done\r\n"); + DBG_PRINTF("[PIEZO] GPIO init done\r\n"); } /* GPIOTE 초기화: P_OUT/N_OUT을 토글 모드로 설정 (PPI 연결 대상) */ @@ -291,7 +291,7 @@ static void dr_piezo_gpiote_init(void) ); nrf_gpiote_task_enable(GPIOTE_CH_N_OUT); - DBG_PRINTF("[DR_PIEZO] GPIOTE init done\r\n"); + DBG_PRINTF("[PIEZO] GPIOTE init done\r\n"); } /* @@ -732,10 +732,10 @@ void dr_piezo_test_pins(void) /* 시스템 전체 초기화: 전원 ON → TX 드라이버 초기화 */ void dr_piezo_system_init(void) { - DBG_PRINTF("[DR_PIEZO] System init...\r\n"); + DBG_PRINTF("[PIEZO] System init...\r\n"); dr_piezo_power_on(); dr_piezo_init(); - DBG_PRINTF("[DR_PIEZO] System ready\r\n"); + DBG_PRINTF("[PIEZO] System ready\r\n"); } /* 시스템 전체 종료: TX 드라이버 해제 → 전원 OFF */ @@ -856,7 +856,7 @@ void dr_piezo_burst_sw(uint8_t cycles) uint32_t _d2 = NRF_P1->OUT; - DBG_PRINTF("[B]S0:%u%u%u\r\n", (_d0>>10)&1, (_d1>>10)&1, (_d2>>10)&1); + //DBG_PRINTF("[B]S0:%u%u%u\r\n", (_d0>>10)&1, (_d1>>10)&1, (_d2>>10)&1); /* Restore P1 port state (nrf_gpio_cfg_output may clear bits) */ NRF_P1->OUT = saved_p1_out;