From 341983c402d157c989ea2f0841665c83783987e2 Mon Sep 17 00:00:00 2001 From: jhchun Date: Thu, 30 Apr 2026 09:38:04 +0900 Subject: [PATCH] =?UTF-8?q?MUX=20setting=201.3ms=20delay=20->=20TIMER4=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20wait=20=EB=B0=A9=EC=8B=9D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ADC 측정 값이 밀리는 현상 개선을 위함 --- .../measurement/adc121s051/dr_adc121s051.c | 9 +- .../measurement/piezo/dr_piezo.c | 92 ++++++++++++++++++- .../measurement/piezo/dr_piezo.h | 20 +++- 3 files changed, 115 insertions(+), 6 deletions(-) diff --git a/project/ble_peripheral/ble_app_bladder_patch/measurement/adc121s051/dr_adc121s051.c b/project/ble_peripheral/ble_app_bladder_patch/measurement/adc121s051/dr_adc121s051.c index 345e19f..f0735db 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/measurement/adc121s051/dr_adc121s051.c +++ b/project/ble_peripheral/ble_app_bladder_patch/measurement/adc121s051/dr_adc121s051.c @@ -638,7 +638,8 @@ dr_adc_err_t dr_adc_burst_capture_transmit(uint8_t freq_option, uint16_t delay_u nrf_delay_us(100); /*--- Step 2: Select piezo channel ---*/ - dr_piezo_select_channel(piezo_ch); + dr_piezo_select_channel_start(piezo_ch); + dr_piezo_wait_mux_settled(); /* dummy read after MUX switch to settle S/H capacitor */ (void)spim_read_raw(); @@ -704,7 +705,8 @@ dr_adc_err_t dr_adc_burst_capture_transmit(uint8_t freq_option, uint16_t delay_u /* Re-select piezo channel before each burst * (burst functions may modify P1 port state) */ - dr_piezo_select_channel(piezo_ch); + dr_piezo_select_channel_start(piezo_ch); + dr_piezo_wait_mux_settled(); /* Execute piezo burst based on frequency option */ switch (freq_option) @@ -874,7 +876,8 @@ dr_adc_err_t dr_adc_capture_channel_only(uint8_t freq_option, uint16_t delay_us, //nrf_delay_us(100); /* channel select (MUX) : ~1.3 ms */ - dr_piezo_select_channel(piezo_ch); + dr_piezo_select_channel_start(piezo_ch); + dr_piezo_wait_mux_settled(); /* dummy read after MUX switch to settle S/H capacitor */ (void)spim_read_raw(); diff --git a/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.c b/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.c index 6896719..a187cbe 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.c +++ b/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.c @@ -60,6 +60,8 @@ #include "nrf_gpiote.h" #include "nrf_ppi.h" #include "nrf_delay.h" +#include "nrfx_timer.h" +#include "nrf_pwr_mgmt.h" #include "power_control.h" #include "app_util_platform.h" @@ -126,6 +128,9 @@ static volatile uint8_t m_remaining_cycles = 0; /* remaining pulse cycle static uint32_t m_period_ticks = PERIOD_TICKS_2MHZ; /* current period (timer ticks) */ static bool m_power_enabled = false; /* DC/DC converter state */ static bool m_initialized = false; /* driver initialised flag */ +static nrfx_timer_t m_mux_settle_timer = NRFX_TIMER_INSTANCE(4); +static volatile bool m_mux_settle_done = true; +static bool m_mux_settle_timer_ready = false; /*============================================================================== * Timer2 IRQ handler @@ -363,6 +368,63 @@ static void dr_piezo_ppi_init(void) nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_CH_N_OUT_TOGGLE_1); } +static void dr_piezo_mux_settle_timeout_handler(nrf_timer_event_t event_type, void *p_context) +{ + (void)p_context; + + if (event_type != NRF_TIMER_EVENT_COMPARE0) + { + return; + } + + nrfx_timer_disable(&m_mux_settle_timer); + m_mux_settle_done = true; +} + +static void dr_piezo_mux_timer_init(void) +{ + nrfx_err_t err; + nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG; + + config.frequency = NRF_TIMER_FREQ_1MHz; + config.mode = NRF_TIMER_MODE_TIMER; + config.bit_width = NRF_TIMER_BIT_WIDTH_16; + config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST; + + err = nrfx_timer_init(&m_mux_settle_timer, &config, dr_piezo_mux_settle_timeout_handler); + if (err == NRFX_SUCCESS) + { + m_mux_settle_timer_ready = true; + } + else + { + m_mux_settle_timer_ready = false; + DBG_PRINTF("[DR_PIEZO] MUX settle timer init failed: %lu\r\n", (unsigned long)err); + } +} + +static void dr_piezo_mux_timer_start(void) +{ + if (!m_mux_settle_timer_ready) + { + nrf_delay_us(DR_PIEZO_MUX_SETTLING_US); + m_mux_settle_done = true; + return; + } + + m_mux_settle_done = false; + nrfx_timer_disable(&m_mux_settle_timer); + nrfx_timer_clear(&m_mux_settle_timer); + nrfx_timer_extended_compare( + &m_mux_settle_timer, + NRF_TIMER_CC_CHANNEL0, + nrfx_timer_us_to_ticks(&m_mux_settle_timer, DR_PIEZO_MUX_SETTLING_US), + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, + true + ); + nrfx_timer_enable(&m_mux_settle_timer); +} + /*============================================================================== * TX driver public functions *============================================================================*/ @@ -399,6 +461,13 @@ void dr_piezo_uninit(void) nrf_gpio_pin_clear(DR_PIEZO_PIN_DMP); nrf_gpio_pin_clear(DR_PIEZO_PIN_P_OUT); nrf_gpio_pin_clear(DR_PIEZO_PIN_N_OUT); + + if (m_mux_settle_timer_ready) + { + nrfx_timer_disable(&m_mux_settle_timer); + nrfx_timer_uninit(&m_mux_settle_timer); + m_mux_settle_timer_ready = false; + } m_tx_active = false; m_initialized = false; @@ -589,7 +658,7 @@ void dr_piezo_mux_init(void) * CH3 = MUXA input3 (1,0,1,1) CH7 = MUXB input3 (0,1,0,0) * MUX settling time (~1.3ms) required after channel switch. */ -void dr_piezo_select_channel(uint8_t channel) +void dr_piezo_select_channel_start(uint8_t channel) { channel = channel & 0x07; /* Mask to 0~7 range */ @@ -631,6 +700,27 @@ void dr_piezo_select_channel(uint8_t channel) /* MUX settling time required after channel change (> 1.2ms) */ nrf_delay_us(DR_PIEZO_MUX_SETTLING_US); + /* Start one-shot timer for MUX settling (> 1.2ms). */ + dr_piezo_mux_timer_start(); +} + +void dr_piezo_wait_mux_settled(void) +{ + while (!m_mux_settle_done) + { + nrf_pwr_mgmt_run(); + } +} + +bool dr_piezo_is_mux_settled(void) +{ + return m_mux_settle_done; +} + +void dr_piezo_select_channel(uint8_t channel) +{ + dr_piezo_select_channel_start(channel); + dr_piezo_wait_mux_settled(); } /* Pin test: toggle each signal pin HIGH/LOW in sequence (for oscilloscope verification) */ diff --git a/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.h b/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.h index 4aaeaa4..97503db 100644 --- a/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.h +++ b/project/ble_peripheral/ble_app_bladder_patch/measurement/piezo/dr_piezo.h @@ -95,11 +95,27 @@ void dr_piezo_test_pins(void); void dr_piezo_mux_init(void); /** - * @brief Select piezo channel (0..7) via 8ch MUX - * @note MUX settling time: ~1.3 ms delay after switching + * @brief Select piezo channel and wait for MUX settling + * @note Uses a one-shot timer for the ~1.3 ms settling interval. */ void dr_piezo_select_channel(uint8_t channel); +/** + * @brief Select piezo channel and start MUX settling timer + * @note Does not wait for settling to complete. + */ +void dr_piezo_select_channel_start(uint8_t channel); + +/** + * @brief Wait until the outstanding MUX settling interval completes + */ +void dr_piezo_wait_mux_settled(void); + +/** + * @brief Check whether the current MUX settling interval has completed + */ +bool dr_piezo_is_mux_settled(void); + /*============================================================================== * System functions (power + TX combined) *============================================================================*/