#include "main.h" #include "CFont.h" #pragma DATA_SECTION(CommandBus,"ZONE6_COM"); #pragma DATA_SECTION(DataBus,"ZONE6_DAT"); volatile Uint16 CommandBus, DataBus; const Uint16 uiBitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; int8 cNumBuffer[7] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; int8 *pNumBuffer = cNumBuffer; COledOperValue OledOperValue; static void CPageApu1(void); static void CPageApu2(void); static void CPageMenu1(void); static void CPageMenu2(void); static void CPageTemp(void); static void CPageSensor1(void); static void CPageSensor2(void); static void CPageSensor3(void); static void CPageSensor4(void); static void CPageWarning1(void); static void CPageWarning2(void); static void CPageFault1(void); static void CPageFault2(void); static void CPageFault3(void); static void CPageFault4(void); static void CPageFault5(void); static void CPageFault6(void); static void CPageAlarmReset(void); static void CPagePassword(void); static void CPageMaintenence(void); static void CPageKeyTest(void); static void CPageShutdown(void); Uint16 CStrLen(const int8 *s); void CInitOledModule(void); void CDrawChar(Uint16 x, Uint16 y, Uint16 ch, Uint16 type); void CInitProgress(void); void CDrawStr(Uint16 x, Uint16 y, int8* str, Uint16 len); void CTextAlign(int8 *buffer, const int8 *str); static inline void CPutPixel(Uint16 x, Uint16 y, Uint16 Color); void CDrawBox(Uint16 x, Uint16 y, Uint16 w, Uint16 h); void CDrawLine(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2); void CLcdWrite(Uint16 Data, Uint16 Command); void CSetDrawRegion(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2); void CSetPageAddress(Uint16 Address); void CSetColumnAddress(Uint16 x); void COledWrite(Uint16 Data, Uint16 Command); void CInitOledStructure(void); static void CStrncpy(int8 *pTarget, const int8 *pSource, Uint16 Size); void CStrncat(int8 *pTarget, const int8 *pSource, Uint16 Size); void CDecToString(int16 Data, int8 *Array, Uint16 ArrayLen); static void CFloatToString(float32 Data, int8 *Array, Uint16 ArrayLen); static void CLineFocus(Uint16 isFocus); static void CHourToString(int32 num, int8 *str); void CAddLineIndent(int8 *buffer, const int8 *str); static const int8* CGetApuStateString(eApuOperIdx idx); static void CDrawTitleBox(Uint16 TitleLen); static void CDrawCenteredLine(Uint16 y, const int8* text); static const CPageHandler PageTable[OLED_PAGE_MAX] = { { OLED_PAGE_APU1, CPageApu1 }, { OLED_PAGE_APU2, CPageApu2 }, { OLED_PAGE_MENU1, CPageMenu1 }, { OLED_PAGE_MENU2, CPageMenu2 }, { OLED_PAGE_TEMP, CPageTemp }, { OLED_PAGE_SENSOR1, CPageSensor1 }, { OLED_PAGE_SENSOR2, CPageSensor2 }, { OLED_PAGE_SENSOR3, CPageSensor3 }, { OLED_PAGE_SENSOR4, CPageSensor4 }, { OLED_PAGE_WARNING1, CPageWarning1 }, { OLED_PAGE_WARNING2, CPageWarning2 }, { OLED_PAGE_FAULT1, CPageFault1 }, { OLED_PAGE_FAULT2, CPageFault2 }, { OLED_PAGE_FAULT3, CPageFault3 }, { OLED_PAGE_FAULT4, CPageFault4 }, { OLED_PAGE_FAULT5, CPageFault5 }, { OLED_PAGE_FAULT6, CPageFault6 }, { OLED_PAGE_RESET_ALARM, CPageAlarmReset }, { OLED_PAGE_PASSWORD, CPagePassword }, { OLED_PAGE_MAINTENENCE, CPageMaintenence }, { OLED_PAGE_KEY_TEST, CPageKeyTest }, { OLED_PAGE_SHUTDOWN, CPageShutdown } }; static void CDrawPageTitle(const int8* title, const int8* pageNumStr) { CStrncpy(OledOperValue.cStrBuff[OLED_ROW_0], title, CStrLen(title)); CDrawStr(10U, OLED_LINE_TITLE, OledOperValue.cStrBuff[OLED_ROW_0], CStrLen((const int8*)OledOperValue.cStrBuff[OLED_ROW_0])); CDrawTitleBox(CStrLen((const int8*)OledOperValue.cStrBuff[OLED_ROW_0]) * 6U); if (pageNumStr != NULL) { CStrncpy(OledOperValue.cStrBuff[OLED_ROW_0], pageNumStr, CStrLen(pageNumStr)); CDrawStr(100U, OLED_LINE_TITLE, OledOperValue.cStrBuff[OLED_ROW_0], CStrLen(OledOperValue.cStrBuff[OLED_ROW_0])); } } static void CDrawPageLine(Uint16 row, const int8* label, const int8* valueStr, const int8* unitStr) { Uint16 drawY = 0U; switch(row) { case OLED_ROW_1: drawY = OLED_LINE_1; break; case OLED_ROW_2: drawY = OLED_LINE_2; break; case OLED_ROW_3: drawY = OLED_LINE_3; break; case OLED_ROW_4: drawY = OLED_LINE_4; break; default: return; // Invalid row } CStrncpy(OledOperValue.cStrBuff[row], label, CStrLen(label)); if (valueStr != NULL) { CStrncat(OledOperValue.cStrBuff[row], valueStr, CStrLen(valueStr)); } if (unitStr != NULL) { CStrncat(OledOperValue.cStrBuff[row], unitStr, CStrLen(unitStr)); } CDrawStr(0U, drawY, OledOperValue.cStrBuff[row], CStrLen(OledOperValue.cStrBuff[row])); } static void CDrawPageLineFloat(Uint16 row, const int8* label, float32 value, const int8* unitStr) { CFloatToString(value, pNumBuffer, sizeof(cNumBuffer)); CDrawPageLine(row, label, pNumBuffer, unitStr); } static void CDrawPageLineInt(Uint16 row, const int8* label, int32 value, const int8* unitStr) { CDecToString((int16)value, pNumBuffer, sizeof(cNumBuffer)); CDrawPageLine(row, label, pNumBuffer, unitStr); } static void CDrawTwoStatusLine(Uint16 row, const int8* label1, Uint16 status1, const int8* label2, Uint16 status2) { Uint16 drawY = 0U; const int8* statusStr1 = (status1 == 1U) ? (const int8*)"1" : (const int8*)"0"; const int8* statusStr2 = (status2 == 1U) ? (const int8*)"1" : (const int8*)"0"; switch(row) { case OLED_ROW_1: drawY = OLED_LINE_1; break; case OLED_ROW_2: drawY = OLED_LINE_2; break; case OLED_ROW_3: drawY = OLED_LINE_3; break; case OLED_ROW_4: drawY = OLED_LINE_4; break; default: return; } // Label 1 CStrncpy(OledOperValue.cStrBuff[row], label1, CStrLen(label1)); // Status 1 CStrncat(OledOperValue.cStrBuff[row], statusStr1, CStrLen(statusStr1)); // Spacing CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 7U); // Label 2 CStrncat(OledOperValue.cStrBuff[row], label2, CStrLen(label2)); // Status 2 CStrncat(OledOperValue.cStrBuff[row], statusStr2, CStrLen(statusStr2)); CDrawStr(0U, drawY, OledOperValue.cStrBuff[row], CStrLen(OledOperValue.cStrBuff[row])); } static void CPageApu1(void) { const int8 *cTemp = ""; float32 fTemp; // TITLE CDrawPageTitle("APU Status", "1/2"); // LINE 1 fTemp = Rx220.GcuData.DcVoltage; CDrawPageLineFloat(OLED_ROW_1, "DC Voltage ", fTemp, " V"); // LINE 2 fTemp = Rx220.GcuData.DcCurrent; CDrawPageLineFloat(OLED_ROW_2, "DC Current ", fTemp, " A"); // LINE 3 fTemp = (Rx220.GcuData.DcVoltage * Rx220.GcuData.DcCurrent); CDrawPageLineFloat(OLED_ROW_3, "Power ", fTemp, " kW"); // LINE 4 cTemp = CGetApuStateString((eApuOperIdx)GeneralOperValue.uiApuState); CStrncpy(OledOperValue.cStrBuff[OLED_ROW_4], "Status", CStrLen((const int8*)"Status")); CAddLineIndent(OledOperValue.cStrBuff[OLED_ROW_4], cTemp); CStrncat(OledOperValue.cStrBuff[OLED_ROW_4], cTemp, CStrLen(cTemp)); CDrawStr(0U, OLED_LINE_4, OledOperValue.cStrBuff[OLED_ROW_4], CStrLen(OledOperValue.cStrBuff[OLED_ROW_4])); } static void CPageApu2(void) { int16 iTemp; // TITLE CDrawPageTitle("APU Status", "2/2"); // LINE 1 iTemp = CGetEngineActualRpm(); CDrawPageLineInt(OLED_ROW_1, "ENG.RPM ", (int32)iTemp, " rpm"); // LINE 2 iTemp = CGetEngCoolantTemperature(); CDrawPageLineInt(OLED_ROW_2, "Coolant ", (int32)iTemp, " ¡É"); // LINE 3 iTemp = Rx320.EcuData.ActualTorque; CDrawPageLineInt(OLED_ROW_3, "Torque ", (int32)iTemp, " %"); // LINE 4 CHourToString((int32)GeneralOperValue.ulTotalOperationHour, pNumBuffer); CDrawPageLine(OLED_ROW_4, "ENG.Hour ", pNumBuffer, " Hr"); } static void CPageMenu1(void) { // TITLE CDrawPageTitle("Menu", "1/2"); // LINE 1 CLineFocus((OledOperValue.uiFocusLine == 0U) ? 1U : 0U); CDrawPageLine(OLED_ROW_1, "1. APU Status ", NULL, NULL); // LINE 2 CLineFocus((OledOperValue.uiFocusLine == 1U) ? 1U : 0U); CDrawPageLine(OLED_ROW_2, "2. Temperature ", NULL, NULL); // LINE 3 CLineFocus((OledOperValue.uiFocusLine == 2U) ? 1U : 0U); CDrawPageLine(OLED_ROW_3, "3. Sensor ", NULL, NULL); // LINE 4 CLineFocus((OledOperValue.uiFocusLine == 3U) ? 1U : 0U); CDrawPageLine(OLED_ROW_4, "4. Warning ", NULL, NULL); } static void CPageMenu2(void) { // TITLE CDrawPageTitle("Menu", "2/2"); // LINE 1 CLineFocus((OledOperValue.uiFocusLine == 0U) ? 1U : 0U); CDrawPageLine(OLED_ROW_1, "5. Fault ", NULL, NULL); // LINE 2 CLineFocus((OledOperValue.uiFocusLine == 1U) ? 1U : 0U); CDrawPageLine(OLED_ROW_2, "6. Alarm Reset ", NULL, NULL); // LINE 3 CLineFocus((OledOperValue.uiFocusLine == 2U) ? 1U : 0U); CDrawPageLine(OLED_ROW_3, "7. Maintenence ", NULL, NULL); } static void CPageTemp(void) { int16 iTemp; // TITLE CDrawPageTitle("Temperature", "1/1"); // LINE 1 iTemp = Rx221.GcuData.PcbTemperature - 40; CDrawPageLineInt(OLED_ROW_1, "PCB Temp. ", (int32)iTemp, " ¡É"); // LINE 2 iTemp = Rx221.GcuData.FetTemperature - 40; CDrawPageLineInt(OLED_ROW_2, "FET Temp. ", (int32)iTemp, " ¡É"); // LINE 3 iTemp = Rx221.GcuData.GenTemperature1 - 40; CDrawPageLineInt(OLED_ROW_3, "Gen.Temp1. ", (int32)iTemp, " ¡É"); // LINE4 iTemp = Rx221.GcuData.GenTemperature2 - 40; CDrawPageLineInt(OLED_ROW_4, "Gen.Temp2. ", (int32)iTemp, " ¡É"); } static void CPageSensor1(void) { float32 fTemp; // TITLE CDrawPageTitle("Apu Sensor", "1/4"); // LINE 1 fTemp = (Adc_EngineHeater_I.fLpfValue < 0.0f) ? 0.0f : Adc_EngineHeater_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_1, "EngineHeater", fTemp, " A"); // LINE 2 fTemp = (Adc_GlowPlug_I.fLpfValue < 0.0f) ? 0.0f : Adc_GlowPlug_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_2, "GlowPlug ", fTemp, " A"); // LINE 3 fTemp = (Adc_Solenoid_I.fLpfValue < 0.0f) ? 0.0f : Adc_Solenoid_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_3, "Solenoid ", fTemp, " A"); // LINE 4 fTemp = (Adc_FuelPump_I.fLpfValue < 0.0f) ? 0.0f : Adc_FuelPump_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_4, "FuelPump ", fTemp, " A"); } static void CPageSensor2(void) { float32 fTemp; // TITLE CDrawPageTitle("Apu Sensor", "2/4"); // LINE 1 fTemp = (Adc_CoolantPump_I.fLpfValue < 0.0f) ? 0.0f : Adc_CoolantPump_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_1, "CoolantPump ", fTemp, " A"); // LINE 2 fTemp = (Adc_Fan1_I.fLpfValue < 0.0f) ? 0.0f : Adc_Fan1_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_2, "Fan1 ", fTemp, " A"); // LINE 3 fTemp = (Adc_Fan2_I.fLpfValue < 0.0f) ? 0.0f : Adc_Fan2_I.fLpfValue; CDrawPageLineFloat(OLED_ROW_3, "Fan2 ", fTemp, " A"); } static void CPageSensor3(void) { int16 iTemp; // TITLE CDrawPageTitle("ECU Sensor", "3/4"); // LINE 1 iTemp = Rx321.EcuData.BarometicPressure; CDrawPageLineInt(OLED_ROW_1, "Barometric ", (int32)iTemp, " mb"); // LINE 2 iTemp = Rx321.EcuData.Fan1Speed; CDrawPageLineInt(OLED_ROW_2, "Fan1 Speed ", (int32)iTemp, " %"); // LINE 3 iTemp = Rx321.EcuData.Fan2Speed; CDrawPageLineInt(OLED_ROW_3, "Fan2 Speed ", (int32)iTemp, " %"); // LINE 4 iTemp = Rx321.EcuData.CoolantPumpSpeed; CDrawPageLineInt(OLED_ROW_4, "C.Pump Speed ", (int32)iTemp, " %"); } static void CPageSensor4(void) { int16 iTemp; // TITLE CDrawPageTitle("GCU Sensor", "4/4"); // LINE 1 iTemp = Rx220.GcuData.Rpm; CDrawPageLineInt(OLED_ROW_1, "GEN.RPM ", (int32)iTemp, " rpm"); } static void CDrawPageLineStatus(Uint16 row, const int8* label, Uint16 status) { const int8* statusStr = (status == 1U) ? (const int8*)"1" : (const int8*)"0"; CDrawPageLine(row, label, statusStr, NULL); } static void CPageWarning1(void) { // TITLE CDrawPageTitle("Warning", "1/2"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "PCBOT:", Rx210.GcuWarning.bit.PcbOverHeat, "FETOT:", Rx210.GcuWarning.bit.FetOverHeat); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "GEOT1:", Rx210.GcuWarning.bit.GenOverHeat1, "GEOT2:", Rx210.GcuWarning.bit.GenOverHeat2); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "ENGOT:", Rx310.EcuWarning.bit.EngineOverHeat, "L-OIL:", Rx310.EcuWarning.bit.LowOilLevel); // LINE 4 CDrawTwoStatusLine(OLED_ROW_4, "INTOT:", Rx310.EcuWarning.bit.IntakeOverHeat, "INTLP:", Rx310.EcuWarning.bit.IntakeLoPressure); } static void CPageWarning2(void) { // TITLE CDrawPageTitle("Warning", "2/2"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "ENGLT:", Rx310.EcuWarning.bit.EngineLoTemperature, "ENGSF:", Rx310.EcuWarning.bit.EngineSensor); // LINE 2 CDrawPageLineStatus(OLED_ROW_2, "DEFAC:", Rx310.EcuWarning.bit.DefaltValueActive); } static void CPageFault1(void) { // TITLE CDrawPageTitle("Apu Fault", "1/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "CARCT:", FaultBitValue.bit.CarCommTimeout, "GCUCT:", FaultBitValue.bit.GcuCommTimeout); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "ECUCT:", FaultBitValue.bit.EcuCommTimeOut, "RPMER:", FaultBitValue.bit.RpmError); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "EHLOC:", FaultBitValue.bit.EngineHeatOverCurrent, "GPLOC:", FaultBitValue.bit.GlowPlugOverCurrent); // LINE 4 CDrawTwoStatusLine(OLED_ROW_4, "SOLOC:", FaultBitValue.bit.SolenoidOverCurrent, "FPLOC:", FaultBitValue.bit.FuelPumpOverCurrent); } static void CPageFault2(void) { // TITLE CDrawPageTitle("Apu Fault", "2/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "CPLOC:", FaultBitValue.bit.CoolantPumpOverCurrent, "F1LOC:", FaultBitValue.bit.Fan1OverCurrent); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "F2LOC:", FaultBitValue.bit.Fan2OverCurrent, "EHLLO:", FaultBitValue.bit.EngineHeatOpen); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "GPLLO:", FaultBitValue.bit.GlowPlugOpen, "SOLLO:", FaultBitValue.bit.SolenoidOpen); // LINE 4 CDrawTwoStatusLine(OLED_ROW_4, "FPLLO:", FaultBitValue.bit.FuelPumpOpen, "CPLLO:", FaultBitValue.bit.CoolantPumpOpen); } static void CPageFault3(void) { // TITLE CDrawPageTitle("Apu Fault", "3/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "F1LLO:", FaultBitValue.bit.Fan1Open, "F2LLO:", FaultBitValue.bit.Fan2Open); } static void CPageFault4(void) { // TITLE CDrawPageTitle("Gcu Fault", "4/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "HTRIP:", Rx210.GcuFault.bit.HwTrip, "HIGBT:", Rx210.GcuFault.bit.HwIgbt); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "HDCOV:", Rx210.GcuFault.bit.HwDc, "GNOCU:", Rx210.GcuFault.bit.GenOverCurrentU); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "GNOCV:", Rx210.GcuFault.bit.GenOverCurrentV, "GNOCW:", Rx210.GcuFault.bit.GenOverCurrentW); // LINE 4 CDrawTwoStatusLine(OLED_ROW_4, "SDCOV:", Rx210.GcuFault.bit.DcOverVoltage, "SDCOC:", Rx210.GcuFault.bit.DcOverCurrent); } static void CPageFault5(void) { // TITLE CDrawPageTitle("Gcu Fault", "5/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "SMOOC:", Rx210.GcuFault.bit.CrankningOverCurrent, "PCBOT:", Rx210.GcuFault.bit.PcbOverHeat); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "FETOT:", Rx210.GcuFault.bit.FetOverHeat, "GW1OT:", Rx210.GcuFault.bit.GenTempOverHeat1); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "GW2OT:", Rx210.GcuFault.bit.GenTempOverHeat2, "GENOS:", Rx210.GcuFault.bit.GenOverSpeed); // LINE 4 CDrawTwoStatusLine(OLED_ROW_4, "RSICF:", Rx210.GcuFault.bit.ResolverIC, "RSPRT:", Rx210.GcuFault.bit.ResolverParity); } static void CPageFault6(void) { // TITLE CDrawPageTitle("Ecu Fault", "6/6"); // LINE 1 CDrawTwoStatusLine(OLED_ROW_1, "OILMS:", Rx310.EcuFault.bit.OilPressureMissing, "INTOT:", Rx310.EcuFault.bit.IntakeOverHeat); // LINE 2 CDrawTwoStatusLine(OLED_ROW_2, "ENGOT:", Rx310.EcuFault.bit.EngineOverHeat, "ACTUA:", Rx310.EcuFault.bit.Actuator); // LINE 3 CDrawTwoStatusLine(OLED_ROW_3, "RPMSG:", Rx310.EcuFault.bit.RpmSignal, "ENGSF:", Rx310.EcuFault.bit.EngineStartFail); } static void CDrawAlarmBox(void) { CDrawLine(5U, 10U, 122U, 10U); // Top CDrawLine(5U, 10U, 5U, 58U); // Left CDrawLine(5U, 59U, 122U, 59U); // Bottom CDrawLine(122U, 10U, 122U, 58U); // Right } static void CDrawPostStatusLine(Uint16 row, const int8* l1, Uint16 s1, const int8* l2, Uint16 s2, const int8* l3, Uint16 s3) { const int8* s1Str = (s1 == 0U) ? (const int8*)"P" : (const int8*)"F"; Uint16 y = 0U; // Label 1 + Status 1 CStrncpy(OledOperValue.cStrBuff[row], l1, CStrLen(l1)); CStrncat(OledOperValue.cStrBuff[row], s1Str, 1U); // Label 2 + Status 2 if (l2 != NULL) { CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 2U); CStrncat(OledOperValue.cStrBuff[row], l2, CStrLen(l2)); CStrncat(OledOperValue.cStrBuff[row], (s2 == 0U) ? (const int8*)"P" : (const int8*)"F", 1U); } // Label 3 + Status 3 if (l3 != NULL) { CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 2U); CStrncat(OledOperValue.cStrBuff[row], l3, 13U); CStrncat(OledOperValue.cStrBuff[row], (s3 == 0U) ? (const int8*)"P" : (const int8*)"F", 1U); } CTextAlign(OledOperValue.cAlignBuffer, OledOperValue.cStrBuff[row]); switch(row) { case OLED_ROW_2: y = OLED_LINE_2; break; case OLED_ROW_3: y = OLED_LINE_3; break; case OLED_ROW_4: y = OLED_LINE_4; break; default: break; } CDrawStr(0U, y, OledOperValue.cAlignBuffer, CStrLen(OledOperValue.cAlignBuffer)); } static void CPageAlarmReset(void) { const int8 *cTemp = ""; // LINE 1 CDrawCenteredLine(OLED_LINE_1, "Reset all faults?"); // LINE 2 CDrawCenteredLine(OLED_LINE_2, "(no clear warnings)"); // LINE 3 cTemp = (OledOperValue.uiResetAnswer == 1U) ? (int8*)"YES" : (int8*)" NO"; CDrawCenteredLine(OLED_LINE_3 + 5U, cTemp); // BOX CDrawAlarmBox(); } static void CPagePassword(void) { const int8 *cTemp = ""; int8 maskBuffer[16]; int16 iTemp[2] = { 0, '\0' }; // TITLE CDrawPageTitle("Input Password", NULL); switch (OledOperValue.uiFocusDigit) { case OLED_PASS_DIGIT_1: { iTemp[0] = GeneralOperValue.uiPassword[OLED_PASS_DIGIT_1] + '0'; cTemp = (int8*)iTemp; CStrncpy(maskBuffer, "[", 2); CStrncat(maskBuffer, cTemp, 1); CStrncat(maskBuffer, "][*][*][*]", 10); break; } case OLED_PASS_DIGIT_2: { iTemp[0] = GeneralOperValue.uiPassword[OLED_PASS_DIGIT_2] + '0'; cTemp = (int8*)iTemp; CStrncpy(maskBuffer, "[*][", 4); CStrncat(maskBuffer, cTemp, 1); CStrncat(maskBuffer, "][*][*]", 7); break; } case OLED_PASS_DIGIT_3: { iTemp[0] = GeneralOperValue.uiPassword[OLED_PASS_DIGIT_3] + '0'; cTemp = (int8*)iTemp; CStrncpy(maskBuffer, "[*][*][", 7); CStrncat(maskBuffer, cTemp, 1); CStrncat(maskBuffer, "][*]", 4); break; } default: { iTemp[0] = GeneralOperValue.uiPassword[OLED_PASS_DIGIT_4] + '0'; cTemp = (int8*)iTemp; CStrncpy(maskBuffer, "[*][*][*][", 10); CStrncat(maskBuffer, cTemp, 1); CStrncat(maskBuffer, "]", 1); break; } } CTextAlign(OledOperValue.cAlignBuffer, maskBuffer); CDrawStr(0U, OLED_LINE_2, OledOperValue.cAlignBuffer, CStrLen(OledOperValue.cAlignBuffer)); } static void CPageMaintenence(void) { const int8 *cTemp = ""; // TITLE CDrawPageTitle("Maintenence", "1/1"); // LINE 1 CLineFocus((OledOperValue.uiFocusLine == OLED_LINE_FOCUS_1) ? 1U : 0U); cTemp = (GeneralOperValue.Maintenence.ManualCranking > 0U) ? (int8*)"ON " : (int8*)"OFF"; CDrawPageLine(OLED_ROW_1, "Manual Cranking ", cTemp, NULL); // LINE 2 CLineFocus((OledOperValue.uiFocusLine == OLED_LINE_FOCUS_2) ? 1U : 0U); cTemp = (GeneralOperValue.Maintenence.LampTest > 0U) ? (int8*)"ON " : (int8*)"OFF"; CDrawPageLine(OLED_ROW_2, "Lamp Test ", cTemp, NULL); // LINE 3 CLineFocus((OledOperValue.uiFocusLine == OLED_LINE_FOCUS_3) ? 1U : 0U); CDrawPageLine(OLED_ROW_3, "Switch Test ", NULL, NULL); } static void CDrawCenteredLine(Uint16 y, const int8* text) { CStrncpy(OledOperValue.cStrBuff[OLED_ROW_0], text, CStrLen(text)); CTextAlign(OledOperValue.cAlignBuffer, OledOperValue.cStrBuff[OLED_ROW_0]); CDrawStr(0U, y, OledOperValue.cAlignBuffer, CStrLen(OledOperValue.cAlignBuffer)); } static void CDrawKeyTestBox(void) { CDrawLine(0U, 0U, 125U, 0U); // Top CDrawLine(0U, 0U, 0U, 22U); // Left CDrawLine(0U, 23U, 2U, 25U); // Left diag CDrawLine(3U, 25U, 123U, 25U); // Bottom CDrawLine(124U, 25U, 126U, 23U); // Right diag CDrawLine(126U, 0U, 126U, 22U); // Right } static void CDrawKeyStatusLine(Uint16 row, const int8* l1, Uint16 s1, const int8* l2, Uint16 s2, const int8* l3, Uint16 s3) { const int8* s1Str = (s1 == 1U) ? (const int8*)"1" : (const int8*)"0"; // Label 1 + Status 1 CStrncpy(OledOperValue.cStrBuff[row], l1, CStrLen(l1)); CStrncat(OledOperValue.cStrBuff[row], s1Str, 1U); // Label 2 + Status 2 if (l2 != NULL) { CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 1U); CStrncat(OledOperValue.cStrBuff[row], l2, CStrLen(l2)); CStrncat(OledOperValue.cStrBuff[row], (s2 == 1U) ? (const int8*)"1" : (const int8*)"0", 1U); } // Label 3 + Status 3 if (l3 != NULL) { CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 1U); CStrncat(OledOperValue.cStrBuff[row], l3, CStrLen(l3)); CStrncat(OledOperValue.cStrBuff[row], (s3 == 1U) ? (const int8*)"1" : (const int8*)"0", 1U); } // Determine Y based on row Uint16 y = 0U; switch(row) { case OLED_ROW_2: y = OLED_LINE_2; break; case OLED_ROW_3: y = OLED_LINE_3; break; case OLED_ROW_4: y = OLED_LINE_4; break; default: break; } CDrawStr(0U, y, OledOperValue.cStrBuff[row], CStrLen(OledOperValue.cStrBuff[row])); } static void CPageKeyTest(void) { // TITLE1 CDrawCenteredLine(OLED_LINE_TITLE + 2U, "Key input Test"); // TITLE2 CDrawCenteredLine(OLED_LINE_1 - 1U, "(Back to Up&Down)"); // BOX CDrawKeyTestBox(); // LINE 2 // " Stat:" + Status // This is special indentation. // I can reuse CDrawKeyStatusLine if I pass proper label. // " Stat:" is 19 chars. CDrawKeyStatusLine(OLED_ROW_2, " Stat:", GPIO_KEY_START(), NULL, 0, NULL, 0); // LINE 3 // " Up:" + s + " " + "Entr:" + s + " " + "Powr:" + s CDrawKeyStatusLine(OLED_ROW_3, " Up:", GPIO_KEY_UP(), "Entr:", GPIO_KEY_ENTER(), "Powr:", GPIO_KEY_POWER()); // LINE 4 // "Down:" + s + " " + "Menu:" + s + " " + "Emgc:" + s CDrawKeyStatusLine(OLED_ROW_4, "Down:", GPIO_KEY_DOWN(), "Menu:", GPIO_KEY_MENU(), "Emgc:", GPIO_KEY_EMERGENCY()); } static void CPageShutdown(void) { // LINE 1 CDrawCenteredLine(OLED_LINE_1, "System"); // LINE 2 CDrawCenteredLine(OLED_LINE_2, "Shutting down..."); } void CSetPage(Uint16 PageNum) { int16 i; if (OledOperValue.uiOldPageNum != PageNum) { COledBufferReset(); OledOperValue.uiOldPageNum = PageNum; } for (i = 0; i < OLED_PAGE_MAX; i++) { if (OledOperValue.uiPageNum == i) { CLineFocus(0U); PageTable[i].pAction(); // CPageHandler ÂüÁ¶ } } } void COledBufferReset(void) { (void) memset(OledOperValue.uiBuff, 0, sizeof(int8) * OLED_WIDTH * OLED_PAGE); (void) memset(OledOperValue.cStrBuff, 0, sizeof(int8) * TXT_LINE_LEN * TXT_MAX_LEN); } static void CDrawTitleBox(Uint16 TitleLen) { CDrawLine(8U, 0U, 8U, 9U); // ¿ÞÂÊ CDrawLine(8U, 10U, 10U, 12U); // ¿ÞÂÊ ¸ð¼­¸® CDrawLine(11U, 12U, (TitleLen + 9U), 12U); // ¾Æ·¡ÂÊ CDrawLine((TitleLen + 10U), 12U, (TitleLen + 12U), 10U); // ¿À¸¥ÂÊ ¸ð¼­¸® CDrawLine((TitleLen + 12U), 0U, (TitleLen + 12U), 9U); // ¿À¸¥ÂÊ if (OledOperValue.uiPageNum != OLED_PAGE_PASSWORD) { // ¼­ºê ŸÀÌÆ² ¹Ú½º CDrawLine(98U, 0U, 98U, 9U); // ¿ÞÂÊ CDrawLine(98U, 10U, 100U, 12U); // ¿ÞÂÊ ¸ð¼­¸® CDrawLine(101U, 12U, 118U, 12U); // ¾Æ·¡ÂÊ CDrawLine(119U, 12U, 121U, 10U); // ¿À¸¥ÂÊ ¸ð¼­¸® CDrawLine(121U, 0U, 121U, 9U); // ¿À¸¥ÂÊ } } void COledReflash(Uint16 x, Uint16 y, Uint16 width, Uint16 height) { Uint16 i, j; for (j = y / 8; j < (y + height) / 8; j++) { for (i = x; i < (x + width); i++) { CSetPageAddress(j); CSetColumnAddress(i); COledWrite(OledOperValue.uiBuff[i][j], MODE_DATA); } } } void CInitOled(void) { Uint16 uiPageNum; int16 i; CInitOledModule(); for(uiPageNum = 0; uiPageNum < 8; uiPageNum++) { COledWrite((Uint16)(0xB0 | uiPageNum), MODE_COMMAND); for(i = 0; i < OLED_WIDTH; i++) { COledWrite(0x00, MODE_DATA); } } CInitProgress(); } void CInitProgress(void) { OledOperValue.Color.TxtColor = 1U; CTextAlign(OledOperValue.cAlignBuffer, "K2 APU"); CDrawStr(0, OLED_LINE_TITLE, OledOperValue.cAlignBuffer, CStrLen(OledOperValue.cAlignBuffer)); CDrawBox(OLED_LOAD_PROGRESS_X, OLED_LOAD_PROGRESS_Y, OLED_LOAD_PROGRESS_W, OLED_LOAD_PROGRESS_H); (void) memset(OledOperValue.cAlignBuffer, 0, sizeof(char) * TXT_MAX_LEN); CTextAlign(OledOperValue.cAlignBuffer, "Initializing System"); CDrawStr(0, OLED_LINE_2, OledOperValue.cAlignBuffer, CStrLen(OledOperValue.cAlignBuffer)); } void CAddLineIndent(int8 *buffer, const int8 *str) { Uint16 i; Uint16 uiSpaceNeeded = (TXT_MAX_LEN - 1) - CStrLen(buffer) - CStrLen(str); if (uiSpaceNeeded > 0) { for (i = 0U; i < uiSpaceNeeded; i++) { CStrncat(buffer, " ", 1); } } } void CTextAlign(int8 *buffer, const int8 *str) { Uint16 uiIndent, uiLen, i, j; uiLen = 0; i = 0; while (str[i] != '\0') // strÀº int8* À̹ǷÎ, int8 ŸÀÔÀÇ ³Î Á¾·á °ª(0) ãÀ½ { uiLen++; i++; } if (uiLen >= TXT_MAX_LEN) { uiIndent = 0; } else { uiIndent = ((TXT_MAX_LEN - 1U) - uiLen) / 2U; } if ((uiIndent > 0U) && (uiIndent < TXT_MAX_LEN)) // ¸®¼Ò½º °úµµ ¼Òºñ ¹æÁö { for (i = 0U; i < uiIndent; i++) { buffer[i] = (int8)' '; } for (j = 0U; j < uiLen; j++) { buffer[i + j] = str[j]; } } buffer[i + uiLen] = 0; } void CDrawBox(Uint16 x, Uint16 y, Uint16 w, Uint16 h) { CDrawLine(x, y, w, y); // À­º¯ CDrawLine(x, (y + 1U), x, (y + h)); // ÁÂÃø ¸·´ë CDrawLine(x, (y + h), w, (y + h)); // ¾Æ·§ º¯ CDrawLine(w, (y + 1U), w, (y + h - 1U)); // ¿ìÃø ¸·´ë } void CSetDrawRegion(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2) { if (x2 > OledOperValue.Point.X2) { OledOperValue.Point.X2 = x2; } if (y2 > OledOperValue.Point.Y2) { OledOperValue.Point.Y2 = y2; } } void CDrawLine(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2) { Uint16 tmp = 0, x = 0, y = 0, dx = 0, dy = 0, swapxy = 0; Uint16 loop_end = 0; Uint16 minor_limit = 0; // º¸Á¶Ãà(y) ÇѰ谪 int16 err = 0, ystep = 0; dx = x2 - x1; dy = (y1 > y2) ? (y1 - y2) : (y2 - y1); if (dy > dx) { swapxy = 1; tmp = dx; dx = dy; dy = tmp; tmp = x1; x1 = y1; y1 = tmp; tmp = x2; x2 = y2; y2 = tmp; loop_end = OLED_HEIGHT - 1; minor_limit = OLED_WIDTH - 1; } else { loop_end = OLED_WIDTH - 1; minor_limit = OLED_HEIGHT - 1; } if (x2 > loop_end) { x2 = loop_end; } err = dx >> 1; ystep = (y2 > y1) ? 1 : -1; y = y1; if (swapxy == 0) { for(x = x1; x <= x2; x++) { if (y > minor_limit) break; CPutPixel(x, y, OledOperValue.Color.TxtColor); err -= (Uint16) dy; if ( err < 0 ) { y += (Uint16) ystep; err += (Uint16) dx; } } } else { for(x = x1; x <= x2; x++) { if (y > minor_limit) break; CPutPixel(y, x, OledOperValue.Color.TxtColor); err -= (Uint16) dy; if ( err < 0 ) { y += (Uint16) ystep; err += (Uint16) dx; } } } } static inline void CPutPixel(Uint16 x, Uint16 y, Uint16 Color) { Uint16 uiPage = y / 8U; Uint16 uiOffset = y % 8U; if (x >= OLED_WIDTH || y >= OLED_HEIGHT) { x = OLED_WIDTH; y = OLED_HEIGHT; } else { if (x < OLED_WIDTH) { if (Color) { OledOperValue.uiBuff[x][uiPage] |= (0x01U << uiOffset); } else { OledOperValue.uiBuff[x][uiPage] &= (Uint16) ~(0x01U << uiOffset); } } } } void CSetPageAddress(Uint16 Address) { COledWrite((Uint16)(Address | 0xB0), MODE_COMMAND); } void CSetColumnAddress(Uint16 x) { Uint16 HighAddress; Uint16 LowAddress; x += 0; // ER_OLEDM024-1G is +2, ER_OLEDM024-2G is +0 HighAddress = ((x >> 4) & 0x0F) | 0x10; LowAddress = x & 0x0F; COledWrite(LowAddress, MODE_COMMAND); COledWrite(HighAddress, MODE_COMMAND); } void CInitXintf(void) { /* for All Zones Timing for all zones based on XTIMCLK = SYSCLKOUT (150MHz) */ EALLOW; XintfRegs.XINTCNF2.bit.XTIMCLK = 1; XintfRegs.XINTCNF2.bit.WRBUFF = 0; /* No write buffering */ XintfRegs.XINTCNF2.bit.CLKOFF = 0; /* XCLKOUT is enabled */ XintfRegs.XINTCNF2.bit.CLKMODE = 1; /* XCLKOUT = XTIMCLK */ /* Zone write timing */ XintfRegs.XTIMING6.bit.XWRLEAD = 1; XintfRegs.XTIMING6.bit.XWRACTIVE = 13; XintfRegs.XTIMING6.bit.XWRTRAIL = 1; /* Zone read timing */ XintfRegs.XTIMING6.bit.XRDLEAD = 1; XintfRegs.XTIMING6.bit.XRDACTIVE = 13; XintfRegs.XTIMING6.bit.XRDTRAIL = 1; XintfRegs.XTIMING6.bit.X2TIMING = 1; XintfRegs.XTIMING6.bit.USEREADY = 1; XintfRegs.XTIMING6.bit.READYMODE = 1; XintfRegs.XTIMING6.bit.XSIZE = 3; GpioCtrlRegs.GPCMUX1.bit.GPIO79 = 3; // OLED_D0 XD0 GpioCtrlRegs.GPCMUX1.bit.GPIO78 = 3; // OLED_D1 XD1 GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 3; // OLED_D2 XD2 GpioCtrlRegs.GPCMUX1.bit.GPIO76 = 3; // OLED_D3 XD3 GpioCtrlRegs.GPCMUX1.bit.GPIO75 = 3; // OLED_D4 XD4 GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 3; // OLED_D5 XD5 GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 3; // OLED_D6 XD6 GpioCtrlRegs.GPCMUX1.bit.GPIO72 = 3; // OLED_D7 XD7 GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 3; // OLED_CS_C XZCS6 GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 3; // OLED_WR_C XWE0 GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 3; // OLED_A0_C XWE1 EDIS; } void CDrawStr(Uint16 x, Uint16 y, int8* str, Uint16 len) { Uint16 i; if ((len > 0U) && (len < TXT_MAX_LEN)) // ¸®¼Ò½º °úµµ ¼Òºñ ¹æÁö { for(i = 0; i < len; i++) { if (str[i] & 0x80) { CDrawChar(x, y, (Uint16)((str[i] << 8) | str[i + 1]), TXT_TYPE_ETC); i++; x += TXT_ENG_WIDTH * 2U; } else { CDrawChar(x, y, (Uint16)str[i], TXT_TYPE_ENG); x += TXT_ENG_WIDTH; } } } } void CDrawChar(Uint16 x, Uint16 y, Uint16 ch, Uint16 type) { const Uint16* pFontData; Uint16 uiFontIndex = 0; Uint16 i, j; Uint16 uiCharWidth; if (type == 0) // Eng Char { uiCharWidth = TXT_ENG_WIDTH; ch -= 0x20U; // font offset pFontData = EngFontTable[ch]; } else { uiCharWidth = TXT_ENG_WIDTH * 2U; ch = (ch == 0xA1C9U) ? 0x00U : ch; pFontData = EtcFontTable[ch]; } CSetDrawRegion(x, y, (x + TXT_ENG_WIDTH), (y + TXT_ENG_HEIGHT)); for(j = 0; j < TXT_ENG_HEIGHT; j++) { for(i = 0; i < uiCharWidth; i++) { if (pFontData[uiFontIndex / 8] & uiBitMask[uiFontIndex % 8]) { CPutPixel((x + i), (y + j), OledOperValue.Color.TxtColor); } else { CPutPixel((x + i), (y + j), OledOperValue.Color.BgColor); } uiFontIndex++; } } } void CInitOledModule(void) { GPIO_OLED_RESET(1U); DELAY_US(2000L); GPIO_OLED_RESET(0U); DELAY_US(2000L); GPIO_OLED_RESET(1U); DELAY_US(2000L); COledWrite(0xFD, MODE_COMMAND); // Command Lock COledWrite(0x12, MODE_COMMAND); // COledWrite(0xAE, MODE_COMMAND); // oled off COledWrite(0xA1, MODE_COMMAND); // 1U segment column address high to low COledWrite(0xC8, MODE_COMMAND); // COM output scan from high to low COledWrite(0x81, MODE_COMMAND); // 1U contrast COledWrite(0xFF, MODE_COMMAND); COledWrite(0xAF, MODE_COMMAND); // oled on CInitOledStructure(); OledOperValue.uiProgressValue = OLED_LOAD_PROGRESS_X + 1; } void COledWrite(Uint16 Data, Uint16 Command) { if (Command == MODE_COMMAND) { CommandBus = Data; } else { DataBus = Data; } } void CInitOledStructure(void) { (void) memset(&OledOperValue, 0, sizeof(COledOperValue)); OledOperValue.uiResetAnswer = 1U; } void CInitKeyOperValue(void) { (void) memset(&KeyOperValue, 0, sizeof(CKeyOperValue)); } Uint16 CStrLen(const int8 *s) { // ¿øº» Æ÷ÀÎÅÍÀÇ ½ÃÀÛ ÁÖ¼Ò¸¦ ÀúÀåÇÕ´Ï´Ù. const int8 *p = s; // Æ÷ÀÎÅͰ¡ ³Î Á¾·á ¹®ÀÚ('\0', Áï ASCII 0)¸¦ °¡¸®Å°Áö ¾ÊÀ» ¶§±îÁö Æ÷ÀÎÅ͸¦ Áõ°¡½Ãŵ´Ï´Ù. // ¹®ÀÚ¿­Àº ¿¬¼ÓµÈ ¸Þ¸ð¸® °ø°£¿¡ ÀúÀåµÇ¾î ÀÖ½À´Ï´Ù. while (*p != '\0') { p++; } // ÃÖÁ¾ ÁÖ¼Ò(³Î ¹®ÀÚ ´ÙÀ½)¿Í ½ÃÀÛ ÁÖ¼ÒÀÇ Â÷À̰¡ ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ µË´Ï´Ù. return (Uint16)(p - s); } static void CStrncpy(int8 *pTarget, const int8 *pSource, Uint16 Size) { Uint16 i; for (i = 0; i < Size; i++) { pTarget[i] = pSource[i]; } pTarget[i] = '\0'; } void CStrncat(int8 *pTarget, const int8 *pSource, Uint16 Size) { Uint16 i; Uint16 uiTargetSize; uiTargetSize = (Uint16)CStrLen(pTarget); if ((uiTargetSize + Size) < TXT_MAX_LEN) { for (i = 0; i < Size; i++) { pTarget[uiTargetSize + i] = pSource[i]; } pTarget[uiTargetSize + i] = '\0'; } } void CDecToString(int16 Data, int8 *Array, Uint16 ArrayLen) { Uint16 uiSign = 0U, uiSignLocate = 0U, i; Uint16 x, y; int32 lData = (int32) Data * 10; int8 cTmp[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; for (i = 0; i < ArrayLen; i++) { Array[i] = ' '; } if (lData < 0) { // Ç¥½ÃÇÒ ¼ýÀÚ°¡ À½¼öÀÎ °æ¿ì uiSign = 1U; lData = -lData; } while (lData > 0U) { cTmp[x++] = (lData % 10) + '0'; lData /= 10U; } if (x == 0) // ¼öÄ¡°¡ 0ÀÇ °æ¿ì. { y = 3U; Array[y++] = '0'; } else { y = 5 - x; // Ãâ·Â µÇ´Â ¹®ÀÚÀÇ Á¤·ÄÀ» À§ÇÔ. x = x - 1; // ¸¶Áö¸·À¸·Î ÀúÀåµÈ ¹öÆÛ À妽ºÀÇ °ªÀº »©ÁÜ. if (y < 1) { uiSignLocate = 0U; } else { if ((y >= 1) && (y <= 5)) { uiSignLocate = (Uint16)(y - 1); // '-' ºÎÈ£¸¦ Ç¥½ÃÇÒ ÀÚ¸® } } if (uiSign == 1U) // '-' ºÎÈ£ Ç¥½Ã À§Ä¡ ÁöÁ¤Çϱâ À§ÇÔ. { if ((uiSignLocate > 0U) && (uiSignLocate < 6U)) { Array[uiSignLocate] = '-'; } } else { Array[uiSignLocate] = ' '; } while (x > 0) { Array[y++] = cTmp[x--]; } } Array[y] = '\0'; // End of string. } static void CFloatToString(float32 Data, int8 *Array, Uint16 ArrayLen) { Uint16 x = 0U, y = 0U, i; int16 iTemp = (int16)(Data * 10); int8 cTmp[4] = { 0x00, 0x00, 0x00, 0x00 }; for (i = 0; i < ArrayLen; i++) { Array[i] = ' '; } while (iTemp > 0U) { cTmp[x++] = (iTemp % 10) + '0'; iTemp /= 10U; } if (x == 0U) // ¼öÄ¡°¡ 0.0ÀÏ °æ¿ì. { y = 3U; Array[y++] = '0'; Array[y++] = '.'; Array[y++] = '0'; } else { if (x == 1U) { y = 3U; Array[y++] = '0'; Array[y++] = '.'; Array[y++] = cTmp[0]; } else { y = 5U - x; // Ãâ·Â µÇ´Â ¹®ÀÚÀÇ Á¤·ÄÀ» À§ÇÔ. x = x - 1U; // ¸¶Áö¸·À¸·Î ÀúÀåµÈ ¹öÆÛ À妽ºÀÇ °ªÀº »©ÁÜ. while (x > 0U) { Array[y++] = cTmp[x--]; if (x == 0U) { Array[y++] = '.'; Array[y++] = cTmp[0]; } } } } Array[y] = '\0'; // End of string. } void CInitializePage(void) { if (AdcOperValue.uiOffsetAdjustStart == 0U) { CDrawLine((Uint16)(OledOperValue.uiProgressValue + 1U), (Uint16)(OLED_LOAD_PROGRESS_Y + 2U), (Uint16)(OledOperValue.uiProgressValue + 1U), (Uint16)(OLED_LOAD_PROGRESS_Y + 8U)); if (OledOperValue.uiProgressValue < OLED_LOAD_PROGRESS_W - 3) // -3Àº ÇÁ·Î±×·¡½º ¹ÙÀÇ Á¿ìÃø 1Çȼ¿ °ø°£ ÁÜ. { OledOperValue.uiProgressValue++; } else { OledOperValue.uiProgressDone = 1U; } } } void CDisplayPostFail(void) { CDrawCenteredLine(OLED_LINE_TITLE, "Power On Self-Test"); CDrawCenteredLine(OLED_LINE_1, "(P:PASS F:FAIL)"); // LINE 2 CDrawPostStatusLine(OLED_ROW_2, "EHT:", PowerOnCheckValue.EngineHeaterSensor, "GPL:", PowerOnCheckValue.GlowPlugSensor, "SOL:", PowerOnCheckValue.SolenoidSensor); // LINE 3 CDrawPostStatusLine(OLED_ROW_3, "FUP:", PowerOnCheckValue.FuelPumpSensor, "CLP:", PowerOnCheckValue.CoolantPumpSensor, "FN1:", PowerOnCheckValue.Fan1Sensor); // LINE 4 // Only FN2 CDrawPostStatusLine(OLED_ROW_4, "FN2:", PowerOnCheckValue.Fan2Sensor, NULL, 0, NULL, 0); } static void CLineFocus(Uint16 isFocus) { if (isFocus == 1U) { OledOperValue.Color.TxtColor = 0U; OledOperValue.Color.BgColor = 1U; } else { OledOperValue.Color.TxtColor = 1U; OledOperValue.Color.BgColor = 0U; } } void CReversString(int8 *str, int16 length) { Uint16 i = 0U; Uint16 end = length - 1U; int8 temp; while (i < end) { temp = str[i]; str[i] = str[end]; str[end] = temp; i++; end--; } } static void CHourToString(int32 num, int8 *str) { Uint16 i = 0U; Uint16 end; Uint32 temp = num; // ÀԷ¹ÞÀº °ª (¿¹: 1234567 -> "12345.67") // 1. ¼Ò¼öÁ¡ µÑ° ÀÚ¸® (100ºÐÀÇ 1) str[i++] = (temp % 10) + '0'; temp = temp / 10; // 2. ¼Ò¼öÁ¡ ù° ÀÚ¸® (10ºÐÀÇ 1) str[i++] = (temp % 10) + '0'; temp = temp / 10; // 3. ¼Ò¼öÁ¡ »ðÀÔ str[i++] = '.'; // 4. Á¤¼öºÎ º¯È¯ // ÀÔ·ÂÀÌ 0À̾ ÃÖ¼Ò "0"Àº ÂïÈ÷µµ·Ï do-while »ç¿ë do { str[i++] = (temp % 10) + '0'; temp = temp / 10; } while (temp != 0); // 5. °ø¹é ä¿ì±â (ÀÚ¸®¼ö ¸ÂÃã) // Á¤¼ö5ÀÚ¸® + Á¡1ÀÚ¸® + ¼Ò¼ö2ÀÚ¸® = ÃÑ 8ÀÚ¸® while (i < 8U) { str[i++] = ' '; } str[i] = '\0'; // ¹®ÀÚ¿­ ³¡ ¾Ë¸² end = i - 1U; i = 0U; while (i < end) { int8 swapTemp = str[i]; str[i] = str[end]; str[end] = swapTemp; i++; end--; } } static const int8* CGetApuStateString(eApuOperIdx idx) { // À妽º¿Í 1:1 ¸ÅĪµÇ´Â ¹®ÀÚ¿­ ¹è¿­ Á¤ÀÇ staticÀ» »ç¿ëÇÏ¿© ÇÔ¼ö È£Ãâ ¶§¸¶´Ù ¹è¿­À» ´Ù½Ã »ý¼ºÇÏÁö ¾Êµµ·Ï ÇÔ static const int8* strTable[] = { "BOOT", // 0: APU_OPER_IDX_BOOT "INIT", // 1: APU_OPER_IDX_INITIAL "POST", // 2: APU_OPER_IDX_POST "EMERGENCY", // 3: APU_OPER_IDX_EMERGENCY "STANDBY", // 4: APU_OPER_IDX_STANDBY "START_CHECK", // 5: APU_OPER_IDX_START_CHECK "PREHEAT", // 6: APU_OPER_IDX_ACTIVE_ENG_HEAT "CRANKING", // 7: APU_OPER_IDX_CRANKING "WARM_UP", // 8: APU_OPER_IDX_ENG_WARMING_UP "CHECK_OPER", // 9: APU_OPER_IDX_CHECK_OPERATION "GENERATING", // 10: APU_OPER_IDX_SET_GCU_GEN_START "STABLED", // 11: APU_OPER_IDX_ENG_START_DONE "STOP", // 12: APU_OPER_IDX_ENG_STOP_NORMAL "COOLDOWN" // 13: APU_OPER_IDX_ENG_STOP_COOLDOWN }; return strTable[idx]; }