# VesiScan BASIC - Zephyr - nRF52840 기반 VesiScan BASIC 펌웨어의 Zephyr/nRF Connect SDK 프로젝트 - 현재 빌드 대상은 `nrf52840dk_nrf52840` 기준 - MCUboot + BLE MCUmgr DFU, BLE NUS 명령, 배터리/IMU/Piezo/echo ADC capture 등 포함 ## 프로젝트 구조 ```text VesiScan-Basic_Zephyr/ ├── CMakeLists.txt ├── prj.conf ├── boards/ │ ├── nrf52840dk_nrf52840.overlay │ └── nrf52840dk_nrf52840.conf ├── sysbuild/ │ ├── mcuboot.conf │ ├── hci_ipc.conf │ └── mcuboot_power_hold_module/ ├── src/ │ ├── main.c / main.h # 부팅, 초기화, main loop │ ├── debug_print.h # DBG_PRINTF/DBG_CORE/DBG_ERR 매크로 │ ├── ble │ │ ├── ble_service.c / ble_service.h # BLE NUS, 광고, 보안, DFU 광고 전환 │ │ └── ble_tx_power.c / ble_tx_power.h # BLE TX Power 동적 제어 │ ├── command/ │ │ ├── handlers/ │ │ │ ├── cmd_device.c / cmd_device.h # 전원, 재부팅, DFU, 생산 완료 명령 │ │ │ ├── cmd_info.c / cmd_info.h # FW/HW/SN/Passkey 정보 명령 │ │ │ ├── cmd_piezo.c / cmd_piezo.h # Piezo/echo 측정 명령 │ │ │ └── cmd_sensor.c / cmd_sensor.h # 배터리, IMU, LED 명령 │ │ ├── ble_cmd_queue.c / ble_cmd_queue.h # BLE RX 명령 work queue │ │ ├── cmd_common.c / cmd_common.h # 응답 패킷 생성 공통 함수 │ │ ├── cmd_table.c / cmd_table.h # 명령 dispatch table │ │ └── parser.c / parser.h # BLE 명령 파서 │ ├── dfu/ │ │ └── dfu_manager.c / dfu_manager.h # MCUboot image 확인, DFU 상태 관리 │ ├── drivers/ │ │ ├── battery/ # 배터리 ADC │ │ ├── echo_adc/ # ADC121S051 SPIM capture │ │ ├── imu/ # ICM42670P I2C/FIFO │ │ ├── led/ # LED 패턴 │ │ └── piezo/ # Piezo TX/MUX 제어 │ ├── measurement/ │ │ └── piezo_measure.c / piezo_measure.h # Piezo burst ~ capture │ ├── nvs/ │ │ └── app_nvs.c / app_nvs.h # settings/NVS 저장소 │ ├── power/ │ │ └── power_control.c / power_control.h # 전원 유지, 버튼, sleep 처리 │ └── system/ # 시스템 공통 모듈용 디렉터리 ├── release/ # 배포용 펌웨어 산출물 │ ├── dfu_application_VBTFW0100_1.0.0+0.zip # BLE DFU 업데이트용 패키지 │ └── VesiScan-Basic_VBTFW0100_1.0.0+0.hex # 생산/전체 플래싱용 통합 HEX ├── tools/ ├── manual/ └── curcuit/ ``` ## 빌드 nRF Connect SDK / west 사용: ```powershell west build -b nrf52840dk_nrf52840 -p auto west flash ``` 또는 로컬에 맞춘 기존 `tools/` 스크립트 또는 VS Code Task를 사용 (`tools/flash_*.ps1`). 빌드 결과로 `zephyr.elf`, `merged.hex` 및 `release/` 아래 versioned HEX/DFU zip 생성됨 아래 파일을 변경한 경우에는 pristine build 필요: - `prj.conf` - `boards/*.overlay` 또는 보드 설정 - `CMakeLists.txt` / sysbuild 설정 ## 전원 동작 | 동작 | 조건 | 결과 | |---|---|---| | 부팅 | 전원 버튼 2초 이상 유지 | P0.08 래치 ON, LED 광고 패턴, BLE 광고 시작 | | 짧은 부팅 시도 | 부팅 중 2초 전 버튼 해제 | 래치 해제, 전원 OFF | | 수동 전원 OFF | ON 상태에서 버튼 재누름 2초 이상 | 광고 중지, LED 표시 후 전원 래치 해제 | | BLE 10분 광고 만료 | 최초 부팅 광고 또는 정상 disconnect 후 광고 | 광고 중지, 전원 OFF 예약 | | DFU/soft reset 복귀 | DFU 확인/리셋 플래그 감지 | 버튼 없이 전원 유지 및 광고 복귀 | ## BLE 명령 포맷 ```text [TAG 4 bytes][DATA N bytes][CRC16 2 bytes] ``` - TAG: ASCII 4바이트, 예: `msn?`, `mbb?` - DATA: 명령별 payload - CRC16: CRC-CCITT, initial `0xFFFF` - 응답 TAG: 보통 요청의 `m`을 `r`로 바꾼 형태, 예: `msn?` -> `rsn:` ## 저장되는 설정 | 항목 | 저장소 key | 쓰기 명령 | 비고 | |---|---|---|---| | 피에조 측정 파라미터 | `vesiscan/piezo` | `mcs?` | validate 통과 시 복원 | | HW version | `vesiscan/hw` | `mwh?` | 고정 길이 ASCII | | Serial number | `vesiscan/serial` | `mws?` | 광고 name에도 사용 | | Passkey | `vesiscan/passkey` | `mpz?` | 고정 길이 6자리 | | 생산 완료 플래그 | `vesiscan/production_done` | `mpd?` | 1이면 생산용 Write 명령 차단 | | BLE bonding/settings | Zephyr `bt` subtree | BLE stack | `CONFIG_BT_SETTINGS=y` | ## 생산 플로우 ```text mwh? -> mws? -> mpz? -> mid? 확인 -> mpd? ``` - `mwh?`: HW version 저장 - `mws?`: Serial number 저장 - `mpz?`: Passkey 저장 - `mid?`: FW/HW/SN 정보 확인 - `mpd?`: 생산 완료 플래그 저장 후 본딩 삭제 및 재부팅 ## BLE 기능 - Device name: `SERIAL_NO` 기반 - Advertising interval: 40ms - Normal advertising timeout: 10분 - DFU advertising: SMP UUID, 미연결 상태 10분 timeout 적용 - NUS UUID 광고 포함 - 연결 파라미터 선호값: Connection Interval 30~60ms / latency 0 / supervision timeout 10s - NUS TX는 mutex + completion semaphore로 순차 전송 - BLE RX는 별도 work queue에서 명령 처리 - 보안 설정: fixed passkey, MITM, Secure Connections only ## BLE 명령 | 명령 | 응답 | 기능 | 비고 | |---|---|---|---| | `msq?` | `rsq:` | 전원 OFF | | | `mss?` | `rss:` | 재부팅 | | | `msr?` | `rsr:` | 본딩 삭제 후 재부팅 | | | `mpd?` | `rpd:` | 생산 완료 처리 | 생산 완료 플래그 저장 후 본딩 삭제 및 재부팅 | | `mdf?` | `rdf:` | DFU 광고 모드 진입 | NUS -> SMP UUID 전환 | | `mls?` | `rls:` | LED 상태 변경 | | | `msn?` | `rsn:` | 배터리 전압 측정 | | | `mim?` | `rim:` | IMU FIFO 측정 | | | `mst?` | `rst:` | 온도 측정 | IMU 내부 온도 | | `mbb?` | `rbb:` -> `reb:` x6 -> `raa:` | 배터리 + IMU + 온도 + 6채널 echo | 주기 측정(자동 측정) | | `mtb?` | `reb:` x6 + `raa:` -> `rim:` | Piezo sweep + IMU FIFO | 정렬모드 | | `mcf?` | `rcf:` | 측정 파라미터 읽기 | | | `mcs?` | `rcs:` | 측정 파라미터 쓰기 | NVS 저장 | | `mid?` | `rid:` | 기기 정보 일괄 읽기 | FW version, HW version, Serial number | | `mfv?` | `rfv:` | FW version 읽기 | | | `mrh?` | `rrh:` | HW version 읽기 | | | `mrs?` | `rrs:` | Serial number 읽기 | | | `mwh?` | `rwh:` | HW version 쓰기 | 생산용, NVS 저장 | | `mws?` | `rws:` | Serial number 쓰기 | 생산용, NVS 저장 | | `mpz?` | `rpz:` | Passkey 쓰기 | 생산용, NVS 저장, 생산 완료 후 `rxd:` 차단 | | `mpa?` | `rpa:` | Piezo 전원 ON | 테스트용 | | `mpb?` | `rpb:` | Piezo 전원 OFF | 테스트용 | | `mpc?` | `rpc:` | Piezo burst only | 테스트용 | | `mec?` | `reb:` -> `raa:` | 단일 채널 burst + echo capture | 테스트용 | | `mad?` | `reb:` -> `raa:` | ADC only capture | 테스트용 | | `maa?` | `reb:` x6 -> `raa:` | 6채널 echo sweep | 테스트용 | ## 주요 prj.conf 설정 | 설정 | 값 | 역할 | |---|---|---| | `CONFIG_SERIAL` | `n` | UART 비활성화, P0.08 충돌 방지 | | `CONFIG_BT` | `y` | BLE stack | | `CONFIG_BT_NUS` | `y` | Nordic UART Service | | `CONFIG_BT_SMP` | `y` | BLE pairing/security | | `CONFIG_BT_SMP_ENFORCE_MITM` | `y` | MITM 요구 | | `CONFIG_BT_SMP_SC_ONLY` | `y` | LE Secure Connections only | | `CONFIG_BT_SETTINGS` | `y` | BLE bonding/settings 저장 | | `CONFIG_BT_L2CAP_TX_MTU` | `247` | 큰 NUS 패킷 전송 | | `CONFIG_ADC` | `y` | 배터리 ADC | | `CONFIG_I2C` | `y` | IMU I2C | | `CONFIG_NRFX_SPIM` | `y` | ADC121S051 SPIM capture | | `CONFIG_BOOTLOADER_MCUBOOT` | `y` | MCUboot 사용 | | `CONFIG_MCUMGR_TRANSPORT_BT` | `y` | BLE DFU transport | | `CONFIG_NVS` | `y` | NVS 저장소 | | `CONFIG_SETTINGS` | `y` | Zephyr settings subsystem | | `CONFIG_SETTINGS_NVS` | `y` | settings NVS backend | ## 주요 핀 매핑 | 이름 | 핀 | 역할 | |---|---|---| | `PWR_HOLD` | P0.08 | 전원 래치, active high | | `BUTTON_CHECK` | P1.08 | 전원 버튼 | | `LED_BLE` | P0.12 | 녹색 LED, active low | | `FUNCTION_LED` | P0.29 | 주황 LED, active low | | Battery ADC | P0.04 / AIN2 | 배터리 전압 측정 | | I2C0 SCL | P1.14 | ICM42670P SCL | | I2C0 SDA | P1.15 | ICM42670P SDA | | `PIEZO_PWR` | P1.09 | Piezo 전원 enable | | `PIEZO_PE` | P0.25 | Piezo pulse enable | | `PIEZO_P_OUT` | P1.07 | Piezo P pulse | | `PIEZO_N_OUT` | P1.06 | Piezo N pulse | | `PIEZO_DMP` | P1.00 | Piezo dump | | `MUX_EN_A` | P0.21 | MUX enable A | | `MUX_EN_B` | P0.23 | MUX enable B | | `MUX_SEL0` | P1.10 | MUX select 0 | | `MUX_SEL1` | P0.28 | MUX select 1 | | `ECHO_SCLK` | P0.14 | ADC121S051 SCLK | | `ECHO_MISO` | P0.15 | ADC121S051 MISO | | `ECHO_CS` | P0.19 | ADC121S051 CS |