배터리/온도 보호 판정 정책 변경

1. 정렬모드    - 판정하지 않음2. 연속 측정 모드    - 측정 응답에 포함되는 배터리/IMU 온도 값으로 저전압/고온 카운트 및 판정    - 배터리 3500mV 이하 또는 온도 40℃ 이상 30회 연속인 경우 약 5분 후 전원 OFF    - FW 내부 60초 주기 모니터는 skip    - 측정에 실패하는 경우 저전압/고온 카운트는 유지3. 정렬모드도 연속 측정 모드도 아닌 경우    - FW 내부 60초 주기 모니터로 저전압/고온 카운트 및 판정    - 배터리 3500mV 이하 또는 온도 40℃ 이상 5회 연속인 경우 약 5분 후 전원 OFF
This commit is contained in:
2026-06-29 16:50:21 +09:00
parent ad38741b46
commit 749e1d4e0e
3 changed files with 249 additions and 66 deletions
+67 -23
View File
@@ -730,7 +730,7 @@ static int cmd_msr(const uint8_t *data, uint8_t data_len)
/*
* 현재 연결의 bond/security 정보를 먼저 지우면 같은 연결에서 rsr: 응답을
* 보낼 수 없. 응답 전송 완료 후 bond 삭제와 reboot 진행한다.
* 보낼 수 없. 응답 전송 완료 후 bond 삭제와 reboot 진행 필요
*/
k_msleep(100);
@@ -842,7 +842,7 @@ static int cmd_mst(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
/*
* 테스트용
* mpa?: piezo TX/RX 전원 레일만 켬
*/
@@ -889,7 +889,7 @@ static int cmd_mpb(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
/*
* 테스트용
* mpc?: burst만 한 번 발생시키는 테스트 명령
* echo를 읽지 않고 초음파가 나가는지만 볼 때 사용
@@ -944,6 +944,10 @@ static int cmd_mpc(const uint8_t *data, uint8_t data_len)
return 1;
}
/*
* 테스트용
* mec?: 단일 채널 burst + echo capture
*/
static int cmd_mec(const uint8_t *data, uint8_t data_len)
{
const piezo_config_t *cfg = piezo_config_get();
@@ -964,10 +968,6 @@ static int cmd_mec(const uint8_t *data, uint8_t data_len)
ARG_UNUSED(freq_option);
/*
* 테스트용
* mec?: 단일 채널 burst + echo capture
*/
if (num_samples > ECHO_ADC_MAX_SAMPLES)
{
num_samples = ECHO_ADC_MAX_SAMPLES;
@@ -1002,12 +1002,11 @@ static int cmd_mec(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
* 테스트용(이전 정렬모드)
* maa?:
* - piezo 6채널 burst 순서대로 쏘고
* - echo 샘플을 채널별로 모은 뒤
* - reb: 패킷 6개 전송
/*
* 테스트용
* mad?: 단일 채널 echo capture만 수행
* - piezo burst는 하지 않고 echo ADC만 수행
* - echo 샘플을 모은 뒤 reb: 패킷 1개 전송
* - raa: 상태값은 전체 작업 성공/실패 요약
*/
static int cmd_mad(const uint8_t *data, uint8_t data_len)
@@ -1058,6 +1057,14 @@ static int cmd_mad(const uint8_t *data, uint8_t data_len)
return 1;
}
/*
* 테스트용(이전 정렬모드)
* maa?:
* - piezo 6채널 burst 순서대로 쏘고
* - echo 샘플을 채널별로 모은 뒤
* - reb: 패킷 6개 전송
* - raa: 상태값은 전체 작업 성공/실패 요약
*/
static int cmd_maa(const uint8_t *data, uint8_t data_len)
{
ARG_UNUSED(data);
@@ -1091,8 +1098,12 @@ static int cmd_maa(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
* 전체 측정 시 사용
/*
* 전체 측정 명령
* mbb?: piezo echo sweep + 배터리 + IMU + IMU 온도 측정
* - 성공 시 rbb 1개, reb 6개, raa 상태값 전송
* - 실패 시 rbb/reb 생략, raa에 실패 원인 코드 전송
* - processing=true 구간에서는 내부 모니터의 I2C 접근을 막는 기준으로 사용
*/
static int cmd_mbb(const uint8_t *data, uint8_t data_len)
{
@@ -1133,7 +1144,10 @@ static int cmd_mbb(const uint8_t *data, uint8_t data_len)
if (status == ECHO_STATUS_OK)
{
/* info 성격 데이터는 echo sweep이 정상 끝났을 때만 읽음 */
/* echo sweep 성공 후에만 부가 센서값 읽기
* - rbb에 포함되는 배터리 전압
* - 실패 시 ECHO_STATUS_BATT로 종료
*/
DBG_PRINTF("[MBB] battery read\r\n");
batt_mv = battery_read_mv();
if (batt_mv < 0)
@@ -1144,6 +1158,10 @@ static int cmd_mbb(const uint8_t *data, uint8_t data_len)
if (status == ECHO_STATUS_OK)
{
/* rbb에 포함되는 IMU 6축 값과 IMU 내부 온도 읽기
* - direct read 경로 사용
* - 실패 시 ECHO_STATUS_IMU로 종료
*/
DBG_PRINTF("[MBB] imu/temp read\r\n");
if (imu_read_with_temperature(accel, gyro, &temp_cdeg) != 0)
{
@@ -1153,7 +1171,17 @@ static int cmd_mbb(const uint8_t *data, uint8_t data_len)
if (status == ECHO_STATUS_OK)
{
/* rbb: 센서(배터리+IMU+온도) 정보 패킷 */
/* mbb? 성공 응답값으로 연속 측정 보호 판정 갱신
* - 실패한 측정은 호출하지 않아 기존 저전압/고온 카운트 유지
* - rbb에 실리는 배터리/IMU 온도 값과 같은 값을 사용
*/
battery_protection_record_continuous(batt_mv, temp_cdeg);
/* 측정 성공 응답 순서
* - rbb: 배터리 + IMU + IMU 온도 요약
* - reb: 채널별 echo raw 데이터
* - raa: 마지막 상태 코드
*/
DBG_PRINTF("[MBB] response tx start\r\n");
send_response_bundle((uint16_t)batt_mv, accel, gyro, temp_cdeg);
@@ -1175,7 +1203,7 @@ static int cmd_mbb(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
/*
* mtb?: piezo sweep + IMU FIFO
*/
static int cmd_mtb(const uint8_t *data, uint8_t data_len)
@@ -1245,7 +1273,7 @@ static int cmd_mtb(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
/*
* mcf?: piezo 측정 파라미터 읽기
* 응답 rcf: + 설정값 echo back
*/
@@ -1259,7 +1287,7 @@ static int cmd_mcf(const uint8_t *data, uint8_t data_len)
return 1;
}
/**
/*
* mcs?: piezo 측정 파라미터 쓰기
*/
static int cmd_mcs(const uint8_t *data, uint8_t data_len)
@@ -1457,9 +1485,16 @@ static int cmd_mqz(const uint8_t *data, uint8_t data_len)
return 1;
}
/*
* LED 상태 변경 명령
* mls?: 앱에서 전달한 LED 상태값을 적용하고 rls로 echo back
* - 파라미터 부족: 0xFFFF
* - 범위 초과: 0xFFFE
* - LED_STATE_OFF 진입 시 IMU FIFO 정지
*/
static int cmd_mls(const uint8_t *data, uint8_t data_len)
{
/* 파라미터 부족 에러 코드 0xFFFF 에코 */
/* 파라미터 부족: 에러 코드 0xFFFF 에코 */
if (data_len < 2)
{
send_response_u16("rls:", 0xFFFF);
@@ -1467,10 +1502,10 @@ static int cmd_mls(const uint8_t *data, uint8_t data_len)
return 1;
}
/* state 2B BE */
/* state 필드: 2바이트 big-endian */
uint16_t state = ((uint16_t)data[0] << 8) | (uint16_t)data[1];
/* 범위 초과 에러 코드 0xFFFE 에코 */
/* 범위 초과: 에러 코드 0xFFFE 에코 */
if (state > LED_STATE_ERROR)
{
send_response_u16("rls:", 0xFFFE);
@@ -1479,6 +1514,15 @@ static int cmd_mls(const uint8_t *data, uint8_t data_len)
}
led_set_state((led_state_t)state);
/* 정렬 LED 상태와 보호 판정 정책 연결
* - ALIGN_SEARCHING/ALIGN_COMPLETE 동안 보호 판정 차단
* - 다른 LED 상태에서는 기존 조건에 따라 보호 판정 재개
*/
battery_protection_set_alignment_mode((state == LED_STATE_ALIGN_SEARCHING) ||
(state == LED_STATE_ALIGN_COMPLETE));
/* OFF 상태에서는 정렬/측정용 FIFO를 함께 정리 */
if (state == LED_STATE_OFF)
{
(void)imu_fifo_stop();