Files
VesiScan-Basic_Zephyr/plan/measurement_pipeline.md
T
2026-04-12 19:16:14 +09:00

198 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 | 1 | 1 |
| 5 | 0 | 1 | 0 | 1 |
---
## 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 대기 (기본 20us) ← 버스트 → 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.c``maa?` 커맨드 핸들러 (6채널 측정 → BLE 전송)
4. 빌드 검증 및 오실로스코프로 타이밍 확인