MUX setting 1.3ms delay -> TIMER4 기반 wait 방식으로 변경

- ADC 측정 값이 밀리는 현상 개선을 위함
This commit is contained in:
2026-04-30 09:38:04 +09:00
parent 00f24c53e1
commit 341983c402
3 changed files with 115 additions and 6 deletions
@@ -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); nrf_delay_us(100);
/*--- Step 2: Select piezo channel ---*/ /*--- 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 */ /* dummy read after MUX switch to settle S/H capacitor */
(void)spim_read_raw(); (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 /* Re-select piezo channel before each burst
* (burst functions may modify P1 port state) */ * (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 */ /* Execute piezo burst based on frequency option */
switch (freq_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); //nrf_delay_us(100);
/* channel select (MUX) : ~1.3 ms */ /* 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 */ /* dummy read after MUX switch to settle S/H capacitor */
(void)spim_read_raw(); (void)spim_read_raw();
@@ -60,6 +60,8 @@
#include "nrf_gpiote.h" #include "nrf_gpiote.h"
#include "nrf_ppi.h" #include "nrf_ppi.h"
#include "nrf_delay.h" #include "nrf_delay.h"
#include "nrfx_timer.h"
#include "nrf_pwr_mgmt.h"
#include "power_control.h" #include "power_control.h"
#include "app_util_platform.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 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_power_enabled = false; /* DC/DC converter state */
static bool m_initialized = false; /* driver initialised flag */ 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 * 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); 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 * TX driver public functions
*============================================================================*/ *============================================================================*/
@@ -400,6 +462,13 @@ void dr_piezo_uninit(void)
nrf_gpio_pin_clear(DR_PIEZO_PIN_P_OUT); nrf_gpio_pin_clear(DR_PIEZO_PIN_P_OUT);
nrf_gpio_pin_clear(DR_PIEZO_PIN_N_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_tx_active = false;
m_initialized = 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) * CH3 = MUXA input3 (1,0,1,1) CH7 = MUXB input3 (0,1,0,0)
* MUX settling time (~1.3ms) required after channel switch. * 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 */ 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) */ /* MUX settling time required after channel change (> 1.2ms) */
nrf_delay_us(DR_PIEZO_MUX_SETTLING_US); 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) */ /* Pin test: toggle each signal pin HIGH/LOW in sequence (for oscilloscope verification) */
@@ -95,11 +95,27 @@ void dr_piezo_test_pins(void);
void dr_piezo_mux_init(void); void dr_piezo_mux_init(void);
/** /**
* @brief Select piezo channel (0..7) via 8ch MUX * @brief Select piezo channel and wait for MUX settling
* @note MUX settling time: ~1.3 ms delay after switching * @note Uses a one-shot timer for the ~1.3 ms settling interval.
*/ */
void dr_piezo_select_channel(uint8_t channel); 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) * System functions (power + TX combined)
*============================================================================*/ *============================================================================*/