first commit
This commit is contained in:
647
Source/Oper.c
Normal file
647
Source/Oper.c
Normal file
@@ -0,0 +1,647 @@
|
||||
/* ========================================================================= */
|
||||
/* 1. Includes */
|
||||
/* ========================================================================= */
|
||||
#include "main.h"
|
||||
|
||||
/* ========================================================================= */
|
||||
/* 2. Local Macros & Constants (내부 전용 매크로 및 상수) */
|
||||
/* ========================================================================= */
|
||||
#define ENGINE_MAXIMUM_SPEED (2800U)
|
||||
#define ENGINE_OPERATION_SPEED (2400U)
|
||||
#define ENGINE_DIFF_SPEED (400U) // 2800 - 2400
|
||||
|
||||
// IDLE_SEQ_MOD
|
||||
#define RPM_RAMP_START (1500U)
|
||||
#define RPM_RAMP_END (2400U)
|
||||
#define RPM_RAMP_RANGE (RPM_RAMP_END - RPM_RAMP_START) // 900
|
||||
#define TIME_RAMP_UP (TIME_1SEC * 3UL) // 3초
|
||||
|
||||
#define LED_OFF (0U)
|
||||
#define LED_ON (1U)
|
||||
#define LED_BLINK (2U)
|
||||
|
||||
/* ========================================================================= */
|
||||
/* 3. Local Typedefs & Structures (내부 전용 사용자 정의 자료형) */
|
||||
/* ========================================================================= */
|
||||
// No Code
|
||||
|
||||
/* ========================================================================= */
|
||||
/* 4. Internal Linkage Function Declarations (내부 동작용 Static 함수 선언) */
|
||||
/* ========================================================================= */
|
||||
static void CInitialStandby(void);
|
||||
static void CEmergencyStop(void);
|
||||
static void CProcessApuStateReady(void);
|
||||
static void CProcessApuStatePreheat(void);
|
||||
static void CProcessApuStateCranking(void);
|
||||
static void CProcessApuStateRetryCranking(void);
|
||||
static void CProcessApuStateEngineIdle(void);
|
||||
static void CProcessApuStateGenerating(void);
|
||||
static void CProcessApuStateCooldown(void);
|
||||
static void CProcessApuStateStopping(void);
|
||||
static void CProcessApuStateTransition(void); // 비상/시동/정지 전이 판별용
|
||||
static void CSetEngineActualRpm(Uint16 Rpm);
|
||||
static float32 CGetGcuLoadPower(void);
|
||||
static Uint16 CDynamicRpmControl(void);
|
||||
static void CLedControl(Uint16 idx, Uint16 state);
|
||||
|
||||
/* ========================================================================= */
|
||||
/* 5. Global Variables & Structure Initialization (전역 변수 및 구조체 초기화) */
|
||||
/* ========================================================================= */
|
||||
// No Code
|
||||
|
||||
/* ========================================================================= */
|
||||
/* Function Definitions */
|
||||
/* ========================================================================= */
|
||||
static void CProcessApuStateReady(void)
|
||||
{
|
||||
// 냉각수 펌프 및 냉각팬 시작
|
||||
CSetAuxCtrlPin(IDX_CS_COOLANT_PUMP, 1U);
|
||||
CSetAuxCtrlPin(IDX_CS_FAN1, 1U);
|
||||
CSetAuxCtrlPin(IDX_CS_FAN2, 1U);
|
||||
|
||||
// ECU 동작 명령 송신, 2400 RPM 설정
|
||||
CSetEcuCommand((Uint16)IDX_ECU_CMD_START);
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_PREHEAT;
|
||||
}
|
||||
|
||||
static void CProcessApuStatePreheat(void)
|
||||
{
|
||||
if (((Rx301.State >> 1U) & 0x07U) == (Uint16)IDX_ECU_STAT_STARTING)
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_CRANKING;
|
||||
}
|
||||
else
|
||||
{
|
||||
// PRE HEAT 상태가 60초 이상 지속 될 경우 알람처리
|
||||
if (CSoftWaitCountProcedure(SOFTTIMER_WAIT_PREHEAT, TIME_60SEC) == (Uint16)TIME_OVER)
|
||||
{
|
||||
// 알람처리를 할지 무기한 대기 할 지 검토 필요
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CProcessApuStateCranking(void)
|
||||
{
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_CRANKING);
|
||||
|
||||
if (((Rx301.State >> 1U) & 0x07U) == (Uint16)IDX_ECU_STAT_IDLE)
|
||||
{
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP_CRANKING);
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_ENGINE_IDLE;
|
||||
GeneralOperValue.uiRetryCrankingCount = 0U;
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_CRANKING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 10초간 시동 시도 → 5초 동안 휴식 → 3회 반복
|
||||
if (CSoftWaitCountProcedure(SOFTTIMER_WAIT_CRANKING, TIME_10SEC) == (Uint16)TIME_OVER)
|
||||
{
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP_CRANKING);
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_RETRY_CRANKING;
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_RETRY_CRANKING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CProcessApuStateRetryCranking(void)
|
||||
{
|
||||
if (GeneralOperValue.uiRetryCrankingCount < 3U)
|
||||
{
|
||||
// 5초 대기 후 재시도
|
||||
if (CSoftWaitCountProcedure(SOFTTIMER_WAIT_RETRY_CRANKING, (TIME_1SEC * 5UL)) == (Uint16)TIME_OVER)
|
||||
{
|
||||
GeneralOperValue.uiRetryCrankingCount++;
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_CRANKING;
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_CRANKING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ulDcuTotalAlarm = (1UL << (Uint32)(Uint16)IDX_FAULT_DCU_CRANKING_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
static void CProcessApuStateEngineIdle(void)
|
||||
{
|
||||
#if 0 // '0' - 기존 코드, '1' - IDLE_SEQ_MOD
|
||||
if (((Rx301.State >> 1U) & 0x07U) == (Uint16)IDX_ECU_STAT_OPERATION)
|
||||
{
|
||||
// 보조엔진제어기의 상태가 OPERATION이고 보조엔진의 속도가 2300 RPM 이상 5초 유지 시 발전상태로 전환
|
||||
if (CGetEngineActualRpm() >= (ENGINE_OPERATION_SPEED - 100U)) // 2300 RPM
|
||||
{
|
||||
if (CSoftWaitCountProcedure(SOFTTIMER_WAIT_OPERATION, TIME_5SEC) == (Uint16)TIME_OVER)
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_GENERATING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_OPERATION);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (((Rx301.State >> 1U) & 0x07U) == (Uint16)IDX_ECU_STAT_OPERATION)
|
||||
{
|
||||
// ECU OPERATION 확인 즉시 발전 상태로 전환 (RPM Ramp는 CProcessApuStateGenerating에서 수행)
|
||||
GeneralOperValue.ulRampStartClock = 0UL;
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_GENERATING;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CProcessApuStateGenerating(void)
|
||||
{
|
||||
#if 0 // '0' - 기존 코드, '1' - IDLE_SEQ_MOD
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_GENERATING); // 발전 명령 송신
|
||||
GeneralOperValue.uiDynamicRPM = CDynamicRpmControl();
|
||||
CSetEngineActualRpm(GeneralOperValue.uiDynamicRPM); // RPM 가변 제어 시작
|
||||
#else
|
||||
Uint32 ulElapsed;
|
||||
Uint16 uiRampRpm;
|
||||
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_GENERATING);
|
||||
|
||||
if (GeneralOperValue.uiRampComplete == 1U)
|
||||
{
|
||||
GeneralOperValue.uiDynamicRPM = CDynamicRpmControl();
|
||||
CSetEngineActualRpm(GeneralOperValue.uiDynamicRPM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GeneralOperValue.ulRampStartClock == 0UL)
|
||||
{
|
||||
GeneralOperValue.ulRampStartClock = CGetSoftClock();
|
||||
CSetEngineActualRpm(RPM_RAMP_START);
|
||||
}
|
||||
else
|
||||
{
|
||||
ulElapsed = (CGetSoftClock() + SYSTEM_10MIN_TIME - GeneralOperValue.ulRampStartClock) % SYSTEM_10MIN_TIME;
|
||||
|
||||
if (ulElapsed < TIME_RAMP_UP)
|
||||
{
|
||||
uiRampRpm = (Uint16)(RPM_RAMP_START + (Uint16)(((Uint32)RPM_RAMP_RANGE * ulElapsed) / TIME_RAMP_UP));
|
||||
CSetEngineActualRpm(uiRampRpm);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeneralOperValue.uiRampComplete = 1U;
|
||||
GeneralOperValue.uiDynamicRPM = CDynamicRpmControl();
|
||||
CSetEngineActualRpm(GeneralOperValue.uiDynamicRPM);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CProcessApuStateCooldown(void)
|
||||
{
|
||||
Uint16 IsRpmZero;
|
||||
Uint16 IsTimeout;
|
||||
|
||||
// 쿨다운: 발전 중지 -> 엔진 IDLE로 변경
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP);
|
||||
CSetEcuCommand((Uint16)IDX_ECU_CMD_STOP);
|
||||
|
||||
IsRpmZero = (CGetEngineActualRpm() == 0U) ? 1U : 0U;
|
||||
IsTimeout = (CSoftWaitCountProcedure(SOFTTIMER_WAIT_AFTER_COOLDOWN, TIME_60SEC) == 1U) ? 1U : 0U;
|
||||
|
||||
if ((IsRpmZero == 1U) || (IsTimeout == 1U))
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_STOPPING;
|
||||
}
|
||||
}
|
||||
|
||||
static void CProcessApuStateStopping(void)
|
||||
{
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_STOPPING)
|
||||
{
|
||||
CInitialStandby();
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_STANDBY;
|
||||
}
|
||||
}
|
||||
|
||||
static void CProcessApuStateTransition(void)
|
||||
{
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_EMERGENCY)
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_STANDBY;
|
||||
CInitialStandby();
|
||||
}
|
||||
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_STANDBY)
|
||||
{
|
||||
if (KeyOperValue.KeyList.EngineStartStop == 1U)
|
||||
{
|
||||
GeneralOperValue.uiRetryCrankingCount = 0U;
|
||||
if ((GeneralOperValue.Conection.Gcu == 1U) && (GeneralOperValue.Conection.Ecu == 1U))
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
CommCheck.Gcu = (GeneralOperValue.Conection.Gcu == 0U) ? COMM_TIME_OUT_COUNT : 0U;
|
||||
CommCheck.Ecu = (GeneralOperValue.Conection.Ecu == 0U) ? COMM_TIME_OUT_COUNT : 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((GeneralOperValue.uiApuState >= (Uint16)IDX_APU_OPER_READY) && (GeneralOperValue.uiApuState <= (Uint16)IDX_APU_OPER_GENERATING))
|
||||
{
|
||||
if (KeyOperValue.KeyList.EngineStartStop == 0U)
|
||||
{
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_GENERATING)
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_COOLDOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_STOPPING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CApuOperProcedure(void)
|
||||
{
|
||||
// 입력 신호 Lo Active
|
||||
Uint16 EngineHeaterSig = (GPIO_ENGINE_HEATER_ACTIVE() == false) ? 1U : 0U;
|
||||
Uint16 FuelPumpSig = (GPIO_FUEL_PUMP_ACTIVE() == false) ? 1U : 0U;
|
||||
Uint16 GlowPlugSig = (GPIO_GLOW_PLUG_ACTIVE() == false) ? 1U : 0U;
|
||||
Uint16 SolenoidSig = (GPIO_SOLENOID_ACTIVE() == false) ? 1U : 0U;
|
||||
Uint16 FailSafeSig = (GPIO_FAIL_SAFE_READ() == false) ? 1U : 0U;
|
||||
|
||||
// 비상 상황 체크
|
||||
if ((GeneralOperValue.uiFaultOccured > 0U) || (KeyOperValue.KeyList.Emergency == 1U) || (FailSafeSig == 1U))
|
||||
{
|
||||
GeneralOperValue.uiApuState = (Uint16)IDX_APU_OPER_EMERGENCY;
|
||||
CEmergencyStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 외부 조작에 의한 상태 변경 확인
|
||||
CProcessApuStateTransition();
|
||||
|
||||
// ECU Aux Bypass 제어
|
||||
if (GeneralOperValue.uiApuState > (Uint16)IDX_APU_OPER_STANDBY)
|
||||
{
|
||||
CSetAuxCtrlPin(IDX_CS_ENG_HEATER, EngineHeaterSig);
|
||||
CSetAuxCtrlPin(IDX_CS_GLOW_PLUG, GlowPlugSig);
|
||||
CSetAuxCtrlPin(IDX_CS_SOLENOID, SolenoidSig);
|
||||
CSetAuxCtrlPin(IDX_CS_FUEL_PUMP, FuelPumpSig);
|
||||
}
|
||||
|
||||
// 각 상태별 동작 수행
|
||||
switch (GeneralOperValue.uiApuState)
|
||||
{
|
||||
case (Uint16)IDX_APU_OPER_READY:
|
||||
{
|
||||
CProcessApuStateReady();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_PREHEAT:
|
||||
{
|
||||
CProcessApuStatePreheat();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_CRANKING:
|
||||
{
|
||||
CProcessApuStateCranking();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_RETRY_CRANKING:
|
||||
{
|
||||
CProcessApuStateRetryCranking();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_ENGINE_IDLE:
|
||||
{
|
||||
CProcessApuStateEngineIdle();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_GENERATING:
|
||||
{
|
||||
CProcessApuStateGenerating();
|
||||
break;
|
||||
}
|
||||
case (Uint16)IDX_APU_OPER_COOLDOWN:
|
||||
{
|
||||
CProcessApuStateCooldown();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CProcessApuStateStopping();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Uint16 CDynamicRpmControl(void)
|
||||
{
|
||||
float32 TargetRPM;
|
||||
Uint16 ReturnRpm;
|
||||
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_GENERATING)
|
||||
{
|
||||
// 0.0kW~17.0kW 부하량에 따라 목표 RPM 실시간 계산
|
||||
TargetRPM = (float32)ENGINE_OPERATION_SPEED + ((CGetGcuLoadPower() * 0.058823F) * (float32)ENGINE_DIFF_SPEED); // 0.058823 = 1/17kw
|
||||
|
||||
ReturnRpm = (Uint16)((float32)(TargetRPM + 0.5F)); // 소수점 반올림
|
||||
}
|
||||
else
|
||||
{
|
||||
// 발전 상태가 아닐 때는 기본 2400 RPM 반환
|
||||
ReturnRpm = ENGINE_OPERATION_SPEED;
|
||||
}
|
||||
|
||||
ReturnRpm = (ENGINE_MAXIMUM_SPEED > ReturnRpm) ? ReturnRpm : ENGINE_MAXIMUM_SPEED;
|
||||
|
||||
return ReturnRpm;
|
||||
}
|
||||
|
||||
static void CInitialStandby(void)
|
||||
{
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP);
|
||||
|
||||
CSetEcuCommand((Uint16)IDX_ECU_CMD_STOP);
|
||||
|
||||
COffChipSelect();
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_CRANKING);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_RETRY_CRANKING);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_PREHEAT);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_PREHEAT);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_OPERATION);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_AFTER_COOLDOWN);
|
||||
|
||||
GeneralOperValue.uiEmergency = 0U;
|
||||
|
||||
GeneralOperValue.ulRampStartClock = 0UL; // IDLE_SEQ_MOD
|
||||
|
||||
GeneralOperValue.uiRampComplete = 0U; // IDLE_SEQ_MOD
|
||||
|
||||
GpioDataRegs.GPBCLEAR.bit.GPIO55 = 1U; // GPIO_FAULT_CMD
|
||||
}
|
||||
|
||||
static void CEmergencyStop(void)
|
||||
{
|
||||
KeyOperValue.KeyList.EngineStartStop = 0U; // 비상정지 상황에서는 시동/정지 키 초기화
|
||||
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP);
|
||||
|
||||
CSetEcuCommand((Uint16)IDX_ECU_CMD_EMERGENCY);
|
||||
|
||||
COffChipSelect();
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_CRANKING);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_RETRY_CRANKING);
|
||||
|
||||
CSoftWaitCountClear(SOFTTIMER_WAIT_AFTER_COOLDOWN);
|
||||
|
||||
GeneralOperValue.uiEmergency = 1U;
|
||||
|
||||
GeneralOperValue.ulRampStartClock = 0UL; // IDLE_SEQ_MOD
|
||||
|
||||
GeneralOperValue.uiRampComplete = 0U; // IDLE_SEQ_MOD
|
||||
|
||||
GpioDataRegs.GPBSET.bit.GPIO55 = 1U; //GPIO_FAULT_CMD
|
||||
}
|
||||
|
||||
static void CSetEngineActualRpm(Uint16 Rpm)
|
||||
{
|
||||
GeneralOperValue.EcuCommand.RpmSetPoint = Rpm;
|
||||
}
|
||||
|
||||
Uint16 CGetEngineActualRpm(void)
|
||||
{
|
||||
return (Uint16)Rx320.ActualRpm;
|
||||
}
|
||||
|
||||
static float32 CGetGcuLoadPower(void)
|
||||
{
|
||||
float32 power = ((float32)Rx220.Power * 0.1F);
|
||||
|
||||
// 범위를 0.0 ~ 17.0 으로 제한
|
||||
if (power > 17.0F)
|
||||
{
|
||||
power = 17.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (power < 0.0F)
|
||||
{
|
||||
power = 0.0;
|
||||
}
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
Uint16 CGetGeneratorRpm(void)
|
||||
{
|
||||
return Rx220.Rpm;
|
||||
}
|
||||
|
||||
void CSetGcuCommand(Uint16 Command)
|
||||
{
|
||||
GeneralOperValue.GcuCommand.PlayCmd = Command;
|
||||
}
|
||||
|
||||
void CSetEcuCommand(Uint16 Command)
|
||||
{
|
||||
if ((Command == (Uint16)IDX_ECU_CMD_STOP) || (Command == (Uint16)IDX_ECU_CMD_EMERGENCY))
|
||||
{
|
||||
GeneralOperValue.EcuCommand.EngineStart = 0U;
|
||||
GeneralOperValue.EcuCommand.EngineStop = 1U;
|
||||
CSetEngineActualRpm(0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
// [ECU_OPER_CMD_START]
|
||||
GeneralOperValue.EcuCommand.EngineStart = 1U;
|
||||
GeneralOperValue.EcuCommand.EngineStop = 0U;
|
||||
#if 0 // RPM 테스트
|
||||
CSetEngineActualRpm(Rx400.SetRPM.PCAN_RPM);
|
||||
#else
|
||||
//CSetEngineActualRpm(2400U);
|
||||
CSetEngineActualRpm(1500U); // Target Idle
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int16 CGetEngCoolantTemperature(void)
|
||||
{
|
||||
return (int16) Rx321.CoolantTemperature - 40; // 온도 오프셋 -40도
|
||||
}
|
||||
|
||||
void CDebugModeProcedure(void)
|
||||
{
|
||||
if (GeneralOperValue.Maintenance.ManualCranking == 1U)
|
||||
{
|
||||
if (GeneralOperValue.uiFaultOccured == 0U)
|
||||
{
|
||||
// 알람이 없을 경우만 동작 하도록 함.
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_CRANKING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSetGcuCommand((Uint16)IDX_GCU_CMD_STOP);
|
||||
}
|
||||
|
||||
if (GeneralOperValue.Maintenance.LampTest == 1U)
|
||||
{
|
||||
CLedControl(0U, 1U);
|
||||
CLedControl(1U, 1U);
|
||||
CLedControl(2U, 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLedControl(0U, 0U);
|
||||
CLedControl(1U, 0U);
|
||||
CLedControl(2U, 0U);
|
||||
}
|
||||
|
||||
if (GeneralOperValue.Maintenance.KeyTest == 1U)
|
||||
{
|
||||
Uint16 uiKeyUp = (GPIO_KEY_UP() == 0U) ? 1U : 0U;
|
||||
Uint16 uiKeyDn = (GPIO_KEY_DOWN() == 0U) ? 1U : 0U;
|
||||
|
||||
if ((uiKeyUp == 1U) && (uiKeyDn == 1U))
|
||||
{
|
||||
GeneralOperValue.Maintenance.KeyTest = 0U;
|
||||
OledOperValue.uiPageNum = (Uint16)IDX_OLED_PAGE_MAINTENANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLedControlProcedure(void)
|
||||
{
|
||||
static const CLedPattern APU_LED_TABLE[] = // LED 룩업 테이블
|
||||
{
|
||||
// FAULT, OPER, STOP
|
||||
{LED_OFF, LED_OFF, LED_ON }, // 0: BOOT
|
||||
{LED_OFF, LED_OFF, LED_ON }, // 1: INITIAL
|
||||
{LED_OFF, LED_OFF, LED_ON }, // 2: POST
|
||||
{LED_ON, LED_OFF, LED_ON }, // 3: EMERGENCY
|
||||
{LED_OFF, LED_OFF, LED_ON }, // 4: STANDBY
|
||||
|
||||
// --- OPER 깜빡임 구간 (준비~예열) ---
|
||||
{LED_OFF, LED_BLINK, LED_OFF }, // 5: READY
|
||||
{LED_OFF, LED_BLINK, LED_OFF }, // 6: PREPARE_START
|
||||
{LED_OFF, LED_BLINK, LED_OFF }, // 7: CRANKING
|
||||
{LED_OFF, LED_BLINK, LED_OFF }, // 8: RETRY_CRANKING
|
||||
{LED_OFF, LED_BLINK, LED_OFF }, // 9: ENGINE_WARM_UP
|
||||
|
||||
{LED_OFF, LED_ON, LED_OFF }, // 10: GENERATING (정상 운전)
|
||||
|
||||
// --- STOP 깜빡임 구간 (APU 정지 시) ---
|
||||
{LED_OFF, LED_ON, LED_BLINK }, // 11: COOLDOWN (STOP 깜빡임, OPER는 켜둠)
|
||||
{LED_OFF, LED_ON, LED_BLINK } // 12: STOPPING (COOLDWON이 순식간에 지나가기 때문에 점멸로 수정)
|
||||
};
|
||||
|
||||
CLedPattern TargetLeds = {0, 0, 0};
|
||||
|
||||
Uint64 SoftClock = CGetSoftClock();
|
||||
Uint16 IsBlinkOn = ((SoftClock % 10000U) < 5000U) ? 1U : 0U; // 0.5s 점멸을 위함
|
||||
Uint16 WarningValue = 0U;
|
||||
|
||||
TargetLeds = APU_LED_TABLE[GeneralOperValue.uiApuState];
|
||||
|
||||
// 발전상태에서 경고 발생시 FAULT LED 깜빡이도록 설정
|
||||
if (GeneralOperValue.uiApuState == (Uint16)IDX_APU_OPER_GENERATING)
|
||||
{
|
||||
WarningValue = ((((Uint16)Rx210.GcuWarning & (Uint16)MASK_LOW_NIBBLE) | ((Uint16)Rx310.EcuWarning & 0xFDU)) > 0U) ? 1U : 0U;
|
||||
}
|
||||
|
||||
// 비상정지 상태가 아닌 경우에만 경고비트에 점멸 대응
|
||||
if ((GeneralOperValue.uiApuState != (Uint16)IDX_APU_OPER_EMERGENCY) && (WarningValue == 1U))
|
||||
{
|
||||
TargetLeds.Fault = (Uint16)LED_BLINK;
|
||||
}
|
||||
|
||||
// FAULT LED 제어
|
||||
if (TargetLeds.Fault == (Uint16)LED_BLINK)
|
||||
{
|
||||
CLedControl(0U, IsBlinkOn);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLedControl(0U, TargetLeds.Fault);
|
||||
}
|
||||
|
||||
// OPERATION LED 제어
|
||||
if (TargetLeds.Operation == (Uint16)LED_BLINK)
|
||||
{
|
||||
CLedControl(1U, IsBlinkOn);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLedControl(1U, TargetLeds.Operation);
|
||||
}
|
||||
|
||||
// STOP LED 제어
|
||||
if (TargetLeds.Stop == (Uint16)LED_BLINK)
|
||||
{
|
||||
CLedControl(2U, IsBlinkOn);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLedControl(2U, TargetLeds.Stop);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLedControl(Uint16 idx, Uint16 state)
|
||||
{
|
||||
/*
|
||||
* idx
|
||||
* 0 : FAULT LED
|
||||
* 1 : OPER LED
|
||||
* 2 : STOP LED
|
||||
*/
|
||||
|
||||
if (idx == 0U)
|
||||
{
|
||||
// GPIO_CPU_LED_FAULT
|
||||
if (state == 0U)
|
||||
{
|
||||
GpioDataRegs.GPACLEAR.bit.GPIO14 = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
GpioDataRegs.GPASET.bit.GPIO14 = 1U;
|
||||
}
|
||||
}
|
||||
else if (idx == 1U)
|
||||
{
|
||||
// GPIO_CPU_LED_OPERATION
|
||||
if (state == 0U)
|
||||
{
|
||||
GpioDataRegs.GPACLEAR.bit.GPIO13 = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
GpioDataRegs.GPASET.bit.GPIO13 = 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// GPIO_CPU_LED_STOP
|
||||
if (state == 0U)
|
||||
{
|
||||
GpioDataRegs.GPACLEAR.bit.GPIO12 = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
GpioDataRegs.GPASET.bit.GPIO12 = 1U;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user