Files
VesiScan-Basic_Zephyr/plan/measurement_pipeline.md
T
2026-06-11 17:48:35 +09:00

7.2 KiB
Raw Blame History

VesiScan BASIC — 초음파 측정 파이프라인 (Zephyr 포팅 계획)

1. 하드웨어 구성

역할
피에조 전원 DC/DC 컨버터 (+/-20V) PWR_EN: P1.9
TX Pulse Enable MOSFET 드라이버 PE: P0.25
TX 양극 출력 MOSFET P_OUT: P1.7
TX 음극 출력 MOSFET N_OUT: P1.6
TX 방전 Dump 회로 DMP: P1.0
채널 선택 8ch 아날로그 MUX EN_MUXA: P0.21, EN_MUXB: P0.23, SEL0: P1.10, SEL1: P0.28
Echo ADC ADC121S051 (TI, 12-bit) SCLK: P0.14, MISO: P0.15, CS: P0.19

MUX 채널 매핑 (6채널 사용)

CH EN_MUXA EN_MUXB SEL0 SEL1
0 1 0 0 0
1 1 0 1 0
2 1 0 0 1
3 1 0 1 1
4 0 1 0 0
5 0 1 1 0

2. 전체 측정 흐름

[측정 커맨드 수신]
        │
        ▼
piezo_power_on()
  └─ PWR_EN = HIGH
  └─ 3ms 안정화 대기

echo_adc_init()
  └─ SPIM3 초기화 (16MHz, SPI Mode 3, CPOL=1 CPHA=1)
  └─ dummy read 1회 (ADC wake-up)

        │
        ▼
┌─── for ch = 0 ~ 5 ───────────────────────────────────────────┐
│                                                               │
│  piezo_select_channel(ch)                                     │
│    └─ MUX 핀 설정                                               │
│    └─ 1300us settling 대기                                     │
│                                                               │
│  [averaging 횟수만큼 반복] (기본 3회)                              │
│    piezo_burst_sw(cycles)          ← SW NOP 버스트              │
│      ├─ __disable_irq()                                       │
│      ├─ PE ON                                                 │
│      ├─ for i in cycles:                                      │
│      │    P_OUT=HIGH, N_OUT=LOW  (NOP × 14)  ┐ 2.1MHz         │
│      │    P_OUT=LOW,  N_OUT=HIGH (NOP × 9)   ┘                │
│      ├─ DMP 펄스 (500ns)                                       │
│      ├─ PE OFF                                                │
│      └─ __enable_irq()                                        │
│                                                               │
│    delay_us 대기 (기본 10us)       ← 버스트 → ADC 시작 딜레이        │
│                                                               │
│    echo_adc_capture(buf, num_samples)  ← SPIM3 연속 읽기     │
│      └─ 100샘플 × 2byte = 200byte                             │
│      └─ 소요시간: ~100us (16MHz SPI)                          │
│                                                               │
│    샘플 합산 (averaging용)                                    │
│                                                               │
│  averaging 나눗셈 → channel_buf[ch] 저장                      │
│                                                               │
└───────────────────────────────────────────────────────────────┘
        │
        ▼
BLE 전송 (채널별)
  reb: [샘플수(2B)] [raw data (200B)] + CRC16   ← 채널당 1패킷
  ...
  raa: [상태(2B)] + CRC16                       ← 완료 패킷

        │
        ▼
piezo_power_off()
  └─ PE, P_OUT, N_OUT, DMP = LOW
  └─ MUX EN 핀 = LOW
  └─ PWR_EN = LOW

3. 타이밍 정리

구간 시간 비고
전원 안정화 3ms DC/DC +/-20V 안정화
MUX settling 1.3ms 채널 전환 후 아날로그 경로 안정화
SW 버스트 (5 cycles @ 2.1MHz) ~2.4µs __disable_irq() 구간
burst → ADC 딜레이 20µs (기본) 에코 신호 도달 대기
ADC 캡처 (100샘플 @ 16MHz SPI) ~100µs 1샘플 = 16 SCLK = 1µs
채널당 총 측정 시간 (averaging 3회) ~4.4ms + 3ms MUX + (burst+딜레이+ADC) × 3
6채널 전체 측정 ~30ms 채널 × 6

4. ADC121S051 SPI 프레임

CS   ────┐                    ┌────
         └────────────────────┘

SCLK ────┐ ┌─┐ ┌─┐     ┌─┐ ┌─┐ ────  (idle HIGH, 16 clocks)
         └─┘ └─┘ └─ ... └─┘ └─┘

DATA ----<Z2><Z1><Z0><D11>...<D1><D0>----
         │← 3 zeros →│← 12 data bits →│

변환 공식: value = (raw16 >> 1) & 0x0FFF
  • SPI Mode 3: CPOL=1(idle HIGH), CPHA=1(rising edge sample)
  • 16MHz clock → 1샘플 = 16 clocks = 1µs
  • 12-bit 출력 (0 ~ 4095), VREF = 3.3V
  • 1LSB = 3300mV / 4096 ≈ 0.8mV

5. BLE 응답 패킷 포맷

reb: (echo raw data)

[r][e][b][:] [num_samples H][num_samples L] [s0_H][s0_L] [s1_H][s1_L] ... [CRC_L][CRC_H]
  4 bytes          2 bytes                    num_samples × 2 bytes          2 bytes
  • 100샘플 기준: 4 + 2 + 200 + 2 = 208 bytes
  • BLE MTU 247byte 이내이므로 단일 패킷으로 전송 가능

raa: (완료)

[r][a][a][:] [status H][status L] [CRC_L][CRC_H]
  4 bytes         2 bytes            2 bytes  = 8 bytes
  • status 0x0000 = 성공

6. Zephyr 구현 계획

신규 파일

파일 내용
src/drivers/piezo/piezo.c SW 버스트, MUX 제어, 전원 제어
src/drivers/piezo/piezo.h 공개 API 선언
src/drivers/echo_adc/echo_adc.c ADC121S051 SPIM3 드라이버
src/drivers/echo_adc/echo_adc.h 공개 API 선언

수정 파일

파일 변경 내용
boards/nrf52840dk_nrf52840.overlay 피에조/MUX GPIO, SPI 핀 비활성화 충돌 처리
prj.conf CONFIG_NRFX_GPIOTE=y, CONFIG_NRFX_SPIM3=y 추가
CMakeLists.txt 신규 소스/인클루드 추가
src/parser.c maa? 커맨드 핸들러 추가

기존 SDK → Zephyr 변환표

nRF5 SDK Zephyr
#include "nrf_gpio.h" #include <hal/nrf_gpio.h>
#include "nrf_gpiote.h" #include <hal/nrf_gpiote.h>
#include "nrfx_spim.h" #include <nrfx_spim.h>
nrf_delay_ms(x) k_msleep(x)
nrf_delay_us(x) k_busy_wait(x)
NRF_P0->OUTSET/OUTCLR 동일 (레지스터 직접 접근)
__disable_irq() / __NOP() 동일 (ARM CMSIS)
NRFX_SPIM_INSTANCE(3) 동일

SW 버스트 NOP 타이밍 (변경 없음)

CPU 64MHz → 1 NOP = 15.625ns. nRF5 SDK, Zephyr 모두 동일하므로 NOP 개수 수정 불필요.

주파수 반주기 1st half NOP 2nd half NOP
1.7 MHz 294ns 18 10
1.8 MHz 278ns 17 11
1.9 MHz 263ns 15 9
2.0 MHz 250ns 15 10
2.1 MHz 238ns 14 9
2.2 MHz 227ns 13 8

7. 구현 순서 (권장)

  1. piezo.c — GPIO 초기화, MUX, 전원, SW 버스트
  2. echo_adc.c — SPIM3 초기화, 단일 샘플 읽기, 연속 캡처
  3. parser.cmaa? 커맨드 핸들러 (6채널 측정 → BLE 전송)
  4. 빌드 검증 및 오실로스코프로 타이밍 확인