- Piezo 6ch 측정 + 센서(배터리, IMU, 온도) 측정: mbb 명령어 추가
- Flash Memory Piezo 측정 파라미터 추가 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# VesiScan-Basic 코드 리뷰 현황 보고서
|
# VesiScan-Basic 코드 리뷰 현황 보고서
|
||||||
|
|
||||||
작성일: 2026-03-16
|
작성일: 2026-03-17
|
||||||
대상: VesiScan BASIC 펌웨어 전체 (nRF52840 + S140 SoftDevice)
|
대상: VesiScan BASIC 펌웨어 전체 (nRF52840 + S140 SoftDevice)
|
||||||
기준 문서: CODE_REVIEW.pdf (2026-03-15)
|
기준 문서: CODE_REVIEW.pdf (2026-03-15)
|
||||||
현재 빌드: DEBUG_MINIMAL_BOOT=1, BLE_DEV_MODE=1
|
현재 빌드: DEBUG_MINIMAL_BOOT=1, BLE_DEV_MODE=1
|
||||||
@@ -157,8 +157,8 @@ cat_interface.c 삭제(EEPROM/AES 코드 전체 삭제). TWI 인스턴스(m_twi)
|
|||||||
| m_encrypted_text[16] | main.c:194 | 삭제 | **미완료** |
|
| m_encrypted_text[16] | main.c:194 | 삭제 | **미완료** |
|
||||||
| m_encrypted_text2[16] | main.c:195 | 삭제 | **미완료** |
|
| m_encrypted_text2[16] | main.c:195 | 삭제 | **미완료** |
|
||||||
| m_decrypted_text[16] | main.c:196 | 삭제 | **미완료** |
|
| m_decrypted_text[16] | main.c:196 | 삭제 | **미완료** |
|
||||||
| DEVICE_NAME | cmd_parse.c | 삭제 | 확인 필요 |
|
| DEVICE_NAME | cmd_parse.c | 삭제 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| HW_NO[12] | cmd_parse.c | 삭제 | **미완료** |
|
| HW_NO[12] | cmd_parse.c | 삭제 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| AES_KEY_SIZE | main.c:154 | 삭제 | **미완료** |
|
| AES_KEY_SIZE | main.c:154 | 삭제 | **미완료** |
|
||||||
| AES_BLOCK_SIZE | main.c:155 | 삭제 | **미완료** |
|
| AES_BLOCK_SIZE | main.c:155 | 삭제 | **미완료** |
|
||||||
| suppress_unused_warnings() | main.c:239 | 삭제 | **미완료** |
|
| suppress_unused_warnings() | main.c:239 | 삭제 | **미완료** |
|
||||||
@@ -167,7 +167,7 @@ cat_interface.c 삭제(EEPROM/AES 코드 전체 삭제). TWI 인스턴스(m_twi)
|
|||||||
|
|
||||||
### 2.3.1 cmd_parse.c → parser.c 통합 현황
|
### 2.3.1 cmd_parse.c → parser.c 통합 현황
|
||||||
|
|
||||||
현재 구조: main.c → `received_command_process()` [cmd_parse.c] → `dr_cmd_parser()` [parser.c] → 실패 시 레거시 if-else 체인 [cmd_parse.c]
|
현재 구조: main.c → `dr_cmd_parser()` [parser.c] (cmd_parse.c 삭제 완료)
|
||||||
|
|
||||||
#### parser.c 명령어 테이블 (g_cmd_table)
|
#### parser.c 명령어 테이블 (g_cmd_table)
|
||||||
|
|
||||||
@@ -207,40 +207,40 @@ cat_interface.c 삭제(EEPROM/AES 코드 전체 삭제). TWI 인스턴스(m_twi)
|
|||||||
| `sst?` | Cmd_sst | false | Ready 응답 | 비활성 |
|
| `sst?` | Cmd_sst | false | Ready 응답 | 비활성 |
|
||||||
| `mfv?` | Cmd_mfv | true | 펌웨어 버전 읽기 | ssv? 대체 |
|
| `mfv?` | Cmd_mfv | true | 펌웨어 버전 읽기 | ssv? 대체 |
|
||||||
|
|
||||||
#### cmd_parse.c 레거시 명령어 (parser.c에 없는 것)
|
#### cmd_parse.c 레거시 명령어 → parser.c 이전 완료
|
||||||
|
|
||||||
| 태그 | 상태 | 기능 | 비고 |
|
| 태그 | 기능 | 비고 |
|
||||||
|------|------|------|------|
|
|------|------|------|
|
||||||
| `spz?` | 활성 | 패스키 쓰기 | → parser.c `mpz?`로 대체 완료 |
|
| `spz?` | 패스키 쓰기 | → parser.c `mpz?`로 대체 완료 |
|
||||||
| `sqz?` | 활성 | 패스키 읽기 | → parser.c `mqz?`로 대체 완료 |
|
| `sqz?` | 패스키 읽기 | → parser.c `mqz?`로 대체 완료 |
|
||||||
| `sxz?` | 활성 | life_cycle 쓰기 | → parser.c `mxz?`로 대체 완료 |
|
| `sxz?` | life_cycle 쓰기 | → parser.c `mxz?`로 대체 완료 |
|
||||||
| `syz?` | 활성 | life_cycle 읽기 | → parser.c `myz?`로 대체 완료 |
|
| `syz?` | life_cycle 읽기 | → parser.c `myz?`로 대체 완료 |
|
||||||
| `sez?` | 활성 (stub) | AGC gain — HW 제거됨 | param_error만 응답 |
|
| `sez?` | AGC gain (stub) | cmd_parse.c와 함께 삭제 |
|
||||||
| `sfz?` | 활성 (stub) | AGC gain — HW 제거됨 | param_error만 응답 |
|
| `sfz?` | AGC gain (stub) | cmd_parse.c와 함께 삭제 |
|
||||||
| `ssv?` | `if(0&&)` 비활성 | 펌웨어 버전 | → parser.c `mfv?`로 대체됨 |
|
| `ssv?` | 펌웨어 버전 | → parser.c `mfv?`로 대체됨 |
|
||||||
| `ssz?` | `if(0&&)` 비활성 | 시리얼번호 쓰기 | → parser.c `mws?`로 대체됨 |
|
| `ssz?` | 시리얼번호 쓰기 | → parser.c `mws?`로 대체됨 |
|
||||||
| `srz?` | `if(0&&)` 비활성 | 시리얼번호 읽기 | → parser.c `mrs?`로 대체됨 |
|
| `srz?` | 시리얼번호 읽기 | → parser.c `mrs?`로 대체됨 |
|
||||||
| `siz?` | `if(0&&)` 비활성 | HW번호 읽기 | → parser.c `mrh?`로 대체됨 |
|
| `siz?` | HW번호 읽기 | → parser.c `mrh?`로 대체됨 |
|
||||||
| `shz?` | `if(0&&)` 비활성 | HW번호 쓰기 | → parser.c `mwh?`로 대체됨 |
|
| `shz?` | HW번호 쓰기 | → parser.c `mwh?`로 대체됨 |
|
||||||
|
|
||||||
#### 통합 남은 작업
|
#### 통합 작업 현황
|
||||||
|
|
||||||
| # | 작업 | 현재 상태 |
|
| # | 작업 | 현재 상태 |
|
||||||
|---|------|----------|
|
|---|------|----------|
|
||||||
| 1 | parser.c에 누락 명령어 추가 (mpz/mqz/mxz/myz) | **완료** |
|
| 1 | parser.c에 누락 명령어 추가 (mpz/mqz/mxz/myz) | **완료** |
|
||||||
| 2 | received_command_process() 래퍼를 main.c로 이동 | **미완료** |
|
| 2 | received_command_process() 래퍼를 main.c로 이동 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| 3 | 전역 변수 (SERIAL_NO, m_static_passkey 등) main.c로 이동 | **미완료** |
|
| 3 | 전역 변수 (SERIAL_NO, m_static_passkey 등) main.c로 이동 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| 4 | cmd_parse.h include 정리 (7개 파일) | **미완료** |
|
| 4 | cmd_parse.h include 정리 (7개 파일) | **완료** (cmd_parse.h 삭제됨) |
|
||||||
| 5 | cmd_parse.c / cmd_parse.h 삭제 | **미완료** |
|
| 5 | cmd_parse.c / cmd_parse.h 삭제 | **완료** |
|
||||||
| 6 | Keil 프로젝트 파일 업데이트 | **미완료** |
|
| 6 | Keil 프로젝트 파일 업데이트 | **완료** |
|
||||||
|
|
||||||
### 2.4 주석 처리된 코드
|
### 2.4 주석 처리된 코드
|
||||||
|
|
||||||
| 위치 | 내용 | 판정 | 현재 상태 |
|
| 위치 | 내용 | 판정 | 현재 상태 |
|
||||||
|------|------|------|----------|
|
|------|------|------|----------|
|
||||||
| main_timer.c:37-88 | FEATURE_DETAIL_VALUE_FULL 주석 블록 | 삭제 | **미완료** |
|
| main_timer.c:37-88 | FEATURE_DETAIL_VALUE_FULL 주석 블록 | 삭제 | **미완료** |
|
||||||
| cmd_parse.c:282-317 | serial_to_passkey_hash, test_eeprom_page_rw | 삭제 | **미완료** |
|
| cmd_parse.c:282-317 | serial_to_passkey_hash, test_eeprom_page_rw | 삭제 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| cmd_parse.c:87-88 | pd_adc_half/full_a_start extern | 삭제 | 확인 필요 |
|
| cmd_parse.c:87-88 | pd_adc_half/full_a_start extern | 삭제 | **완료** (cmd_parse.c 삭제됨) |
|
||||||
| battery_saadc.c:22 | //#include "fstorage.h" | 삭제 | **미완료** |
|
| battery_saadc.c:22 | //#include "fstorage.h" | 삭제 | **미완료** |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -297,11 +297,11 @@ uvprojx 수정 작업 없음.
|
|||||||
|
|
||||||
- `binary_tx_handler()` 함수 본체 삭제
|
- `binary_tx_handler()` 함수 본체 삭제
|
||||||
- 모든 호출처를 `dr_binary_tx_safe()`로 교체 완료
|
- 모든 호출처를 `dr_binary_tx_safe()`로 교체 완료
|
||||||
- cmd_parse.c (22곳 + 함수 포인터 1곳)
|
- parser.c (17곳)
|
||||||
- battery_saadc.c (2곳)
|
- battery_saadc.c (2곳)
|
||||||
- app_raw.c (2곳)
|
- app_raw.c (2곳)
|
||||||
- tmp235_q1.c (1곳)
|
- tmp235_q1.c (1곳)
|
||||||
- parser.c (17곳)
|
- cmd_parse.c (22곳) → 이후 cmd_parse.c 삭제됨
|
||||||
- main.h 선언 제거, dr_util.c/dr_adc121s051.c의 옛날 extern 선언 제거
|
- main.h 선언 제거, dr_util.c/dr_adc121s051.c의 옛날 extern 선언 제거
|
||||||
- `dr_binary_tx_safe()`는 NRF_ERROR_RESOURCES 시 최대 100회 재시도 후 패킷 드롭, 연결 에러 시 graceful 리턴
|
- `dr_binary_tx_safe()`는 NRF_ERROR_RESOURCES 시 최대 100회 재시도 후 패킷 드롭, 연결 에러 시 graceful 리턴
|
||||||
- `data_tx_handler()`의 APP_ERROR_CHECK도 DBG_PRINTF로 교체 — 예상치 못한 에러 시에도 패킷 드롭 후 정상 동작 유지
|
- `data_tx_handler()`의 APP_ERROR_CHECK도 DBG_PRINTF로 교체 — 예상치 못한 에러 시에도 패킷 드롭 후 정상 동작 유지
|
||||||
@@ -316,11 +316,11 @@ uvprojx 수정 작업 없음.
|
|||||||
|
|
||||||
#### B3: extern + 초기화 동시 사용
|
#### B3: extern + 초기화 동시 사용
|
||||||
|
|
||||||
파일: cmd_parse.c
|
파일: cmd_parse.c (삭제됨)
|
||||||
|
|
||||||
현재 상태: **완료**
|
현재 상태: **완료**
|
||||||
|
|
||||||
`extern int8_t pd_adc_counts[4] = {8, 16, 24, 32};` 선언이 제거됨.
|
`extern int8_t pd_adc_counts[4] = {8, 16, 24, 32};` 선언이 제거됨. 이후 cmd_parse.c 삭제.
|
||||||
|
|
||||||
#### B4: memset/memcpy 버퍼 크기 불일치 및 매직 넘버
|
#### B4: memset/memcpy 버퍼 크기 불일치 및 매직 넘버
|
||||||
|
|
||||||
@@ -334,6 +334,33 @@ uvprojx 수정 작업 없음.
|
|||||||
|
|
||||||
스택/힙 오버플로우로 인한 메모리 손상 가능성이 있는 심각한 버그.
|
스택/힙 오버플로우로 인한 메모리 손상 가능성이 있는 심각한 버그.
|
||||||
|
|
||||||
|
#### B5: maa? 명령 err=2 (MAA_NUM_SAMPLES 초과)
|
||||||
|
|
||||||
|
파일: parser.c, dr_adc121s051.c
|
||||||
|
|
||||||
|
현재 상태: **완료** — jhChun 26.03.17
|
||||||
|
|
||||||
|
MAA_NUM_SAMPLES(140)이 DR_ADC_ECHO_SAMPLES_MAX(100)보다 커서 maa_async_start()에서 무조건 DR_ADC_ERR_INVALID_PARAM(err=2) 반환. MAA_NUM_SAMPLES를 100으로 변경하여 해결.
|
||||||
|
|
||||||
|
#### B5-2: mec/maa 명령 시 Piezo 전원 미관리
|
||||||
|
|
||||||
|
파일: parser.c, dr_adc121s051.c
|
||||||
|
|
||||||
|
현재 상태: **완료** — jhChun 26.03.17
|
||||||
|
|
||||||
|
- mec?, maa? 수신 시 `dr_piezo_is_power_on()` 확인 후 꺼져있으면 자동 `dr_piezo_system_init()` (Active)
|
||||||
|
- mec: 응답 송신 후 즉시 `dr_piezo_power_off()` (Sleep)
|
||||||
|
- maa: 비동기 완료 콜백에서 `dr_piezo_power_off()` (Sleep)
|
||||||
|
- `dr_piezo_is_power_on()` 함수 신규 추가 (dr_piezo.c/h)
|
||||||
|
|
||||||
|
#### B5-3: Cmd_mpa dr_piezo_power_on() 중복 호출
|
||||||
|
|
||||||
|
파일: parser.c
|
||||||
|
|
||||||
|
현재 상태: **완료** — jhChun 26.03.17
|
||||||
|
|
||||||
|
`dr_piezo_power_on()` + `dr_piezo_system_init()` 둘 다 호출하고 있었으나, `dr_piezo_system_init()` 내부에 이미 `dr_piezo_power_on()`이 포함되어 있어 중복 제거.
|
||||||
|
|
||||||
### 5.2 심각도 중간 (MEDIUM)
|
### 5.2 심각도 중간 (MEDIUM)
|
||||||
|
|
||||||
#### B6: battery_event_handler에서 floating-point 연산
|
#### B6: battery_event_handler에서 floating-point 연산
|
||||||
@@ -360,11 +387,7 @@ batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0 * 142) / 100;
|
|||||||
|
|
||||||
파일: cmd_parse.c:57
|
파일: cmd_parse.c:57
|
||||||
|
|
||||||
현재 상태: **완료** (해결됨)
|
현재 상태: **완료** (cmd_parse.c 삭제됨)
|
||||||
|
|
||||||
변수가 5초 타임아웃 추적에 활용되고 있음:
|
|
||||||
- cmd_parse.c:483에서 초기값 확인
|
|
||||||
- cmd_parse.c:489에서 5초 경과 비교
|
|
||||||
|
|
||||||
#### B9: config_load() goto 기반 흐름
|
#### B9: config_load() goto 기반 흐름
|
||||||
|
|
||||||
@@ -509,6 +532,9 @@ BLE_GAP_EVT_CONNECTED/DISCONNECTED 핸들러에 IMU 타이머 start/stop 로직
|
|||||||
| 2 | B1: BLE TX 큐 풀 시 시스템 먹통 (binary_tx_handler → dr_binary_tx_safe 교체) | HIGH | **완료** |
|
| 2 | B1: BLE TX 큐 풀 시 시스템 먹통 (binary_tx_handler → dr_binary_tx_safe 교체) | HIGH | **완료** |
|
||||||
| 3 | B2: BLE TX 에러 핸들링 로직 반전 | HIGH | **완료** |
|
| 3 | B2: BLE TX 에러 핸들링 로직 반전 | HIGH | **완료** |
|
||||||
| 4 | B3: extern + 초기화 동시 사용 | HIGH | **완료** |
|
| 4 | B3: extern + 초기화 동시 사용 | HIGH | **완료** |
|
||||||
|
| 5 | B5: maa? err=2 (MAA_NUM_SAMPLES > DR_ADC_ECHO_SAMPLES_MAX) | HIGH | **완료** |
|
||||||
|
| 6 | B5-2: mec/maa Piezo 자동 전원 관리 | MEDIUM | **완료** |
|
||||||
|
| 7 | B5-3: Cmd_mpa dr_piezo_power_on 중복 호출 | LOW | **완료** |
|
||||||
|
|
||||||
### 1차 정리 (미사용 코드/EEPROM 삭제)
|
### 1차 정리 (미사용 코드/EEPROM 삭제)
|
||||||
|
|
||||||
@@ -517,7 +543,7 @@ BLE_GAP_EVT_CONNECTED/DISCONNECTED 핸들러에 IMU 타이머 start/stop 로직
|
|||||||
| 5 | 미사용 HW 드라이버 삭제 (1.2절) | **완료** |
|
| 5 | 미사용 HW 드라이버 삭제 (1.2절) | **완료** |
|
||||||
| 6 | cat_interface.c EEPROM 기능 삭제 + TWI를 i2c_manager.c로 통합 (1.5절) | **완료** |
|
| 6 | cat_interface.c EEPROM 기능 삭제 + TWI를 i2c_manager.c로 통합 (1.5절) | **완료** |
|
||||||
| 7 | cmd_parse.c EEPROM 호출 -> FDS 전환 (1.5.4절) | **완료** |
|
| 7 | cmd_parse.c EEPROM 호출 -> FDS 전환 (1.5.4절) | **완료** |
|
||||||
| 8 | cmd_parse.c → parser.c 통합 (2.3.1절) | **진행 중** (명령어 이전 완료, 파일 삭제 미완료) |
|
| 8 | cmd_parse.c → parser.c 통합 (2.3.1절) | **완료** |
|
||||||
| 9 | 미사용 전역변수 + HW_NO 삭제 (2.2-2.3절) | **미완료** |
|
| 9 | 미사용 전역변수 + HW_NO 삭제 (2.2-2.3절) | **미완료** |
|
||||||
| 10 | DEBUG_MINIMAL_BOOT 조건 제거 (3절) | **미완료** |
|
| 10 | DEBUG_MINIMAL_BOOT 조건 제거 (3절) | **미완료** |
|
||||||
| 11 | Keil uvprojx 소스 참조 제거 (4절) | 확인 필요 |
|
| 11 | Keil uvprojx 소스 참조 제거 (4절) | 확인 필요 |
|
||||||
|
|||||||
@@ -791,7 +791,7 @@ dr_adc_err_t dr_adc_burst_capture_transmit(uint8_t freq_option, uint16_t delay_u
|
|||||||
if (num_samples == 0 || num_samples > DR_ADC_ECHO_SAMPLES_MAX)
|
if (num_samples == 0 || num_samples > DR_ADC_ECHO_SAMPLES_MAX)
|
||||||
return DR_ADC_ERR_INVALID_PARAM;
|
return DR_ADC_ERR_INVALID_PARAM;
|
||||||
if (freq_option > 9) freq_option = 0; /* Invalid -> default 1.8MHz */
|
if (freq_option > 9) freq_option = 0; /* Invalid -> default 1.8MHz */
|
||||||
if (cycles < 3 || cycles > 9) cycles = 5; /* Valid range: 3~9, default 5 */
|
if (cycles < 3 || cycles > 7) cycles = 5; /* Valid range: 3~7, default 5 */
|
||||||
if (averaging == 0) averaging = 1; /* Minimum 1 */
|
if (averaging == 0) averaging = 1; /* Minimum 1 */
|
||||||
if (averaging > 1000) averaging = 1000; /* Maximum 1000 */
|
if (averaging > 1000) averaging = 1000; /* Maximum 1000 */
|
||||||
if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; /* 채널 범위 검증 */
|
if (piezo_ch >= MAA_NUM_CHANNELS) piezo_ch = 0; /* 채널 범위 검증 */
|
||||||
@@ -1018,7 +1018,7 @@ dr_adc_err_t dr_adc_capture_channel_only(uint8_t freq_option, uint16_t delay_us,
|
|||||||
if (num_samples == 0 || num_samples > MAA_SAMPLES_MAX)
|
if (num_samples == 0 || num_samples > MAA_SAMPLES_MAX)
|
||||||
return DR_ADC_ERR_INVALID_PARAM;
|
return DR_ADC_ERR_INVALID_PARAM;
|
||||||
if (freq_option > 3) freq_option = 0;
|
if (freq_option > 3) freq_option = 0;
|
||||||
if (cycles < 3 || cycles > 9) cycles = 5;
|
if (cycles < 3 || cycles > 7) cycles = 5;
|
||||||
if (averaging == 0) averaging = 1;
|
if (averaging == 0) averaging = 1;
|
||||||
if (averaging > 1000) averaging = 1000;
|
if (averaging > 1000) averaging = 1000;
|
||||||
if (piezo_ch > (MAA_NUM_CHANNELS - 1)) piezo_ch = 0;
|
if (piezo_ch > (MAA_NUM_CHANNELS - 1)) piezo_ch = 0;
|
||||||
@@ -1448,6 +1448,13 @@ static void maa_async_send_completion(uint16_t status)
|
|||||||
|
|
||||||
g_maa_ctx.state = MAA_ASYNC_IDLE;
|
g_maa_ctx.state = MAA_ASYNC_IDLE;
|
||||||
ADC_LOG("maa_async: complete, status=0x%04X", status);
|
ADC_LOG("maa_async: complete, status=0x%04X", status);
|
||||||
|
|
||||||
|
/* 완료 콜백 호출 (mbb? 등에서 센서 측정 체인 트리거용) */
|
||||||
|
if (g_maa_ctx.on_complete_cb) {
|
||||||
|
void (*cb)(void) = g_maa_ctx.on_complete_cb;
|
||||||
|
g_maa_ctx.on_complete_cb = NULL; /* 1회성: 재호출 방지 */
|
||||||
|
cb();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
@@ -1471,12 +1478,13 @@ dr_adc_err_t maa_async_start(uint8_t freq_option, uint16_t delay_us,
|
|||||||
g_maa_ctx.freq_option = freq_option;
|
g_maa_ctx.freq_option = freq_option;
|
||||||
g_maa_ctx.delay_us = delay_us;
|
g_maa_ctx.delay_us = delay_us;
|
||||||
g_maa_ctx.num_samples = num_samples;
|
g_maa_ctx.num_samples = num_samples;
|
||||||
g_maa_ctx.cycles = (cycles < 3 || cycles > 9) ? 5 : cycles;
|
g_maa_ctx.cycles = (cycles < 3 || cycles > 7) ? 5 : cycles;
|
||||||
g_maa_ctx.averaging = (averaging == 0) ? 1 : ((averaging > 1000) ? 1000 : averaging);
|
g_maa_ctx.averaging = (averaging == 0) ? 1 : ((averaging > 1000) ? 1000 : averaging);
|
||||||
g_maa_ctx.ble_buffer = ble_buffer;
|
g_maa_ctx.ble_buffer = ble_buffer;
|
||||||
g_maa_ctx.current_ch = 0;
|
g_maa_ctx.current_ch = 0;
|
||||||
g_maa_ctx.current_pkt = 0;
|
g_maa_ctx.current_pkt = 0;
|
||||||
g_maa_ctx.data_offset = 0;
|
g_maa_ctx.data_offset = 0;
|
||||||
|
g_maa_ctx.on_complete_cb = NULL; /* 기본: 콜백 없음 (maa?) */
|
||||||
|
|
||||||
ADC_LOG("maa_async_start: freq=%u delay=%u samples=%u cycles=%u avg=%u",
|
ADC_LOG("maa_async_start: freq=%u delay=%u samples=%u cycles=%u avg=%u",
|
||||||
freq_option, delay_us, num_samples, g_maa_ctx.cycles, g_maa_ctx.averaging);
|
freq_option, delay_us, num_samples, g_maa_ctx.cycles, g_maa_ctx.averaging);
|
||||||
@@ -1568,3 +1576,8 @@ void maa_async_set_auto_power(bool on)
|
|||||||
g_maa_ctx.auto_powered = on;
|
g_maa_ctx.auto_powered = on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void maa_async_set_on_complete(void (*cb)(void))
|
||||||
|
{
|
||||||
|
g_maa_ctx.on_complete_cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ dr_adc_err_t dr_adc_measure_echo(dr_adc_echo_t *echo, const dr_adc_echo_config_t
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Piezo burst + Echo capture in one call
|
* @brief Piezo burst + Echo capture in one call
|
||||||
* @param cycles Number of burst cycles (3~9)
|
* @param cycles Number of burst cycles (3~7)
|
||||||
* @param delay_us Delay before capture (us)
|
* @param delay_us Delay before capture (us)
|
||||||
* @param num_samples Number of samples to capture
|
* @param num_samples Number of samples to capture
|
||||||
* @param echo Pointer to echo result structure
|
* @param echo Pointer to echo result structure
|
||||||
@@ -455,6 +455,7 @@ typedef struct {
|
|||||||
uint16_t total_packets; /**< Total packets for current channel */
|
uint16_t total_packets; /**< Total packets for current channel */
|
||||||
uint16_t data_packets; /**< Data packets for current channel */
|
uint16_t data_packets; /**< Data packets for current channel */
|
||||||
bool auto_powered; /**< true: 자동 전원 ON → 완료 후 OFF */
|
bool auto_powered; /**< true: 자동 전원 ON → 완료 후 OFF */
|
||||||
|
void (*on_complete_cb)(void); /**< 비동기 캡처 완료 후 호출될 콜백 (NULL이면 미사용) */
|
||||||
} maa_async_ctx_t;
|
} maa_async_ctx_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -466,7 +467,7 @@ typedef struct {
|
|||||||
* @param freq_option Frequency: 0=1.8MHz, 1=2.1MHz, 2=2.0MHz, 3=1.7MHz
|
* @param freq_option Frequency: 0=1.8MHz, 1=2.1MHz, 2=2.0MHz, 3=1.7MHz
|
||||||
* @param delay_us Capture delay (us)
|
* @param delay_us Capture delay (us)
|
||||||
* @param num_samples Samples per channel (1~200)
|
* @param num_samples Samples per channel (1~200)
|
||||||
* @param cycles Burst cycles (3~9)
|
* @param cycles Burst cycles (3~7)
|
||||||
* @param averaging Averaging count (1~1000)
|
* @param averaging Averaging count (1~1000)
|
||||||
* @param ble_buffer Working buffer (>= 240 bytes)
|
* @param ble_buffer Working buffer (>= 240 bytes)
|
||||||
* @return dr_adc_err_t DR_ADC_OK if started successfully
|
* @return dr_adc_err_t DR_ADC_OK if started successfully
|
||||||
@@ -507,5 +508,11 @@ void maa_async_abort(void);
|
|||||||
*/
|
*/
|
||||||
void maa_async_set_auto_power(bool on);
|
void maa_async_set_auto_power(bool on);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 비동기 캡처 완료 콜백 설정
|
||||||
|
* raa: 전송 + 전원 OFF 이후 호출된다. NULL이면 콜백 없음.
|
||||||
|
*/
|
||||||
|
void maa_async_set_on_complete(void (*cb)(void));
|
||||||
|
|
||||||
#endif /* DR_ADC121S051_H */
|
#endif /* DR_ADC121S051_H */
|
||||||
|
|
||||||
|
|||||||
205
pc_firm/parser.c
205
pc_firm/parser.c
@@ -80,13 +80,18 @@ extern bool con_single; /* 단일 연결 모드 플래그 */
|
|||||||
extern bool lock_check; /* 보안 잠금 상태 플래그 */
|
extern bool lock_check; /* 보안 잠금 상태 플래그 */
|
||||||
|
|
||||||
|
|
||||||
extern bool info4; /* true: 추가 정보(배터리/온도/IMU) 포함 측정 */
|
extern bool info4; /* true: 센서값을 전역 변수에 저장 (BLE 전송 안 함) */
|
||||||
extern bool ble_got_new_data; /* true: BLE로 새 데이터 수신됨 (처리 대기) */
|
extern bool ble_got_new_data; /* true: BLE로 새 데이터 수신됨 (처리 대기) */
|
||||||
extern bool go_batt; /* true: 배터리 측정 요청 플래그 */
|
extern bool go_batt; /* true: 배터리 측정 요청 플래그 */
|
||||||
extern bool motion_data_once; /* true: IMU 1회 측정, false: 연속 측정 */
|
extern bool motion_data_once; /* true: IMU 1회 측정, false: 연속 측정 */
|
||||||
extern bool motion_raw_data_enabled;/* true: IMU 원시 데이터 전송 활성화 */
|
extern bool motion_raw_data_enabled;/* true: IMU 원시 데이터 전송 활성화 */
|
||||||
extern int imu_read_direct(void); /* IMU 레지스터 직접 읽기 + BLE 전송 */
|
extern int imu_read_direct(void); /* IMU 레지스터 직접 읽기 + BLE 전송 */
|
||||||
|
|
||||||
|
/* info4 모드 센서값 저장 변수 (mbb? rbb: 패킷 조립용) */
|
||||||
|
extern volatile uint16_t info_batt; /* 배터리 전압 (mV) */
|
||||||
|
extern volatile uint16_t info_temp; /* 온도 (°C x 100) */
|
||||||
|
extern volatile uint16_t info_imu[6]; /* IMU 6축 (accel XYZ + gyro XYZ) */
|
||||||
|
|
||||||
extern void pressure_all_level_meas(void); /* 압력 센서 전체 측정 */
|
extern void pressure_all_level_meas(void); /* 압력 센서 전체 측정 */
|
||||||
extern void battery_timer_stop(void); /* 배터리 타이머 중지 */
|
extern void battery_timer_stop(void); /* 배터리 타이머 중지 */
|
||||||
extern void main_timer_start(void); /* 메인 타이머 시작 (주기적 측정 트리거) */
|
extern void main_timer_start(void); /* 메인 타이머 시작 (주기적 측정 트리거) */
|
||||||
@@ -108,7 +113,7 @@ extern config_data_t m_config; /* 전체 설정 구조체 (FDS 저장 대
|
|||||||
#define AGC_GAIN_SW(x) do { if(x) nrf_gpio_pin_set(GAIN_SW_PIN); else nrf_gpio_pin_clear(GAIN_SW_PIN); } while(0)
|
#define AGC_GAIN_SW(x) do { if(x) nrf_gpio_pin_set(GAIN_SW_PIN); else nrf_gpio_pin_clear(GAIN_SW_PIN); } while(0)
|
||||||
|
|
||||||
|
|
||||||
/* 피에조 초음파 트랜스듀서 제어 함수 */
|
/* ---- 피에조 관련 제어 함수 ---- */
|
||||||
extern void dr_piezo_power_on( void ); /* 피에조 회로 전원 ON (TX/RX 보드) */
|
extern void dr_piezo_power_on( void ); /* 피에조 회로 전원 ON (TX/RX 보드) */
|
||||||
extern void dr_piezo_power_off( void ); /* 피에조 회로 전원 OFF */
|
extern void dr_piezo_power_off( void ); /* 피에조 회로 전원 OFF */
|
||||||
extern bool dr_piezo_is_power_on( void ); /* 피에조 전원 상태 확인 */
|
extern bool dr_piezo_is_power_on( void ); /* 피에조 전원 상태 확인 */
|
||||||
@@ -117,6 +122,7 @@ extern void dr_piezo_burst_sw_18mhz(uint8_t cycles); /* 1.8MHz 버스트 펄스
|
|||||||
extern void dr_piezo_burst_sw_20mhz(uint8_t cycles); /* 2.0MHz 버스트 펄스 발생 */
|
extern void dr_piezo_burst_sw_20mhz(uint8_t cycles); /* 2.0MHz 버스트 펄스 발생 */
|
||||||
extern void dr_piezo_burst_sw_17mhz(uint8_t cycles); /* 1.7MHz 버스트 펄스 발생 */
|
extern void dr_piezo_burst_sw_17mhz(uint8_t cycles); /* 1.7MHz 버스트 펄스 발생 */
|
||||||
|
|
||||||
|
|
||||||
/* ---- 전역 변수 정의 (헤더에서 extern 선언) ---- */
|
/* ---- 전역 변수 정의 (헤더에서 extern 선언) ---- */
|
||||||
dr_platform_if_t g_plat = { 0, 0, 0 };
|
dr_platform_if_t g_plat = { 0, 0, 0 };
|
||||||
/* 플랫폼 인터페이스 구조체:
|
/* 플랫폼 인터페이스 구조체:
|
||||||
@@ -126,10 +132,11 @@ dr_platform_if_t g_plat = { 0, 0, 0 };
|
|||||||
bool g_log_enable = false;
|
bool g_log_enable = false;
|
||||||
/* 디버그 로그 전역 활성화 플래그 (g_plat.log와 함께 사용) */
|
/* 디버그 로그 전역 활성화 플래그 (g_plat.log와 함께 사용) */
|
||||||
|
|
||||||
/* ---- 내부 상수/구조체 정의 ---- */
|
|
||||||
|
|
||||||
|
/* ---- 내부 상수/구조체 정의 ---- */
|
||||||
#define DR_MAX_DATA 128 /* TAG 이후 데이터의 최대 바이트 수 */
|
#define DR_MAX_DATA 128 /* TAG 이후 데이터의 최대 바이트 수 */
|
||||||
|
|
||||||
|
|
||||||
/* 파싱된 명령 구조체 - 수신 패킷을 TAG와 데이터로 분리한 결과 */
|
/* 파싱된 명령 구조체 - 수신 패킷을 TAG와 데이터로 분리한 결과 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char tag[5]; /* 명령 TAG 문자열 (예: "sta?") 4글자 + '\0' */
|
char tag[5]; /* 명령 TAG 문자열 (예: "sta?") 4글자 + '\0' */
|
||||||
@@ -328,8 +335,8 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out)
|
|||||||
* BLE 명령어
|
* BLE 명령어
|
||||||
*
|
*
|
||||||
* A. 디바이스 상태 제어
|
* A. 디바이스 상태 제어
|
||||||
* - 전원 OFF (msq? / rsq:) : 확인 필요
|
* - 전원 OFF (msq? / rsq:)
|
||||||
* - 재부팅 (mss? / rss:) : 확인 필요
|
* - 재부팅 (mss? / rss:)
|
||||||
* - 본딩 정보 삭제 및 재부팅 (msr? / rsr:) : 확인 필요
|
* - 본딩 정보 삭제 및 재부팅 (msr? / rsr:) : 확인 필요
|
||||||
* - GPIO 제어(핀 테스트용, cmd? / rmd:)
|
* - GPIO 제어(핀 테스트용, cmd? / rmd:)
|
||||||
*
|
*
|
||||||
@@ -339,21 +346,22 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out)
|
|||||||
* - 시리얼 넘버 읽기 (mrs? / rrs:)
|
* - 시리얼 넘버 읽기 (mrs? / rrs:)
|
||||||
* - 시리얼 넘버 쓰기 (mws? / rws:)
|
* - 시리얼 넘버 쓰기 (mws? / rws:)
|
||||||
* - 펌웨어 버전 읽기 (mfv? / rfv:)
|
* - 펌웨어 버전 읽기 (mfv? / rfv:)
|
||||||
* - 패스키 읽기 (mqz? / rqz:) : 확인 필요, 필요 유무 검토(암호화 혹은 삭제)
|
* - 패스키 읽기 (mqz? / rqz:) : 필요 유무 검토(암호화 혹은 삭제)
|
||||||
* - 패스키 쓰기 (mpz? / rpz:) : 확인 필요
|
* - 패스키 쓰기 (mpz? / rpz:)
|
||||||
*
|
*
|
||||||
* C. 각종 센서 측정
|
* C. 각종 센서 측정
|
||||||
* - 배터리 전압 측정 (msn? / rsn:) - test용
|
* - 배터리 전압 측정 (msn? / rsn:) - test용
|
||||||
* - IMU 단발 측정 (msp? / rsp:) : 동기 - test용
|
* - IMU 단발 측정 (msp? / rsp:) : 동기 - test용
|
||||||
* - IMU 연속 스트리밍 (msi? / rsi:) : 비동기(타이머) 1초 주기, 확인 필요 - test용
|
* - IMU 연속 스트리밍 (msi? / rsi:) : 비동기(타이머) 1초 주기, 확인 필요 - test용
|
||||||
* - 온도 측정 (mso? / rso:) : 확인 필요 - test용
|
* - 온도 측정 (mso? / rso:) - test용
|
||||||
*
|
*
|
||||||
* D. Piezo 초음파 측정
|
* D. Piezo 초음파 측정
|
||||||
* - TX/RX 전원 활성화 (mpa? / rpa:)
|
* - TX/RX 전원 활성화 (mpa? / rpa:) - test용
|
||||||
* - TX/RX 전원 비활성화 (mpb? / rpb:)
|
* - TX/RX 전원 비활성화 (mpb? / rpb:) - test용
|
||||||
* - 단일 채널 Burst (mpc? / rpc:) - test용
|
* - 단일 채널 Burst (mpc? / rpc:) - test용
|
||||||
* - 단일 채널 Burst + ADC -> echo capture (mec? / reb: -> red: -> ree:)
|
* - 단일 채널 Burst + ADC -> echo capture (mec? / reb: -> red: -> ree:) : TX/RX Active -> 응답 -> TX/RX Sleep
|
||||||
* - 모든 채널 Burst + ADC -> echo capture (maa? / reb: -> red: -> raa:) : 확인 필요, 현재 모든 채널 = 4
|
* - 모든 채널 Burst + ADC -> echo capture (maa? / reb: -> red: -> raa:) : TX/RX Active -> 응답 -> TX/RX Sleep
|
||||||
|
* - 모든 채널 Burst + ADC -> echo capture (mbb? / reb: -> red: -> raa:) + 각종 센서 측정(배터리, IMU, 온도) : TX/RX Active -> 응답 -> TX/RX Sleep (NEW!)
|
||||||
*
|
*
|
||||||
* 삭제 명령어
|
* 삭제 명령어
|
||||||
* - 디바이스 활성화/슬립 : TX 전원 활성화/비활성화와 동일 기능
|
* - 디바이스 활성화/슬립 : TX 전원 활성화/비활성화와 동일 기능
|
||||||
@@ -364,7 +372,6 @@ static bool dr_parse_cmd(const uint8_t *buffer, uint8_t length, ParsedCmd *out)
|
|||||||
* - 단일 채널 ADC
|
* - 단일 채널 ADC
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
* 핸들러 함수 프로토타입 선언
|
* 핸들러 함수 프로토타입 선언
|
||||||
* - 반환값: 1=성공, 0=실패/비활성
|
* - 반환값: 1=성공, 0=실패/비활성
|
||||||
@@ -399,7 +406,8 @@ static int Cmd_mpa(const ParsedCmd *cmd); /* mpa? 피에조 TX/RX 회로 활
|
|||||||
static int Cmd_mpb(const ParsedCmd *cmd); /* mpb? 피에조 TX/RX 회로 비활성화 (전원 OFF) */
|
static int Cmd_mpb(const ParsedCmd *cmd); /* mpb? 피에조 TX/RX 회로 비활성화 (전원 OFF) */
|
||||||
static int Cmd_mpc(const ParsedCmd *cmd); /* mpc? 피에조 버스트 발생 (주파수/사이클 제어) */
|
static int Cmd_mpc(const ParsedCmd *cmd); /* mpc? 피에조 버스트 발생 (주파수/사이클 제어) */
|
||||||
static int Cmd_mec(const ParsedCmd *cmd); /* mec? 피에조 버스트 + 에코 캡처 (16비트 원시) */
|
static int Cmd_mec(const ParsedCmd *cmd); /* mec? 피에조 버스트 + 에코 캡처 (16비트 원시) */
|
||||||
static int Cmd_maa(const ParsedCmd *cmd); /* maa? 4채널 전체 캡처 (비동기 전송) */
|
static int Cmd_maa(const ParsedCmd *cmd); /* maa? 6채널 전체 캡처 (비동기 전송) */
|
||||||
|
static int Cmd_mbb(const ParsedCmd *cmd); /* mbb? 6채널 캡처 + 센서 측정 (배터리 + 온도 + IMU) */
|
||||||
|
|
||||||
|
|
||||||
/* ---- 명령 테이블 ---- */
|
/* ---- 명령 테이블 ---- */
|
||||||
@@ -411,13 +419,8 @@ typedef struct {
|
|||||||
int (*handler)(const ParsedCmd *cmd); /* 핸들러 함수 포인터 (1=성공, 0=실패) */
|
int (*handler)(const ParsedCmd *cmd); /* 핸들러 함수 포인터 (1=성공, 0=실패) */
|
||||||
} CmdEntry;
|
} CmdEntry;
|
||||||
|
|
||||||
/* 전체 명령 테이블 - 수신된 TAG와 순차 비교하여 일치하는 핸들러 호출
|
/* 전체 명령 테이블 - 수신된 TAG와 순차 비교하여 일치하는 핸들러 호출 */
|
||||||
*
|
|
||||||
* enabled=false인 명령은 개발 중
|
|
||||||
* 동일 핸들러를 여러 TAG에 매핑하여 레거시 호환성 유지 (예: mcj?=scj?, msn?=ssn?) -> 레거시 정리 중
|
|
||||||
*/
|
|
||||||
static CmdEntry g_cmd_table[] = {
|
static CmdEntry g_cmd_table[] = {
|
||||||
|
|
||||||
/* A. 디바이스 상태 제어 */
|
/* A. 디바이스 상태 제어 */
|
||||||
{ "msq?", true, Cmd_msq },
|
{ "msq?", true, Cmd_msq },
|
||||||
{ "mss?", true, Cmd_mss },
|
{ "mss?", true, Cmd_mss },
|
||||||
@@ -447,6 +450,7 @@ static CmdEntry g_cmd_table[] = {
|
|||||||
{ "mpc?", true, Cmd_mpc },
|
{ "mpc?", true, Cmd_mpc },
|
||||||
{ "mec?", true, Cmd_mec },
|
{ "mec?", true, Cmd_mec },
|
||||||
{ "maa?", true, Cmd_maa },
|
{ "maa?", true, Cmd_maa },
|
||||||
|
{ "mbb?", true, Cmd_mbb },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 명령 테이블 엔트리 수 (컴파일 타임 계산) */
|
/* 명령 테이블 엔트리 수 (컴파일 타임 계산) */
|
||||||
@@ -512,7 +516,6 @@ static int dr_cmd_dispatch(const ParsedCmd *cmd)
|
|||||||
int dr_cmd_parser(const uint8_t *buf, uint8_t len)
|
int dr_cmd_parser(const uint8_t *buf, uint8_t len)
|
||||||
{
|
{
|
||||||
ParsedCmd cmd;
|
ParsedCmd cmd;
|
||||||
g_plat.log("parser!!!!!!!!\r\n");
|
|
||||||
|
|
||||||
if (g_plat.log) g_plat.log("[PARSER] in len=%u crc=%u\r\n", len, g_plat.crc_check);
|
if (g_plat.log) g_plat.log("[PARSER] in len=%u crc=%u\r\n", len, g_plat.crc_check);
|
||||||
|
|
||||||
@@ -538,9 +541,6 @@ int dr_cmd_parser(const uint8_t *buf, uint8_t len)
|
|||||||
* 각 명령 핸들러 구현부
|
* 각 명령 핸들러 구현부
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
|
||||||
/* 2026-03-17: mta?, mtr? 삭제 */
|
|
||||||
|
|
||||||
|
|
||||||
/* msn? - 배터리 잔량 ADC 측정
|
/* msn? - 배터리 잔량 ADC 측정
|
||||||
* 응답: battery_level_meas() 내부에서 BLE 전송 처리 */
|
* 응답: battery_level_meas() 내부에서 BLE 전송 처리 */
|
||||||
static int Cmd_msn(const ParsedCmd *cmd)
|
static int Cmd_msn(const ParsedCmd *cmd)
|
||||||
@@ -553,14 +553,9 @@ static int Cmd_msn(const ParsedCmd *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 2026-03-17: mpn? 삭제 (압력센서 미탑재) */
|
|
||||||
|
|
||||||
/* mso? - TMP235-Q1 온도 센서 전압 측정
|
/* mso? - TMP235-Q1 온도 센서 전압 측정
|
||||||
* SAADC로 TMP235 출력 전압을 측정하여 BLE로 응답한다.
|
* SAADC로 TMP235 출력 전압을 측정하여 BLE로 응답
|
||||||
* 응답은 tmp235_q1.c의 콜백에서 자동 전송. */
|
* 응답은 tmp235_q1.c의 콜백에서 자동 전송 */
|
||||||
static int Cmd_mso(const ParsedCmd *cmd)
|
static int Cmd_mso(const ParsedCmd *cmd)
|
||||||
{
|
{
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
@@ -675,8 +670,6 @@ static int Cmd_mss(const ParsedCmd *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2026-03-17: mst? 삭제 */
|
|
||||||
|
|
||||||
/* mfv? - 펌웨어 버전 읽기
|
/* mfv? - 펌웨어 버전 읽기
|
||||||
*
|
*
|
||||||
* 응답: "rfv:" + 12자 ASCII 버전 문자열 (DR_DEVICE_VERSION)
|
* 응답: "rfv:" + 12자 ASCII 버전 문자열 (DR_DEVICE_VERSION)
|
||||||
@@ -748,7 +741,7 @@ static int Cmd_mpb(const ParsedCmd *cmd)
|
|||||||
* 에코 캡처 없이 버스트만 발생 (테스트/디버그용)
|
* 에코 캡처 없이 버스트만 발생 (테스트/디버그용)
|
||||||
*
|
*
|
||||||
* 파라미터 (Little-Endian uint16 x 3):
|
* 파라미터 (Little-Endian uint16 x 3):
|
||||||
* word 0: cycles (3~9, 기본값=5) - 버스트 펄스 사이클 수
|
* word 0: cycles (3~7, 기본값=5) - 버스트 펄스 사이클 수
|
||||||
* word 1: freq_option (기본값=1) - 주파수 선택
|
* word 1: freq_option (기본값=1) - 주파수 선택
|
||||||
* 0=1.8MHz, 1=2.1MHz(기본), 2=2.0MHz, 3=1.7MHz, 4=2.2MHz
|
* 0=1.8MHz, 1=2.1MHz(기본), 2=2.0MHz, 3=1.7MHz, 4=2.2MHz
|
||||||
* word 2: piezo_ch (0~7, 기본값=0) - 피에조 채널 선택
|
* word 2: piezo_ch (0~7, 기본값=0) - 피에조 채널 선택
|
||||||
@@ -785,8 +778,8 @@ static int Cmd_mpc(const ParsedCmd *cmd)
|
|||||||
cycles, freq_option, freq_str, piezo_ch);
|
cycles, freq_option, freq_str, piezo_ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 사이클 범위 검증: 3~9 유효 */
|
/* 사이클 범위 검증: 3~7 유효 */
|
||||||
if (cycles < 3 || cycles > 9) {
|
if (cycles < 3 || cycles > 7) {
|
||||||
dr_ble_return_1("rpc:", 2); /* 에러 응답: 범위 초과 */
|
dr_ble_return_1("rpc:", 2); /* 에러 응답: 범위 초과 */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -840,7 +833,7 @@ static int Cmd_mec(const ParsedCmd *cmd)
|
|||||||
{
|
{
|
||||||
uint16_t freq_option = 0; /* 기본 1.8MHz */
|
uint16_t freq_option = 0; /* 기본 1.8MHz */
|
||||||
uint16_t delay_us = 20; /* 기본 20us 딜레이 */
|
uint16_t delay_us = 20; /* 기본 20us 딜레이 */
|
||||||
uint16_t num_samples = 140; /* 기본 140샘플 (약 20cm 거리) */
|
uint16_t num_samples = 140; /* 기본 100샘플 */
|
||||||
uint16_t cycles = 5; /* 기본 5사이클 (유효: 3~7) */
|
uint16_t cycles = 5; /* 기본 5사이클 (유효: 3~7) */
|
||||||
uint16_t averaging = 1; /* 기본 1 (평균화 없음), 최대 1000 */
|
uint16_t averaging = 1; /* 기본 1 (평균화 없음), 최대 1000 */
|
||||||
uint16_t piezo_ch = 0; /* 기본 채널 0 (유효: 0~7) */
|
uint16_t piezo_ch = 0; /* 기본 채널 0 (유효: 0~7) */
|
||||||
@@ -979,11 +972,7 @@ static int Cmd_cmd(const ParsedCmd *cmd)
|
|||||||
*
|
*
|
||||||
* 버전 마커: 0xA000 (vA) = 비동기 4채널
|
* 버전 마커: 0xA000 (vA) = 비동기 4채널
|
||||||
*/
|
*/
|
||||||
#define MAA_FREQ_OPTION 1 /* 기본 2.1MHz */
|
/* 피에조 캡처 파라미터: FDS(m_config)에서 로드, 앱에서 변경 가능 */
|
||||||
#define MAA_DELAY_US 10 /* 버스트 후 10us 딜레이 */
|
|
||||||
#define MAA_NUM_SAMPLES 100 /* 140샘플 (약 25cm 거리) */
|
|
||||||
#define MAA_CYCLES 7 /* 7사이클 버스트 */
|
|
||||||
#define MAA_AVERAGING 5 /* 5회 평균화 */
|
|
||||||
|
|
||||||
static int Cmd_maa(const ParsedCmd *cmd)
|
static int Cmd_maa(const ParsedCmd *cmd)
|
||||||
{
|
{
|
||||||
@@ -1023,11 +1012,11 @@ static int Cmd_maa(const ParsedCmd *cmd)
|
|||||||
* - auto_powered=true면 완료 후 자동 전원 OFF
|
* - auto_powered=true면 완료 후 자동 전원 OFF
|
||||||
*=======================================================================*/
|
*=======================================================================*/
|
||||||
err = maa_async_start(
|
err = maa_async_start(
|
||||||
(uint8_t)MAA_FREQ_OPTION,
|
m_config.piezo_freq_option,
|
||||||
MAA_DELAY_US,
|
m_config.piezo_delay_us,
|
||||||
MAA_NUM_SAMPLES,
|
m_config.piezo_num_samples,
|
||||||
(uint8_t)MAA_CYCLES,
|
m_config.piezo_cycles,
|
||||||
(uint16_t)MAA_AVERAGING,
|
m_config.piezo_averaging,
|
||||||
ble_bin_buffer
|
ble_bin_buffer
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1049,6 +1038,128 @@ static int Cmd_maa(const ParsedCmd *cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mbb? 비동기 캡처 완료 후 콜백 - 센서 측정 체인 실행
|
||||||
|
*
|
||||||
|
* raa: 전송 + 피에조 전원 OFF 이후 호출
|
||||||
|
* info4 모드로 센서값을 전역 변수에 저장한 뒤, rbb: 패킷으로 일괄 전송
|
||||||
|
* SAADC 측정은 비동기(콜백)이므로 dr_sd_delay_ms()로 완료 대기
|
||||||
|
*
|
||||||
|
* 순서: 배터리 → IMU → (피에조 ON) → 온도
|
||||||
|
* 응답: rbb: [배터리mV(2)] [IMU 6축(12)] [온도°Cx100(2)] = 20바이트
|
||||||
|
*/
|
||||||
|
static void all_sensors(void)
|
||||||
|
{
|
||||||
|
if (g_plat.log) g_plat.log("[Cmd_mbb] measuring sensors\r\n");
|
||||||
|
|
||||||
|
info4 = true; /* 센서값을 전역 변수에 저장 (BLE 전송 안 함) */
|
||||||
|
|
||||||
|
/* 1) 배터리 전압 측정 → info_batt에 저장 */
|
||||||
|
battery_level_meas();
|
||||||
|
dr_sd_delay_ms(50); /* SAADC 콜백 완료 대기 */
|
||||||
|
|
||||||
|
/* 2) IMU 6축 단발 읽기 → info_imu[6]에 저장 */
|
||||||
|
hw_i2c_init_once();
|
||||||
|
imu_read_direct();
|
||||||
|
|
||||||
|
/* 3) 온도 측정 → info_temp에 저장 (TMP235는 피에조 전원 필요) */
|
||||||
|
if (!dr_piezo_is_power_on())
|
||||||
|
{
|
||||||
|
if (g_plat.log) g_plat.log("[Cmd_mbb] TX/RX Sleep -> Active for TEMP\r\n");
|
||||||
|
dr_piezo_system_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp235_voltage_level_meas();
|
||||||
|
dr_sd_delay_ms(50); /* SAADC 콜백 완료 대기 */
|
||||||
|
|
||||||
|
info4 = false;
|
||||||
|
|
||||||
|
/* rbb: 패킷 조립 및 전송 : [TAG 4B] [배터리 2B] [IMU 12B] [온도 2B] = 20바이트 = 10워드 */
|
||||||
|
uint8_t *buf = ble_bin_buffer;
|
||||||
|
|
||||||
|
buf[0] = 'r'; buf[1] = 'b'; buf[2] = 'b'; buf[3] = ':';
|
||||||
|
buf[4] = (uint8_t)(info_batt & 0xFF);
|
||||||
|
buf[5] = (uint8_t)(info_batt >> 8);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
buf[6 + i * 2] = (uint8_t)(info_imu[i] & 0xFF);
|
||||||
|
buf[6 + i * 2 + 1] = (uint8_t)(info_imu[i] >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[18] = (uint8_t)(info_temp & 0xFF);
|
||||||
|
buf[19] = (uint8_t)(info_temp >> 8);
|
||||||
|
dr_binary_tx_safe(buf, 10); /* 20바이트 = 10워드 */
|
||||||
|
|
||||||
|
if (g_plat.log) g_plat.log("[Cmd_mbb] rbb: sent (batt=%u temp=%u)\r\n", info_batt, info_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mbb? - 6채널 전체 캡처 + 센서 측정 (배터리/온도/IMU)
|
||||||
|
*
|
||||||
|
* 센서 측정(rbb:) → 6채널 비동기 캡처(reb:/red:/raa:) → TX/RX OFF
|
||||||
|
*
|
||||||
|
* 파라미터: mode (uint16, word 0) - 현재 mode=0만 지원
|
||||||
|
*
|
||||||
|
* 응답 흐름:
|
||||||
|
* 1) 센서 측정: rbb: [배터리(2) + IMU 6축(12) + 온도(2)]
|
||||||
|
* 2) 각 채널(CH0~CH5): reb: [헤더] → red: [데이터...]
|
||||||
|
* 3) 캡처 완료: raa: [상태]
|
||||||
|
*/
|
||||||
|
static int Cmd_mbb(const ParsedCmd *cmd)
|
||||||
|
{
|
||||||
|
uint16_t mode = 0;
|
||||||
|
dr_adc_err_t err;
|
||||||
|
|
||||||
|
(void)dr_get_u16(cmd, 0, &mode);
|
||||||
|
|
||||||
|
if (mode > 0)
|
||||||
|
{
|
||||||
|
dr_ble_return_1("raa:", 0xFFFF);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
all_sensors();
|
||||||
|
|
||||||
|
if (maa_async_is_busy())
|
||||||
|
{
|
||||||
|
dr_ble_return_1("raa:", 0xFFFE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 피에조 전원: OFF일 경우 ON → 완료 후 OFF */
|
||||||
|
if (!dr_piezo_is_power_on())
|
||||||
|
{
|
||||||
|
if (g_plat.log) g_plat.log("[Cmd_mbb] TX/RX Sleep -> Active\r\n");
|
||||||
|
dr_piezo_system_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 비동기 6채널 캡처 시작 (m_config 파라미터 사용) */
|
||||||
|
err = maa_async_start(
|
||||||
|
m_config.piezo_freq_option,
|
||||||
|
m_config.piezo_delay_us,
|
||||||
|
m_config.piezo_num_samples,
|
||||||
|
m_config.piezo_cycles,
|
||||||
|
m_config.piezo_averaging,
|
||||||
|
ble_bin_buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
if (err != DR_ADC_OK)
|
||||||
|
{
|
||||||
|
if (g_plat.log) g_plat.log("[Cmd_mbb] start failed err=%d\r\n", err);
|
||||||
|
single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err));
|
||||||
|
dr_binary_tx_safe(ble_bin_buffer, 3);
|
||||||
|
dr_piezo_power_off();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 완료 시 무조건 전원 OFF (전체 측정 사이클) */
|
||||||
|
maa_async_set_auto_power(true);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
* 설정: HW/시리얼 넘버 FDS 읽기/쓰기
|
* 설정: HW/시리얼 넘버 FDS 읽기/쓰기
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* [모듈 개요] 배터리 전압 및 압력센서 ADC 측정 모듈
|
* [모듈 개요] 배터리 전압 및 압력센서 ADC 측정 모듈 ---> 압력 센서 미탑재로 압력 센서 부분 삭제 예정
|
||||||
*
|
*
|
||||||
* nRF52840의 SAADC(Successive Approximation ADC)를 사용하여 다음을 수행한다:
|
* nRF52840의 SAADC(Successive Approximation ADC)를 사용하여 다음을 수행:
|
||||||
* 1) 배터리 전압 측정 (AIN2 채널, 1/3 프리스케일링)
|
* 1) 배터리 전압 측정 (AIN2 채널, 1/3 프리스케일링)
|
||||||
* - 5초 주기 타이머(battery_loop)로 반복 측정
|
* - 5초 주기 타이머(battery_loop)로 반복 측정
|
||||||
* - 저전압(3100mV 이하) 10회 연속 감지 시 자동 전원 OFF
|
* - 저전압(3100mV 이하) 10회 연속 감지 시 자동 전원 OFF
|
||||||
@@ -42,18 +42,22 @@
|
|||||||
//#include "fstorage.h"
|
//#include "fstorage.h"
|
||||||
#include "battery_saadc.h"
|
#include "battery_saadc.h"
|
||||||
#include "main_timer.h"
|
#include "main_timer.h"
|
||||||
#include "main.h" /* 2026-03-17: cmd_parse.h 삭제 → main.h */
|
#include "main.h"
|
||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
|
|
||||||
/* SAADC 내부 기준전압 600mV */
|
/* SAADC 내부 기준전압 600mV */
|
||||||
#define BATTERY_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
|
#define BATTERY_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
|
||||||
|
|
||||||
/* 1/3 프리스케일링 보상 계수 (입력 전압을 1/3로 분압하므로 x3, 추가 x2 = 총 x6) */
|
/* 1/3 프리스케일링 보상 계수 (입력 전압을 1/3로 분압하므로 x3, 추가 x2 = 총 x6) */
|
||||||
#define BATTERY_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
|
#define BATTERY_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
|
||||||
|
|
||||||
/* 10비트 ADC 최대 디지털 값 */
|
/* 10비트 ADC 최대 디지털 값 */
|
||||||
#define BATTERY_ADC_RES_10BITS 1023 /**< Maximum digital value for 10-bit ADC conversion. */
|
#define BATTERY_ADC_RES_10BITS 1023 /**< Maximum digital value for 10-bit ADC conversion. */
|
||||||
//#define PRESSURE_RESULT_IN_MILLI_VOLTS(adc) ((adc * 3600) / 1023)
|
//#define PRESSURE_RESULT_IN_MILLI_VOLTS(adc) ((adc * 3600) / 1023)
|
||||||
|
|
||||||
#define PRESSURE_OFFSET_DEFAULT 0 // 압력 offset. 캘리브레이션 시 사용 가능
|
#define PRESSURE_OFFSET_DEFAULT 0 // 압력 offset. 캘리브레이션 시 사용 가능
|
||||||
#define MV_PER_ADC_STEP 805 // 약 0.805mV per 1 LSB (nRF 12bit + scaling)
|
#define MV_PER_ADC_STEP 805 // 약 0.805mV per 1 LSB (nRF 12bit + scaling)
|
||||||
|
|
||||||
/**@brief Macro to convert the result of ADC conversion in millivolts.
|
/**@brief Macro to convert the result of ADC conversion in millivolts.
|
||||||
*
|
*
|
||||||
* @param[in] ADC_VALUE ADC result.
|
* @param[in] ADC_VALUE ADC result.
|
||||||
@@ -65,29 +69,33 @@
|
|||||||
|
|
||||||
/* 배터리 측정용 더블 버퍼 (SAADC가 비동기로 교대 사용) */
|
/* 배터리 측정용 더블 버퍼 (SAADC가 비동기로 교대 사용) */
|
||||||
static nrf_saadc_value_t adc_bufs[2];
|
static nrf_saadc_value_t adc_bufs[2];
|
||||||
|
|
||||||
/* 압력센서 2채널 ADC 버퍼 [0]=AIN7(P1), [1]=AIN4(P2) */
|
/* 압력센서 2채널 ADC 버퍼 [0]=AIN7(P1), [1]=AIN4(P2) */
|
||||||
static int16_t pressure_adc_buf[2]; //cj add 25/11/19
|
static int16_t pressure_adc_buf[2]; //cj add 25/11/19
|
||||||
static uint16_t convert_adc_to_mV(int16_t raw_adc); //cj add 25/11/19
|
static uint16_t convert_adc_to_mV(int16_t raw_adc); //cj add 25/11/19
|
||||||
|
|
||||||
/* 배터리 모니터링 반복 타이머 정의 */
|
/* 배터리 모니터링 반복 타이머 정의 */
|
||||||
APP_TIMER_DEF(m_battery_loop_timer_id);
|
APP_TIMER_DEF(m_battery_loop_timer_id);
|
||||||
|
|
||||||
/* 배터리 측정 주기: 5초 (밀리초 단위) */
|
/* 배터리 측정 주기: 5초 (밀리초 단위) */
|
||||||
#define BATTERY_LOOP_INTERVAL 5000
|
#define BATTERY_LOOP_INTERVAL 5000
|
||||||
|
|
||||||
/* 저전압 체크 플래그 — battery_loop에서 true로 설정, 핸들러에서 소비 */
|
/* 저전압 체크 플래그 — battery_loop에서 true로 설정, 핸들러에서 소비 */
|
||||||
bool low_battery_check = false;
|
bool low_battery_check = false;
|
||||||
|
|
||||||
/* info4: 전체 센서 데이터 수집 모드 플래그 (cmd_parse에서 설정) */
|
/* info4: 전체 센서 데이터 수집 모드 플래그 (cmd_parse에서 설정) */
|
||||||
extern bool info4; //cmd_parse
|
extern bool info4; // main.c
|
||||||
|
|
||||||
// cj add edit 25/11/24
|
// cj add edit 25/11/24
|
||||||
/* info4 모드에서 압력센서 측정값을 임시 저장하는 변수 (mV 단위) */
|
/* info4 모드에서 압력센서 측정값을 임시 저장하는 변수 (mV 단위) */
|
||||||
volatile uint16_t info_p1;
|
volatile uint16_t info_p1;
|
||||||
volatile uint16_t info_p2;
|
volatile uint16_t info_p2;
|
||||||
|
|
||||||
|
|
||||||
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
|
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
|
||||||
|
|
||||||
/* true가 되면 main_timer에서 전원 OFF 시퀀스 실행 */
|
/* true가 되면 main_timer에서 전원 OFF 시퀀스 실행 */
|
||||||
extern bool go_device_power_off;
|
extern bool go_device_power_off;
|
||||||
|
|
||||||
/* 다른 작업(IMU 등) 처리 중이면 true — 배터리 측정 스킵용 */
|
/* 다른 작업(IMU 등) 처리 중이면 true — 배터리 측정 스킵용 */
|
||||||
extern volatile bool processing;
|
extern volatile bool processing;
|
||||||
|
|
||||||
@@ -95,8 +103,10 @@ extern volatile bool processing;
|
|||||||
extern which_cmd_t cmd_type_t;
|
extern which_cmd_t cmd_type_t;
|
||||||
|
|
||||||
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
||||||
|
|
||||||
/* info4 모드에서 배터리 전압을 임시 저장 (mV 단위) */
|
/* info4 모드에서 배터리 전압을 임시 저장 (mV 단위) */
|
||||||
volatile uint16_t info_batt; //48_c
|
volatile uint16_t info_batt; //48_c
|
||||||
|
|
||||||
/* info4 순차 측정 제어 플래그: go_batt→ go_temp → motion */
|
/* info4 순차 측정 제어 플래그: go_batt→ go_temp → motion */
|
||||||
extern bool go_temp; //
|
extern bool go_temp; //
|
||||||
extern bool go_batt; //cmd_parse
|
extern bool go_batt; //cmd_parse
|
||||||
@@ -123,7 +133,9 @@ extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
|||||||
{
|
{
|
||||||
/* 음수 ADC 값은 0으로 처리 (노이즈 등으로 발생 가능) */
|
/* 음수 ADC 값은 0으로 처리 (노이즈 등으로 발생 가능) */
|
||||||
if (raw_adc < 0)
|
if (raw_adc < 0)
|
||||||
|
{
|
||||||
raw_adc = 0;
|
raw_adc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* 805 uV/LSB 스케일링: raw x 805 = uV, /1000 = mV */
|
/* 805 uV/LSB 스케일링: raw x 805 = uV, /1000 = mV */
|
||||||
int32_t mv = (int32_t)raw_adc * MV_PER_ADC_STEP; // 단위: 805 uV
|
int32_t mv = (int32_t)raw_adc * MV_PER_ADC_STEP; // 단위: 805 uV
|
||||||
@@ -131,11 +143,14 @@ extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
|||||||
|
|
||||||
/* 0~3500mV 범위로 클램핑하여 유효 범위 보장 */
|
/* 0~3500mV 범위로 클램핑하여 유효 범위 보장 */
|
||||||
if (mv < 0)
|
if (mv < 0)
|
||||||
|
{
|
||||||
mv = 0;
|
mv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mv > 3500)
|
if (mv > 3500)
|
||||||
|
{
|
||||||
mv = 3500;
|
mv = 3500;
|
||||||
|
}
|
||||||
|
|
||||||
return (uint16_t)mv;
|
return (uint16_t)mv;
|
||||||
}
|
}
|
||||||
@@ -192,15 +207,11 @@ void pressure_all_event_handler(nrf_drv_saadc_evt_t const * p_event)
|
|||||||
result_data[1] = p2_mV;
|
result_data[1] = p2_mV;
|
||||||
format_data(ble_bin_buffer, "rpn:", result_data,2);
|
format_data(ble_bin_buffer, "rpn:", result_data,2);
|
||||||
dr_binary_tx_safe(ble_bin_buffer,4);
|
dr_binary_tx_safe(ble_bin_buffer,4);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 배터리 전압 ADC 완료 콜백
|
* @brief 배터리 전압 ADC 완료 콜백
|
||||||
*
|
*
|
||||||
@@ -214,7 +225,6 @@ void pressure_all_event_handler(nrf_drv_saadc_evt_t const * p_event)
|
|||||||
*/
|
*/
|
||||||
void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
|
void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* 저전압 연속 감지 카운터 (static으로 호출 간 유지) */
|
/* 저전압 연속 감지 카운터 (static으로 호출 간 유지) */
|
||||||
static uint8_t low_battery_cnt = 0;
|
static uint8_t low_battery_cnt = 0;
|
||||||
|
|
||||||
@@ -238,60 +248,60 @@ void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
|
|||||||
|
|
||||||
/* ADC값 → mV 변환 (매크로: ADC x 600/1023 x 6) */
|
/* ADC값 → mV 변환 (매크로: ADC x 600/1023 x 6) */
|
||||||
batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val);
|
batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val);
|
||||||
|
|
||||||
/* 분압 저항 보정 계수 1.42 적용 → 실제 배터리 전압 */
|
/* 분압 저항 보정 계수 1.42 적용 → 실제 배터리 전압 */
|
||||||
batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42;
|
batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42;
|
||||||
|
|
||||||
/* === 저전압 체크 모드 (battery_loop 타이머에서 설정) === */
|
/* === 저전압 체크 모드 (battery_loop 타이머에서 설정) === */
|
||||||
if(low_battery_check == true) {
|
if(low_battery_check == true)
|
||||||
|
{
|
||||||
low_battery_check = false;
|
low_battery_check = false;
|
||||||
|
|
||||||
/* 배터리 전압이 LOW_BATTERY_VOLTAGE(3100mV) 이하인지 확인 */
|
/* 배터리 전압이 LOW_BATTERY_VOLTAGE(3100mV) 이하인지 확인 */
|
||||||
if(batt_lvl_in_milli_volt_1 <= LOW_BATTERY_VOLTAGE) {
|
if(batt_lvl_in_milli_volt_1 <= LOW_BATTERY_VOLTAGE)
|
||||||
|
{
|
||||||
/* 10회 연속 저전압 감지 시 전원 OFF 시퀀스 시작 */
|
/* 10회 연속 저전압 감지 시 전원 OFF 시퀀스 시작 */
|
||||||
if(low_battery_cnt >= 10) {
|
if(low_battery_cnt >= 10)
|
||||||
|
{
|
||||||
low_battery_cnt = 0;
|
low_battery_cnt = 0;
|
||||||
/*go to power off and fds save */
|
/*go to power off and fds save */
|
||||||
DBG_PRINTF("Save FDS parameters and then Power OFF\r\n");
|
DBG_PRINTF("Save FDS parameters and then Power OFF\r\n");
|
||||||
go_device_power_off = true;
|
go_device_power_off = true;
|
||||||
main_timer_start();
|
main_timer_start();
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* 아직 10회 미만 — 카운터 증가 후 경고 출력 */
|
/* 아직 10회 미만 — 카운터 증가 후 경고 출력 */
|
||||||
low_battery_cnt++;
|
low_battery_cnt++;
|
||||||
DBG_PRINTF("WARNING!!! low_battery cnt = %d, Batt = %d(mV)\r\n", low_battery_cnt, batt_lvl_in_milli_volt_1);
|
DBG_PRINTF("WARNING!!! low_battery cnt = %d, Batt = %d(mV)\r\n", low_battery_cnt, batt_lvl_in_milli_volt_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* === info4 모드: 전체 센서 수집 중 배터리 값 저장 === */
|
|
||||||
else if (info4 == true){
|
|
||||||
|
|
||||||
|
/* === info4 모드: 전체 센서 수집 중 배터리 값 저장 === */
|
||||||
|
else if (info4 == true)
|
||||||
|
{
|
||||||
info_batt = batt_lvl_in_milli_volt_1;
|
info_batt = batt_lvl_in_milli_volt_1;
|
||||||
DBG_PRINTF("INFOTn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
DBG_PRINTF("INFOTn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* === 일반 모드: 단독 배터리 측정 요청에 대한 응답 전송 === */
|
/* === 일반 모드: 단독 배터리 측정 요청에 대한 응답 전송 === */
|
||||||
else {
|
else
|
||||||
if(cmd_type_t == CMD_UART) {
|
{
|
||||||
|
if (cmd_type_t == CMD_UART)
|
||||||
|
{
|
||||||
DBG_PRINTF("Tn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
DBG_PRINTF("Tn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
||||||
} else if(cmd_type_t == CMD_BLE) {
|
}
|
||||||
|
else if (cmd_type_t == CMD_BLE)
|
||||||
|
{
|
||||||
/* "rsn:" 헤더와 함께 배터리 전압을 바이너리로 BLE 전송 */
|
/* "rsn:" 헤더와 함께 배터리 전압을 바이너리로 BLE 전송 */
|
||||||
single_format_data(ble_bin_buffer, "rsn:", batt_lvl_in_milli_volt_1);
|
single_format_data(ble_bin_buffer, "rsn:", batt_lvl_in_milli_volt_1);
|
||||||
|
|
||||||
dr_binary_tx_safe(ble_bin_buffer,3);
|
dr_binary_tx_safe(ble_bin_buffer,3);
|
||||||
//data_tx_handler(ble_tx_buffer);
|
//data_tx_handler(ble_tx_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* info4 모드: 배터리 측정 완료 → 다음 단계(온도 측정)로 전환 */
|
|
||||||
if (info4 == true){
|
|
||||||
go_batt =false; /* 배터리 측정 완료 표시 */
|
|
||||||
go_temp = true; /* 온도 측정 시작 플래그 설정 */
|
|
||||||
main_timer_start(); /* 메인 타이머 시작 → 온도 측정 트리거 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,8 +319,7 @@ static void battery_configure(void)
|
|||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
/* AIN2 채널 설정: 싱글엔드 입력, 1/3 프리스케일링 (기본값) */
|
/* AIN2 채널 설정: 싱글엔드 입력, 1/3 프리스케일링 (기본값) */
|
||||||
nrf_saadc_channel_config_t config =
|
nrf_saadc_channel_config_t config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
|
||||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
|
|
||||||
err_code = nrf_drv_saadc_channel_init(0, &config);
|
err_code = nrf_drv_saadc_channel_init(0, &config);
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
@@ -335,33 +344,40 @@ void pressure_all_configure(void)
|
|||||||
|
|
||||||
/* SAADC 드라이버 초기화 (이미 초기화된 경우 무시) */
|
/* SAADC 드라이버 초기화 (이미 초기화된 경우 무시) */
|
||||||
err_code = nrf_drv_saadc_init(NULL, pressure_all_event_handler);
|
err_code = nrf_drv_saadc_init(NULL, pressure_all_event_handler);
|
||||||
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
||||||
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE)
|
||||||
|
{
|
||||||
DBG_PRINTF("SAADC init err=%d\r\n", err_code);
|
DBG_PRINTF("SAADC init err=%d\r\n", err_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 채널 0: AIN7 (압력센서1, P1) */
|
/* 채널 0: AIN7 (압력센서1, P1) */
|
||||||
nrf_saadc_channel_config_t ch0_cfg =
|
nrf_saadc_channel_config_t ch0_cfg = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
|
||||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
|
|
||||||
/* 채널 1: AIN4 (압력센서2, P2) */
|
/* 채널 1: AIN4 (압력센서2, P2) */
|
||||||
nrf_saadc_channel_config_t ch1_cfg =
|
nrf_saadc_channel_config_t ch1_cfg = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
|
||||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
|
|
||||||
|
|
||||||
err_code = nrf_drv_saadc_channel_init(0, &ch0_cfg);
|
err_code = nrf_drv_saadc_channel_init(0, &ch0_cfg);
|
||||||
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
||||||
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE)
|
||||||
|
{
|
||||||
DBG_PRINTF("SAADC ch0 init err=%d\r\n", err_code);
|
DBG_PRINTF("SAADC ch0 init err=%d\r\n", err_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err_code = nrf_drv_saadc_channel_init(1, &ch1_cfg);
|
err_code = nrf_drv_saadc_channel_init(1, &ch1_cfg);
|
||||||
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
||||||
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE)
|
||||||
|
{
|
||||||
DBG_PRINTF("SAADC ch1 init err=%d\r\n", err_code);
|
DBG_PRINTF("SAADC ch1 init err=%d\r\n", err_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2채널 ADC 버퍼 등록 ([0]=P1, [1]=P2) */
|
/* 2채널 ADC 버퍼 등록 ([0]=P1, [1]=P2) */
|
||||||
err_code = nrf_drv_saadc_buffer_convert(pressure_adc_buf, 2);
|
err_code = nrf_drv_saadc_buffer_convert(pressure_adc_buf, 2);
|
||||||
if (err_code != NRF_SUCCESS) {
|
|
||||||
|
if (err_code != NRF_SUCCESS)
|
||||||
|
{
|
||||||
DBG_PRINTF("SAADC buf conv err=%d\r\n", err_code);
|
DBG_PRINTF("SAADC buf conv err=%d\r\n", err_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -380,8 +396,6 @@ void battery_level_meas(void)
|
|||||||
battery_configure(); /* SAADC 배터리용 초기화 */
|
battery_configure(); /* SAADC 배터리용 초기화 */
|
||||||
err_code = nrf_drv_saadc_sample(); /* ADC 샘플링 트리거 (비동기) */
|
err_code = nrf_drv_saadc_sample(); /* ADC 샘플링 트리거 (비동기) */
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -409,13 +423,16 @@ void pressure_all_level_meas(void) //add cj add 25/11/19
|
|||||||
void battery_loop(void * p_context) /* For 1sec */
|
void battery_loop(void * p_context) /* For 1sec */
|
||||||
{
|
{
|
||||||
UNUSED_PARAMETER(p_context);
|
UNUSED_PARAMETER(p_context);
|
||||||
|
|
||||||
/* 다른 센서 처리 중이면 배터리 측정 스킵 (충돌 방지) */
|
/* 다른 센서 처리 중이면 배터리 측정 스킵 (충돌 방지) */
|
||||||
if(processing==true)
|
if(processing==true)
|
||||||
{
|
{
|
||||||
processing = false ; // add 20241218
|
processing = false ; // add 20241218
|
||||||
//low_battery_check = true;
|
//low_battery_check = true;
|
||||||
return;}
|
return;
|
||||||
else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
low_battery_check = true; /* 저전압 감지 모드로 측정 */
|
low_battery_check = true; /* 저전압 감지 모드로 측정 */
|
||||||
battery_level_meas(); /* 배터리 ADC 1회 측정 시작 */
|
battery_level_meas(); /* 배터리 ADC 1회 측정 시작 */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
#define CONFIG_REC_KEY (0x7010)
|
#define CONFIG_REC_KEY (0x7010)
|
||||||
|
|
||||||
/* 매직 넘버: 플래시에 저장된 데이터가 유효한 설정인지 판별하는 데 사용 */
|
/* 매직 넘버: 플래시에 저장된 데이터가 유효한 설정인지 판별하는 데 사용 */
|
||||||
#define CONFIG_MAGIC_NUMBER_VALUE (0x20231226)
|
#define CONFIG_MAGIC_NUMBER_VALUE (0x20260318)
|
||||||
|
|
||||||
/* 전역 설정 데이터 구조체 인스턴스 */
|
/* 전역 설정 데이터 구조체 인스턴스 */
|
||||||
config_data_t m_config;
|
config_data_t m_config;
|
||||||
@@ -118,12 +118,15 @@ void fds_default_value_set(void)
|
|||||||
/* Reset status */
|
/* Reset status */
|
||||||
m_config.reset_status = reset_status_dflt;
|
m_config.reset_status = reset_status_dflt;
|
||||||
|
|
||||||
/* Measurement parameters */
|
|
||||||
m_config.pd_adc_cnt = 8;
|
|
||||||
m_config.pd_delay_us = 8000;
|
|
||||||
|
|
||||||
/* Device usage count */
|
/* Device usage count */
|
||||||
m_config.life_cycle = 0;
|
m_config.life_cycle = 0;
|
||||||
|
|
||||||
|
/* 피에조 캡처 파라미터 기본값 */
|
||||||
|
m_config.piezo_freq_option = 1; /* 2.1MHz */
|
||||||
|
m_config.piezo_delay_us = 10; /* 버스트 후 10us */
|
||||||
|
m_config.piezo_num_samples = 100; /* 100샘플 */
|
||||||
|
m_config.piezo_cycles = 7; /* 7사이클 */
|
||||||
|
m_config.piezo_averaging = 5; /* 5회 평균화 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,7 +212,8 @@ static void wait_for_fds_ready( void )
|
|||||||
nrf_pwr_mgmt_run();
|
nrf_pwr_mgmt_run();
|
||||||
nrf_delay_ms(1);
|
nrf_delay_ms(1);
|
||||||
timeout++;
|
timeout++;
|
||||||
if (timeout > 3000) { /* 3 second timeout */
|
if (timeout > 3000) /* 3 second timeout */
|
||||||
|
{
|
||||||
DBG_PRINTF("[FDS] TIMEOUT!\r\n");
|
DBG_PRINTF("[FDS] TIMEOUT!\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,7 +249,8 @@ void config_load( void )
|
|||||||
DBG_PRINTF("[FDS] find rc=%u\r\n", rc);
|
DBG_PRINTF("[FDS] find rc=%u\r\n", rc);
|
||||||
|
|
||||||
/* FDS may not be fully ready yet - retry before writing defaults */
|
/* FDS may not be fully ready yet - retry before writing defaults */
|
||||||
if (rc != NRF_SUCCESS && cfg_retry < 10) {
|
if (rc != NRF_SUCCESS && cfg_retry < 10)
|
||||||
|
{
|
||||||
cfg_retry++;
|
cfg_retry++;
|
||||||
DBG_PRINTF("[FDS] retry %u/10\r\n", cfg_retry);
|
DBG_PRINTF("[FDS] retry %u/10\r\n", cfg_retry);
|
||||||
nrf_delay_ms(100);
|
nrf_delay_ms(100);
|
||||||
@@ -259,7 +264,8 @@ void config_load( void )
|
|||||||
|
|
||||||
/* Open the record and read its contents. */
|
/* Open the record and read its contents. */
|
||||||
rc = fds_record_open(&desc, &config);
|
rc = fds_record_open(&desc, &config);
|
||||||
if (rc != NRF_SUCCESS) {
|
if (rc != NRF_SUCCESS)
|
||||||
|
{
|
||||||
/* CRC error or corrupt record - delete and use defaults */
|
/* CRC error or corrupt record - delete and use defaults */
|
||||||
DBG_PRINTF("[FDS] open ERR=%u, deleting\r\n", rc);
|
DBG_PRINTF("[FDS] open ERR=%u, deleting\r\n", rc);
|
||||||
(void)fds_record_delete(&desc);
|
(void)fds_record_delete(&desc);
|
||||||
@@ -275,8 +281,7 @@ void config_load( void )
|
|||||||
rc = fds_record_close(&desc);
|
rc = fds_record_close(&desc);
|
||||||
APP_ERROR_CHECK(rc);
|
APP_ERROR_CHECK(rc);
|
||||||
|
|
||||||
DBG_PRINTF("[FDS] magic=0x%08X (expect 0x%08X)\r\n",
|
DBG_PRINTF("[FDS] magic=0x%08X (expect 0x%08X)\r\n", m_config.magic_number, CONFIG_MAGIC_NUMBER_VALUE);
|
||||||
m_config.magic_number, CONFIG_MAGIC_NUMBER_VALUE);
|
|
||||||
|
|
||||||
if( m_config.magic_number != (uint32_t)CONFIG_MAGIC_NUMBER_VALUE )
|
if( m_config.magic_number != (uint32_t)CONFIG_MAGIC_NUMBER_VALUE )
|
||||||
{ // first init
|
{ // first init
|
||||||
@@ -315,14 +320,18 @@ void config_load( void )
|
|||||||
|
|
||||||
fds_flag_write = true;
|
fds_flag_write = true;
|
||||||
rc = fds_record_write(&desc, &m_dummy_record);
|
rc = fds_record_write(&desc, &m_dummy_record);
|
||||||
if (rc != NRF_SUCCESS) {
|
|
||||||
|
if (rc != NRF_SUCCESS)
|
||||||
|
{
|
||||||
DBG_PRINTF("[FDS] Write ERR=%u\r\n", rc);
|
DBG_PRINTF("[FDS] Write ERR=%u\r\n", rc);
|
||||||
fds_flag_write = false;
|
fds_flag_write = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( fds_flag_write )
|
while( fds_flag_write )
|
||||||
{
|
{
|
||||||
nrf_pwr_mgmt_run();
|
nrf_pwr_mgmt_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH) )
|
if( (rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH) )
|
||||||
{
|
{
|
||||||
rc = fds_gc();
|
rc = fds_gc();
|
||||||
@@ -332,6 +341,7 @@ void config_load( void )
|
|||||||
{
|
{
|
||||||
APP_ERROR_CHECK(rc);
|
APP_ERROR_CHECK(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
NRF_LOG_FLUSH();
|
NRF_LOG_FLUSH();
|
||||||
goto cfg_load_start;
|
goto cfg_load_start;
|
||||||
}
|
}
|
||||||
@@ -362,15 +372,19 @@ void config_save( void )
|
|||||||
DBG_PRINTF("[CFG_SAVE] start\r\n");
|
DBG_PRINTF("[CFG_SAVE] start\r\n");
|
||||||
|
|
||||||
/* Wait for any previous FDS operation to complete */
|
/* Wait for any previous FDS operation to complete */
|
||||||
if (fds_flag_write) {
|
if (fds_flag_write)
|
||||||
|
{
|
||||||
uint32_t wait_cnt = 0;
|
uint32_t wait_cnt = 0;
|
||||||
|
|
||||||
DBG_PRINTF("[CFG_SAVE] waiting for prev FDS op...\r\n");
|
DBG_PRINTF("[CFG_SAVE] waiting for prev FDS op...\r\n");
|
||||||
while (fds_flag_write && wait_cnt < 3000) {
|
while (fds_flag_write && wait_cnt < 3000)
|
||||||
|
{
|
||||||
nrf_pwr_mgmt_run();
|
nrf_pwr_mgmt_run();
|
||||||
nrf_delay_ms(1);
|
nrf_delay_ms(1);
|
||||||
wait_cnt++;
|
wait_cnt++;
|
||||||
}
|
}
|
||||||
if (fds_flag_write) {
|
if (fds_flag_write)
|
||||||
|
{
|
||||||
DBG_PRINTF("[CFG_SAVE] TIMEOUT! forcing flag clear\r\n");
|
DBG_PRINTF("[CFG_SAVE] TIMEOUT! forcing flag clear\r\n");
|
||||||
fds_flag_write = false;
|
fds_flag_write = false;
|
||||||
}
|
}
|
||||||
@@ -391,6 +405,7 @@ void config_save( void )
|
|||||||
fds_flag_write = true;
|
fds_flag_write = true;
|
||||||
rc = fds_record_update(&desc, &m_dummy_record);
|
rc = fds_record_update(&desc, &m_dummy_record);
|
||||||
DBG_PRINTF("[CFG_SAVE] update rc=%u\r\n", rc);
|
DBG_PRINTF("[CFG_SAVE] update rc=%u\r\n", rc);
|
||||||
|
|
||||||
if( rc == FDS_ERR_NO_SPACE_IN_FLASH )
|
if( rc == FDS_ERR_NO_SPACE_IN_FLASH )
|
||||||
{
|
{
|
||||||
fds_flag_write = false;
|
fds_flag_write = false;
|
||||||
@@ -400,6 +415,7 @@ void config_save( void )
|
|||||||
rc = fds_record_update(&desc, &m_dummy_record);
|
rc = fds_record_update(&desc, &m_dummy_record);
|
||||||
DBG_PRINTF("[CFG_SAVE] retry rc=%u\r\n", rc);
|
DBG_PRINTF("[CFG_SAVE] retry rc=%u\r\n", rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc != NRF_SUCCESS )
|
if( rc != NRF_SUCCESS )
|
||||||
{
|
{
|
||||||
DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc);
|
DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc);
|
||||||
@@ -412,6 +428,7 @@ void config_save( void )
|
|||||||
fds_flag_write = true;
|
fds_flag_write = true;
|
||||||
rc = fds_record_write(&desc, &m_dummy_record);
|
rc = fds_record_write(&desc, &m_dummy_record);
|
||||||
DBG_PRINTF("[CFG_SAVE] write rc=%u\r\n", rc);
|
DBG_PRINTF("[CFG_SAVE] write rc=%u\r\n", rc);
|
||||||
|
|
||||||
if( rc != NRF_SUCCESS )
|
if( rc != NRF_SUCCESS )
|
||||||
{
|
{
|
||||||
DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc);
|
DBG_PRINTF("[CFG_SAVE] FAIL rc=%u\r\n", rc);
|
||||||
|
|||||||
@@ -40,15 +40,20 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t magic_number; /* 4B - 0x20231226 */
|
uint32_t magic_number; /* 4B - 0x20231226 */
|
||||||
char hw_no[12]; /* 12B - HW Number */
|
char hw_no[12]; /* 12B - HW Version */
|
||||||
char serial_no[12]; /* 12B - Serial Number */
|
char serial_no[12]; /* 12B - Serial Number */
|
||||||
uint8_t static_passkey[6]; /* 6B - BLE Passkey */
|
uint8_t static_passkey[6]; /* 6B - BLE Passkey */
|
||||||
uint8_t bond_data_delete; /* 1B - Bond delete flag */
|
uint8_t bond_data_delete; /* 1B - Bond delete flag */
|
||||||
int8_t reset_status; /* 1B - Reset status */
|
int8_t reset_status; /* 1B - Reset status */
|
||||||
uint8_t pd_adc_cnt; /* 1B - ADC sample count */
|
uint32_t life_cycle; /* 4B - Device usage count */
|
||||||
uint16_t pd_delay_us; /* 2B - PD delay (us) */
|
|
||||||
uint32_t life_cycle; /* 4B - Device usage count (sxz/syz command) */
|
/* Piezo 측정 파라미터 - 8B */
|
||||||
} config_data_t; /* Total: 45 bytes - FDS에 저장하는 디바이스 설정 */
|
uint8_t piezo_freq_option; /* 1B - Frequency : 송신 펄스 주파수 (0=1.8M, 1=2.1M, 2=2.0M, 3=1.7M) */
|
||||||
|
uint8_t piezo_cycles; /* 1B - Burst Cycle : 송신 펄스 사이클 수 (3~7) */
|
||||||
|
uint16_t piezo_averaging; /* 2B - 채널당 반복 측정 횟수 */
|
||||||
|
uint16_t piezo_delay_us; /* 2B - 송신 펄스 출력 후 ADC 시작 시까지 대기시간(us) */
|
||||||
|
uint16_t piezo_num_samples; /* 2B - 측정 ADC 샘플 개수(80~140) */
|
||||||
|
} config_data_t; /* Total: 48 bytes - FDS에 저장하는 디바이스 설정 */
|
||||||
|
|
||||||
extern config_data_t m_config;
|
extern config_data_t m_config;
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* [모듈 개요] ICM42670P IMU 드라이버 상위 레이어
|
* [모듈 개요] ICM42670P IMU 드라이버 상위 레이어
|
||||||
*
|
*
|
||||||
* ICM42670P IMU 센서의 초기화, 설정, 데이터 읽기를 담당하는 애플리케이션
|
* ICM42670P IMU 센서의 초기화, 설정, 데이터 읽기를 담당하는 애플리케이션 레이어 모듈
|
||||||
* 레이어 모듈이다. InvenSense 드라이버 API를 래핑하여 사용한다.
|
* InvenSense 드라이버 API를 래핑하여 사용
|
||||||
*
|
*
|
||||||
* 주요 기능:
|
* 주요 기능:
|
||||||
* 1) setup_imu_device() - IMU 초기화 및 WHOAMI 확인 (0x67 = ICM42670P)
|
* 1) setup_imu_device() - IMU 초기화 및 WHOAMI 확인 (0x67 = ICM42670P)
|
||||||
@@ -28,8 +28,7 @@
|
|||||||
* - 센서 설정 → 전원 ON → 80ms 대기 → 12바이트 읽기 → 슬립
|
* - 센서 설정 → 전원 ON → 80ms 대기 → 12바이트 읽기 → 슬립
|
||||||
*
|
*
|
||||||
* 마운팅 매트릭스:
|
* 마운팅 매트릭스:
|
||||||
* Q30 고정소수점 형식의 3x3 회전 매트릭스로, 보드에 장착된 센서의
|
* Q30 고정소수점 형식의 3x3 회전 매트릭스로, 보드에 장착된 센서의물리적 방향을 소프트웨어 좌표계에 맞춰 보정
|
||||||
* 물리적 방향을 소프트웨어 좌표계에 맞춰 보정한다.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "sdk_config.h"
|
#include "sdk_config.h"
|
||||||
@@ -43,7 +42,6 @@
|
|||||||
|
|
||||||
#include "app_util_platform.h"
|
#include "app_util_platform.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
/* 2026-03-17: cmd_parse.h 삭제 — main.h는 이미 포함됨 */
|
|
||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
#include "nrf_delay.h"
|
#include "nrf_delay.h"
|
||||||
|
|
||||||
@@ -60,7 +58,7 @@
|
|||||||
* Static and extern variables
|
* Static and extern variables
|
||||||
* -------------------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* IMU 드라이버 객체 — 드라이버 API 호출 시 항상 이 구조체를 전달 */
|
/* IMU 드라이버 객체 — 드라이버 API 호출 시 항상 이 구조체 전달 */
|
||||||
static struct inv_imu_device icm_driver;
|
static struct inv_imu_device icm_driver;
|
||||||
|
|
||||||
/* BLE 전송용 바이너리 버퍼 */
|
/* BLE 전송용 바이너리 버퍼 */
|
||||||
@@ -69,7 +67,7 @@ static struct inv_imu_device icm_driver;
|
|||||||
/*
|
/*
|
||||||
* ICM42670P 마운팅 매트릭스 (Q30 고정소수점)
|
* ICM42670P 마운팅 매트릭스 (Q30 고정소수점)
|
||||||
*
|
*
|
||||||
* 센서가 보드에 장착된 물리적 방향에 따라 좌표 변환을 수행한다.
|
* 센서가 보드에 장착된 물리적 방향에 따라 좌표 변환
|
||||||
* Q30 형식: 1.0 = (1 << 30) = 0x40000000
|
* Q30 형식: 1.0 = (1 << 30) = 0x40000000
|
||||||
*
|
*
|
||||||
* SM_REVB_DB (개발보드): X→-Y, Y→X 변환 (90도 회전)
|
* SM_REVB_DB (개발보드): X→-Y, Y→X 변환 (90도 회전)
|
||||||
@@ -143,7 +141,7 @@ int setup_imu_device(struct inv_imu_serif *icm_serif)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* configure_imu_device()
|
* configure_imu_device()
|
||||||
* IMU 센서 동작 파라미터를 설정한다.
|
* IMU 센서 동작 파라미터 설정
|
||||||
*
|
*
|
||||||
* 설정 항목:
|
* 설정 항목:
|
||||||
* - FIFO: 비활성화 (USE_FIFO=0일 때, 레지스터 직접 읽기 모드)
|
* - FIFO: 비활성화 (USE_FIFO=0일 때, 레지스터 직접 읽기 모드)
|
||||||
@@ -161,7 +159,7 @@ int configure_imu_device(void)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* FIFO 비활성화 — 레지스터에서 직접 데이터를 읽는다 */
|
/* FIFO 비활성화 — 레지스터에서 직접 데이터를 읽기 */
|
||||||
if (!USE_FIFO)
|
if (!USE_FIFO)
|
||||||
rc |= inv_imu_configure_fifo(&icm_driver, INV_IMU_FIFO_DISABLED);
|
rc |= inv_imu_configure_fifo(&icm_driver, INV_IMU_FIFO_DISABLED);
|
||||||
|
|
||||||
@@ -199,9 +197,9 @@ int configure_imu_device(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* get_imu_data()
|
* get_imu_data()
|
||||||
* IMU에서 센서 데이터를 읽는다.
|
* IMU에서 센서 데이터 읽기
|
||||||
* USE_FIFO 설정에 따라 FIFO 또는 레지스터에서 데이터를 가져온다.
|
* USE_FIFO 설정에 따라 FIFO 또는 레지스터에서 데이터를 가져옴
|
||||||
* 읽은 데이터는 imu_callback()을 통해 처리된다.
|
* 읽은 데이터는 imu_callback()을 통해 처리
|
||||||
*/
|
*/
|
||||||
int get_imu_data(void)
|
int get_imu_data(void)
|
||||||
{
|
{
|
||||||
@@ -255,7 +253,7 @@ static void get_accel_and_gyr_fsr(int16_t * accel_fsr_g, int16_t * gyro_fsr_dps)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* imu_callback()
|
* imu_callback()
|
||||||
* IMU 드라이버가 새 센서 데이터를 읽을 때마다 호출되는 콜백 함수.
|
* IMU 드라이버가 새 센서 데이터를 읽을 때마다 호출되는 콜백 함수
|
||||||
*
|
*
|
||||||
* 처리 흐름:
|
* 처리 흐름:
|
||||||
* 1) 이벤트에서 가속도/자이로 원시 데이터 추출
|
* 1) 이벤트에서 가속도/자이로 원시 데이터 추출
|
||||||
@@ -370,12 +368,9 @@ void imu_callback(inv_imu_sensor_event_t *event)
|
|||||||
{
|
{
|
||||||
motion_raw_data_enabled = false;
|
motion_raw_data_enabled = false;
|
||||||
|
|
||||||
|
/* info4 모드: 전역 배열 info_imu[6]에 데이터 저장, 외부 모듈에서 이 배열을 폴링하여 데이터 사용 */
|
||||||
if (info4 == true)
|
if (info4 == true)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* info4 모드: 전역 배열 info_imu[6]에 데이터를 저장한다.
|
|
||||||
* 외부 모듈에서 이 배열을 폴링하여 데이터를 사용한다.
|
|
||||||
*/
|
|
||||||
info_imu[0] = (uint16_t)accel[0];
|
info_imu[0] = (uint16_t)accel[0];
|
||||||
info_imu[1] = (uint16_t)accel[1];
|
info_imu[1] = (uint16_t)accel[1];
|
||||||
info_imu[2] = (uint16_t)accel[2];
|
info_imu[2] = (uint16_t)accel[2];
|
||||||
@@ -384,27 +379,30 @@ void imu_callback(inv_imu_sensor_event_t *event)
|
|||||||
info_imu[5] = (uint16_t)gyro[2];
|
info_imu[5] = (uint16_t)gyro[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(cmd_type_t == CMD_UART) {
|
|
||||||
/* UART 모드: "Tp" 접두사로 6축 데이터를 텍스트 형식으로 출력 */
|
/* UART 모드: "Tp" 접두사로 6축 데이터를 텍스트 형식으로 출력 */
|
||||||
|
else if(cmd_type_t == CMD_UART) {
|
||||||
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||||
} else if(cmd_type_t == CMD_BLE) {
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BLE 모드: 6축 데이터를 바이너리 패킷으로 BLE 전송
|
* BLE 모드: 6축 데이터를 바이너리 패킷으로 BLE 전송
|
||||||
* ssp_data[0~2] = 가속도 XYZ, ssp_data[3~5] = 자이로 XYZ
|
* ssp_data[0~2] = 가속도 XYZ, ssp_data[3~5] = 자이로 XYZ
|
||||||
* format_data()로 "rsp:" 태그 + 12바이트 데이터를 패킷화
|
* format_data()로 "rsp:" 태그 + 12바이트 데이터를 패킷화
|
||||||
* dr_binary_tx_safe()로 8바이트 BLE 전송
|
* dr_binary_tx_safe()로 8바이트 BLE 전송
|
||||||
*/
|
*/
|
||||||
|
else if(cmd_type_t == CMD_BLE) {
|
||||||
ssp_data[0] = (uint16_t)accel[0];
|
ssp_data[0] = (uint16_t)accel[0];
|
||||||
ssp_data[1] = (uint16_t)accel[1];
|
ssp_data[1] = (uint16_t)accel[1];
|
||||||
ssp_data[2] = (uint16_t)accel[2];
|
ssp_data[2] = (uint16_t)accel[2];
|
||||||
ssp_data[3] = (uint16_t)gyro[0];
|
ssp_data[3] = (uint16_t)gyro[0];
|
||||||
ssp_data[4] = (uint16_t)gyro[1];
|
ssp_data[4] = (uint16_t)gyro[1];
|
||||||
ssp_data[5] = (uint16_t)gyro[2];
|
ssp_data[5] = (uint16_t)gyro[2];
|
||||||
|
|
||||||
format_data(imu_bin_buffer, "rsp:", ssp_data,12);
|
format_data(imu_bin_buffer, "rsp:", ssp_data,12);
|
||||||
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||||
dr_binary_tx_safe(imu_bin_buffer,8);
|
dr_binary_tx_safe(imu_bin_buffer,8);
|
||||||
if(custom_add_data==true)
|
|
||||||
{
|
if(custom_add_data==true) {
|
||||||
custom_add_data = false;
|
custom_add_data = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -544,7 +542,7 @@ int imu_read_direct(void)
|
|||||||
DBG_PRINTF("[IMU] A:%d,%d,%d G:%d,%d,%d\r\n",
|
DBG_PRINTF("[IMU] A:%d,%d,%d G:%d,%d,%d\r\n",
|
||||||
accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||||
|
|
||||||
/* BLE 전송용 데이터 패킹: "rsp:" 태그 + 6축 데이터(12바이트) */
|
/* 데이터 패킹 */
|
||||||
ssp_data[0] = (uint16_t)accel[0];
|
ssp_data[0] = (uint16_t)accel[0];
|
||||||
ssp_data[1] = (uint16_t)accel[1];
|
ssp_data[1] = (uint16_t)accel[1];
|
||||||
ssp_data[2] = (uint16_t)accel[2];
|
ssp_data[2] = (uint16_t)accel[2];
|
||||||
@@ -552,8 +550,19 @@ int imu_read_direct(void)
|
|||||||
ssp_data[4] = (uint16_t)gyro[1];
|
ssp_data[4] = (uint16_t)gyro[1];
|
||||||
ssp_data[5] = (uint16_t)gyro[2];
|
ssp_data[5] = (uint16_t)gyro[2];
|
||||||
|
|
||||||
|
if (info4 == true) {
|
||||||
|
/* info4 모드: 전역 배열에 저장 (mbb?에서 rbb: 패킷으로 일괄 전송) */
|
||||||
|
info_imu[0] = ssp_data[0];
|
||||||
|
info_imu[1] = ssp_data[1];
|
||||||
|
info_imu[2] = ssp_data[2];
|
||||||
|
info_imu[3] = ssp_data[3];
|
||||||
|
info_imu[4] = ssp_data[4];
|
||||||
|
info_imu[5] = ssp_data[5];
|
||||||
|
} else {
|
||||||
|
/* 일반 모드: "rsp:" 태그로 BLE 즉시 전송 */
|
||||||
format_data(imu_bin_buffer, "rsp:", ssp_data, 12);
|
format_data(imu_bin_buffer, "rsp:", ssp_data, 12);
|
||||||
dr_binary_tx_safe(imu_bin_buffer, 8);
|
dr_binary_tx_safe(imu_bin_buffer, 8);
|
||||||
|
}
|
||||||
|
|
||||||
/* IMU 슬립 모드: PWR_MGMT0 = 0x00 → 가속도/자이로 모두 OFF (전력 절감) */
|
/* IMU 슬립 모드: PWR_MGMT0 = 0x00 → 가속도/자이로 모두 OFF (전력 절감) */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ char HW_NO[HW_NO_LENGTH]; /* 하드웨어 번호 (FDS
|
|||||||
bool bond_data_delete; /* 본딩 데이터 삭제 요청 플래그 */
|
bool bond_data_delete; /* 본딩 데이터 삭제 요청 플래그 */
|
||||||
uint32_t m_life_cycle; /* 디바이스 수명 사이클 카운터 */
|
uint32_t m_life_cycle; /* 디바이스 수명 사이클 카운터 */
|
||||||
uint8_t resetCount = 0; /* 통신 타임아웃 카운터 (리셋 감지용) */
|
uint8_t resetCount = 0; /* 통신 타임아웃 카운터 (리셋 감지용) */
|
||||||
bool info4; /* 추가 정보(배터리/온도/IMU) 포함 측정 플래그 */
|
bool info4; /* 센서 측정 정보(배터리/IMU/온도) 포함 측정 플래그 */
|
||||||
uint8_t m_reset_status; /* 리셋 상태 코드 (1=정상, 2=SW리셋, 5=보안리셋, 10=본딩완료) */
|
uint8_t m_reset_status; /* 리셋 상태 코드 (1=정상, 2=SW리셋, 5=보안리셋, 10=본딩완료) */
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
@@ -318,10 +318,13 @@ static void power_hold_init(void)
|
|||||||
*/
|
*/
|
||||||
static void power_control_handler(on_off_cont_t device_power_st)
|
static void power_control_handler(on_off_cont_t device_power_st)
|
||||||
{
|
{
|
||||||
if (device_power_st == OFF) {
|
if (device_power_st == OFF)
|
||||||
|
{
|
||||||
nrf_gpio_pin_clear(POWER_HOLD); /* P0.8 LOW → 전원 래치 해제 → 전원 차단 */
|
nrf_gpio_pin_clear(POWER_HOLD); /* P0.8 LOW → 전원 래치 해제 → 전원 차단 */
|
||||||
DBG_PRINTF("[PWR] OFF\r\n");
|
DBG_PRINTF("[PWR] OFF\r\n");
|
||||||
} else if (device_power_st == ON) {
|
}
|
||||||
|
else if (device_power_st == ON)
|
||||||
|
{
|
||||||
nrf_gpio_pin_set(POWER_HOLD); /* P0.8 HIGH → 전원 유지 */
|
nrf_gpio_pin_set(POWER_HOLD); /* P0.8 HIGH → 전원 유지 */
|
||||||
DBG_PRINTF("[PWR] ON\r\n");
|
DBG_PRINTF("[PWR] ON\r\n");
|
||||||
}
|
}
|
||||||
@@ -404,7 +407,8 @@ static void load_flash_config(void)
|
|||||||
m_need_save_defaults = false;
|
m_need_save_defaults = false;
|
||||||
|
|
||||||
/* 하드웨어 번호 — 비어있으면 기본값 채움 */
|
/* 하드웨어 번호 — 비어있으면 기본값 채움 */
|
||||||
if (m_config.hw_no[0] == 0 || m_config.hw_no[0] == (char)0xFF) {
|
if (m_config.hw_no[0] == 0 || m_config.hw_no[0] == (char)0xFF)
|
||||||
|
{
|
||||||
memset(m_config.hw_no, 0, HW_NO_LENGTH);
|
memset(m_config.hw_no, 0, HW_NO_LENGTH);
|
||||||
memcpy(m_config.hw_no, HARDWARE_VERSION, strlen(HARDWARE_VERSION));
|
memcpy(m_config.hw_no, HARDWARE_VERSION, strlen(HARDWARE_VERSION));
|
||||||
DBG_PRINTF("[CFG] HW empty, set default: %s\r\n", HARDWARE_VERSION);
|
DBG_PRINTF("[CFG] HW empty, set default: %s\r\n", HARDWARE_VERSION);
|
||||||
@@ -412,7 +416,8 @@ static void load_flash_config(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 시리얼 번호 — 비어있으면 기본값 채움 */
|
/* 시리얼 번호 — 비어있으면 기본값 채움 */
|
||||||
if (m_config.serial_no[0] == 0 || m_config.serial_no[0] == (char)0xFF) {
|
if (m_config.serial_no[0] == 0 || m_config.serial_no[0] == (char)0xFF)
|
||||||
|
{
|
||||||
memset(m_config.serial_no, 0, SERIAL_NO_LENGTH);
|
memset(m_config.serial_no, 0, SERIAL_NO_LENGTH);
|
||||||
memcpy(m_config.serial_no, FIRMWARE_SERIAL_NO, strlen(FIRMWARE_SERIAL_NO));
|
memcpy(m_config.serial_no, FIRMWARE_SERIAL_NO, strlen(FIRMWARE_SERIAL_NO));
|
||||||
DBG_PRINTF("[CFG] S/N empty, set default: %s\r\n", FIRMWARE_SERIAL_NO);
|
DBG_PRINTF("[CFG] S/N empty, set default: %s\r\n", FIRMWARE_SERIAL_NO);
|
||||||
@@ -472,7 +477,8 @@ static void PM_s(void * p_context)
|
|||||||
UNUSED_PARAMETER(p_context);
|
UNUSED_PARAMETER(p_context);
|
||||||
APP_ERROR_CHECK(app_timer_stop(m_PM_timer_id));
|
APP_ERROR_CHECK(app_timer_stop(m_PM_timer_id));
|
||||||
|
|
||||||
if (m_reset_status == 5) {
|
if (m_reset_status == 5)
|
||||||
|
{
|
||||||
DBG_PRINTF("[PM] Kill\r\n");
|
DBG_PRINTF("[PM] Kill\r\n");
|
||||||
sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
|
sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
|
||||||
}
|
}
|
||||||
@@ -628,7 +634,8 @@ static void nus_data_handler(ble_nus_evt_t * p_evt)
|
|||||||
DBG_PRINTF("[NUS] RX len=%d\r\n", p_evt->params.rx_data.length);
|
DBG_PRINTF("[NUS] RX len=%d\r\n", p_evt->params.rx_data.length);
|
||||||
|
|
||||||
/* 콜백에서는 복사만 하고, 메인 루프에서 처리 */
|
/* 콜백에서는 복사만 하고, 메인 루프에서 처리 */
|
||||||
if (p_evt->params.rx_data.length <= BLE_NUS_MAX_DATA_LEN) {
|
if (p_evt->params.rx_data.length <= BLE_NUS_MAX_DATA_LEN)
|
||||||
|
{
|
||||||
memcpy((void *)pending_cmd_buf, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
|
memcpy((void *)pending_cmd_buf, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
|
||||||
pending_cmd_len = p_evt->params.rx_data.length;
|
pending_cmd_len = p_evt->params.rx_data.length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,16 +215,11 @@ void main_loop(void * p_context) /* For x ms */
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* For System Control */
|
|
||||||
/* ---- 시스템 제어 이벤트 처리 ---- */
|
/* ---- 시스템 제어 이벤트 처리 ---- */
|
||||||
|
|
||||||
|
|
||||||
/* 디바이스 전원 OFF 처리 */
|
/* 디바이스 전원 OFF 처리 */
|
||||||
if(go_device_power_off == true){
|
if(go_device_power_off == true){
|
||||||
main_timer_stop(); /* 타이머 정지 */
|
main_timer_stop(); /* 타이머 정지 */
|
||||||
|
|
||||||
DBG_PRINTF("Off main_timer\r\n");
|
DBG_PRINTF("Off main_timer\r\n");
|
||||||
device_power_off(); /* 디바이스 전원 OFF 실행 */
|
device_power_off(); /* 디바이스 전원 OFF 실행 */
|
||||||
}
|
}
|
||||||
@@ -232,20 +227,13 @@ void main_loop(void * p_context) /* For x ms */
|
|||||||
/* 슬립 모드 진입 처리 */
|
/* 슬립 모드 진입 처리 */
|
||||||
if(go_sleep_mode_enter == true){
|
if(go_sleep_mode_enter == true){
|
||||||
main_timer_stop(); /* 타이머 정지 */
|
main_timer_stop(); /* 타이머 정지 */
|
||||||
|
|
||||||
DBG_PRINTF("sleep main timer\r\n");
|
DBG_PRINTF("sleep main timer\r\n");
|
||||||
|
|
||||||
|
|
||||||
sleep_mode_enter(); /* 슬립 모드 진입 실행 */
|
sleep_mode_enter(); /* 슬립 모드 진입 실행 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NVIC 시스템 리셋 처리 */
|
/* NVIC 시스템 리셋 처리 */
|
||||||
if(go_NVIC_SystemReset == true) {
|
if(go_NVIC_SystemReset == true) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main_timer_stop(); /* 타이머 정지 */
|
main_timer_stop(); /* 타이머 정지 */
|
||||||
|
|
||||||
NVIC_SystemReset(); /* ARM Cortex-M4 시스템 리셋 */
|
NVIC_SystemReset(); /* ARM Cortex-M4 시스템 리셋 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,7 +242,7 @@ void main_loop(void * p_context) /* For x ms */
|
|||||||
/**
|
/**
|
||||||
* @brief 메인 루프 타이머 시작
|
* @brief 메인 루프 타이머 시작
|
||||||
*
|
*
|
||||||
* 싱글샷 모드로 MAIN_LOOP_INTERVAL(10ms 또는 80ms) 후 main_loop()를 호출한다.
|
* 싱글샷 모드로 MAIN_LOOP_INTERVAL(10ms 또는 80ms) 후 main_loop()를 호출
|
||||||
*/
|
*/
|
||||||
void main_timer_start(void)
|
void main_timer_start(void)
|
||||||
{
|
{
|
||||||
@@ -264,7 +252,7 @@ void main_timer_start(void)
|
|||||||
/**
|
/**
|
||||||
* @brief 지정된 간격(ms)으로 메인 루프 타이머 시작
|
* @brief 지정된 간격(ms)으로 메인 루프 타이머 시작
|
||||||
*
|
*
|
||||||
* IMU 연속 스트리밍 등 기본 간격과 다른 주기가 필요할 때 사용.
|
* IMU 연속 스트리밍 등 기본 간격과 다른 주기가 필요할 때 사용
|
||||||
*/
|
*/
|
||||||
void main_timer_start_ms(uint32_t interval_ms)
|
void main_timer_start_ms(uint32_t interval_ms)
|
||||||
{
|
{
|
||||||
@@ -282,8 +270,8 @@ void main_timer_stop(void)
|
|||||||
/**
|
/**
|
||||||
* @brief 메인 루프 타이머 초기화 (앱 시작 시 1회 호출)
|
* @brief 메인 루프 타이머 초기화 (앱 시작 시 1회 호출)
|
||||||
*
|
*
|
||||||
* 싱글샷 모드 타이머를 생성하고, 콜백으로 main_loop()를 등록한다.
|
* 싱글샷 모드 타이머를 생성하고, 콜백으로 main_loop()를 등록
|
||||||
* 싱글샷이므로 매 호출마다 main_timer_start()로 수동 재시작해야 한다.
|
* 싱글샷이므로 매 호출마다 main_timer_start()로 수동 재시작해야 함
|
||||||
*/
|
*/
|
||||||
void main_timer_init(void)
|
void main_timer_init(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* [한국어 설명] PWM 펄스 생성기
|
* PWM 펄스 생성기
|
||||||
*
|
*
|
||||||
* === 현재 상태 ===
|
* === 현재 상태 ===
|
||||||
* SKIP_PWM 매크로가 정의되어 있어 PWM 기능이 비활성화됨.
|
* SKIP_PWM 매크로가 정의되어 있어 PWM 기능이 비활성화됨.
|
||||||
* init/start/stop 함수는 모두 Stub(빈 껍데기) 구현으로,
|
* init/start/stop 함수는 모두 Stub으로,
|
||||||
* 로그만 출력하고 실제 PWM 동작은 하지 않는다.
|
* 로그만 출력하고 실제 PWM 동작은 하지 않는다.
|
||||||
* 빌드 호환성을 위해 함수 인터페이스만 유지.
|
* 빌드 호환성을 위해 함수 인터페이스만 유지.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,9 +9,8 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* [모듈 개요] TMP235-Q1 아날로그 온도센서 드라이버
|
* [모듈 개요] TMP235-Q1 아날로그 온도센서 드라이버
|
||||||
*
|
*
|
||||||
* TMP235-Q1은 온도에 비례하는 아날로그 전압(Vout)을 출력하는 센서이다.
|
* TMP235-Q1은 온도에 비례하는 아날로그 전압(Vout)을 출력하는 센서
|
||||||
* nRF52840 SAADC의 AIN3 채널로 Vout을 읽고, mV로 변환한 뒤
|
* nRF52840 SAADC의 AIN3 채널로 Vout을 읽고, mV로 변환한 뒤 온도(°C)로 계산
|
||||||
* 온도(°C)로 계산한다.
|
|
||||||
*
|
*
|
||||||
* 온도 계산 공식 (구간별 선형 보간):
|
* 온도 계산 공식 (구간별 선형 보간):
|
||||||
* - Vout <= 1500mV (0~100°C): Ta = (Vout - 500) / 10.0
|
* - Vout <= 1500mV (0~100°C): Ta = (Vout - 500) / 10.0
|
||||||
@@ -61,13 +60,17 @@
|
|||||||
static nrf_saadc_value_t adc_buf;
|
static nrf_saadc_value_t adc_buf;
|
||||||
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
|
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
|
||||||
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
||||||
|
|
||||||
/* 현재 명령 소스: CMD_UART 또는 CMD_BLE */
|
/* 현재 명령 소스: CMD_UART 또는 CMD_BLE */
|
||||||
extern which_cmd_t cmd_type_t;
|
extern which_cmd_t cmd_type_t;
|
||||||
|
|
||||||
/* info4: 전체 센서 데이터 수집 모드 플래그 */
|
/* info4: 전체 센서 데이터 수집 모드 플래그 */
|
||||||
extern bool info4; //cmd_parse
|
extern bool info4; // main.c
|
||||||
|
|
||||||
/* 온도 측정 순서 제어 플래그 */
|
/* 온도 측정 순서 제어 플래그 */
|
||||||
extern bool go_temp; //cmd_parse
|
extern bool go_temp; // main_timer.c
|
||||||
/* info4 모드에서 온도값을 임시 저장 (°C x 100, 정수 표현) */
|
|
||||||
|
/* info4 모드에서 온도값 임시 저장 (°C x 100, 정수 표현) */
|
||||||
volatile uint16_t info_temp; //48_C
|
volatile uint16_t info_temp; //48_C
|
||||||
extern bool motion_raw_data_enabled;
|
extern bool motion_raw_data_enabled;
|
||||||
|
|
||||||
@@ -87,9 +90,9 @@ extern bool motion_raw_data_enabled;
|
|||||||
*/
|
*/
|
||||||
void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout reading */
|
void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout reading */
|
||||||
{
|
{
|
||||||
|
|
||||||
float led_temp; /* 계산된 온도 (°C, 부동소수점) */
|
float led_temp; /* 계산된 온도 (°C, 부동소수점) */
|
||||||
uint16_t led_temp_16; /* BLE 전송용 온도 (°C x 100, 정수) */
|
uint16_t led_temp_16; /* BLE 전송용 온도 (°C x 100, 정수) */
|
||||||
|
|
||||||
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
|
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
|
||||||
{
|
{
|
||||||
nrf_saadc_value_t adc_result;
|
nrf_saadc_value_t adc_result;
|
||||||
@@ -113,31 +116,40 @@ void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout
|
|||||||
* 100~125°C 구간: 기울기 10.1 mV/°C
|
* 100~125°C 구간: 기울기 10.1 mV/°C
|
||||||
* 125~150°C 구간: 기울기 10.6 mV/°C
|
* 125~150°C 구간: 기울기 10.6 mV/°C
|
||||||
*/
|
*/
|
||||||
if(tmp235_voltage_in_milli_volts <= 1500) {
|
if(tmp235_voltage_in_milli_volts <= 1500)
|
||||||
|
{
|
||||||
/* 0~100°C: Ta = (Vout - 500mV) / 10.0 mV/°C */
|
/* 0~100°C: Ta = (Vout - 500mV) / 10.0 mV/°C */
|
||||||
led_temp = (tmp235_voltage_in_milli_volts - 500.0f) / 10.0f + 0.0f;
|
led_temp = (tmp235_voltage_in_milli_volts - 500.0f) / 10.0f + 0.0f;
|
||||||
}else if(tmp235_voltage_in_milli_volts <= 1750) {
|
}
|
||||||
|
else if(tmp235_voltage_in_milli_volts <= 1750)
|
||||||
|
{
|
||||||
/* 100~125°C: 기울기가 10.1로 약간 증가 */
|
/* 100~125°C: 기울기가 10.1로 약간 증가 */
|
||||||
led_temp = (tmp235_voltage_in_milli_volts - 1500.0f) / 10.1f + 100.0f;
|
led_temp = (tmp235_voltage_in_milli_volts - 1500.0f) / 10.1f + 100.0f;
|
||||||
}else if(tmp235_voltage_in_milli_volts <= 2000) {
|
}
|
||||||
|
else if(tmp235_voltage_in_milli_volts <= 2000)
|
||||||
|
{
|
||||||
/* 125~150°C: 기울기가 10.6으로 더 증가 */
|
/* 125~150°C: 기울기가 10.6으로 더 증가 */
|
||||||
led_temp = (tmp235_voltage_in_milli_volts - 1752.5f) / 10.6f + 125.0f;
|
led_temp = (tmp235_voltage_in_milli_volts - 1752.5f) / 10.6f + 125.0f;
|
||||||
}else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* 150°C 초과 — 센서 측정 범위 벗어남 */
|
/* 150°C 초과 — 센서 측정 범위 벗어남 */
|
||||||
DBG_PRINTF("ERR!!! Temprature is over 150c\r\n");
|
DBG_PRINTF("ERR!!! Temprature is over 150c\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* info4 모드: 온도값을 정수(°C x 100)로 저장 (예: 36.50°C → 3650) */
|
/* info4 모드: 온도값을 정수(°C x 100)로 저장 (예: 36.50°C → 3650) */
|
||||||
if (info4 == true){
|
if (info4 == true)
|
||||||
|
{
|
||||||
info_temp =(uint16_t)(led_temp*100);
|
info_temp =(uint16_t)(led_temp*100);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* UART 모드: 소수점 2자리까지 텍스트로 출력 */
|
/* UART 모드: 소수점 2자리까지 텍스트로 출력 */
|
||||||
else if(cmd_type_t == CMD_UART) {
|
else if(cmd_type_t == CMD_UART)
|
||||||
|
{
|
||||||
DBG_PRINTF("To%.2f\r\n\r\n",led_temp);
|
DBG_PRINTF("To%.2f\r\n\r\n",led_temp);
|
||||||
|
}
|
||||||
/* BLE 모드: °C x 100 정수를 "rso:" 헤더로 바이너리 전송 */
|
/* BLE 모드: °C x 100 정수를 "rso:" 헤더로 바이너리 전송 */
|
||||||
} else if(cmd_type_t == CMD_BLE) {
|
else if(cmd_type_t == CMD_BLE)
|
||||||
|
{
|
||||||
led_temp_16 = (uint16_t)(led_temp*100);
|
led_temp_16 = (uint16_t)(led_temp*100);
|
||||||
single_format_data(ble_bin_buffer, "rso:", led_temp_16);
|
single_format_data(ble_bin_buffer, "rso:", led_temp_16);
|
||||||
|
|
||||||
@@ -148,15 +160,6 @@ void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* info4 모드: 온도 측정 완료 → 다음 단계(IMU 측정)로 전환 */
|
|
||||||
if (info4 == true){
|
|
||||||
|
|
||||||
go_temp = false; /* 온도 측정 완료 표시 */
|
|
||||||
|
|
||||||
|
|
||||||
motion_raw_data_enabled = true; /* IMU 데이터 수집 시작 플래그 */
|
|
||||||
main_timer_start(); /* 메인 타이머 시작 → IMU 측정 트리거 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,8 +176,7 @@ void tmp235_init(void)
|
|||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
/* AIN3 채널 설정: TMP235-Q1 Vout 핀 (싱글엔드 입력) */
|
/* AIN3 채널 설정: TMP235-Q1 Vout 핀 (싱글엔드 입력) */
|
||||||
nrf_saadc_channel_config_t config =
|
nrf_saadc_channel_config_t config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3); /* TMP235_Q1 Voltage Output Measurement */
|
||||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3); /* TMP235_Q1 Voltage Output Measurement */
|
|
||||||
err_code = nrf_drv_saadc_channel_init(0, &config);
|
err_code = nrf_drv_saadc_channel_init(0, &config);
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
@@ -197,8 +199,7 @@ void tmp235_init(void)
|
|||||||
*/
|
*/
|
||||||
void tmp235_voltage_level_meas(void)
|
void tmp235_voltage_level_meas(void)
|
||||||
{
|
{
|
||||||
tmp235_init();
|
tmp235_init(); // init 함수에 있는 걸 그냥 여기 넣어도
|
||||||
//tmp235_uninit();
|
//tmp235_uninit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user