#include "main.h" void CInitAlarmOperValue(void); void CKeyMainPowerProcess(void); void CKeyArrowUpProcess(void); void CKeyArrowDownProcess(void); void CKeyEnterProcess(void); void CKeyMenuProcess(void); void CKeyEngineStartStopProcess(void); void CKeyEmergencyProcess(void); void CInitAdcStructure(void); Uint16 CAlarmCheck(ALARM_TYPE Idx, float32 fValue, Uint16 uiCheckDetectTime, Uint16 uiCheckType); static inline Uint16 CheckOpenFault(Uint16 isCsHigh, Uint16 isFuseHigh); Uint32 CGetKey(void); void CKeyCheck(Uint32 ulChangeKey, Uint32 ulKeyRead); static void MoveFocusLine(Uint16 maxLines, Uint16 direction); static void CChangePasswordDigit(Uint16 direction); static inline void CCalcAdcSum(CAdcCalcValue *AdcBuff); CAdcCalcValue Adc_EngineHeater_I; CAdcCalcValue Adc_GlowPlug_I; CAdcCalcValue Adc_Solenoid_I; CAdcCalcValue Adc_FuelPump_I; CAdcCalcValue Adc_CoolantPump_I; CAdcCalcValue Adc_Fan1_I; CAdcCalcValue Adc_Fan2_I; CAdcOperValue AdcOperValue; CAlarmOperValue AlarmOperValue[IDX_FAULT_MAX]; CFaultBitValue FaultBitValue; CKeyOperValue KeyOperValue; static const CKeyHandler KeyTable[IDX_KEY_MAX] = { { IDX_KEY_MAIN_POWER, CKeyMainPowerProcess }, { IDX_KEY_ARR_UP, CKeyArrowUpProcess }, { IDX_KEY_ARR_DOWN, CKeyArrowDownProcess }, { IDX_KEY_ENTER, CKeyEnterProcess }, { IDX_KEY_MENU, CKeyMenuProcess }, { IDX_KEY_ENG_START_STOP, CKeyEngineStartStopProcess }, { IDX_KEY_EMERGENCY, CKeyEmergencyProcess } }; interrupt void CAdcInterrupt(void) { Uint16 uiTemp[IDX_ADC_MAX]; Uint16 i; const volatile Uint16 *pAdcAddress = &AdcRegs.ADCRESULT0; for (i = 0U; i < IDX_ADC_MAX; i++) { uiTemp[i] = (*(pAdcAddress++) >> 4); } Adc_EngineHeater_I.iAdcValue = (int16) uiTemp[IDX_ADC_ENGINE_HEATER_I]; Adc_GlowPlug_I.iAdcValue = (int16) uiTemp[IDX_ADC_GLOW_PLUG_I]; Adc_Solenoid_I.iAdcValue = (int16) uiTemp[IDX_ADC_SOLENOID_I]; Adc_FuelPump_I.iAdcValue = (int16) uiTemp[IDX_ADC_FUEL_PUMP_I]; Adc_CoolantPump_I.iAdcValue = (int16) uiTemp[IDX_ADC_COOLANT_PUMP_I]; Adc_Fan1_I.iAdcValue = (int16) uiTemp[IDX_ADC_FAN1_I]; Adc_Fan2_I.iAdcValue = (int16) uiTemp[IDX_ADC_FAN2_I]; CCalcAdcSum(&Adc_EngineHeater_I); CCalcAdcSum(&Adc_GlowPlug_I); CCalcAdcSum(&Adc_Solenoid_I); CCalcAdcSum(&Adc_FuelPump_I); CCalcAdcSum(&Adc_CoolantPump_I); CCalcAdcSum(&Adc_Fan1_I); CCalcAdcSum(&Adc_Fan2_I); if (AdcOperValue.uiOffsetAdjustStart == 1U) // ADC Calibration { Adc_EngineHeater_I.fTempAdcOffset += Adc_EngineHeater_I.fSampledValue; Adc_GlowPlug_I.fTempAdcOffset += Adc_GlowPlug_I.fSampledValue; Adc_Solenoid_I.fTempAdcOffset += Adc_Solenoid_I.fSampledValue; Adc_FuelPump_I.fTempAdcOffset += Adc_FuelPump_I.fSampledValue; Adc_CoolantPump_I.fTempAdcOffset += Adc_CoolantPump_I.fSampledValue; Adc_Fan1_I.fTempAdcOffset += Adc_Fan1_I.fSampledValue; Adc_Fan2_I.fTempAdcOffset += Adc_Fan2_I.fSampledValue; AdcOperValue.uiAdcOffsetIndex--; if (AdcOperValue.uiAdcOffsetIndex == 0U) { Adc_EngineHeater_I.fOffset -= (Adc_EngineHeater_I.fTempAdcOffset / 10000.0f); Adc_GlowPlug_I.fOffset -= (Adc_GlowPlug_I.fTempAdcOffset / 10000.0f); Adc_Solenoid_I.fOffset -= (Adc_Solenoid_I.fTempAdcOffset / 10000.0f); Adc_FuelPump_I.fOffset -= (Adc_FuelPump_I.fTempAdcOffset / 10000.0f); Adc_CoolantPump_I.fOffset -= (Adc_CoolantPump_I.fTempAdcOffset / 10000.0f); Adc_Fan1_I.fOffset -= (Adc_Fan1_I.fTempAdcOffset / 10000.0f); Adc_Fan2_I.fOffset -= (Adc_Fan2_I.fTempAdcOffset / 10000.0f); AdcOperValue.uiOffsetAdjustStart = 0U; } } // Reinitialize for next ADC sequence AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1U; // Reset SEQ1 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1U; // Clear INT SEQ1 bit PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1; // Acknowledge interrupt to PIE } void CDisplayAlarmPopup(void) { Uint64 ullFaultValue = ((Uint64)FaultBitValue.ulTotal & 0x3FFFFUL) | (((Uint64)Rx210.GcuFault.uiTotal & 0xFFFFU) << 19UL) | (((Uint64)Rx310.EcuFault.uiTotal & 0x3FU) << 35UL); Uint32 ulWarningValue = ((Uint32)Rx210.GcuWarning.uiTotal & 0x7U) | (((Uint32)Rx310.EcuWarning.uiTotal & 0xFU) << 4U); Uint16 i; if (OledOperValue.uiAlarmPopCheck == 0U) { if (ulWarningValue > 0U) { for (i = 0U; i < 16U; i++) { if ((ulWarningValue >> i) == 1U) { OledOperValue.uiAlarmPopCheck = 1U; OledOperValue.uiPrevAlarmPage = OledOperValue.uiPageNum; OledOperValue.uiPageNum = ((i / 9U) + OLED_PAGE_WARNING1); break; } } } if (ullFaultValue > 0U) { for (i = 0U; i < 64U; i++) { if ((ullFaultValue >> i) == 1U) { OledOperValue.uiAlarmPopCheck = 1U; OledOperValue.uiPrevAlarmPage = OledOperValue.uiPageNum; OledOperValue.uiPageNum = (((i % 64U) / 8U) + OLED_PAGE_FAULT1); break; } } } } } void CAlarmProcedure(void) { int16 iDiffRpm = 0U; if (CGetApuOperIndex() == APU_OPER_IDX_EMERGENCY) { // ŸÀÓ ¾Æ¿ô ¹ß»ý ½Ã ¿¬°á¼ö¸³ ºñÆ®´Â Ŭ¸®¾î ÇÑ´Ù. GeneralOperValue.Conection.CarComputer = (FaultBitValue.bit.CarCommTimeout == 1U) ? 0U : GeneralOperValue.Conection.CarComputer; GeneralOperValue.Conection.Gcu = (FaultBitValue.bit.GcuCommTimeout == 1U) ? 0U : GeneralOperValue.Conection.Gcu; GeneralOperValue.Conection.Ecu = (FaultBitValue.bit.EcuCommTimeOut == 1U) ? 0U : GeneralOperValue.Conection.Ecu; if (GeneralOperValue.uiAlarmReset == 1U) { GeneralOperValue.uiAlarmReset = 0U; CInitAlarmOperValue(); } } else { if (GeneralOperValue.uiApuState > APU_OPER_IDX_EMERGENCY) { // Comm Timeout Checks FaultBitValue.bit.CarCommTimeout = CAlarmCheck(IDX_FAULT_CAR_COMM, (float32)CommCheck.CarComputer, AlarmOperValue[IDX_FAULT_CAR_COMM].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.GcuCommTimeout = CAlarmCheck(IDX_FAULT_GCU_COMM, (float32)CommCheck.Gcu, AlarmOperValue[IDX_FAULT_GCU_COMM].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.EcuCommTimeOut = CAlarmCheck(IDX_FAULT_ECU_COMM, (float32)CommCheck.Ecu, AlarmOperValue[IDX_FAULT_ECU_COMM].uiCheckTime, ALARM_OVER_CHECK); if ((GeneralOperValue.Conection.Gcu == 1U) && (GeneralOperValue.Conection.Ecu == 1U)) { // RPM¿À·ù´Â º¸Á¶¹ßÀü±âÁ¦¾î±â¿Í º¸Á¶¿£ÁøÁ¦¾î±âÀÇ Åë½ÅÀÌ ¿¬°áµÇ¾úÀ» ¶§ °ËÃâÇÑ´Ù. iDiffRpm = (int16)CGetGeneratorRpm() - (int16)CGetEngineActualRpm(); iDiffRpm = ABS(iDiffRpm); FaultBitValue.bit.RpmError = CAlarmCheck(IDX_FAULT_RPM_ERR, (float32)iDiffRpm, AlarmOperValue[IDX_FAULT_RPM_ERR].uiCheckTime, ALARM_OVER_CHECK); } FaultBitValue.bit.EngineHeatOverCurrent = CAlarmCheck(IDX_FAULT_ENGINE_HEAT_OC, Adc_EngineHeater_I.fLpfValue, AlarmOperValue[IDX_FAULT_ENGINE_HEAT_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.GlowPlugOverCurrent = CAlarmCheck(IDX_FAULT_GLOW_PLUG_OC, Adc_GlowPlug_I.fLpfValue, AlarmOperValue[IDX_FAULT_GLOW_PLUG_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.SolenoidOverCurrent = CAlarmCheck(IDX_FAULT_SOLENOID_OC, Adc_Solenoid_I.fLpfValue, AlarmOperValue[IDX_FAULT_SOLENOID_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.FuelPumpOverCurrent = CAlarmCheck(IDX_FAULT_FUEL_PUMP_OC, Adc_FuelPump_I.fLpfValue, AlarmOperValue[IDX_FAULT_FUEL_PUMP_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.CoolantPumpOverCurrent = CAlarmCheck(IDX_FAULT_COOLANT_PUMP_OC, Adc_CoolantPump_I.fLpfValue, AlarmOperValue[IDX_FAULT_COOLANT_PUMP_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.Fan1OverCurrent = CAlarmCheck(IDX_FAULT_FAN1_OC, Adc_Fan1_I.fLpfValue, AlarmOperValue[IDX_FAULT_FAN1_OC].uiCheckTime, ALARM_OVER_CHECK); FaultBitValue.bit.Fan2OverCurrent = CAlarmCheck(IDX_FAULT_FAN2_OC, Adc_Fan2_I.fLpfValue, AlarmOperValue[IDX_FAULT_FAN2_OC].uiCheckTime, ALARM_OVER_CHECK); // Fuse ½ÅÈ£´Â °¢ ÀåÄ¡¿¡ ´ëÀÀÇÏ´Â CS°¡ ON »óÅ¿¡¼­ ÀÛµ¿ÇϹǷΠCS°¡ HIÀÏ ¶§, Fuse ½ÅÈ£°¡ HI¸é ´Ü¼± if (CGetApuOperIndex() > APU_OPER_IDX_STANDBY) { FaultBitValue.bit.EngineHeatOpen = CheckOpenFault(GPIO_ENGINE_HEATER_CS_READ(), GPIO_ENGINE_HEATER_FUSE()); FaultBitValue.bit.GlowPlugOpen = CheckOpenFault(GPIO_GLOW_PLUG_CS_READ(), GPIO_GLOW_PLUG_FUSE()); FaultBitValue.bit.SolenoidOpen = CheckOpenFault(GPIO_SOLENOID_CS_READ(), GPIO_SOLENOID_FUSE()); FaultBitValue.bit.FuelPumpOpen = CheckOpenFault(GPIO_FUEL_PUMP_CS_READ(), GPIO_FUEL_PUMP_FUSE()); FaultBitValue.bit.CoolantPumpOpen = CheckOpenFault(GPIO_COOLANT_PUMP_CS_READ(), GPIO_COOLANT_PUMP_FUSE()); FaultBitValue.bit.Fan1Open = CheckOpenFault(GPIO_FAN1_CS_READ(), GPIO_FAN1_FUSE()); FaultBitValue.bit.Fan2Open = CheckOpenFault(GPIO_FAN2_CS_READ(), GPIO_FAN2_FUSE()); } } } } Uint16 CAlarmCheck(ALARM_TYPE Idx, float32 fValue, Uint16 uiCheckDetectTime, Uint16 uiCheckType) { Uint16 uiCheckStatus = 0; if (AlarmOperValue[Idx].uiCheck == 0U) { if (uiCheckType == ALARM_OVER_CHECK) { // Over Check ! if (fValue >= AlarmOperValue[Idx].fCheckLimit) { uiCheckStatus = 1U; } } else { // Under Check ! if (fValue <= AlarmOperValue[Idx].fCheckLimit) { uiCheckStatus = 1U; } } if (uiCheckStatus == 1U) { if (AlarmOperValue[Idx].uiCheckCount < uiCheckDetectTime) { AlarmOperValue[Idx].uiCheckCount++; } else { AlarmOperValue[Idx].uiCheck = 1U; AlarmOperValue[Idx].uiCheckCount = 0U; AlarmOperValue[Idx].fFaultValue = fValue; } } else { AlarmOperValue[Idx].uiCheckCount = 0U; } } return AlarmOperValue[Idx].uiCheck; } static inline Uint16 CheckOpenFault(Uint16 isCsHigh, Uint16 isFuseHigh) { // µÎ ½ÅÈ£°¡ ¸ðµÎ 1(High)ÀÏ ¶§¸¸ 1(Fault) ¹Ýȯ return ((isCsHigh == 1U) && (isFuseHigh == 1U)) ? 1U : 0U; } void CInitAlarmOperValue(void) { int16 i; for (i = 0; i < IDX_FAULT_MAX; i++) { (void) memset(&AlarmOperValue[i], 0, sizeof(CAlarmOperValue)); } (void) memset(&FaultBitValue, 0, sizeof(CFaultBitValue)); (void) memset(&CommCheck, 0, sizeof(CCommCheck)); // ü°è/GCU/ECU Åë½Å ¹× ½ÅÈ£ ´Ü¼±Àº ´Ù¸¥ ÇÔ¼ö¿¡¼­ ó¸® /* * Alarm Check Standard Value * Alarm Count per 1mS */ AlarmOperValue[IDX_FAULT_CAR_COMM].fCheckLimit = (float32)(COMM_TIME_OUT_COUNT); // 3 Seconds AlarmOperValue[IDX_FAULT_CAR_COMM].uiCheckTime = 1U; // ½Ã°£À» °¨Áö ÇϹǷΠÁï½Ã °ËÃâ AlarmOperValue[IDX_FAULT_GCU_COMM].fCheckLimit = (float32)(COMM_TIME_OUT_COUNT); // 3 Seconds AlarmOperValue[IDX_FAULT_GCU_COMM].uiCheckTime = 1U; // ½Ã°£À» °¨Áö ÇϹǷΠÁï½Ã °ËÃâ AlarmOperValue[IDX_FAULT_ECU_COMM].fCheckLimit = (float32)(COMM_TIME_OUT_COUNT); // 3 Seconds AlarmOperValue[IDX_FAULT_ECU_COMM].uiCheckTime = 1U; // ½Ã°£À» °¨Áö ÇϹǷΠÁï½Ã °ËÃâ AlarmOperValue[IDX_FAULT_RPM_ERR].fCheckLimit = 300.0f; // Value AlarmOperValue[IDX_FAULT_RPM_ERR].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_ENGINE_HEAT_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_ENGINE_HEAT_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_GLOW_PLUG_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_GLOW_PLUG_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_SOLENOID_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_SOLENOID_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_FUEL_PUMP_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_FUEL_PUMP_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_COOLANT_PUMP_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_COOLANT_PUMP_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_FAN1_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_FAN1_OC].uiCheckTime = 10U; // Value AlarmOperValue[IDX_FAULT_FAN2_OC].fCheckLimit = 10.0f; // Value AlarmOperValue[IDX_FAULT_FAN2_OC].uiCheckTime = 10U; // Value } void CInitAdc(void) { InitAdc(); // ADC Initialize in DSP2833x_Adc.c AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x0; // No prescaler AdcRegs.ADCTRL1.bit.CPS = 0x1; // scaler 12.5Mhz AdcRegs.ADCTRL3.bit.SMODE_SEL = 0x0; // sequentail mode AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0x0; // EOS AdcRegs.ADCTRL1.bit.SEQ_CASC = 0x1; // Cascade Sequence Mode AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Engine_Heater_I AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Glow_Plug_I AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // Solenoid_I AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // Fuel_Pump_I AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // Cooling_Pump_I AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // Fan1_I AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // Fan2_I AdcRegs.ADCMAXCONV.all = IDX_ADC_MAX; // Setup 16 channel conversion for cascade sequence mode AdcRegs.ADCREFSEL.bit.REF_SEL = 0x1; // external Reference 2.048[V], 'b01 - 2.048, b10 - 1.500[V], 'b11 - 1.024[v] AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0x0; AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1; // Enable SEQ1 interrupt (every EOS) AdcRegs.ADCTRL1.bit.ACQ_PS = 6; // Sample and hold duration(width) = (ACQ_PS + 1) CInitAdcStructure(); CInitAlarmOperValue(); } void CInitAdcStructure(void) { (void) memset(&AdcOperValue, 0, sizeof(CAdcOperValue)); (void) memset(&Adc_EngineHeater_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_GlowPlug_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_Solenoid_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_FuelPump_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_CoolantPump_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_Fan1_I, 0, sizeof(CAdcCalcValue)); (void) memset(&Adc_Fan2_I, 0, sizeof(CAdcCalcValue)); AdcOperValue.uiAdcOffsetIndex = 10000U; Adc_EngineHeater_I.fGain = 0.005637f; Adc_GlowPlug_I.fGain = 0.005637f; Adc_Solenoid_I.fGain = 0.005637f; Adc_FuelPump_I.fGain = 0.005637f; Adc_CoolantPump_I.fGain = 0.005637f; Adc_Fan1_I.fGain = 0.005637f; Adc_Fan2_I.fGain = 0.005637f; Adc_EngineHeater_I.fOffset = -2.333f; Adc_GlowPlug_I.fOffset = -2.333f; Adc_Solenoid_I.fOffset = -2.333f; Adc_FuelPump_I.fOffset = -2.333f; Adc_CoolantPump_I.fOffset = -2.333f; Adc_Fan1_I.fOffset = -2.333f; Adc_Fan2_I.fOffset = -2.333f; } static inline void CCalcAdcSum(CAdcCalcValue *AdcBuff) { #if 1 AdcBuff->fSampledValue = ((float32) AdcBuff->iAdcValue * AdcBuff->fGain) + AdcBuff->fOffset; AdcBuff->fSampledSum += AdcBuff->fSampledValue; AdcBuff->uiSamplingCount++; if (AdcBuff->uiSamplingCount >= 100) { AdcBuff->uiSamplingCount = 0; AdcBuff->fSampledSum /= 100; AdcBuff->fLpfValue = (ADC_LPF_GAIN * AdcBuff->fSampledSum) + ((1.0f - ADC_LPF_GAIN) * AdcBuff->fLpfValue); AdcBuff->fSampledSum = 0.0f; } #else AdcBuff->fSampledValue = ((float32) AdcBuff->iAdcValue * AdcBuff->fGain) + AdcBuff->fOffset; AdcBuff->fLpfValue = (ADC_LPF_GAIN * AdcBuff->fSampledValue) + ((1.0f - ADC_LPF_GAIN) * AdcBuff->fLpfValue); #endif } Uint32 CGetKey(void) { Uint16 i, ucDiv, ucMod; Uint32 ulGpioData = 0UL, ulKeyRead = 0UL; Uint16 ucKeyGpioList[7] = { 67, 39, 31, 30, 29, 66, 64}; for (i = 0; i < IDX_KEY_MAX; i++) { ucDiv = ucKeyGpioList[i] / 32; ucMod = ucKeyGpioList[i] % 32; if (ucDiv == 0U) // GPIO-A { ulGpioData = GpioDataRegs.GPADAT.all; } else if (ucDiv == 1U) { ulGpioData = GpioDataRegs.GPBDAT.all; } else { ulGpioData = GpioDataRegs.GPCDAT.all; } if (((ulGpioData >> ucMod) & 0x01UL) == 0U) // Push Check { ulKeyRead |= (0x01UL << i); } } return ulKeyRead; } void CKeyCheckProcedure(void) { static Uint32 ulLongKeyCnt = 0UL; // ·ÕŰ Ä«¿îÆ®¿ë º¯¼ö static Uint16 uiLongKeyProcessed = 0U; // ·ÕŰ ó¸® ¿Ï·á Ç÷¡±× (Áߺ¹ ½ÇÇà ¹æÁö) static Uint32 ulPrevKey = 0UL; Uint32 ulChangeKey; Uint32 ulReadKey = CGetKey(); ulChangeKey = (ulPrevKey ^ ulReadKey) & ~KEY_POWER_MASK; // ÇöÀç Ű¿Í ÀÌÀü ۸¦ ºñ±³ÇϵÇ, ·ÕŰ(Bit 0)´Â º¯È­ °¨Áö¿¡¼­ Á¦¿ÜÇÔ (& ~KEY_POWER_MASK) if (ulChangeKey > 0UL) { if (KeyOperValue.uiKeyWait == 0U) // äÅ͸µ ¹«½Ã ½ÃÀÛ { KeyOperValue.uiKeyWait = 1U; KeyOperValue.uiKeyWaitCount = 20; // 20ms } else { // Àü¿øÅ°¸¦ Á¦¿ÜÇÑ ³ª¸ÓÁö ۵éÀº POST ´Ü°è°¡ ³Ñ¾î°¡¾ßÁö µ¿ÀÛÇÑ´Ù. if ((KeyOperValue.uiKeyWaitCount == 0U) && (CGetApuOperIndex() > APU_OPER_IDX_POST)) { ulPrevKey = (ulPrevKey & KEY_POWER_MASK) | (ulReadKey & ~KEY_POWER_MASK); // ulPrevKeyÀÇ ³ª¸ÓÁö ºñÆ®´Â À¯ÁöÇÏ°í º¯°æµÈ ºñÆ®¸¸ °»½Å CKeyCheck(ulChangeKey, ulReadKey); // ÀÏ¹Ý Å° µ¿ÀÛ } } } else { // º¯È­°¡ ¾øÀ¸¸é äÅ͸µ ´ë±â ÃʱâÈ­ (ÀÏ¹Ý Å°¿ë) // ´Ü, ´­·ÁÀÖ´Â »óÅ À¯Áö¸¦ À§ÇØ ulPrevKey °»½ÅÀº ÇÊ¿ä ¾øÀ½ if ((KeyOperValue.uiKeyWait) != 0U && (KeyOperValue.uiKeyWaitCount == 0U)) { KeyOperValue.uiKeyWait = 0U; } } // Bit 0ÀÌ ´­·Á ÀÖ´ÂÁö È®ÀÎ (1 = ´­¸²) if ((ulReadKey & KEY_POWER_MASK) == KEY_POWER_MASK) { // ÀÌ¹Ì Ã³¸®°¡ ³¡³­ »óŰ¡ ¾Æ´Ï¶ó¸é Ä«¿îÆ® Áõ°¡ if (uiLongKeyProcessed == 0U) { ulLongKeyCnt++; // 1ÃÊ(1000ms) µµ´Þ ½Ã µ¿ÀÛ ¼öÇà if (ulLongKeyCnt >= LONG_KEY_TIME) { CKeyCheck(KEY_POWER_MASK, ulReadKey); // ·ÕŰ µ¿ÀÛ ¼öÇà (CKeyCheck¿¡ ·ÕŰ ºñÆ®¸¸ Àü´Þ) uiLongKeyProcessed = 1U; // ¶¼±â Àü±îÁö ´Ù½Ã µ¿ÀÛÇÏÁö ¾Êµµ·Ï Ç÷¡±× ¼³Á¤ ulLongKeyCnt = LONG_KEY_TIME; // Ä«¿îÆ® ¿À¹öÇÃ·Î¿ì ¹æÁö } } } else { // ۸¦ ¶ÃÀ» ¶§ º¯¼öµé ÃʱâÈ­ ulLongKeyCnt = 0UL; uiLongKeyProcessed = 0U; // ulPrevKeyÀÇ Bit 0 »óŵµ 0À¸·Î µ¿±âÈ­ (´ÙÀ½ ºñ±³¸¦ À§ÇØ) ulPrevKey &= ~KEY_POWER_MASK; } } void CKeyWaitCount(void) { if (KeyOperValue.uiKeyWait == 1U) { if (KeyOperValue.uiKeyWaitCount > 0U) { KeyOperValue.uiKeyWaitCount--; } else { KeyOperValue.uiKeyWait = 0U; } } } void CKeyCheck(Uint32 ulChangeKey, Uint32 ulKeyRead) { Uint16 i; for (i = 0U; i < IDX_KEY_MAX; i++) { if ((ulChangeKey & (0x1UL << i)) > 0U) { if ((ulKeyRead & (0x1UL << i)) > 0U) { KeyTable[i].pAction(); } } } } void CKeyArrowUpProcess(void) { if (OledOperValue.uiPageNum == OLED_PAGE_APU2) { OledOperValue.uiPageNum = OLED_PAGE_APU1; } else if (OledOperValue.uiPageNum == OLED_PAGE_MENU1) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_1) { OledOperValue.uiFocusLine = OLED_LINE_FOCUS_1; } else { MoveFocusLine(4U, DIR_UP); } } else if (OledOperValue.uiPageNum == OLED_PAGE_MENU2) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_1) { // Go back to Menu 1 OledOperValue.uiFocusLine = OLED_LINE_FOCUS_4; OledOperValue.uiPageNum = OLED_PAGE_MENU1; } else { MoveFocusLine(3U, DIR_UP); } } else if ((OledOperValue.uiPageNum > OLED_PAGE_SENSOR1) && (OledOperValue.uiPageNum <= OLED_PAGE_SENSOR4)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum - 1U; } else if ((OledOperValue.uiPageNum > OLED_PAGE_WARNING1) && (OledOperValue.uiPageNum <= OLED_PAGE_WARNING2)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum - 1U; } else if ((OledOperValue.uiPageNum > OLED_PAGE_FAULT1) && (OledOperValue.uiPageNum <= OLED_PAGE_FAULT6)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum - 1U; } else if (OledOperValue.uiPageNum == OLED_PAGE_PASSWORD) { CChangePasswordDigit(DIR_UP); } else if (OledOperValue.uiPageNum == OLED_PAGE_RESET_ALARM) { OledOperValue.uiResetAnswer = OledOperValue.uiResetAnswer ^ 1U; // toggle } else { if (OledOperValue.uiPageNum == OLED_PAGE_MAINTENENCE) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_1) { OledOperValue.uiFocusLine = OLED_LINE_FOCUS_1; } else { MoveFocusLine(3U, DIR_UP); } } } } void CKeyArrowDownProcess(void) { if (OledOperValue.uiPageNum == OLED_PAGE_APU1) { OledOperValue.uiPageNum = OLED_PAGE_APU2; } else if (OledOperValue.uiPageNum == OLED_PAGE_MENU1) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_4) { // Bottom of Menu 1 -> Go to Menu 2 OledOperValue.uiFocusLine = OLED_LINE_FOCUS_1; OledOperValue.uiPageNum = OLED_PAGE_MENU2; } else { MoveFocusLine(4U, DIR_DOWN); } } else if (OledOperValue.uiPageNum == OLED_PAGE_MENU2) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_3) { OledOperValue.uiFocusLine = OLED_LINE_FOCUS_3; } else { MoveFocusLine(3U, DIR_DOWN); } } else if ((OledOperValue.uiPageNum >= OLED_PAGE_SENSOR1) && (OledOperValue.uiPageNum < OLED_PAGE_SENSOR4)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum + 1U; } else if ((OledOperValue.uiPageNum >= OLED_PAGE_WARNING1) && (OledOperValue.uiPageNum < OLED_PAGE_WARNING2)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum + 1U; } else if ((OledOperValue.uiPageNum >= OLED_PAGE_FAULT1) && (OledOperValue.uiPageNum < OLED_PAGE_FAULT6)) { OledOperValue.uiPageNum = OledOperValue.uiPageNum + 1U; } else if (OledOperValue.uiPageNum == OLED_PAGE_PASSWORD) { CChangePasswordDigit(DIR_DOWN); } else if (OledOperValue.uiPageNum == OLED_PAGE_RESET_ALARM) { OledOperValue.uiResetAnswer = OledOperValue.uiResetAnswer ^ 1U; // toggle } else { if (OledOperValue.uiPageNum == OLED_PAGE_MAINTENENCE) { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_3) { OledOperValue.uiFocusLine = OLED_LINE_FOCUS_3; } else { MoveFocusLine(3U, DIR_DOWN); } } } } static void CChangePasswordDigit(Uint16 direction) { // Ensure the focus digit is within valid range to avoid out-of-bounds access if (OledOperValue.uiFocusDigit <= OLED_PASS_DIGIT_4) { Uint16 *pDigit = &GeneralOperValue.uiPassword[OledOperValue.uiFocusDigit]; if (direction == DIR_UP) { *pDigit = (*pDigit + 1U) % 10U; } else // DIR_DOWN { if (*pDigit == 0U) { *pDigit = 9U; } else { *pDigit = (*pDigit - 1U) % 10U; } } } } static void MoveFocusLine(Uint16 maxLines, Uint16 direction) { if (direction == DIR_UP) { OledOperValue.uiFocusLine = (OledOperValue.uiFocusLine + maxLines - 1U) % maxLines; } else // DIR_DOWN { OledOperValue.uiFocusLine = (OledOperValue.uiFocusLine + 1U) % maxLines; } } void CKeyEnterProcess(void) { switch (OledOperValue.uiPageNum) { case OLED_PAGE_MENU1: { switch (OledOperValue.uiFocusLine) { case OLED_MENU_APU: { OledOperValue.uiPageNum = OLED_PAGE_APU1; break; } case OLED_MENU_TEMP: { OledOperValue.uiPageNum = OLED_PAGE_TEMP; break; } case OLED_MENU_SENSOR: { OledOperValue.uiPageNum = OLED_PAGE_SENSOR1; break; } default: { if (OledOperValue.uiFocusLine == OLED_MENU_WARNING) { OledOperValue.uiPageNum = OLED_PAGE_WARNING1; } break; } } break; } case OLED_PAGE_MENU2: { switch (OledOperValue.uiFocusLine) { case OLED_LINE_FOCUS_1: // Fault { OledOperValue.uiPageNum = OLED_PAGE_FAULT1; break; } case OLED_LINE_FOCUS_2: // Reset { OledOperValue.uiPrevFocusLine = OledOperValue.uiFocusLine; OledOperValue.uiPageNum = OLED_PAGE_RESET_ALARM; break; } case OLED_LINE_FOCUS_3: // Maintenence { OledOperValue.uiPrevFocusLine = OledOperValue.uiFocusLine; OledOperValue.uiPageNum = OLED_PAGE_PASSWORD; OledOperValue.uiFocusDigit = OLED_PASS_DIGIT_1; break; } default: break; } break; } case OLED_PAGE_PASSWORD: { if (OledOperValue.uiFocusDigit < OLED_PASS_DIGIT_4) { OledOperValue.uiFocusDigit = (OledOperValue.uiFocusDigit + 1U) % 4U; } else { // Check password const Uint16 uiPassword[4] = DEBUG_MENU_PASSWORD; if (memcmp(GeneralOperValue.uiPassword, uiPassword, sizeof(uiPassword)) == 0U) { GeneralOperValue.uiMaintenence = 1U; OledOperValue.uiPageNum = OLED_PAGE_MAINTENENCE; OledOperValue.uiFocusLine = OLED_LINE_FOCUS_1; } else { OledOperValue.uiFocusDigit = OLED_PASS_DIGIT_1; } } break; } case OLED_PAGE_RESET_ALARM: { // Selected "YES" if (OledOperValue.uiResetAnswer == 1U) { if (CApuSystemAlarmCheck() > 0) { GeneralOperValue.uiAlarmReset = 1U; OledOperValue.uiAlarmPopCheck = 0U; OledOperValue.uiAlreadyAlarm = 0U; } } OledOperValue.uiPageNum = OLED_PAGE_MENU2; break; } case OLED_PAGE_MAINTENENCE: { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_1) { GeneralOperValue.Maintenence.ManualCranking = GeneralOperValue.Maintenence.ManualCranking ^ 1U; // Toggle } else if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_2) { GeneralOperValue.Maintenence.LampTest = GeneralOperValue.Maintenence.LampTest ^ 1U; // Toggle } else { if (OledOperValue.uiFocusLine == OLED_LINE_FOCUS_3) { GeneralOperValue.Maintenence.KeyTest = GeneralOperValue.Maintenence.KeyTest ^ 1U; // Toggle OledOperValue.uiPageNum = OLED_PAGE_KEY_TEST; } } break; } default: { // Handle Fault/Warning page return logic if ((OledOperValue.uiPageNum >= OLED_PAGE_WARNING1) && (OledOperValue.uiPageNum <= OLED_PAGE_FAULT6)) { if (OledOperValue.uiAlarmPopCheck == 1U) { OledOperValue.uiAlreadyAlarm = 1U; OledOperValue.uiPageNum = OledOperValue.uiPrevAlarmPage; } } break; } } } void CKeyMenuProcess(void) { // Return to main menus from sub-pages if ((OledOperValue.uiPageNum == OLED_PAGE_MENU1) || (OledOperValue.uiPageNum == OLED_PAGE_MENU2)) { OledOperValue.uiPageNum = OLED_PAGE_APU1; OledOperValue.uiFocusLine = 0U; } else { if ((OledOperValue.uiPageNum >= OLED_PAGE_FAULT1) && (OledOperValue.uiPageNum <= OLED_PAGE_MAINTENENCE)) { // Return to Menu 2 from Faults or Debug if (OledOperValue.uiPageNum == OLED_PAGE_MAINTENENCE) { GeneralOperValue.uiMaintenence = 0U; OledOperValue.uiFocusLine = OledOperValue.uiPrevFocusLine; } OledOperValue.uiPageNum = OLED_PAGE_MENU2; } else { // Return to Menu 1 from others (APU, Temp, Sensor, Warning) OledOperValue.uiPageNum = OLED_PAGE_MENU1; } } } void CKeyMainPowerProcess(void) { if (CGetApuOperIndex() <= APU_OPER_IDX_STANDBY) { // APU°¡ Á¤Áö »óÅ¿¡¼­¸¸ Àü¿ø ½ºÀ§Ä¡ ÀÔ·Â °¡´É OledOperValue.uiPageNum = OLED_PAGE_SHUTDOWN; if (CSoftWaitCountProcedure(SOFTTIMER_WAIT_SHUTDOWN, TIME_1SEC) == TIME_OVER) { GPIO_POWER_HOLD(0); } } } void CKeyEngineStartStopProcess(void) { KeyOperValue.KeyList.bit.EngineStartStop = KeyOperValue.KeyList.bit.EngineStartStop ^ 1U; // Toggle } void CKeyEmergencyProcess(void) { // ºñ»óÁ¤Áö ½ºÀ§Ä¡¸¦ Ŭ¸®¾î Çϱâ À§Çؼ­´Â APU ½Ã½ºÅÛ¿¡ ¾Ë¶÷ÀÌ ¾ø¾î¾ß ÇÑ´Ù. KeyOperValue.KeyList.bit.Emergency = KeyOperValue.KeyList.bit.Emergency ^ 1U; // Toggle }