Initial Commit

This commit is contained in:
2026-07-06 11:14:35 +09:00
parent e6de6e8cc3
commit e55b283b39
31 changed files with 1023 additions and 2123 deletions
+20 -46
View File
@@ -18,6 +18,9 @@
#define ECHO_MISO_NODE DT_NODELABEL(echo_miso)
#define ECHO_CS_NODE DT_NODELABEL(echo_cs)
/* SPIM END event 대기 최대 반복 횟수 */
#define ECHO_ADC_SPIM_END_TIMEOUT_LOOPS 100000U
/* ADC SPI 핀 */
static const struct gpio_dt_spec echo_sclk = GPIO_DT_SPEC_GET(ECHO_SCLK_NODE, gpios);
static const struct gpio_dt_spec echo_miso = GPIO_DT_SPEC_GET(ECHO_MISO_NODE, gpios);
@@ -42,7 +45,7 @@ static uint32_t gpio_abs_pin(const struct gpio_dt_spec *spec)
return NRF_GPIO_PIN_MAP(port, spec->pin);
}
/* SPIM RX 전송 */
/* SPIM RX 전송: ADC wake/dummy read용 nrfx 경로 */
static int echo_adc_transfer_rx(uint8_t *buf, size_t len)
{
nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(buf, len);
@@ -68,37 +71,7 @@ static void echo_adc_unpack_samples(uint16_t *samples, uint16_t num_samples)
}
}
/* 무응답 샘플 확인 */
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;
}
/* 속도 우선 캡처 */
/* 샘플마다 CS를 직접 제어하고 SPIM RX 2바이트를 수행 */
static int echo_adc_capture_fast(uint16_t *samples, uint16_t num_samples)
{
NRF_SPIM_Type *spim = echo_spim.p_reg;
@@ -116,9 +89,19 @@ static int echo_adc_capture_fast(uint16_t *samples, uint16_t num_samples)
cs_port->OUTCLR = cs_mask;
spim->TASKS_START = 1;
/* 전송 완료 대기 */
/* 전송 완료 대기: SPIM이 꼬인 경우 IRQ lock 상태로 영구 정지하지 않도록 timeout 처리 */
uint32_t timeout = ECHO_ADC_SPIM_END_TIMEOUT_LOOPS;
while (!spim->EVENTS_END)
{
if (--timeout == 0U)
{
spim->EVENTS_STOPPED = 0;
spim->TASKS_STOP = 1;
cs_port->OUTSET = cs_mask;
spim->EVENTS_END = 0;
DBG_PRINTF("[ECHO] SPIM END timeout sample=%u\r\n", i);
return -ETIMEDOUT;
}
}
cs_port->OUTSET = cs_mask;
@@ -130,14 +113,14 @@ static int echo_adc_capture_fast(uint16_t *samples, uint16_t num_samples)
int echo_adc_init(void)
{
/* 중복 초기화 방지 */
// 중복 초기화 방지
if (echo_adc_initialized || nrfx_spim_init_check(&echo_spim))
{
echo_adc_initialized = true;
return 0;
}
/* GPIO 준비 확인 */
// GPIO 준비 확인
const struct gpio_dt_spec *pins[] = { &echo_sclk, &echo_miso, &echo_cs };
for (size_t i = 0; i < ARRAY_SIZE(pins); i++)
@@ -190,7 +173,7 @@ int echo_adc_wake(void)
int echo_adc_capture(uint16_t *samples, uint16_t num_samples)
{
/* 입력값 검사 */
// 입력값 검사
if (samples == NULL)
{
return -EINVAL;
@@ -207,14 +190,5 @@ int echo_adc_capture(uint16_t *samples, uint16_t num_samples)
return err;
}
/* 빠른 캡처 우선 */
err = echo_adc_capture_fast(samples, num_samples);
if ((err == 0) && !echo_adc_samples_all_zero(samples, num_samples))
{
return 0;
}
/* 실패 시 안정 캡처 */
DBG_PRINTF("[ECHO] fast capture fallback err=%d\r\n", err);
return echo_adc_capture_slow(samples, num_samples);
return echo_adc_capture_fast(samples, num_samples);
}