ADC 데이터 샘플 간 간격 줄이기

This commit is contained in:
2026-06-11 17:49:20 +09:00
parent 1f7436e27d
commit 728f5dab76
2 changed files with 205 additions and 15 deletions
+84 -15
View File
@@ -8,6 +8,7 @@
#include <zephyr/devicetree.h>
#include <zephyr/sys/util.h>
#include <nrfx_spim.h>
#include <hal/nrf_spim.h>
#include <errno.h>
#include "echo_adc.h"
@@ -30,6 +31,11 @@ static nrfx_spim_t echo_spim = NRFX_SPIM_INSTANCE(NRF_SPIM3);
static bool echo_adc_initialized;
static uint8_t raw_capture[ECHO_ADC_MAX_SAMPLES * 2];
static NRF_GPIO_Type *gpio_reg_for_spec(const struct gpio_dt_spec *spec)
{
return (spec->port == DEVICE_DT_GET(DT_NODELABEL(gpio1))) ? NRF_P1 : NRF_P0;
}
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;
@@ -50,6 +56,79 @@ static int echo_adc_transfer_rx(uint8_t *buf, size_t len)
return 0;
}
static void echo_adc_unpack_samples(uint16_t *samples, uint16_t num_samples)
{
for (uint16_t i = 0; i < num_samples; i++)
{
uint16_t raw16 = ((uint16_t)raw_capture[i * 2U] << 8) |
(uint16_t)raw_capture[i * 2U + 1U];
samples[i] = (raw16 >> 1) & 0x0FFF;
}
}
static bool echo_adc_samples_all_zero(const uint16_t *samples, uint16_t num_samples)
{
for (uint16_t i = 0; i < num_samples; i++)
{
if (samples[i] != 0U)
{
return false;
}
}
return true;
}
static int echo_adc_capture_slow(uint16_t *samples, uint16_t num_samples)
{
for (uint16_t i = 0; i < num_samples; i++)
{
int err = echo_adc_transfer_rx(&raw_capture[i * 2U], 2U);
if (err)
{
return err;
}
}
echo_adc_unpack_samples(samples, num_samples);
return 0;
}
static int echo_adc_capture_fast(uint16_t *samples, uint16_t num_samples)
{
NRF_SPIM_Type *spim = echo_spim.p_reg;
NRF_GPIO_Type *cs_port = gpio_reg_for_spec(&echo_cs);
uint32_t cs_mask = BIT(echo_cs.pin);
nrf_spim_enable(spim);
spim->RXD.MAXCNT = 2U;
for (uint16_t i = 0; i < num_samples; i++)
{
cs_port->OUTCLR = cs_mask;
spim->RXD.PTR = (uint32_t)&raw_capture[i * 2U];
spim->EVENTS_END = 0;
spim->TASKS_START = 1;
uint32_t timeout = 10000U;
while (!spim->EVENTS_END && (timeout > 0U))
{
timeout--;
}
cs_port->OUTSET = cs_mask;
if (timeout == 0U)
{
DBG_PRINTF("[ECHO] fast capture timeout\r\n");
return -ETIMEDOUT;
}
}
echo_adc_unpack_samples(samples, num_samples);
return 0;
}
int echo_adc_init(void)
{
if (echo_adc_initialized || nrfx_spim_init_check(&echo_spim))
@@ -124,22 +203,12 @@ int echo_adc_capture(uint16_t *samples, uint16_t num_samples)
return err;
}
for (uint16_t i = 0; i < num_samples; i++)
err = echo_adc_capture_fast(samples, num_samples);
if ((err == 0) && !echo_adc_samples_all_zero(samples, num_samples))
{
/*
* Keep the framing that matched the old firmware behavior:
* one 16-clock / 2-byte SPI frame per sample.
*/
err = echo_adc_transfer_rx(&raw_capture[i * 2U], 2U);
if (err)
{
return err;
}
uint16_t raw16 = ((uint16_t)raw_capture[i * 2U] << 8) |
(uint16_t)raw_capture[i * 2U + 1U];
samples[i] = (raw16 >> 1) & 0x0FFF;
return 0;
}
return 0;
DBG_PRINTF("[ECHO] fast capture fallback err=%d\r\n", err);
return echo_adc_capture_slow(samples, num_samples);
}