코드 정리
- 주석 영문으로 변경 - Allman 스타일로 통일
This commit is contained in:
@@ -1,32 +1,32 @@
|
||||
// file: debug_print.h
|
||||
/*******************************************************************************
|
||||
* [한국어 설명] 디버그 출력 매크로 (조건부 컴파일)
|
||||
* Debug print macros (conditional compilation)
|
||||
*
|
||||
* SEGGER RTT(Real Time Transfer)를 이용한 디버그 출력 매크로.
|
||||
* J-Link 디버거를 통해 실시간으로 로그를 PC에 전송한다.
|
||||
* UART를 사용하지 않으므로 시스템 타이밍에 미치는 영향이 적다.
|
||||
* Debug output macros using SEGGER RTT (Real Time Transfer).
|
||||
* Sends logs to the PC in real time via J-Link debugger.
|
||||
* Minimal impact on system timing since UART is not used.
|
||||
*
|
||||
* === 조건부 컴파일 ===
|
||||
* ENABLE_PRINTF = 1: DBG_PRINTF가 SEGGER_RTT_printf(채널0)로 치환됨
|
||||
* -> 실제 로그 출력 (디버깅 시 사용)
|
||||
* ENABLE_PRINTF = 0: DBG_PRINTF가 빈 매크로로 치환됨
|
||||
* -> 코드에서 완전히 제거 (릴리스 빌드 시 사용)
|
||||
* === Conditional compilation ===
|
||||
* ENABLE_PRINTF = 1: DBG_PRINTF maps to SEGGER_RTT_printf (channel 0)
|
||||
* -> Actual log output (for debugging)
|
||||
* ENABLE_PRINTF = 0: DBG_PRINTF maps to an empty macro
|
||||
* -> Completely removed from code (for release builds)
|
||||
*
|
||||
* === 사용법 ===
|
||||
* DBG_PRINTF("값: %d\r\n", value); // printf와 동일한 포맷 문자열
|
||||
* 출력은 SEGGER RTT Viewer 또는 J-Link RTT Client에서 확인.
|
||||
* === Usage ===
|
||||
* DBG_PRINTF("val: %d\r\n", value); // Same format string as printf
|
||||
* View output in SEGGER RTT Viewer or J-Link RTT Client.
|
||||
******************************************************************************/
|
||||
#ifndef DEBUG_PRINT_H
|
||||
#define DEBUG_PRINT_H
|
||||
|
||||
#define ENABLE_PRINTF 1 /* 1=디버그 출력 활성화, 0=전역 비활성화 */
|
||||
#define ENABLE_PRINTF 1 /* 1=Enable debug output, 0=Disable globally */
|
||||
|
||||
#if ENABLE_PRINTF
|
||||
#include "SEGGER_RTT.h"
|
||||
/* SEGGER RTT 채널 0으로 포맷 문자열 출력 */
|
||||
/* Print formatted string to SEGGER RTT channel 0 */
|
||||
#define DBG_PRINTF(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||
#else
|
||||
/* 빈 매크로: 컴파일러가 호출 코드를 완전히 제거 */
|
||||
/* Empty macro: compiler removes all call-site code */
|
||||
#define DBG_PRINTF(...) // Do nothing
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*******************************************************************************
|
||||
* @file led_control.c
|
||||
* @brief LED 직접 제어 드라이버 (BSP 미사용)
|
||||
* @brief Direct LED control driver (no BSP)
|
||||
* @date 2026-03-30
|
||||
*
|
||||
* app_timer 1개로 2색 LED(녹색/주황)의 복합 blink 패턴 구현
|
||||
* 단순 on/off 상태는 타이머 없이 즉시 GPIO 제어
|
||||
* 복합 패턴(에러 등)은 phase 기반 state machine으로 처리
|
||||
* Implements dual-color LED (green/orange) blink patterns with a single app_timer.
|
||||
* Simple on/off states use immediate GPIO control without a timer.
|
||||
* Complex patterns (e.g. error) are handled by a phase-based state machine.
|
||||
******************************************************************************/
|
||||
|
||||
#include "led_control.h"
|
||||
@@ -13,20 +13,20 @@
|
||||
#include "app_timer.h"
|
||||
|
||||
/*==============================================================================
|
||||
* 내부 상수
|
||||
* Internal constants
|
||||
*============================================================================*/
|
||||
#define MS_TO_TICKS(ms) APP_TIMER_TICKS(ms)
|
||||
|
||||
/*==============================================================================
|
||||
* 색상
|
||||
* Colors
|
||||
*============================================================================*/
|
||||
#define COLOR_NONE 0
|
||||
#define COLOR_GREEN 1
|
||||
#define COLOR_ORANGE 2
|
||||
|
||||
/*==============================================================================
|
||||
* 에러 패턴 상수 (No.7)
|
||||
* 3Hz 깜빡 3회 = 166ms on + 166ms off × 3 = ~1초, 이후 꺼짐 1초
|
||||
* Error pattern constants (No.7)
|
||||
* 3Hz blink x3 = 166ms on + 166ms off x 3 = ~1s, then off for 1s
|
||||
*============================================================================*/
|
||||
#define ERROR_BLINK_ON_MS 166
|
||||
#define ERROR_BLINK_OFF_MS 166
|
||||
@@ -34,42 +34,42 @@
|
||||
#define ERROR_PAUSE_MS 1000
|
||||
|
||||
/*==============================================================================
|
||||
* 패턴 테이블 (단순 blink 용)
|
||||
* Pattern table (for simple blink)
|
||||
*============================================================================*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t on_ms; /* LED 켜짐 시간 (ms) */
|
||||
uint32_t off_ms; /* LED 꺼짐 시간 (ms) */
|
||||
uint8_t color; /* COLOR_GREEN 또는 COLOR_ORANGE */
|
||||
bool repeat; /* true: 무한 반복, false: 1회 후 OFF */
|
||||
uint32_t on_ms; /* LED on duration (ms) */
|
||||
uint32_t off_ms; /* LED off duration (ms) */
|
||||
uint8_t color; /* COLOR_GREEN or COLOR_ORANGE */
|
||||
bool repeat; /* true: repeat forever, false: once then OFF */
|
||||
} led_pattern_t;
|
||||
|
||||
static const led_pattern_t m_patterns[LED_STATE_COUNT] =
|
||||
{
|
||||
[LED_STATE_OFF] = { 0, 0, COLOR_NONE, false },
|
||||
[LED_STATE_POWER_ON] = { 2000, 0, COLOR_GREEN, false }, /* 초록 점등 2초 → 유지 */
|
||||
[LED_STATE_POWER_OFF] = { 2000, 0, COLOR_GREEN, false }, /* 초록 점등 2초 → OFF */
|
||||
[LED_STATE_ADVERTISING] = { 500, 500, COLOR_GREEN, true }, /* 초록 점멸 1초 */
|
||||
[LED_STATE_DETACH_WARNING] = { 1000, 3000, COLOR_GREEN, true }, /* 초록 1초 on / 3초 off */
|
||||
[LED_STATE_ALIGN_SEARCHING] = { 1000, 1000, COLOR_ORANGE, true }, /* 주황 점멸 1초 */
|
||||
[LED_STATE_ALIGN_COMPLETE] = { 3000, 1000, COLOR_GREEN, true }, /* 초록 3초 on / 1초 off */
|
||||
[LED_STATE_ERROR] = { 0, 0, COLOR_ORANGE, true } /* 별도 state machine */
|
||||
[LED_STATE_POWER_ON] = { 2000, 0, COLOR_GREEN, false }, /* Green on 2s, stay on */
|
||||
[LED_STATE_POWER_OFF] = { 2000, 0, COLOR_GREEN, false }, /* Green on 2s, then OFF */
|
||||
[LED_STATE_ADVERTISING] = { 500, 500, COLOR_GREEN, true }, /* Green blink 1s interval */
|
||||
[LED_STATE_DETACH_WARNING] = { 1000, 3000, COLOR_GREEN, true }, /* Green 1s on / 3s off */
|
||||
[LED_STATE_ALIGN_SEARCHING] = { 1000, 1000, COLOR_ORANGE, true }, /* Orange blink 1s interval */
|
||||
[LED_STATE_ALIGN_COMPLETE] = { 3000, 1000, COLOR_GREEN, true }, /* Green 3s on / 1s off */
|
||||
[LED_STATE_ERROR] = { 0, 0, COLOR_ORANGE, true } /* Separate state machine */
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
* 모듈 변수
|
||||
* Module variables
|
||||
*============================================================================*/
|
||||
APP_TIMER_DEF(m_led_timer);
|
||||
|
||||
static led_state_t m_current_state = LED_STATE_OFF;
|
||||
static bool m_phase_on; /* true: LED 켜진 구간, false: 꺼진 구간 */
|
||||
static bool m_phase_on; /* true: LED on phase, false: off phase */
|
||||
|
||||
/* 에러 패턴 전용 */
|
||||
static uint8_t m_error_blink_cnt; /* 현재까지 깜빡인 횟수 */
|
||||
/* Error pattern only */
|
||||
static uint8_t m_error_blink_cnt; /* Blink count so far */
|
||||
static uint8_t m_error_phase; /* 0: blink-on, 1: blink-off, 2: pause */
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO 헬퍼
|
||||
* GPIO helpers
|
||||
*============================================================================*/
|
||||
|
||||
static inline void led_green_on(void)
|
||||
@@ -122,7 +122,7 @@ static void led_color_on(uint8_t color)
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* 타이머 시작 헬퍼
|
||||
* Timer start helper
|
||||
*============================================================================*/
|
||||
static void timer_start_ms(uint32_t ms)
|
||||
{
|
||||
@@ -131,7 +131,7 @@ static void timer_start_ms(uint32_t ms)
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* 에러 패턴 state machine (No.7)
|
||||
* Error pattern state machine (No.7)
|
||||
* phase 0: LED ON (166ms) → phase 1
|
||||
* phase 1: LED OFF (166ms) → cnt++ → cnt<3 ? phase 0 : phase 2
|
||||
* phase 2: PAUSE (1000ms) → cnt=0, phase 0
|
||||
@@ -148,30 +148,30 @@ static void error_pattern_tick(void)
|
||||
{
|
||||
switch (m_error_phase)
|
||||
{
|
||||
case 0: /* ON 구간 끝 → OFF */
|
||||
case 0: /* ON phase done -> OFF */
|
||||
led_all_off();
|
||||
m_error_phase = 1;
|
||||
timer_start_ms(ERROR_BLINK_OFF_MS);
|
||||
break;
|
||||
|
||||
case 1: /* OFF 구간 끝 */
|
||||
case 1: /* OFF phase done */
|
||||
m_error_blink_cnt++;
|
||||
if (m_error_blink_cnt < ERROR_BLINK_COUNT)
|
||||
{
|
||||
/* 다시 ON */
|
||||
/* Back to ON */
|
||||
m_error_phase = 0;
|
||||
led_color_on(COLOR_ORANGE);
|
||||
timer_start_ms(ERROR_BLINK_ON_MS);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 3회 완료 → pause */
|
||||
/* 3 blinks done -> pause */
|
||||
m_error_phase = 2;
|
||||
timer_start_ms(ERROR_PAUSE_MS);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* pause 끝 → 처음부터 */
|
||||
case 2: /* Pause done -> restart */
|
||||
m_error_blink_cnt = 0;
|
||||
m_error_phase = 0;
|
||||
led_color_on(COLOR_ORANGE);
|
||||
@@ -184,13 +184,13 @@ static void error_pattern_tick(void)
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* 타이머 콜백
|
||||
* Timer callback
|
||||
*============================================================================*/
|
||||
static void led_timer_handler(void * p_context)
|
||||
{
|
||||
(void)p_context;
|
||||
|
||||
/* 에러 상태는 별도 처리 */
|
||||
/* Error state handled separately */
|
||||
if (m_current_state == LED_STATE_ERROR)
|
||||
{
|
||||
error_pattern_tick();
|
||||
@@ -201,7 +201,7 @@ static void led_timer_handler(void * p_context)
|
||||
|
||||
if (m_phase_on)
|
||||
{
|
||||
/* ON→OFF 전환 */
|
||||
/* ON -> OFF transition */
|
||||
led_all_off();
|
||||
m_phase_on = false;
|
||||
|
||||
@@ -211,40 +211,40 @@ static void led_timer_handler(void * p_context)
|
||||
}
|
||||
else if (!p->repeat)
|
||||
{
|
||||
/* 1회성: off_ms == 0 이면 그냥 유지 (POWER_ON) 또는 끄기 (POWER_OFF) */
|
||||
/* One-shot: if off_ms == 0, stay on (POWER_ON) or turn off (POWER_OFF) */
|
||||
if (m_current_state == LED_STATE_POWER_OFF)
|
||||
{
|
||||
led_all_off();
|
||||
m_current_state = LED_STATE_OFF;
|
||||
}
|
||||
/* POWER_ON: 점등 유지 상태 → 타이머 x */
|
||||
/* POWER_ON: stay lit, no timer */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* OFF → ON 전환 */
|
||||
/* OFF -> ON transition */
|
||||
if (p->repeat)
|
||||
{
|
||||
led_color_on(p->color);
|
||||
m_phase_on = true;
|
||||
timer_start_ms(p->on_ms);
|
||||
}
|
||||
/* repeat == false && off_ms > 0 인 경우는 현재 없음 */
|
||||
/* No current case where repeat == false && off_ms > 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* 공개 함수
|
||||
* Public functions
|
||||
*============================================================================*/
|
||||
|
||||
void led_init(void)
|
||||
{
|
||||
/* GPIO 출력 설정 */
|
||||
/* Configure GPIO outputs */
|
||||
nrf_gpio_cfg_output(LED_PIN_GREEN);
|
||||
nrf_gpio_cfg_output(LED_PIN_ORANGE);
|
||||
led_all_off();
|
||||
|
||||
/* 타이머 생성 (single-shot) */
|
||||
/* Create timer (single-shot) */
|
||||
app_timer_create(&m_led_timer, APP_TIMER_MODE_SINGLE_SHOT, led_timer_handler);
|
||||
|
||||
m_current_state = LED_STATE_OFF;
|
||||
@@ -254,7 +254,7 @@ void led_set_state(led_state_t state)
|
||||
{
|
||||
if (state >= LED_STATE_COUNT) return;
|
||||
|
||||
/* 이전 패턴 중단 */
|
||||
/* Stop previous pattern */
|
||||
app_timer_stop(m_led_timer);
|
||||
led_all_off();
|
||||
|
||||
@@ -266,15 +266,15 @@ void led_set_state(led_state_t state)
|
||||
switch (state)
|
||||
{
|
||||
case LED_STATE_OFF:
|
||||
/* 이미 all off */
|
||||
/* Already all off */
|
||||
break;
|
||||
|
||||
/* 에러 패턴: 별도 state machine */
|
||||
/* Error pattern: separate state machine */
|
||||
case LED_STATE_ERROR:
|
||||
error_pattern_start();
|
||||
break;
|
||||
|
||||
/* 그 외: on 구간부터 시작 */
|
||||
/* All others: start from ON phase */
|
||||
default:
|
||||
led_color_on(p->color);
|
||||
m_phase_on = true;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* @file led_control.h
|
||||
* @brief LED 직접 제어 드라이버 (BSP 미사용)
|
||||
* @brief Direct LED control driver (no BSP)
|
||||
* @date 2026-03-30
|
||||
*
|
||||
* 녹색(P0.12) + 주황(P0.29) 2색 LED를 app_timer 기반으로 제어
|
||||
* 각 상태별 on/off 시간, 색상, 반복 패턴을 테이블로 관리
|
||||
* Controls dual-color LED green(P0.12) + orange(P0.29) via app_timer.
|
||||
* On/off timing, color, and repeat pattern managed per state in a table.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LED_CONTROL_H__
|
||||
@@ -14,39 +14,39 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
/*==============================================================================
|
||||
* LED 핀 정의
|
||||
* LED pin definitions
|
||||
*============================================================================*/
|
||||
#define LED_PIN_GREEN NRF_GPIO_PIN_MAP(0, 12) /* 녹색 LED */
|
||||
#define LED_PIN_ORANGE NRF_GPIO_PIN_MAP(0, 29) /* 주황 LED */
|
||||
#define LED_ACTIVE_LOW 1 /* 1 = Active Low (GPIO LOW에서 LED 켜짐) */
|
||||
#define LED_PIN_GREEN NRF_GPIO_PIN_MAP(0, 12) /* Green LED */
|
||||
#define LED_PIN_ORANGE NRF_GPIO_PIN_MAP(0, 29) /* Orange LED */
|
||||
#define LED_ACTIVE_LOW 1 /* 1 = Active Low (LED on when GPIO LOW) */
|
||||
|
||||
/*==============================================================================
|
||||
* LED 상태 열거형
|
||||
* LED state enumeration
|
||||
*============================================================================*/
|
||||
typedef enum
|
||||
{
|
||||
LED_STATE_OFF = 0, /* 모든 LED 소등 */
|
||||
LED_STATE_POWER_ON, /* 1: 전원 ON - 초록 소등 → 녹색 점등 2초 */
|
||||
LED_STATE_POWER_OFF, /* 2: 전원 OFF - 초록 점등 2초 → 소등 */
|
||||
LED_STATE_ADVERTISING, /* 3: 블루투스 스캐닝 - 초록 점멸 1초 간격(반복) */
|
||||
LED_STATE_DETACH_WARNING, /* 4: 정상 작동중(미부착 시) - 초록 점등 1초 / 소등 3초 (반복) */
|
||||
LED_STATE_ALIGN_SEARCHING, /* 5: 정렬모드(탐지중) - 주황 점멸 1초 간격 (반복) */
|
||||
LED_STATE_ALIGN_COMPLETE, /* 6: 정렬모드(탐지 완료) - 초록 점등 3초 / 소등 1초 */
|
||||
LED_STATE_ERROR, /* 7: 오류 발생 - 주황 3Hz 깜빡 3회 / 꺼짐 1초 (반복) */
|
||||
LED_STATE_COUNT /* 배열 크기 */
|
||||
LED_STATE_OFF = 0, /* All LEDs off */
|
||||
LED_STATE_POWER_ON, /* 1: Power ON - green on 2s */
|
||||
LED_STATE_POWER_OFF, /* 2: Power OFF - green on 2s then off */
|
||||
LED_STATE_ADVERTISING, /* 3: BLE advertising - green blink 1s interval (repeat) */
|
||||
LED_STATE_DETACH_WARNING, /* 4: Normal operation (detached) - green 1s on / 3s off (repeat) */
|
||||
LED_STATE_ALIGN_SEARCHING, /* 5: Alignment mode (searching) - orange blink 1s interval (repeat) */
|
||||
LED_STATE_ALIGN_COMPLETE, /* 6: Alignment mode (complete) - green 3s on / 1s off */
|
||||
LED_STATE_ERROR, /* 7: Error - orange 3Hz blink x3 / off 1s (repeat) */
|
||||
LED_STATE_COUNT /* Array size */
|
||||
} led_state_t;
|
||||
|
||||
/*==============================================================================
|
||||
* 공개 함수
|
||||
* Public functions
|
||||
*============================================================================*/
|
||||
|
||||
/** @brief LED GPIO 초기화 + 타이머 생성 - main()에서 1회 호출 */
|
||||
/** @brief Initialize LED GPIO + create timer - call once from main() */
|
||||
void led_init(void);
|
||||
|
||||
/** @brief LED 상태 변경 - 이전 패턴을 즉시 중단하고 새 패턴 시작 */
|
||||
/** @brief Change LED state - immediately stops previous pattern and starts new one */
|
||||
void led_set_state(led_state_t state);
|
||||
|
||||
/** @brief 현재 LED 상태 조회 */
|
||||
/** @brief Get current LED state */
|
||||
led_state_t led_get_state(void);
|
||||
|
||||
#endif /* LED_CONTROL_H__ */
|
||||
|
||||
@@ -2,30 +2,30 @@
|
||||
TEST medi50 Dec 23
|
||||
*******************************************************************************
|
||||
*
|
||||
* [모듈 개요]
|
||||
* 메인 이벤트 루프 타이머 모듈 (10ms 간격, 싱글샷 모드).
|
||||
* [Module overview]
|
||||
* Main event loop timer module (10ms interval, single-shot mode).
|
||||
*
|
||||
* 센서 데이터 수집 및 시스템 제어 이벤트를 플래그 기반으로 디스패치한다.
|
||||
* app_timer 싱글샷 모드를 사용하므로, 이벤트 처리 완료 후
|
||||
* 필요 시 main_timer_start()로 수동 재시작해야 한다.
|
||||
* Dispatches sensor data collection and system control events via flags.
|
||||
* Uses app_timer single-shot mode; after processing, call main_timer_start()
|
||||
* manually to restart if needed.
|
||||
*
|
||||
* [이벤트 플래그 및 처리 순서]
|
||||
* motion_raw_data_enabled → IMU 데이터 읽기 (icm42670_main 호출)
|
||||
* - motion_data_once == true: 단발성 읽기 (HW I2C 초기화 후 1회)
|
||||
* - motion_data_once == false: 연속 읽기 (BLE 전송 대기 중이 아닐 때)
|
||||
* go_batt → 배터리 전압 측정 (battery_level_meas)
|
||||
* go_temp → 온도 측정 (tmp235_voltage_level_meas)
|
||||
* go_device_power_off → 디바이스 전원 OFF (device_power_off)
|
||||
* go_sleep_mode_enter → 슬립 모드 진입 (sleep_mode_enter)
|
||||
* go_NVIC_SystemReset → NVIC 시스템 리셋
|
||||
* [Event flags and processing order]
|
||||
* motion_raw_data_enabled -> IMU data read (calls icm42670_main)
|
||||
* - motion_data_once == true: one-shot read (after HW I2C init)
|
||||
* - motion_data_once == false: continuous read (when not waiting for BLE TX)
|
||||
* go_batt -> Battery voltage measurement (battery_level_meas)
|
||||
* go_temp -> Temperature measurement (tmp235_voltage_level_meas)
|
||||
* go_device_power_off -> Device power OFF (device_power_off)
|
||||
* go_sleep_mode_enter -> Enter sleep mode (sleep_mode_enter)
|
||||
* go_NVIC_SystemReset -> NVIC system reset
|
||||
*
|
||||
* [info4 모드 측정 순서]
|
||||
* IMU 연속 읽기 → go_batt(배터리) → go_temp(온도) → motion_data_once(IMU 단발)
|
||||
* 온도 측정 완료 시 motion_data_once=true로 설정하여 다시 IMU로 돌아간다.
|
||||
* [info4 mode measurement order]
|
||||
* IMU continuous read -> go_batt (battery) -> go_temp (temp) -> motion_data_once (IMU one-shot)
|
||||
* After temperature measurement, motion_data_once=true to return to IMU.
|
||||
*
|
||||
* [타이머 설정]
|
||||
* - 일반 모드: 10ms 간격 (MAIN_LOOP_INTERVAL)
|
||||
* - FEATURE_DETAIL_VALUE_FULL 모드: 80ms 간격 (디테일 프린트아웃용)
|
||||
* [Timer settings]
|
||||
* - Normal mode: 10ms interval (MAIN_LOOP_INTERVAL)
|
||||
* - FEATURE_DETAIL_VALUE_FULL mode: 80ms interval (for detail printout)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@@ -56,16 +56,16 @@
|
||||
#include "tmp235_q1.h"
|
||||
//#include "fstorage.h"
|
||||
#include "power_control.h"
|
||||
#include "main.h" /* 2026-03-17: cmd_parse.h 삭제 → main.h */
|
||||
#include "main.h" /* 2026-03-17: cmd_parse.h removed, use main.h */
|
||||
#include "debug_print.h"
|
||||
#include "i2c_manager.h" //add cj
|
||||
|
||||
/* 메인 루프 싱글샷 타이머 인스턴스 */
|
||||
/* Main loop single-shot timer instance */
|
||||
APP_TIMER_DEF(m_main_loop_timer_id);
|
||||
|
||||
#if FEATURE_DETAIL_VALUE_FULL
|
||||
/* 디테일 프린트아웃 모드: 80ms 간격으로 메인 루프 실행 */
|
||||
#define MAIN_LOOP_INTERVAL 80 /* 디테일 프린트아웃이 있을경우 Full_Mode Main Prosessing 수행하는 타이머 */
|
||||
/* Detail printout mode: run main loop at 80ms interval */
|
||||
#define MAIN_LOOP_INTERVAL 80 /* Timer for Full_Mode main processing when detail printout is enabled */
|
||||
|
||||
//extern bool pd_adc_full_a_start;
|
||||
//extern bool pd_adc_full_b_start;
|
||||
@@ -75,36 +75,36 @@ APP_TIMER_DEF(m_main_loop_timer_id);
|
||||
|
||||
extern which_cmd_t cmd_type_t;
|
||||
#else
|
||||
/* 일반 모드: 10ms 간격으로 메인 루프 실행 */
|
||||
/* Normal mode: run main loop at 10ms interval */
|
||||
#define MAIN_LOOP_INTERVAL 10
|
||||
#endif
|
||||
|
||||
/* ========================================================================== */
|
||||
/* 이벤트 플래그 (외부 모듈에서 설정, main_loop에서 처리) */
|
||||
/* Event flags (set by external modules, processed in main_loop) */
|
||||
/* ========================================================================== */
|
||||
bool go_batt= false; /* 배터리 측정 요청 플래그 */
|
||||
bool go_temp= false; /* 온도 측정 요청 플래그 */
|
||||
bool go_device_power_off = false; /* 디바이스 전원 OFF 요청 플래그 */
|
||||
bool go_sleep_mode_enter = false; /* 슬립 모드 진입 요청 플래그 */
|
||||
bool go_NVIC_SystemReset = false; /* 시스템 리셋 요청 플래그 */
|
||||
bool motion_raw_data_enabled = false; /* IMU 모션 데이터 읽기 활성화 플래그 */
|
||||
bool ble_got_new_data = false; /* BLE로 새 데이터 전송 완료 여부 */
|
||||
bool motion_data_once = false; /* IMU 단발성 읽기 모드 (true: 1회만 읽기) */
|
||||
bool go_batt= false; /* Battery measurement request flag */
|
||||
bool go_temp= false; /* Temperature measurement request flag */
|
||||
bool go_device_power_off = false; /* Device power OFF request flag */
|
||||
bool go_sleep_mode_enter = false; /* Sleep mode entry request flag */
|
||||
bool go_NVIC_SystemReset = false; /* System reset request flag */
|
||||
bool motion_raw_data_enabled = false; /* IMU motion data read enable flag */
|
||||
bool ble_got_new_data = false; /* BLE new data transmission complete */
|
||||
bool motion_data_once = false; /* IMU one-shot read mode (true: read once) */
|
||||
|
||||
/**
|
||||
* @brief 메인 이벤트 루프 (싱글샷 타이머 콜백)
|
||||
* @brief Main event loop (single-shot timer callback)
|
||||
*
|
||||
* 플래그 기반 이벤트 디스패처로, 설정된 플래그에 따라 해당 처리를 수행한다.
|
||||
* 싱글샷 타이머이므로 연속 실행이 필요한 경우 처리 내부에서 main_timer_start()를
|
||||
* 다시 호출하여 타이머를 재시작해야 한다.
|
||||
* Flag-based event dispatcher; processes actions based on set flags.
|
||||
* Since the timer is single-shot, call main_timer_start() again from
|
||||
* within the handler to continue execution.
|
||||
*
|
||||
* [처리 우선순위] (코드 순서대로 검사)
|
||||
* 1. IMU 모션 데이터 (motion_raw_data_enabled)
|
||||
* 2. 배터리 측정 (go_batt)
|
||||
* 3. 온도 측정 (go_temp)
|
||||
* 4. 전원 OFF (go_device_power_off)
|
||||
* 5. 슬립 모드 (go_sleep_mode_enter)
|
||||
* 6. 시스템 리셋 (go_NVIC_SystemReset)
|
||||
* [Processing priority] (checked in code order)
|
||||
* 1. IMU motion data (motion_raw_data_enabled)
|
||||
* 2. Battery measurement (go_batt)
|
||||
* 3. Temperature measurement (go_temp)
|
||||
* 4. Power OFF (go_device_power_off)
|
||||
* 5. Sleep mode (go_sleep_mode_enter)
|
||||
* 6. System reset (go_NVIC_SystemReset)
|
||||
*/
|
||||
void main_loop(void * p_context) /* For x ms */
|
||||
{
|
||||
@@ -140,36 +140,36 @@ void main_loop(void * p_context) /* For x ms */
|
||||
|
||||
// For Motion Data Sampling
|
||||
|
||||
/* ---- IMU 모션 데이터 읽기 ---- */
|
||||
/* ---- IMU motion data read ---- */
|
||||
/*
|
||||
* motion_raw_data_enabled가 true이면 IMU(ICM42670P) 데이터를 읽는다.
|
||||
* If motion_raw_data_enabled is true, read IMU (ICM42670P) data.
|
||||
*
|
||||
* motion_data_once == true:
|
||||
* 단발성 읽기 모드. HW I2C를 초기화한 후 icm42670_main()을 1회 호출.
|
||||
* info4 모드에서 배터리/온도 측정 후 다시 IMU로 돌아올 때 사용.
|
||||
* One-shot read mode. Initialize HW I2C then call icm42670_main() once.
|
||||
* Used in info4 mode to return to IMU after battery/temp measurement.
|
||||
*
|
||||
* motion_data_once == false:
|
||||
* 연속 읽기 모드. BLE 전송 대기 중(ble_got_new_data==false)이면
|
||||
* icm42670_main()을 호출하고 10ms 후 타이머를 재시작하여 반복 실행.
|
||||
* Continuous read mode. If not waiting for BLE TX (ble_got_new_data==false),
|
||||
* call icm42670_main() and restart timer after 10ms for repeated execution.
|
||||
*/
|
||||
if(motion_raw_data_enabled == true) {
|
||||
main_timer_stop(); /* 타이머 정지 (재진입 방지) */
|
||||
main_timer_stop(); /* Stop timer (prevent re-entry) */
|
||||
if(motion_data_once == true)
|
||||
{
|
||||
/* 단발성 모드: HW I2C 초기화 후 IMU 데이터 1회 읽기 */
|
||||
hw_i2c_init_once(); /* HW TWI 모드로 전환 (400kHz) */
|
||||
icm42670_main(); /* IMU 데이터 읽기 및 처리 */
|
||||
/* One-shot mode: init HW I2C then read IMU data once */
|
||||
hw_i2c_init_once(); /* Switch to HW TWI mode (400kHz) */
|
||||
icm42670_main(); /* Read and process IMU data */
|
||||
}
|
||||
else{
|
||||
/* 연속 모드: BLE 전송 대기 중이 아니면 반복 읽기 */
|
||||
/* Continuous mode: repeat read if not waiting for BLE TX */
|
||||
if(ble_got_new_data==false){
|
||||
//for(uint16_t i=0 ; i<60 ;i++)
|
||||
//{
|
||||
DBG_PRINTF("IMU \r\n");
|
||||
|
||||
icm42670_main(); /* IMU 데이터 읽기 */
|
||||
motion_raw_data_enabled = true; /* 플래그 유지 (연속 읽기) */
|
||||
main_timer_start_ms(1000); /* 1초 후 다음 IMU 읽기 */
|
||||
icm42670_main(); /* Read IMU data */
|
||||
motion_raw_data_enabled = true; /* Keep flag set (continuous read) */
|
||||
main_timer_start_ms(1000); /* Next IMU read after 1s */
|
||||
}
|
||||
// else if(ble_got_new_data==true){
|
||||
// motion_data_once = true;
|
||||
@@ -178,71 +178,71 @@ void main_loop(void * p_context) /* For x ms */
|
||||
}
|
||||
|
||||
|
||||
/* ---- 배터리 전압 측정 ---- */
|
||||
/* ---- Battery voltage measurement ---- */
|
||||
/*
|
||||
* go_batt 플래그가 true이면 배터리 레벨을 측정한다.
|
||||
* info4 모드에서 IMU 연속 읽기 이후 호출되는 단계.
|
||||
* 측정 완료 후 타이머가 정지된 상태로 유지된다.
|
||||
* If go_batt is true, measure battery level.
|
||||
* Called after IMU continuous read in info4 mode.
|
||||
* Timer remains stopped after measurement.
|
||||
*/
|
||||
if(go_batt == true) {
|
||||
DBG_PRINTF("IMU BATT\r\n");
|
||||
main_timer_stop(); /* 타이머 정지 */
|
||||
go_batt = false; /* 플래그 소비 (1회 실행) */
|
||||
main_timer_stop(); /* Stop timer */
|
||||
go_batt = false; /* Consume flag (one-shot) */
|
||||
// go_temp = true;
|
||||
battery_level_meas(); /* SAADC를 이용한 배터리 전압 측정 */
|
||||
battery_level_meas(); /* Measure battery voltage via SAADC */
|
||||
// nrf_delay_ms(20);
|
||||
// m48_adc_start_init();
|
||||
// main_timer_start();
|
||||
}
|
||||
|
||||
|
||||
/* ---- 온도 측정 ---- */
|
||||
/* ---- Temperature measurement ---- */
|
||||
/*
|
||||
* go_temp 플래그가 true이면 TMP235-Q1 센서로 온도를 측정한다.
|
||||
* info4 모드에서 배터리 측정 이후 호출되는 단계.
|
||||
* 측정 완료 후 motion_data_once=true로 설정하여
|
||||
* 다음 IMU 읽기는 단발성 모드(HW I2C 재초기화)로 전환된다.
|
||||
* If go_temp is true, measure temperature via TMP235-Q1 sensor.
|
||||
* Called after battery measurement in info4 mode.
|
||||
* After completion, sets motion_data_once=true so the next IMU read
|
||||
* uses one-shot mode (with HW I2C re-init).
|
||||
*/
|
||||
if(go_temp == true) {
|
||||
DBG_PRINTF("IMU Temp\r\n");
|
||||
main_timer_stop(); /* 타이머 정지 */
|
||||
main_timer_stop(); /* Stop timer */
|
||||
// go_batt = false;
|
||||
go_temp = false; /* 플래그 소비 (1회 실행) */
|
||||
motion_data_once = true; /* 다음 IMU 읽기를 단발성 모드로 전환 */
|
||||
tmp235_voltage_level_meas(); /* TMP235-Q1 온도 센서 전압 측정 */
|
||||
go_temp = false; /* Consume flag (one-shot) */
|
||||
motion_data_once = true; /* Switch next IMU read to one-shot mode */
|
||||
tmp235_voltage_level_meas(); /* Measure TMP235-Q1 temperature sensor voltage */
|
||||
// motion_raw_data_enabled = true;
|
||||
// main_timer_start();
|
||||
|
||||
}
|
||||
|
||||
/* ---- 시스템 제어 이벤트 처리 ---- */
|
||||
/* ---- System control event handling ---- */
|
||||
|
||||
/* 디바이스 전원 OFF 처리 */
|
||||
/* Device power OFF handling */
|
||||
if(go_device_power_off == true){
|
||||
main_timer_stop(); /* 타이머 정지 */
|
||||
main_timer_stop(); /* Stop timer */
|
||||
DBG_PRINTF("Off main_timer\r\n");
|
||||
device_power_off(); /* 디바이스 전원 OFF 실행 */
|
||||
device_power_off(); /* Execute device power OFF */
|
||||
}
|
||||
|
||||
/* 슬립 모드 진입 처리 */
|
||||
/* Sleep mode entry handling */
|
||||
if(go_sleep_mode_enter == true){
|
||||
main_timer_stop(); /* 타이머 정지 */
|
||||
main_timer_stop(); /* Stop timer */
|
||||
DBG_PRINTF("sleep main timer\r\n");
|
||||
sleep_mode_enter(); /* 슬립 모드 진입 실행 */
|
||||
sleep_mode_enter(); /* Execute sleep mode entry */
|
||||
}
|
||||
|
||||
/* NVIC 시스템 리셋 처리 */
|
||||
/* NVIC system reset handling */
|
||||
if(go_NVIC_SystemReset == true) {
|
||||
main_timer_stop(); /* 타이머 정지 */
|
||||
NVIC_SystemReset(); /* ARM Cortex-M4 시스템 리셋 */
|
||||
main_timer_stop(); /* Stop timer */
|
||||
NVIC_SystemReset(); /* ARM Cortex-M4 system reset */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 메인 루프 타이머 시작
|
||||
* @brief Start main loop timer
|
||||
*
|
||||
* 싱글샷 모드로 MAIN_LOOP_INTERVAL(10ms 또는 80ms) 후 main_loop()를 호출
|
||||
* Single-shot mode; calls main_loop() after MAIN_LOOP_INTERVAL (10ms or 80ms)
|
||||
*/
|
||||
void main_timer_start(void)
|
||||
{
|
||||
@@ -250,9 +250,9 @@ void main_timer_start(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 지정된 간격(ms)으로 메인 루프 타이머 시작
|
||||
* @brief Start main loop timer with specified interval (ms)
|
||||
*
|
||||
* IMU 연속 스트리밍 등 기본 간격과 다른 주기가 필요할 때 사용
|
||||
* Used when a different period than the default is needed (e.g. IMU streaming)
|
||||
*/
|
||||
void main_timer_start_ms(uint32_t interval_ms)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ void main_timer_start_ms(uint32_t interval_ms)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 메인 루프 타이머 정지
|
||||
* @brief Stop main loop timer
|
||||
*/
|
||||
void main_timer_stop(void)
|
||||
{
|
||||
@@ -268,10 +268,10 @@ void main_timer_stop(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 메인 루프 타이머 초기화 (앱 시작 시 1회 호출)
|
||||
* @brief Initialize main loop timer (call once at app startup)
|
||||
*
|
||||
* 싱글샷 모드 타이머를 생성하고, 콜백으로 main_loop()를 등록
|
||||
* 싱글샷이므로 매 호출마다 main_timer_start()로 수동 재시작해야 함
|
||||
* Creates a single-shot timer with main_loop() as callback.
|
||||
* Must manually restart via main_timer_start() after each firing.
|
||||
*/
|
||||
void main_timer_init(void)
|
||||
{
|
||||
|
||||
@@ -6,32 +6,32 @@
|
||||
* @brief
|
||||
*******************************************************************************
|
||||
*
|
||||
* [헤더 개요]
|
||||
* 메인 이벤트 루프 타이머의 공용 인터페이스 헤더.
|
||||
* [Header overview]
|
||||
* Public interface header for the main event loop timer.
|
||||
*
|
||||
* 10ms(일반) 또는 80ms(디테일) 간격의 싱글샷 타이머를 사용하여
|
||||
* main_loop() 콜백에서 센서 데이터 수집 및 시스템 제어를 수행한다.
|
||||
* Uses a single-shot timer at 10ms (normal) or 80ms (detail) interval.
|
||||
* The main_loop() callback handles sensor data collection and system control.
|
||||
*
|
||||
* [주요 함수]
|
||||
* main_timer_start() : 타이머 시작 (싱글샷, 수동 재시작 필요)
|
||||
* main_timer_stop() : 타이머 정지
|
||||
* main_timer_init() : 타이머 초기화 (앱 시작 시 1회 호출)
|
||||
* [Key functions]
|
||||
* main_timer_start() : Start timer (single-shot, manual restart required)
|
||||
* main_timer_stop() : Stop timer
|
||||
* main_timer_init() : Initialize timer (call once at app startup)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef TIMER_ROUTINE_H__
|
||||
#define TIMER_ROUTINE_H__
|
||||
|
||||
/** @brief 메인 루프 타이머 시작 (싱글샷, MAIN_LOOP_INTERVAL 후 main_loop 호출) */
|
||||
/** @brief Start main loop timer (single-shot, calls main_loop after MAIN_LOOP_INTERVAL) */
|
||||
void main_timer_start(void);
|
||||
|
||||
/** @brief 지정된 간격(ms)으로 메인 루프 타이머 시작 */
|
||||
/** @brief Start main loop timer with specified interval (ms) */
|
||||
void main_timer_start_ms(uint32_t interval_ms);
|
||||
|
||||
/** @brief 메인 루프 타이머 정지 */
|
||||
/** @brief Stop main loop timer */
|
||||
void main_timer_stop(void);
|
||||
|
||||
/** @brief 메인 루프 타이머 초기화 (앱 시작 시 1회, 싱글샷 모드로 생성) */
|
||||
/** @brief Initialize main loop timer (call once at startup, creates single-shot timer) */
|
||||
void main_timer_init(void);
|
||||
|
||||
#endif //TIMER_ROUTINE_H__
|
||||
|
||||
@@ -3,24 +3,24 @@
|
||||
//=========power_control.c====================
|
||||
*******************************************************************************
|
||||
*
|
||||
* [모듈 개요]
|
||||
* 디바이스 전원 시퀀스를 관리하는 모듈 (전원 켜기 / 끄기 / 슬립).
|
||||
* [Module overview]
|
||||
* Device power sequence manager (power on / off / sleep).
|
||||
*
|
||||
* [전원 켜기 흐름]
|
||||
* [Power-on flow]
|
||||
* device_activated()
|
||||
* → power_loop 타이머 시작 → 즉시 완료 (센서 초기화 불필요)
|
||||
* → 센서(IMU)는 측정 명령 시 imu_read_direct()가 자체 처리
|
||||
* -> Start power_loop timer -> completes immediately (no sensor init needed)
|
||||
* -> Sensor (IMU) is handled by imu_read_direct() at measurement time
|
||||
*
|
||||
* [슬립 모드]
|
||||
* [Sleep mode]
|
||||
* device_sleep_mode()
|
||||
* → processing 플래그 해제
|
||||
* -> Clear processing flag
|
||||
*
|
||||
* [재활성화]
|
||||
* [Reactivation]
|
||||
* device_reactivated()
|
||||
* → I2C 재초기화 후 전원 시퀀스를 처음부터 다시 시작
|
||||
* -> Re-init I2C then restart power sequence from the beginning
|
||||
*
|
||||
* [타이머]
|
||||
* 싱글샷 모드 app_timer, 20ms 간격으로 power_loop 호출
|
||||
* [Timer]
|
||||
* Single-shot app_timer, calls power_loop at 20ms interval
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdbool.h>
|
||||
@@ -38,53 +38,53 @@
|
||||
#include "i2c_manager.h"
|
||||
|
||||
|
||||
/* 전원 시퀀스용 싱글샷 타이머 인스턴스 */
|
||||
/* Single-shot timer instance for power sequence */
|
||||
APP_TIMER_DEF(m_power_timer_id);
|
||||
|
||||
/* 전원 시퀀스 상태머신의 타이머 간격 (20ms) */
|
||||
/* Power sequence state machine timer interval (20ms) */
|
||||
// 2025-12-08 change to #define POWER_LOOP_INTERVAL 30 -> 20
|
||||
#define POWER_LOOP_INTERVAL 20
|
||||
|
||||
/* 전원 시퀀스 현재 단계 (0: I2C 초기화, 1: 예약, 2: 완료) */
|
||||
/* Power sequence current step (0: I2C init, 1: reserved, 2: complete) */
|
||||
static uint8_t p_order;
|
||||
|
||||
/* 데이터 처리 중 플래그 (외부 모듈에서 선언) */
|
||||
/* Data processing flag (declared in external module) */
|
||||
extern volatile bool processing;
|
||||
|
||||
/* 전원 시퀀스 잠금 플래그 (true = 전원 시퀀스 진행 중) */
|
||||
/* Power sequence lock flag (true = sequence in progress) */
|
||||
bool lock_check = false;
|
||||
|
||||
/**
|
||||
* @brief 디바이스 슬립 모드 진입
|
||||
* @brief Enter device sleep mode
|
||||
*
|
||||
* 데이터 처리 플래그(processing)를 해제하여
|
||||
* 메인 루프가 더 이상 센서 데이터를 처리하지 않도록 한다.
|
||||
* Clears the processing flag so the main loop stops
|
||||
* processing sensor data.
|
||||
*
|
||||
* @return 0 (항상 성공)
|
||||
* @return 0 (always succeeds)
|
||||
*/
|
||||
int device_sleep_mode(void){
|
||||
int rc = 0;
|
||||
nrf_delay_ms(2);
|
||||
DBG_PRINTF("Device_Sleep_Mode OK!\r\n");
|
||||
nrf_delay_ms(10);
|
||||
processing = false; /* 데이터 처리 플래그 해제 → 센서 처리 중단 */
|
||||
processing = false; /* Clear processing flag -> stop sensor handling */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 디바이스 전원 켜기 (전원 시퀀스 시작)
|
||||
* @brief Power on device (start power sequence)
|
||||
*
|
||||
* 전원 시퀀스 단계를 0으로 초기화하고, 잠금 플래그를 설정한 뒤
|
||||
* 타이머를 시작하여 power_loop() 상태머신을 구동한다.
|
||||
* Resets the sequence step to 0, sets the lock flag, and starts
|
||||
* the timer to drive the power_loop() state machine.
|
||||
*
|
||||
* @return 0 (항상 성공)
|
||||
* @return 0 (always succeeds)
|
||||
*/
|
||||
int device_activated(void){
|
||||
int rc = 0;
|
||||
p_order = 0; /* 상태머신 시작 단계 (Step 0: I2C 초기화) */
|
||||
lock_check =true; /* 전원 시퀀스 진행 중 잠금 */
|
||||
power_timer_start(); /* 20ms 후 power_loop() 첫 호출 */
|
||||
p_order = 0; /* State machine start step (Step 0: I2C init) */
|
||||
lock_check =true; /* Lock: power sequence in progress */
|
||||
power_timer_start(); /* First power_loop() call after 20ms */
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -101,60 +101,60 @@ int device_activated(void){
|
||||
* 2: Complete
|
||||
*/
|
||||
/*
|
||||
* 전원 시퀀스 상태머신 (20ms 싱글샷 타이머 콜백).
|
||||
* Power sequence state machine (20ms single-shot timer callback).
|
||||
*
|
||||
* [실행 흐름]
|
||||
* 1) 타이머 콜백 진입 → 타이머 정지 (싱글샷이므로)
|
||||
* 2) 현재 p_order에 해당하는 초기화 단계 실행
|
||||
* 3) p_order < 2이면 다음 단계로 진행하고 타이머 재시작
|
||||
* 4) p_order == 2이면 전원 시퀀스 완료
|
||||
* [Execution flow]
|
||||
* 1) Timer callback entry -> stop timer (single-shot)
|
||||
* 2) Execute init step for current p_order
|
||||
* 3) If p_order < 2, advance to next step and restart timer
|
||||
* 4) If p_order == 2, power sequence complete
|
||||
*
|
||||
* 센서 초기화 불필요 — imu_read_direct()가 매 측정 시 자체 처리
|
||||
* No sensor init needed -- imu_read_direct() handles it per measurement.
|
||||
*/
|
||||
void power_loop(void *p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_context);
|
||||
|
||||
power_timer_stop(); /* 현재 타이머 정지 (싱글샷 → 수동 재시작 필요) */
|
||||
power_timer_stop(); /* Stop current timer (single-shot, manual restart needed) */
|
||||
|
||||
/* 센서 초기화 불필요 — imu_read_direct()가 매 측정 시 자체 처리 */
|
||||
/* 추후 전원 시퀀스 단계가 필요하면 여기에 switch(p_order) 추가 */
|
||||
/* No sensor init needed -- imu_read_direct() handles it per measurement */
|
||||
/* Add switch(p_order) here if future power sequence steps are needed */
|
||||
p_order = 2;
|
||||
|
||||
/* Advance to next step or finish */
|
||||
/* 다음 단계로 진행하거나, 시퀀스 완료 처리 */
|
||||
/* Advance to next step or finish sequence */
|
||||
if (p_order < 2) {
|
||||
p_order++; /* 다음 단계로 이동 */
|
||||
power_timer_start(); /* 20ms 후 다음 단계 실행 */
|
||||
p_order++; /* Move to next step */
|
||||
power_timer_start(); /* Execute next step after 20ms */
|
||||
} else {
|
||||
/* 전원 시퀀스 전체 완료 */
|
||||
/* Power sequence fully complete */
|
||||
DBG_PRINTF("[PWR] Device Activated OK!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 디바이스 재활성화 (슬립 복귀 시)
|
||||
* @brief Reactivate device (on wake from sleep)
|
||||
*
|
||||
* I2C를 재초기화하고, 전원 시퀀스를 처음부터 다시 시작한다.
|
||||
* 슬립 모드에서 깨어날 때 호출된다.
|
||||
* Re-initializes I2C and restarts the power sequence from the beginning.
|
||||
* Called when waking from sleep mode.
|
||||
*
|
||||
* @return 0 (항상 성공)
|
||||
* @return 0 (always succeeds)
|
||||
*/
|
||||
int device_reactivated(void){
|
||||
int rc = 0;
|
||||
sw_i2c_init_once(); /* I2C 버스 재초기화 */
|
||||
nrf_delay_ms(10); /* 안정화 대기 */
|
||||
lock_check = true; /* 전원 시퀀스 진행 중 잠금 */
|
||||
p_order = 0; /* 상태머신을 Step 0부터 재시작 */
|
||||
power_timer_start(); /* 20ms 후 power_loop() 시작 */
|
||||
sw_i2c_init_once(); /* Re-initialize I2C bus */
|
||||
nrf_delay_ms(10); /* Stabilization delay */
|
||||
lock_check = true; /* Lock: power sequence in progress */
|
||||
p_order = 0; /* Restart state machine from Step 0 */
|
||||
power_timer_start(); /* Start power_loop() after 20ms */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 전원 시퀀스 타이머 시작
|
||||
* @brief Start power sequence timer
|
||||
*
|
||||
* 싱글샷 모드로 POWER_LOOP_INTERVAL(20ms) 후 power_loop()를 호출한다.
|
||||
* Single-shot mode; calls power_loop() after POWER_LOOP_INTERVAL (20ms).
|
||||
*/
|
||||
void power_timer_start(void)
|
||||
{
|
||||
@@ -163,7 +163,7 @@ void power_timer_start(void)
|
||||
|
||||
|
||||
/**
|
||||
* @brief 전원 시퀀스 타이머 정지
|
||||
* @brief Stop power sequence timer
|
||||
*/
|
||||
void power_timer_stop(void)
|
||||
{
|
||||
@@ -173,10 +173,10 @@ void power_timer_stop(void)
|
||||
|
||||
|
||||
/**
|
||||
* @brief 전원 시퀀스 타이머 초기화 (앱 시작 시 1회 호출)
|
||||
* @brief Initialize power sequence timer (call once at app startup)
|
||||
*
|
||||
* 싱글샷 모드 타이머를 생성하고, 콜백으로 power_loop()를 등록한다.
|
||||
* 싱글샷이므로 매 단계마다 power_timer_start()로 수동 재시작해야 한다.
|
||||
* Creates a single-shot timer with power_loop() as callback.
|
||||
* Must manually restart via power_timer_start() after each step.
|
||||
*/
|
||||
void power_timer_init(void) //active start
|
||||
{
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
* @brief
|
||||
*******************************************************************************
|
||||
*
|
||||
* [헤더 개요]
|
||||
* 디바이스 전원 시퀀스 관리 모듈의 공용 인터페이스 헤더.
|
||||
* [Header overview]
|
||||
* Public interface header for the device power sequence manager.
|
||||
*
|
||||
* [주요 함수 요약]
|
||||
* device_activated() : 전원 켜기 → power_loop 상태머신 시작
|
||||
* device_sleep_mode() : 슬립 모드 진입 (처리 중단)
|
||||
* device_reactivated() : 슬립 복귀 → 전원 시퀀스 재시작
|
||||
* power_loop() : 20ms 간격 전원 시퀀스 상태머신 콜백
|
||||
* power_timer_start/stop : 전원 시퀀스 타이머 제어
|
||||
* power_timer_init() : 전원 시퀀스 타이머 초기화 (앱 시작 시 1회)
|
||||
* [Key functions]
|
||||
* device_activated() : Power on -> start power_loop state machine
|
||||
* device_sleep_mode() : Enter sleep mode (stop processing)
|
||||
* device_reactivated() : Wake from sleep -> restart power sequence
|
||||
* power_loop() : 20ms power sequence state machine callback
|
||||
* power_timer_start/stop : Power sequence timer control
|
||||
* power_timer_init() : Initialize power sequence timer (call once at startup)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@@ -24,25 +24,25 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/** @brief 디바이스 슬립 모드 진입 (processing 해제) */
|
||||
/** @brief Enter device sleep mode (clears processing flag) */
|
||||
int device_sleep_mode(void);
|
||||
|
||||
/** @brief 디바이스 전원 켜기 (전원 시퀀스 상태머신 시작) */
|
||||
/** @brief Power on device (start power sequence state machine) */
|
||||
int device_activated(void);
|
||||
|
||||
/** @brief 디바이스 재활성화 (슬립 복귀 시 I2C 재초기화 후 시퀀스 재시작) */
|
||||
/** @brief Reactivate device (re-init I2C and restart sequence on wake from sleep) */
|
||||
int device_reactivated(void);
|
||||
|
||||
/** @brief 전원 시퀀스 상태머신 (20ms 타이머 콜백, Step 0→1→2) */
|
||||
/** @brief Power sequence state machine (20ms timer callback, Step 0->1->2) */
|
||||
void power_loop(void * p_context); /* For x ms */
|
||||
|
||||
/** @brief 전원 시퀀스 타이머 시작 (20ms 싱글샷) */
|
||||
/** @brief Start power sequence timer (20ms single-shot) */
|
||||
void power_timer_start(void);
|
||||
|
||||
/** @brief 전원 시퀀스 타이머 정지 */
|
||||
/** @brief Stop power sequence timer */
|
||||
void power_timer_stop(void);;
|
||||
|
||||
/** @brief 전원 시퀀스 타이머 초기화 (앱 시작 시 1회 호출) */
|
||||
/** @brief Initialize power sequence timer (call once at app startup) */
|
||||
void power_timer_init(void);
|
||||
#endif //_POWER_CONTROL_H_
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ void ble_security_quick_pm_handler(pm_evt_t const *p_evt)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
|
||||
// DEV 모드: 보안 실패 이벤트는 SDK 핸들러에 전달하지 않음 (disconnect 방지)
|
||||
// DEV mode: do not forward security failure events to SDK handler (prevent disconnect)
|
||||
if (m_state.dev_mode && p_evt->evt_id == PM_EVT_CONN_SEC_FAILED) {
|
||||
DBG_PRINTF("Security failed: error=%d\r\n",
|
||||
p_evt->params.conn_sec_failed.error);
|
||||
@@ -133,13 +133,13 @@ void ble_security_quick_pm_handler(pm_evt_t const *p_evt)
|
||||
p_evt->params.conn_sec_failed.error);
|
||||
|
||||
if (m_state.dev_mode) {
|
||||
// DEV 모드: 보안 실패 무시 — 연결 유지
|
||||
// DEV mode: ignore security failure, keep connection
|
||||
DBG_PRINTF("DEV: Ignoring sec failure, keeping connection\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_evt->params.conn_sec_failed.error == PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING) {
|
||||
// Key missing: 재페어링 시도, 실패 시 disconnect로 폴백
|
||||
// Key missing: attempt re-pairing, fall back to disconnect on failure
|
||||
err_code = pm_conn_secure(p_evt->conn_handle, true);
|
||||
if (err_code != NRF_ERROR_INVALID_STATE &&
|
||||
err_code != NRF_ERROR_BUSY &&
|
||||
@@ -147,11 +147,11 @@ void ble_security_quick_pm_handler(pm_evt_t const *p_evt)
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
if (err_code != NRF_SUCCESS) {
|
||||
// 재페어링 불가 → disconnect
|
||||
// Re-pairing not possible -> disconnect
|
||||
pm_handler_disconnect_on_sec_failure(p_evt);
|
||||
}
|
||||
} else {
|
||||
// 기타 보안 실패 → bond 삭제 후 재페어링 시도
|
||||
// Other security failure -> delete bond then attempt re-pairing
|
||||
pm_peer_id_t peer_id;
|
||||
if (pm_peer_id_get(p_evt->conn_handle, &peer_id) == NRF_SUCCESS
|
||||
&& peer_id != PM_PEER_ID_INVALID) {
|
||||
|
||||
Reference in New Issue
Block a user