Compare commits

...

2 Commits

Author SHA1 Message Date
jhChun 9e48c084b4 SAADC 안정성 개선: 버퍼/해제 순서 수정
- 배터리 SAADC 더블 버퍼 -> 싱글 버퍼(1회 측정 후 해제이므로 불필요)
- 콜백 내 buffer_convert 제거(해제 직전 다음 버퍼 등록 제거)
- uninit 순서 변경: channel_uninit -> uninit(채널 먼저 해제)
- 5초마다 배터리를 측정하는 battery_loop에 info4(전체 측정) 체크 추가(전체 측정 중 SAADC 동시 init 충돌 방지)
2026-03-30 12:10:53 +09:00
jhChun a9fa050bb0 SAADC 우선순위 변경
- NRFX_SAADC_CONFIG_IRQ_PRIORITY = 0 -> 6
- C:\jhChun\VesiScan-Basic_jhChun_new\components\libraries\util\app_util_platform.h
- 위 경로에 Cortex-M4(nRF52840) 우선순위 배분표가 정의되어 있음
- 0, 1, 4는 SoftDevice 전용, 앱 사용 가능한 우선순위는 2, 3, 5, 6(권장), 7
- 권장되는 우선순위인 6위로 변경
- SAADC 해상도 10 -> 12bit 변경 및 콜백 내 연산 int -> float 변경으로 ISR 처리 시간이 길어지고, SoftDevice와 충돌 가능성이 높아지는 것으로 추측
- 충돌이 발생하는 경우 콜백 지연 또는 누락
2026-03-30 11:41:59 +09:00
3 changed files with 24 additions and 21 deletions
@@ -58,8 +58,9 @@
#define BATTERY_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\ #define BATTERY_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
((((ADC_VALUE) * BATTERY_REF_VOLTAGE_IN_MILLIVOLTS) / BATTERY_ADC_RES_12BITS) * BATTERY_PRE_SCALING_COMPENSATION) ((((ADC_VALUE) * BATTERY_REF_VOLTAGE_IN_MILLIVOLTS) / BATTERY_ADC_RES_12BITS) * BATTERY_PRE_SCALING_COMPENSATION)
/* 배터리 측정용 더블 버퍼 (SAADC가 비동기로 교대 사용) */ /* 배터리 측정용 싱글 버퍼 (1회 측정 후 uninit하므로 더블 버퍼 불필요) */
static nrf_saadc_value_t adc_bufs[2]; static nrf_saadc_value_t adc_buf;
//static nrf_saadc_value_t adc_bufs[2]; // 이전: 더블 버퍼 (연속 측정용)
/* 배터리 모니터링 반복 타이머 정의 */ /* 배터리 모니터링 반복 타이머 정의 */
@@ -129,18 +130,17 @@ void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
nrf_saadc_value_t register_val = 0; nrf_saadc_value_t register_val = 0;
float batt_lvl_in_milli_volt_0 = 0; /* 보정 전 전압 (부동소수점) */ float batt_lvl_in_milli_volt_0 = 0; /* 보정 전 전압 (부동소수점) */
float batt_lvl_in_milli_volt_1 = 0; /* 분압 보정 후 최종 전압 (부동소수점) */ float batt_lvl_in_milli_volt_1 = 0; /* 분압 보정 후 최종 전압 (부동소수점) */
uint32_t err_code = 0;
/* ADC 변환 결과 읽기 */ /* ADC 변환 결과 읽기 */
register_val = p_event->data.done.p_buffer[0]; register_val = p_event->data.done.p_buffer[0];
/* 다음 변환을 위해 버퍼 재등록 */ //err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1); // 이전: 다음 변환을 위해 버퍼 재등록
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1); //APP_ERROR_CHECK(err_code);
APP_ERROR_CHECK(err_code);
/* SAADC 해제 — 다른 ADC 측정(온도, 압력)과 하드웨어 공유 */ /* SAADC 해제 — 다른 ADC 측정(온도, 압력)과 하드웨어 공유 */
nrf_drv_saadc_uninit(); /* 1회 측정 후 해제이므로 buffer_convert(다음 버퍼 등록) 불필요 */
nrf_drv_saadc_channel_uninit(0); nrf_drv_saadc_channel_uninit(0);
nrf_drv_saadc_uninit();
/* 콜백 완료 알림 (all_sensors 대기 해제용) */ /* 콜백 완료 알림 (all_sensors 대기 해제용) */
battery_saadc_done = true; battery_saadc_done = true;
@@ -211,9 +211,9 @@ void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
*/ */
static void battery_configure(void) static void battery_configure(void)
{ {
/* SAADC 드라이버 초기화 (16x 오버샘플링으로 노이즈 저감) */ /* SAADC 드라이버 초기화 (4x 오버샘플링으로 노이즈 저감) */
nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG; nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT; saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT; // 10 -> 12bit
saadc_config.oversample = NRF_SAADC_OVERSAMPLE_4X; saadc_config.oversample = NRF_SAADC_OVERSAMPLE_4X;
ret_code_t err_code = nrf_drv_saadc_init(&saadc_config, battery_event_handler); ret_code_t err_code = nrf_drv_saadc_init(&saadc_config, battery_event_handler);
APP_ERROR_CHECK(err_code); APP_ERROR_CHECK(err_code);
@@ -225,12 +225,13 @@ static void battery_configure(void)
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);
/* 더블 버퍼 등록 — SAADC가 교대로 사용하여 데이터 손실 방지 */ /* 싱글 버퍼 등록 (1회 측정 후 uninit) */
err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[0], 1); err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[1], 1);
APP_ERROR_CHECK(err_code); APP_ERROR_CHECK(err_code);
//err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[0], 1); // 이전: 더블 버퍼
//APP_ERROR_CHECK(err_code);
//err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[1], 1);
//APP_ERROR_CHECK(err_code);
} }
/** /**
@@ -250,17 +251,17 @@ void battery_level_meas(void)
/** /**
* @brief 배터리 모니터링 타이머 콜백 (5초 주기) * @brief 배터리 모니터링 타이머 콜백 (5초 주기) - 주기 확인 필요(너무 짧음)
* *
* 저전압 체크 플래그를 설정하고 배터리 측정을 시작한다.
* 다른 작업(IMU 등) 처리 중이면 측정을 건너뛴다. * 다른 작업(IMU 등) 처리 중이면 측정을 건너뛴다.
* 그렇지 않으면 저전압 체크 플래그를 설정하고 배터리 측정을 시작한다.
*/ */
void battery_loop(void * p_context) /* For 1sec */ void battery_loop(void * p_context) /* For 1sec */
{ {
UNUSED_PARAMETER(p_context); UNUSED_PARAMETER(p_context);
/* 다른 센서 처리 중이면 배터리 측정 스킵 (충돌 방지) */ /* 다른 센서 처리 중 또는 MBB 센서 수집 중이면 배터리 측정 스킵 (SAADC 충돌 방지) */
if(processing==true) if (processing == true || info4 == true)
{ {
processing = false ; // add 20241218 processing = false ; // add 20241218
//low_battery_check = true; //low_battery_check = true;
@@ -3587,7 +3587,7 @@
// <7=> 7 // <7=> 7
#ifndef NRFX_SAADC_CONFIG_IRQ_PRIORITY #ifndef NRFX_SAADC_CONFIG_IRQ_PRIORITY
#define NRFX_SAADC_CONFIG_IRQ_PRIORITY 0 #define NRFX_SAADC_CONFIG_IRQ_PRIORITY 6
#endif #endif
// <e> NRFX_SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. // <e> NRFX_SAADC_CONFIG_LOG_ENABLED - Enables logging in the module.
@@ -106,8 +106,10 @@ void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout
//DBG_PRINTF("[TMP] adc=%d\r\n", adc_result); //DBG_PRINTF("[TMP] adc=%d\r\n", adc_result);
/* SAADC 해제 — 배터리/압력센서 측정과 하드웨어 공유 */ /* SAADC 해제 — 배터리/압력센서 측정과 하드웨어 공유 */
nrf_drv_saadc_channel_uninit(0); // 채널 먼저 해제
nrf_drv_saadc_uninit(); nrf_drv_saadc_uninit();
nrf_drv_saadc_channel_uninit(0); //nrf_drv_saadc_uninit(); // 이전: 드라이버 먼저 해제
//nrf_drv_saadc_channel_uninit(0);
/* ADC값 → TMP235 출력전압(mV) 변환 */ /* ADC값 → TMP235 출력전압(mV) 변환 */
tmp235_voltage_in_milli_volts = TMP235_VOUT_IN_MILLI_VOLTS(adc_result); tmp235_voltage_in_milli_volts = TMP235_VOUT_IN_MILLI_VOLTS(adc_result);