190 lines
5.8 KiB
C
190 lines
5.8 KiB
C
/*******************************************************************************
|
|
TEST medi50 Dec 23
|
|
//=========power_control.c====================
|
|
*******************************************************************************
|
|
*
|
|
* [모듈 개요]
|
|
* 디바이스 전원 시퀀스를 관리하는 모듈 (전원 켜기 / 끄기 / 슬립).
|
|
*
|
|
* [전원 켜기 흐름]
|
|
* device_activated()
|
|
* → power_loop 타이머 시작 → 즉시 완료 (센서 초기화 불필요)
|
|
* → 센서(IMU)는 측정 명령 시 imu_read_direct()가 자체 처리
|
|
*
|
|
* [슬립 모드]
|
|
* device_sleep_mode()
|
|
* → processing 플래그 해제
|
|
*
|
|
* [재활성화]
|
|
* device_reactivated()
|
|
* → I2C 재초기화 후 전원 시퀀스를 처음부터 다시 시작
|
|
*
|
|
* [타이머]
|
|
* 싱글샷 모드 app_timer, 20ms 간격으로 power_loop 호출
|
|
*
|
|
******************************************************************************/
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "main.h"
|
|
#include "power_control.h"
|
|
#include "nrf_delay.h"
|
|
|
|
|
|
#include "nrf_log.h"
|
|
#include "app_timer.h"
|
|
#include "debug_print.h"
|
|
#include "i2c_manager.h"
|
|
|
|
|
|
/* 전원 시퀀스용 싱글샷 타이머 인스턴스 */
|
|
APP_TIMER_DEF(m_power_timer_id);
|
|
|
|
/* 전원 시퀀스 상태머신의 타이머 간격 (20ms) */
|
|
// 2025-12-08 change to #define POWER_LOOP_INTERVAL 30 -> 20
|
|
#define POWER_LOOP_INTERVAL 20
|
|
|
|
/* 전원 시퀀스 현재 단계 (0: I2C 초기화, 1: 예약, 2: 완료) */
|
|
static uint8_t p_order;
|
|
|
|
/* 데이터 처리 중 플래그 (외부 모듈에서 선언) */
|
|
extern volatile bool processing;
|
|
|
|
/* 전원 시퀀스 잠금 플래그 (true = 전원 시퀀스 진행 중) */
|
|
bool lock_check = false;
|
|
|
|
/**
|
|
* @brief 디바이스 슬립 모드 진입
|
|
*
|
|
* 데이터 처리 플래그(processing)를 해제하여
|
|
* 메인 루프가 더 이상 센서 데이터를 처리하지 않도록 한다.
|
|
*
|
|
* @return 0 (항상 성공)
|
|
*/
|
|
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; /* 데이터 처리 플래그 해제 → 센서 처리 중단 */
|
|
return rc;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 디바이스 전원 켜기 (전원 시퀀스 시작)
|
|
*
|
|
* 전원 시퀀스 단계를 0으로 초기화하고, 잠금 플래그를 설정한 뒤
|
|
* 타이머를 시작하여 power_loop() 상태머신을 구동한다.
|
|
*
|
|
* @return 0 (항상 성공)
|
|
*/
|
|
int device_activated(void){
|
|
int rc = 0;
|
|
p_order = 0; /* 상태머신 시작 단계 (Step 0: I2C 초기화) */
|
|
lock_check =true; /* 전원 시퀀스 진행 중 잠금 */
|
|
power_timer_start(); /* 20ms 후 power_loop() 첫 호출 */
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* @brief Power-up sequence state machine
|
|
*
|
|
* Executes hardware initialization steps
|
|
* Called by app_timer at POWER_LOOP_INTERVAL (20ms)
|
|
*
|
|
* Sequence:
|
|
* 0: I2C init
|
|
* 1: (reserved)
|
|
* 2: Complete
|
|
*/
|
|
/*
|
|
* 전원 시퀀스 상태머신 (20ms 싱글샷 타이머 콜백).
|
|
*
|
|
* [실행 흐름]
|
|
* 1) 타이머 콜백 진입 → 타이머 정지 (싱글샷이므로)
|
|
* 2) 현재 p_order에 해당하는 초기화 단계 실행
|
|
* 3) p_order < 2이면 다음 단계로 진행하고 타이머 재시작
|
|
* 4) p_order == 2이면 전원 시퀀스 완료
|
|
*
|
|
* 센서 초기화 불필요 — imu_read_direct()가 매 측정 시 자체 처리
|
|
*/
|
|
void power_loop(void *p_context)
|
|
{
|
|
UNUSED_PARAMETER(p_context);
|
|
|
|
power_timer_stop(); /* 현재 타이머 정지 (싱글샷 → 수동 재시작 필요) */
|
|
|
|
/* 센서 초기화 불필요 — imu_read_direct()가 매 측정 시 자체 처리 */
|
|
/* 추후 전원 시퀀스 단계가 필요하면 여기에 switch(p_order) 추가 */
|
|
p_order = 2;
|
|
|
|
/* Advance to next step or finish */
|
|
/* 다음 단계로 진행하거나, 시퀀스 완료 처리 */
|
|
if (p_order < 2) {
|
|
p_order++; /* 다음 단계로 이동 */
|
|
power_timer_start(); /* 20ms 후 다음 단계 실행 */
|
|
} else {
|
|
/* 전원 시퀀스 전체 완료 */
|
|
DBG_PRINTF("[PWR] Device Activated OK!\r\n");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 디바이스 재활성화 (슬립 복귀 시)
|
|
*
|
|
* I2C를 재초기화하고, 전원 시퀀스를 처음부터 다시 시작한다.
|
|
* 슬립 모드에서 깨어날 때 호출된다.
|
|
*
|
|
* @return 0 (항상 성공)
|
|
*/
|
|
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() 시작 */
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* @brief 전원 시퀀스 타이머 시작
|
|
*
|
|
* 싱글샷 모드로 POWER_LOOP_INTERVAL(20ms) 후 power_loop()를 호출한다.
|
|
*/
|
|
void power_timer_start(void)
|
|
{
|
|
APP_ERROR_CHECK(app_timer_start(m_power_timer_id, APP_TIMER_TICKS(POWER_LOOP_INTERVAL), NULL));
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 전원 시퀀스 타이머 정지
|
|
*/
|
|
void power_timer_stop(void)
|
|
{
|
|
APP_ERROR_CHECK(app_timer_stop(m_power_timer_id));
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 전원 시퀀스 타이머 초기화 (앱 시작 시 1회 호출)
|
|
*
|
|
* 싱글샷 모드 타이머를 생성하고, 콜백으로 power_loop()를 등록한다.
|
|
* 싱글샷이므로 매 단계마다 power_timer_start()로 수동 재시작해야 한다.
|
|
*/
|
|
void power_timer_init(void) //active start
|
|
{
|
|
APP_ERROR_CHECK(app_timer_create(&m_power_timer_id, APP_TIMER_MODE_SINGLE_SHOT, power_loop));
|
|
|
|
// 2025-12-08 change to APP_TIMER_MODE_REPEATED mode
|
|
//APP_ERROR_CHECK(app_timer_create(&m_power_timer_id, APP_TIMER_MODE_REPEATED, power_loop));
|
|
|
|
|
|
}
|