1979 lines
67 KiB
Plaintext
1979 lines
67 KiB
Plaintext
/* ========================================================================= */
|
|
/* 1. Includes */
|
|
/* ========================================================================= */
|
|
#include "main.h"
|
|
|
|
/* ========================================================================= */
|
|
/* 2. Local Macros & Constants (내부 전용 매크로 및 상수) */
|
|
/* ========================================================================= */
|
|
#pragma DATA_SECTION(CommandBus,"ZONE6_COM");
|
|
#pragma DATA_SECTION(DataBus,"ZONE6_DAT");
|
|
|
|
#define ASCII_NULL ((int8)0) // NULL '\0'
|
|
#define ASCII_BLANK ((int8)32) // 공백 ' '
|
|
#define ASCII_L_PAREN ((int8)40) // 여는 소괄호 '('
|
|
#define ASCII_R_PAREN ((int8)41) // 닫는 소괄호 ')'
|
|
#define ASCII_MINUS ((int8)45) // 마이너스 '-'
|
|
#define ASCII_DOT ((int8)46) // 소수점 '.'
|
|
|
|
#define ASCII_0 ((int8)48) // '0'
|
|
|
|
#define ASCII_E ((int8)69) // 'E'
|
|
#define ASCII_R ((int8)82) // 'R'
|
|
#define ASCII_T ((int8)84) // 'T'
|
|
#define ASCII_Y ((int8)89) // 'Y'
|
|
|
|
/* ========================================================================= */
|
|
/* 3. Local Typedefs & Structures (내부 전용 사용자 정의 자료형) */
|
|
/* ========================================================================= */
|
|
static volatile Uint16 CommandBus, DataBus;
|
|
|
|
/* ========================================================================= */
|
|
/* 4. Internal Linkage Function Declarations (내부 동작용 Static 함수 선언) */
|
|
/* ========================================================================= */
|
|
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 CPageFault7(void);
|
|
static void CPageAlarmReset(void);
|
|
static void CPagePassword(void);
|
|
static void CPageMaintenance(void);
|
|
static void CPageVersion(void);
|
|
static void CPageKeyTest(void);
|
|
static void CPageShutdown(void);
|
|
static Uint16 CStrLen(const int8 *s);
|
|
static void CInitOledModule(void);
|
|
static void CDrawChar(Uint16 x, Uint16 y, Uint16 ch, Uint16 type);
|
|
static void CInitProgress(void);
|
|
static void CDrawStr(Uint16 x, Uint16 y, const int8* str);
|
|
static void CTextAlign(int8 *buffer, const int8 *str);
|
|
static inline void CPutPixel(Uint16 x, Uint16 y, Uint16 Color);
|
|
static void CDrawBox(Uint16 x, Uint16 y, Uint16 w, Uint16 h);
|
|
static void CDrawLine(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2);
|
|
static void CSetDrawRegion(Uint16 x, Uint16 y);
|
|
static void CSetPageAddress(Uint16 Address);
|
|
static void CSetColumnAddress(Uint16 x);
|
|
static void COledWrite(Uint16 Data, Uint16 Command);
|
|
static void CInitOledStructure(void);
|
|
static void CStrncpy(int8 *pTarget, const int8 *pSource, Uint16 Size);
|
|
static void CStrncat(int8 *pTarget, const int8 *pSource, Uint16 Size);
|
|
static 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);
|
|
static void CMakeVersionString(int8 Buffer[], int16 v1, int16 v2, int16 v3);
|
|
static void CAddLineIndent(int8 *buffer, const int8 *str);
|
|
static const int8* CGetApuStateString(Uint16 idx);
|
|
static void CDrawTitleBox(Uint16 TitleLen);
|
|
static void CDrawCenteredLine(Uint16 y, const int8* text);
|
|
static void CCopyStr(int8 *pTarget, const int8 *pSource);
|
|
static void CAppendStr(int8 *pTarget, const int8 *pSource);
|
|
static void CDrawLineText(Uint16 x, Uint16 y, const int8* str);
|
|
static void CDrawFaultStatusLine(Uint16 row, const int8* label1, Uint16 status1, const int8* label2, Uint16 status2);
|
|
static void CDrawSimpleLine(Uint16 row, const int8* label);
|
|
static void CDrawStatusTitle(const int8* title, const int8* pageNumStr);
|
|
static void CDrawSensorTitle(const int8* title, const int8* pageNumStr);
|
|
static void CDrawFaultTitle(const int8* title, const int8* pageNumStr);
|
|
|
|
/* ========================================================================= */
|
|
/* 5. Global Variables & Structure Initialization (전역 변수 및 구조체 초기화) */
|
|
/* ========================================================================= */
|
|
COledOperValue OledOperValue;
|
|
|
|
/* ========================================================================= */
|
|
/* Function Definitions */
|
|
/* ========================================================================= */
|
|
static void CDrawPageTitle(const int8* title, const int8* pageNumStr)
|
|
{
|
|
Uint16 uiTitleLen = 0U;
|
|
|
|
CCopyStr(OledOperValue.cStrBuff[IDX_OLED_ROW_0], title);
|
|
CDrawStr(10U, (Uint16)IDX_OLED_LINE_TITLE, OledOperValue.cStrBuff[IDX_OLED_ROW_0]);
|
|
|
|
if (title != NULL)
|
|
{
|
|
while ((title[uiTitleLen] != ASCII_NULL) && (uiTitleLen < (Uint16)TXT_MAX_LEN))
|
|
{
|
|
uiTitleLen++;
|
|
}
|
|
}
|
|
CDrawTitleBox(uiTitleLen * 6U);
|
|
|
|
if (pageNumStr != NULL)
|
|
{
|
|
CCopyStr(OledOperValue.cStrBuff[IDX_OLED_ROW_0], pageNumStr);
|
|
CDrawStr(100U, (Uint16)IDX_OLED_LINE_TITLE, OledOperValue.cStrBuff[IDX_OLED_ROW_0]);
|
|
}
|
|
}
|
|
|
|
static void CDrawPageLine(Uint16 row, const int8* label, const int8* valueStr, const int8* unitStr)
|
|
{
|
|
Uint16 drawY;
|
|
Uint16 len = 0U;
|
|
|
|
drawY = (row == (Uint16)IDX_OLED_ROW_1) ? (Uint16)IDX_OLED_LINE_1 : ((row == (Uint16)IDX_OLED_ROW_2) ? (Uint16)IDX_OLED_LINE_2 : ((row == (Uint16)IDX_OLED_ROW_3) ? (Uint16)IDX_OLED_LINE_3 : (Uint16)IDX_OLED_LINE_4));
|
|
|
|
CCopyStr(OledOperValue.cStrBuff[row], label);
|
|
|
|
if (valueStr != NULL)
|
|
{
|
|
CAppendStr(OledOperValue.cStrBuff[row], valueStr);
|
|
}
|
|
|
|
if (unitStr != NULL)
|
|
{
|
|
CAppendStr(OledOperValue.cStrBuff[row], unitStr);
|
|
}
|
|
|
|
while ((OledOperValue.cStrBuff[row][len] != ASCII_NULL) && (len < (Uint16)(TXT_MAX_LEN - 1U)))
|
|
{
|
|
len++;
|
|
}
|
|
|
|
while (len < (Uint16)(TXT_MAX_LEN - 1U))
|
|
{
|
|
OledOperValue.cStrBuff[row][len] = ASCII_BLANK; // ' '
|
|
len++;
|
|
}
|
|
|
|
OledOperValue.cStrBuff[row][len] = ASCII_NULL;
|
|
|
|
CDrawLineText(0U, drawY, (const int8*)OledOperValue.cStrBuff[row]);
|
|
}
|
|
|
|
static void CDrawPageLineFloat(Uint16 row, const int8* label, float32 value, const int8* unitStr)
|
|
{
|
|
int8 tempBuff[16];
|
|
|
|
CFloatToString(value, tempBuff, sizeof(tempBuff));
|
|
CDrawPageLine(row, label, (const int8*)tempBuff, unitStr);
|
|
}
|
|
|
|
static void CDrawPageLineTwoFloat(Uint16 row, const int8* label, float32 value1, float32 value2)
|
|
{
|
|
int8 finalBuf[32];
|
|
Uint16 j = 0U;
|
|
Uint32 intPart;
|
|
Uint32 decPart;
|
|
Uint16 uiTmp; /* 복합 수식 연산 결과를 담을 임시 변수 */
|
|
float32 fTmp; /* 부동소수점 연산 결과를 담을 임시 변수 */
|
|
|
|
/* --- Value 1 처리 --- */
|
|
intPart = (Uint32)value1;
|
|
fTmp = ((value1 - (float32)intPart) * 10.0F) + 0.5F;
|
|
decPart = (Uint32)fTmp;
|
|
|
|
if (decPart >= 10U)
|
|
{
|
|
intPart++;
|
|
decPart = 0U;
|
|
}
|
|
|
|
/* 십의 자리 */
|
|
uiTmp = (Uint16)((intPart / 10U) + 48U);
|
|
finalBuf[j] = (intPart >= 10U) ? (int8)uiTmp : ASCII_BLANK;
|
|
j++;
|
|
|
|
/* 일의 자리 */
|
|
uiTmp = (Uint16)((intPart % 10U) + 48U);
|
|
finalBuf[j] = (int8)uiTmp;
|
|
j++;
|
|
|
|
finalBuf[j] = ASCII_DOT; /* '.' */
|
|
j++;
|
|
|
|
/* 소수점 첫째 자리 */
|
|
uiTmp = (Uint16)(decPart + 48U);
|
|
finalBuf[j] = (int8)uiTmp;
|
|
j++;
|
|
|
|
/* 구분자들 */
|
|
finalBuf[j] = (int8)86; /* 'V' */
|
|
j++;
|
|
finalBuf[j] = (int8)44; /* ',' */
|
|
j++;
|
|
finalBuf[j] = ASCII_BLANK; /* ' ' */
|
|
j++;
|
|
|
|
|
|
/* --- Value 2 처리 --- */
|
|
intPart = (Uint32)value2;
|
|
fTmp = ((value2 - (float32)intPart) * 10.0F) + 0.5F;
|
|
decPart = (Uint32)fTmp;
|
|
|
|
if (decPart >= 10U)
|
|
{
|
|
intPart++;
|
|
decPart = 0U;
|
|
}
|
|
|
|
if (intPart > 99U)
|
|
{
|
|
intPart = 99U;
|
|
}
|
|
|
|
/* 십의 자리 */
|
|
uiTmp = (Uint16)((intPart / 10U) + 48U);
|
|
finalBuf[j] = (intPart >= 10U) ? (int8)uiTmp : ASCII_BLANK;
|
|
j++;
|
|
|
|
/* 일의 자리 */
|
|
uiTmp = (Uint16)((intPart % 10U) + 48U);
|
|
finalBuf[j] = (int8)uiTmp;
|
|
j++;
|
|
|
|
finalBuf[j] = ASCII_DOT; /* '.' */
|
|
j++;
|
|
|
|
/* 소수점 첫째 자리 */
|
|
uiTmp = (Uint16)(decPart + 48U);
|
|
finalBuf[j] = (int8)uiTmp;
|
|
j++;
|
|
|
|
finalBuf[j] = ASCII_NULL; /* '\0' */
|
|
|
|
CDrawPageLine(row, label, finalBuf, (const int8*)"A");
|
|
}
|
|
|
|
static void CDrawPageLineInt(Uint16 row, const int8* label, int32 value, const int8* unitStr)
|
|
{
|
|
int8 tempBuff[16];
|
|
|
|
CDecToString((int16)value, tempBuff, sizeof(tempBuff));
|
|
CDrawPageLine(row, label, (const int8*)tempBuff, unitStr);
|
|
}
|
|
|
|
static void CDrawTwoStatusLine(Uint16 row, const int8* label1, Uint16 status1, const int8* label2, Uint16 status2)
|
|
{
|
|
const int8* statusStr1 = (status1 == 1U) ? (const int8*)"1" : (const int8*)"0";
|
|
const int8* statusStr2 = (status2 == 1U) ? (const int8*)"1" : (const int8*)"0";
|
|
Uint16 drawY = 0U;
|
|
|
|
if (row == (Uint16)IDX_OLED_ROW_1)
|
|
{
|
|
drawY = (Uint16)IDX_OLED_LINE_1;
|
|
}
|
|
else if (row == (Uint16)IDX_OLED_ROW_2)
|
|
{
|
|
drawY = (Uint16)IDX_OLED_LINE_2;
|
|
}
|
|
else if (row == (Uint16)IDX_OLED_ROW_3)
|
|
{
|
|
drawY = (Uint16)IDX_OLED_LINE_3;
|
|
}
|
|
else
|
|
{
|
|
drawY = (Uint16)IDX_OLED_LINE_4;
|
|
}
|
|
|
|
// 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));
|
|
|
|
CDrawLineText(0U, drawY, OledOperValue.cStrBuff[row]);
|
|
}
|
|
|
|
static void CPageApu1(void)
|
|
{
|
|
static Uint16 uiDummyRun = 1U;
|
|
|
|
int16 iTemp;
|
|
const int8 *cTemp = (const int8*)"";
|
|
float32 fTemp;
|
|
|
|
/* TITLE */
|
|
CDrawStatusTitle((const int8*)"APU Status", (const int8*)"1/2");
|
|
|
|
/* LINE 1: DC Voltage */
|
|
fTemp = (float32)Rx220.DcVoltage / 10.0F;
|
|
|
|
//if ((isfinite(fTemp) != 0) && (uiDummyRun == 0U))
|
|
if (1)
|
|
{
|
|
CDrawPageLineFloat(IDX_OLED_ROW_1, (const int8*)"DC Voltage ", fTemp, (const int8*)" V");
|
|
}
|
|
else
|
|
{
|
|
CDrawPageLineFloat(IDX_OLED_ROW_1, (const int8*)"DC Voltage ", 0.0F, (const int8*)" V");
|
|
}
|
|
|
|
/* LINE 2: Power */
|
|
fTemp = (float32)Rx220.Power / 10.0F;
|
|
|
|
//if ((isfinite(fTemp) != 0) && (uiDummyRun == 0U))
|
|
if (1)
|
|
{
|
|
CDrawPageLineFloat(IDX_OLED_ROW_2, (const int8*)"Power ", fTemp, (const int8*)" kW");
|
|
}
|
|
else
|
|
{
|
|
CDrawPageLineFloat(IDX_OLED_ROW_2, (const int8*)"Power ", 0.0F, (const int8*)" kW");
|
|
}
|
|
|
|
/* LINE 3: Speed */
|
|
iTemp = (int16)Rx320.ActualRpm;
|
|
CDrawPageLineInt(IDX_OLED_ROW_3, (const int8*)"Speed ", (int32)iTemp, (const int8*)" rpm");
|
|
|
|
/* LINE 4: Status */
|
|
cTemp = CGetApuStateString(GeneralOperValue.uiApuState);
|
|
|
|
CStrncpy(OledOperValue.cStrBuff[IDX_OLED_ROW_4], (const int8*)"Status", CStrLen((const int8*)"Status"));
|
|
CAddLineIndent(OledOperValue.cStrBuff[IDX_OLED_ROW_4], cTemp);
|
|
|
|
if (cTemp != NULL)
|
|
{
|
|
CStrncat(OledOperValue.cStrBuff[IDX_OLED_ROW_4], cTemp, CStrLen(cTemp));
|
|
}
|
|
|
|
CDrawLineText(0U, (Uint16)IDX_OLED_LINE_4, OledOperValue.cStrBuff[IDX_OLED_ROW_4]);
|
|
|
|
uiDummyRun = (uiDummyRun == 1U) ? 0U : uiDummyRun;
|
|
}
|
|
|
|
static void CPageApu2(void)
|
|
{
|
|
int8 tempBuff[16];
|
|
int16 iTemp;
|
|
|
|
// TITLE
|
|
CDrawStatusTitle("APU Status", "2/2");
|
|
|
|
// LINE 1
|
|
iTemp = CGetEngCoolantTemperature();
|
|
CDrawPageLineInt((Uint16)IDX_OLED_ROW_1, "Coolant ", (int32)iTemp, " \xA1\xC9");
|
|
|
|
// LINE 2
|
|
iTemp = (int16)Rx320.ActualTorque;
|
|
CDrawPageLineInt((Uint16)IDX_OLED_ROW_2, "Torque ", (int32)iTemp, " %");
|
|
|
|
// LINE 3
|
|
GeneralOperValue.ulTotalOperationHour = ((Uint32)Rx322.TotalOperTimeL) | ((Uint32)Rx322.TotalOperTimeH << 16U);
|
|
CHourToString((int32)GeneralOperValue.ulTotalOperationHour, tempBuff);
|
|
CDrawPageLine((Uint16)IDX_OLED_ROW_3, (const int8*)"ENG.Hour ", (const int8*)tempBuff, (const int8*)" Hr");
|
|
}
|
|
|
|
static void CPageMenu1(void)
|
|
{
|
|
/* TITLE */
|
|
CDrawStatusTitle((const int8*)"Menu", (const int8*)"1/2");
|
|
|
|
/* LINE 1 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 0U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_1, (const int8*)"1. APU Status ");
|
|
|
|
/* LINE 2 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 1U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_2, (const int8*)"2. Temperature ");
|
|
|
|
/* LINE 3 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 2U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_3, (const int8*)"3. Sensor ");
|
|
|
|
/* LINE 4 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 3U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_4, (const int8*)"4. Warning ");
|
|
}
|
|
|
|
static void CPageMenu2(void)
|
|
{
|
|
/* TITLE */
|
|
CDrawStatusTitle((const int8*)"Menu", (const int8*)"2/2");
|
|
|
|
/* LINE 1 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 0U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_1, (const int8*)"5. Fault ");
|
|
|
|
/* LINE 2 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 1U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_2, (const int8*)"6. Alarm Reset ");
|
|
|
|
/* LINE 3 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 2U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_3, (const int8*)"7. Maintenance ");
|
|
|
|
/* LINE 4 */
|
|
CLineFocus((OledOperValue.uiFocusLine == 3U) ? 1U : 0U);
|
|
CDrawSimpleLine((Uint16)IDX_OLED_ROW_4, (const int8*)"8. Version ");
|
|
}
|
|
|
|
static void CPageTemp(void)
|
|
{
|
|
int16 iTemp;
|
|
|
|
// TITLE
|
|
CDrawStatusTitle("Temperature", "1/1");
|
|
|
|
// LINE 1
|
|
iTemp = (int16)((int16)Rx221.PcbTemperature - 40);
|
|
CDrawPageLineInt(IDX_OLED_ROW_1, "PCB Temp. ", (int32)iTemp, " \xA1\xC9");
|
|
|
|
// LINE 2
|
|
iTemp = (int16)((int16)Rx221.FetTemperature - 40);
|
|
CDrawPageLineInt(IDX_OLED_ROW_2, "FET Temp. ", (int32)iTemp, " \xA1\xC9");
|
|
|
|
// LINE 3
|
|
iTemp = (int16)((int16)Rx221.GenTemperature1 - 40);
|
|
CDrawPageLineInt(IDX_OLED_ROW_3, "Gen.Temp1. ", (int32)iTemp, " \xA1\xC9");
|
|
|
|
// LINE4
|
|
iTemp = (int16)((int16)Rx221.GenTemperature2 - 40);
|
|
CDrawPageLineInt(IDX_OLED_ROW_4, "Gen.Temp2. ", (int32)iTemp, " \xA1\xC9");
|
|
}
|
|
static void CPageSensor1(void)
|
|
{
|
|
float32 fTemp1, fTemp2;
|
|
|
|
// TITLE
|
|
CDrawSensorTitle("APU Sensor", "1/4");
|
|
|
|
// LINE 1
|
|
fTemp1 = (Adc_EngineHeater_V.fLpfValue < 0.0F) ? 0.0F : Adc_EngineHeater_V.fLpfValue;
|
|
fTemp2 = (Adc_EngineHeater_I.fLpfValue < 0.0F) ? 0.0F : Adc_EngineHeater_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_1, "EngHeat ", fTemp1, fTemp2);
|
|
|
|
// LINE 2
|
|
fTemp1 = (Adc_GlowPlug_V.fLpfValue < 0.0F) ? 0.0F : Adc_GlowPlug_V.fLpfValue;
|
|
fTemp2 = (Adc_GlowPlug_I.fLpfValue < 0.0F) ? 0.0F : Adc_GlowPlug_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_2, "GlowPlg ", fTemp1, fTemp2);
|
|
|
|
// LINE 3
|
|
fTemp1 = (Adc_Solenoid_V.fLpfValue < 0.0F) ? 0.0F : Adc_Solenoid_V.fLpfValue;
|
|
fTemp2 = (Adc_Solenoid_I.fLpfValue < 0.0F) ? 0.0F : Adc_Solenoid_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_3, "Solnoid ", fTemp1, fTemp2);
|
|
|
|
// LINE 4
|
|
fTemp1 = (Adc_FuelPump_V.fLpfValue < 0.0F) ? 0.0F : Adc_FuelPump_V.fLpfValue;
|
|
fTemp2 = (Adc_FuelPump_I.fLpfValue < 0.0F) ? 0.0F : Adc_FuelPump_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_4, "FuelPmp ", fTemp1, fTemp2);
|
|
}
|
|
|
|
static void CPageSensor2(void)
|
|
{
|
|
float32 fTemp1, fTemp2;
|
|
|
|
// TITLE
|
|
CDrawSensorTitle("APU Sensor", "2/4");
|
|
|
|
// LINE 1
|
|
fTemp1 = (Adc_CoolantPump_V.fLpfValue < 0.0F) ? 0.0F : Adc_CoolantPump_V.fLpfValue;
|
|
fTemp2 = (Adc_CoolantPump_I.fLpfValue < 0.0F) ? 0.0F : Adc_CoolantPump_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_1, "CoolPmp ", fTemp1, fTemp2);
|
|
|
|
// LINE 2
|
|
fTemp1 = (Adc_Fan1_V.fLpfValue < 0.0F) ? 0.0F : Adc_Fan1_V.fLpfValue;
|
|
fTemp2 = (Adc_Fan1_I.fLpfValue < 0.0F) ? 0.0F : Adc_Fan1_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_2, "Fan1 ", fTemp1, fTemp2);
|
|
|
|
// LINE 3
|
|
fTemp1 = (Adc_Fan2_V.fLpfValue < 0.0F) ? 0.0F : Adc_Fan2_V.fLpfValue;
|
|
fTemp2 = (Adc_Fan2_I.fLpfValue < 0.0F) ? 0.0F : Adc_Fan2_I.fLpfValue;
|
|
CDrawPageLineTwoFloat(IDX_OLED_ROW_3, "Fan2 ", fTemp1, fTemp2);
|
|
}
|
|
|
|
static void CPageSensor3(void)
|
|
{
|
|
int16 iTemp;
|
|
|
|
// TITLE
|
|
CDrawSensorTitle("ECU Sensor", "3/4");
|
|
|
|
// LINE 1
|
|
iTemp = (int16)Rx321.BarometricPressure;
|
|
CDrawPageLineInt(IDX_OLED_ROW_1, "Barometric ", (int32)iTemp, " mb");
|
|
|
|
// LINE 2
|
|
iTemp = (int16)Rx321.Fan1Speed;
|
|
CDrawPageLineInt(IDX_OLED_ROW_2, "Fan1 Speed ", (int32)iTemp, " %");
|
|
|
|
// LINE 3
|
|
iTemp = (int16)Rx321.Fan2Speed;
|
|
CDrawPageLineInt(IDX_OLED_ROW_3, "Fan2 Speed ", (int32)iTemp, " %");
|
|
|
|
// LINE 4
|
|
iTemp = (int16)Rx321.CoolantPumpSpeed;
|
|
CDrawPageLineInt(IDX_OLED_ROW_4, "C.Pump Speed ", (int32)iTemp, " %");
|
|
}
|
|
|
|
static void CPageSensor4(void)
|
|
{
|
|
int16 iTemp;
|
|
|
|
// TITLE
|
|
CDrawSensorTitle("GCU Sensor", "4/4");
|
|
|
|
// LINE 1
|
|
iTemp = (int16)Rx220.Rpm;
|
|
CDrawPageLineInt(IDX_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(IDX_OLED_ROW_1, "PCBOT:", CIsBitSet((Uint32)Rx210.GcuWarning, (Uint16)IDX_WARNING_GCU_PCB_OT), "FETOT:", CIsBitSet((Uint32)Rx210.GcuWarning, (Uint16)IDX_WARNING_GCU_FET_OT));
|
|
|
|
// LINE 2
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_2, "GEOT1:", CIsBitSet((Uint32)Rx210.GcuWarning, (Uint16)IDX_WARNING_GCU_WINDING1_OH), "GEOT2:", CIsBitSet((Uint32)Rx210.GcuWarning, (Uint16)IDX_WARNING_GCU_WINDING2_OH));
|
|
|
|
// LINE 3
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_3, "ENGOT:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_ENGINE_OH), "LOILP:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_LO_OIL_PRESS));
|
|
|
|
// LINE 4
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_4, "INTOT:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_INTAKE_OH), "INTLP:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_INTAKE_LO_PRESS));
|
|
}
|
|
|
|
static void CPageWarning2(void)
|
|
{
|
|
/* TITLE */
|
|
CDrawPageTitle("Warning", "2/2");
|
|
|
|
/* LINE 1 */
|
|
CDrawTwoStatusLine((Uint16)IDX_OLED_ROW_1, (const int8*)"ENGLT:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_ENGINE_LO_TEMP), (const int8*)"ENGSF:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_ENGINE_SENSOR));
|
|
|
|
/* LINE 2 */
|
|
CDrawPageLineStatus((Uint16)IDX_OLED_ROW_2, (const int8*)"DEFAC:", CIsBitSet((Uint32)Rx310.EcuWarning, (Uint16)IDX_WARNING_ECU_DEFAULT_ACTIVE));
|
|
}
|
|
|
|
static void CPageFault1(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("APU Fault", "1/7");
|
|
|
|
// LINE 1
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_1, "CARCT:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_CAR_COMM), "GCUCT:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_GCU_COMM));
|
|
|
|
// LINE 2
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_2, "ECUCT:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_ECU_COMM), "RPMER:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_RPM_ERR));
|
|
|
|
// LINE 3
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_3, "EHLOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_ENGINE_HEAT_OC), "GPLOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_GLOW_PLUG_OC));
|
|
|
|
// LINE 4
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_4, "SOLOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_SOLENOID_OC), "FPLOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FUEL_PUMP_OC));
|
|
}
|
|
|
|
static void CPageFault2(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("APU Fault", "2/7");
|
|
|
|
// LINE 1
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_1, "CPLOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_COOLANT_PUMP_OC), "F1LOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN1_OC));
|
|
|
|
// LINE 2
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_2, "F2LOC:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN2_OC), "EHVUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_ENGINE_HEAT_UV));
|
|
|
|
// LINE 3
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_3, "EHVOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_ENGINE_HEAT_OV), "GPVUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_GLOW_PLUG_UV));
|
|
|
|
// LINE 4
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_4, "GPVOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_GLOW_PLUG_OV), "SLVUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_SOLENOID_UV));
|
|
}
|
|
|
|
static void CPageFault3(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("APU Fault", "3/7");
|
|
|
|
// LINE 1
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_1, "SLVOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_SOLENOID_OV), "FPVUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FUEL_PUMP_UV));
|
|
|
|
// LINE 2
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_2, "FPVOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FUEL_PUMP_OV), "CPVUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_COOLANT_PUMP_UV));
|
|
|
|
// LINE 3
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_3, "CPVOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_COOLANT_PUMP_OV), "F1VUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN1_UV));
|
|
|
|
// LINE 4
|
|
CDrawTwoStatusLine(IDX_OLED_ROW_4, "F1VOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN1_OV), "F2VUV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN2_UV));
|
|
}
|
|
|
|
static void CPageFault4(void)
|
|
{
|
|
/* TITLE */
|
|
CDrawFaultTitle((const int8*)"APU Fault", (const int8*)"4/7");
|
|
|
|
/* LINE 1: */
|
|
CDrawFaultStatusLine((Uint16)IDX_OLED_ROW_1, (const int8*)"F2VOV:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_FAN2_OV), (const int8*)"CRKFL:", CIsBitSet(ulDcuTotalAlarm, (Uint16)IDX_FAULT_DCU_CRANKING_FAIL));
|
|
}
|
|
|
|
static void CPageFault5(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("GCU Fault", "5/7");
|
|
|
|
// LINE 1
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_1, "HTRIP:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_HWTRIP), "HIGBT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_HWIGBT));
|
|
|
|
// LINE 2
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_2, "HDCOV:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_HW_DC), "GNOCU:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_GEN_OCU));
|
|
|
|
// LINE 3
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_3, "GNOCV:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_GEN_OCW), "GNOCW:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_GEN_OCW));
|
|
|
|
// LINE 4
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_4, "SDCOV:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_DC_OV), "SDCOC:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_DC_OC));
|
|
}
|
|
|
|
static void CPageFault6(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("GCU Fault", "6/7");
|
|
|
|
// LINE 1
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_1, "SMOOC:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_CRANK_OC), "PCBOT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_PCB_OT));
|
|
|
|
// LINE 2
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_2, "FETOT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_FET_OT), "GW1OT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_WINDING1_OH));
|
|
|
|
// LINE 3
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_3, "GW2OT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_WINDING2_OH), "GENOS:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_GEN_OS));
|
|
|
|
// LINE 4
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_4, "RSICF:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_RES_IC), "RSPRT:", CIsBitSet(ulGcuTotalAlarm, (Uint16)IDX_FAULT_GCU_RES_PRTY));
|
|
}
|
|
|
|
static void CPageFault7(void)
|
|
{
|
|
// TITLE
|
|
CDrawFaultTitle("ECU Fault", "7/7");
|
|
|
|
// LINE 1
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_1, "OILMS:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_OIL_MS), "INTOT:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_INT_OH));
|
|
|
|
// LINE 2
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_2, "ENGOH:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_ENG_OH), "ACTUA:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_ACTUATOR));
|
|
|
|
// LINE 3
|
|
CDrawFaultStatusLine(IDX_OLED_ROW_3, "RPMSG:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_RPM_SIG), "ENGSF:", CIsBitSet(ulEcuTotalAlarm, (Uint16)IDX_FAULT_ECU_ENG_SF));
|
|
}
|
|
|
|
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)
|
|
{
|
|
Uint16 y = 0U;
|
|
const int8* pPrintStr = NULL; // 실제 출력할 문자열을 가리킬 포인터
|
|
|
|
OledOperValue.cStrBuff[row][0] = ASCII_NULL; // '\0'
|
|
|
|
// Label 1 + Status 1
|
|
if (l1 != NULL)
|
|
{
|
|
CStrncat(OledOperValue.cStrBuff[row], l1, CStrLen(l1));
|
|
CStrncat(OledOperValue.cStrBuff[row], (s1 == 0U) ? (const int8*)"P" : (const int8*)"F", 1U);
|
|
}
|
|
|
|
// Label 2 + Status 2
|
|
if (l2 != NULL)
|
|
{
|
|
if (OledOperValue.cStrBuff[row][0] != ASCII_NULL) // '\0'
|
|
{
|
|
CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 1U);
|
|
}
|
|
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)
|
|
{
|
|
if (OledOperValue.cStrBuff[row][0] != ASCII_NULL) // '\0'
|
|
{
|
|
CStrncat(OledOperValue.cStrBuff[row], (const int8*)" ", 1U);
|
|
}
|
|
CStrncat(OledOperValue.cStrBuff[row], l3, CStrLen(l3));
|
|
CStrncat(OledOperValue.cStrBuff[row], (s3 == 0U) ? (const int8*)"P" : (const int8*)"F", 1U);
|
|
}
|
|
|
|
if (row == (Uint16)IDX_OLED_ROW_4)
|
|
{
|
|
pPrintStr = OledOperValue.cStrBuff[row];
|
|
}
|
|
else
|
|
{
|
|
CTextAlign(OledOperValue.cAlignBuffer, OledOperValue.cStrBuff[row]);
|
|
pPrintStr = OledOperValue.cAlignBuffer;
|
|
}
|
|
|
|
// Y 좌표 설정
|
|
if (row == (Uint16)IDX_OLED_ROW_2)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_2;
|
|
}
|
|
else if (row == (Uint16)IDX_OLED_ROW_3)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_3;
|
|
}
|
|
else
|
|
{
|
|
if (row == (Uint16)IDX_OLED_ROW_4)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_4;
|
|
}
|
|
}
|
|
|
|
if (pPrintStr != NULL)
|
|
{
|
|
CDrawLineText(0U, y, (const int8*)pPrintStr);
|
|
}
|
|
}
|
|
|
|
static void CPageAlarmReset(void)
|
|
{
|
|
const int8 *cTemp = "";
|
|
|
|
// LINE 1
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_1, "Reset all faults?");
|
|
|
|
// LINE 2
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_2, "(no clear warnings)");
|
|
|
|
// LINE 3
|
|
cTemp = (OledOperValue.uiResetAlarmAnswer == 1U) ? (int8*)"YES" : (int8*)" NO";
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_3 + 5U, cTemp);
|
|
|
|
// BOX
|
|
CDrawAlarmBox();
|
|
}
|
|
|
|
static void CPagePassword(void)
|
|
{
|
|
const int8 *cTemp = "";
|
|
int8 maskBuffer[16];
|
|
Uint16 uiTemp[2] = { 0, '\0' };
|
|
|
|
// TITLE
|
|
CDrawStatusTitle("Input Password", NULL);
|
|
|
|
switch (OledOperValue.uiFocusDigit)
|
|
{
|
|
case (Uint16)IDX_OLED_PASS_DIGIT_1:
|
|
{
|
|
uiTemp[0] = GeneralOperValue.uiPassword[IDX_OLED_PASS_DIGIT_1] + 48U; // 48 : '0'
|
|
cTemp = (int8*)uiTemp;
|
|
CStrncpy(maskBuffer, "[", 2);
|
|
CStrncat(maskBuffer, cTemp, 1);
|
|
CStrncat(maskBuffer, "][*][*][*]", 10);
|
|
break;
|
|
}
|
|
case (Uint16)IDX_OLED_PASS_DIGIT_2:
|
|
{
|
|
uiTemp[0] = GeneralOperValue.uiPassword[IDX_OLED_PASS_DIGIT_2] + 48U; // 48 : '0'
|
|
cTemp = (int8*)uiTemp;
|
|
CStrncpy(maskBuffer, "[*][", 4);
|
|
CStrncat(maskBuffer, cTemp, 1);
|
|
CStrncat(maskBuffer, "][*][*]", 7);
|
|
break;
|
|
}
|
|
case (Uint16)IDX_OLED_PASS_DIGIT_3:
|
|
{
|
|
uiTemp[0] = GeneralOperValue.uiPassword[IDX_OLED_PASS_DIGIT_3] + 48U; // 48 : '0'
|
|
cTemp = (int8*)uiTemp;
|
|
CStrncpy(maskBuffer, "[*][*][", 7);
|
|
CStrncat(maskBuffer, cTemp, 1);
|
|
CStrncat(maskBuffer, "][*]", 4);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
uiTemp[0] = GeneralOperValue.uiPassword[IDX_OLED_PASS_DIGIT_4] + 48U; // 48 : '0'
|
|
cTemp = (int8*)uiTemp;
|
|
CStrncpy(maskBuffer, "[*][*][*][", 10);
|
|
CStrncat(maskBuffer, cTemp, 1);
|
|
CStrncat(maskBuffer, "]", 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_2, (const int8*)maskBuffer);
|
|
}
|
|
static void CPageMaintenance(void)
|
|
{
|
|
const int8 *cTemp = "";
|
|
|
|
// TITLE
|
|
CDrawStatusTitle("Maintenance", "1/1");
|
|
|
|
// LINE 1
|
|
CLineFocus((OledOperValue.uiFocusLine == (Uint16)IDX_OLED_LINE_FOCUS_1) ? 1U : 0U);
|
|
cTemp = (GeneralOperValue.Maintenance.ManualCranking > 0U) ? (int8*)"ON " : (int8*)"OFF";
|
|
CDrawPageLine(IDX_OLED_ROW_1, "Manual Cranking ", cTemp, NULL);
|
|
|
|
// LINE 2
|
|
CLineFocus((OledOperValue.uiFocusLine == (Uint16)IDX_OLED_LINE_FOCUS_2) ? 1U : 0U);
|
|
cTemp = (GeneralOperValue.Maintenance.LampTest > 0U) ? (int8*)"ON " : (int8*)"OFF";
|
|
CDrawPageLine(IDX_OLED_ROW_2, "Lamp Test ", cTemp, NULL);
|
|
|
|
// LINE 3
|
|
CLineFocus((OledOperValue.uiFocusLine == (Uint16)IDX_OLED_LINE_FOCUS_3) ? 1U : 0U);
|
|
CDrawPageLine(IDX_OLED_ROW_3, "Switch Test ", NULL, NULL);
|
|
}
|
|
|
|
static void CPageVersion(void)
|
|
{
|
|
int8 cTemp[16];
|
|
|
|
// TITLE
|
|
CDrawStatusTitle("Version", "1/1");
|
|
|
|
// LINE 1 is blank
|
|
|
|
// LINE 2
|
|
CMakeVersionString(cTemp, (int16)FIRMWARE_VERSION_MAJOR, (int16)FIRMWARE_VERSION_MINOR, (int16)FIRMWARE_VERSION_PATCH);
|
|
CDrawPageLine(IDX_OLED_ROW_2, " DCU : ", cTemp, NULL);
|
|
|
|
// LINE 3
|
|
CMakeVersionString(cTemp, (int16)Rx200.VersionMajor, (int16)Rx200.VersionMinor, (int16)Rx200.VersionPatch);
|
|
CDrawPageLine(IDX_OLED_ROW_3, " GCU : ", cTemp, NULL);
|
|
|
|
// LINE 4
|
|
CMakeVersionString(cTemp, (int16)Rx300.VersionMajor, (int16)Rx300.VersionMinor, (int16)Rx300.VersionPatch);
|
|
CDrawPageLine(IDX_OLED_ROW_4, " ECU : ", cTemp, NULL);
|
|
}
|
|
|
|
static void CDrawCenteredLine(Uint16 y, const int8* text)
|
|
{
|
|
CStrncpy(OledOperValue.cStrBuff[IDX_OLED_ROW_0], text, CStrLen(text));
|
|
CTextAlign(OledOperValue.cAlignBuffer, OledOperValue.cStrBuff[IDX_OLED_ROW_0]);
|
|
CDrawStr(0U, y, 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";
|
|
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*)" ", 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
|
|
if (row == (Uint16)IDX_OLED_ROW_2)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_2;
|
|
}
|
|
else if (row == (Uint16)IDX_OLED_ROW_3)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_3;
|
|
}
|
|
else
|
|
{
|
|
if (row == (Uint16)IDX_OLED_ROW_4)
|
|
{
|
|
y = (Uint16)IDX_OLED_LINE_4;
|
|
}
|
|
}
|
|
|
|
CDrawLineText(0U, y, OledOperValue.cStrBuff[row]);
|
|
}
|
|
|
|
static void CPageKeyTest(void)
|
|
{
|
|
// TITLE1
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_TITLE + 2U, "Button input Test");
|
|
|
|
// TITLE2
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_1 - 1U, "(Back to Up&Down)");
|
|
|
|
// BOX
|
|
CDrawKeyTestBox();
|
|
|
|
// LINE 2
|
|
CDrawKeyStatusLine((Uint16)IDX_OLED_ROW_2, " Stat:", ((GPIO_KEY_START() | GPIO_KEY_REMOTE_START() | GPIO_KEY_REMOTE_STOP()) == 0U) ? 1U : 0U, NULL, 0, NULL, 0);
|
|
|
|
// LINE 3
|
|
CDrawKeyStatusLine((Uint16)IDX_OLED_ROW_3, " Up:", (GPIO_KEY_UP() == 0U) ? 1U : 0U, "Entr:", (GPIO_KEY_ENTER() == 0U) ? 1U : 0U, "Powr:", (GPIO_KEY_POWER() == 0U) ? 1U : 0U);
|
|
|
|
// LINE 4
|
|
CDrawKeyStatusLine((Uint16)IDX_OLED_ROW_4, "Down:", (GPIO_KEY_DOWN() == 0U) ? 1U : 0U, "Menu:", (GPIO_KEY_MENU() == 0U) ? 1U : 0U, "Emgc:", ((GPIO_KEY_EMERGENCY() | GPIO_KEY_REMOTE_EMERGENCY()) == 0U) ? 1U : 0U);
|
|
}
|
|
|
|
static void CPageShutdown(void)
|
|
{
|
|
// LINE 1
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_1, "System");
|
|
|
|
// LINE 2
|
|
CDrawCenteredLine((Uint16)IDX_OLED_LINE_2, "Shutting down...");
|
|
}
|
|
|
|
void CSetPage(Uint16 PageNum)
|
|
{
|
|
static const CPageHandler PageTable[IDX_OLED_PAGE_MAX] =
|
|
{
|
|
{ IDX_OLED_PAGE_APU1, &CPageApu1 },
|
|
{ IDX_OLED_PAGE_APU2, &CPageApu2 },
|
|
{ IDX_OLED_PAGE_MENU1, &CPageMenu1 },
|
|
{ IDX_OLED_PAGE_MENU2, &CPageMenu2 },
|
|
{ IDX_OLED_PAGE_TEMP, &CPageTemp },
|
|
{ IDX_OLED_PAGE_SENSOR1, &CPageSensor1 },
|
|
{ IDX_OLED_PAGE_SENSOR2, &CPageSensor2 },
|
|
{ IDX_OLED_PAGE_SENSOR3, &CPageSensor3 },
|
|
{ IDX_OLED_PAGE_SENSOR4, &CPageSensor4 },
|
|
{ IDX_OLED_PAGE_WARNING1, &CPageWarning1 },
|
|
{ IDX_OLED_PAGE_WARNING2, &CPageWarning2 },
|
|
{ IDX_OLED_PAGE_FAULT1, &CPageFault1 },
|
|
{ IDX_OLED_PAGE_FAULT2, &CPageFault2 },
|
|
{ IDX_OLED_PAGE_FAULT3, &CPageFault3 },
|
|
{ IDX_OLED_PAGE_FAULT4, &CPageFault4 },
|
|
{ IDX_OLED_PAGE_FAULT5, &CPageFault5 },
|
|
{ IDX_OLED_PAGE_FAULT6, &CPageFault6 },
|
|
{ IDX_OLED_PAGE_FAULT7, &CPageFault7 },
|
|
{ IDX_OLED_PAGE_RESET_ALARM, &CPageAlarmReset },
|
|
{ IDX_OLED_PAGE_PASSWORD, &CPagePassword },
|
|
{ IDX_OLED_PAGE_MAINTENANCE, &CPageMaintenance },
|
|
{ IDX_OLED_PAGE_VERSION, &CPageVersion },
|
|
{ IDX_OLED_PAGE_KEY_TEST, &CPageKeyTest },
|
|
{ IDX_OLED_PAGE_SHUTDOWN, &CPageShutdown }
|
|
};
|
|
|
|
Uint16 i;
|
|
|
|
if (OledOperValue.uiOldPageNum != PageNum)
|
|
{
|
|
COledBufferReset();
|
|
OledOperValue.uiOldPageNum = PageNum;
|
|
}
|
|
|
|
for (i = 0U; i < (Uint16)IDX_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 != (Uint16)IDX_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 / 8U); j < ((y + height) / 8U); j++)
|
|
{
|
|
for (i = x; i < (x + width); i++)
|
|
{
|
|
CSetPageAddress(j);
|
|
CSetColumnAddress(i);
|
|
COledWrite(OledOperValue.uiBuff[i][j], MODE_DATA);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CInitOled(void)
|
|
{
|
|
Uint16 uiPageNum;
|
|
Uint16 i;
|
|
|
|
CInitOledModule();
|
|
|
|
for(uiPageNum = 0U; uiPageNum < 8U; uiPageNum++)
|
|
{
|
|
COledWrite((Uint16)(0xB0U | uiPageNum), (Uint16)MODE_COMMAND);
|
|
|
|
for(i = 0U; i < (Uint16)OLED_WIDTH; i++)
|
|
{
|
|
COledWrite((Uint16)0x00, (Uint16)MODE_DATA);
|
|
}
|
|
}
|
|
|
|
CInitProgress();
|
|
}
|
|
|
|
static void CInitProgress(void)
|
|
{
|
|
OledOperValue.Color.TxtColor = 1U;
|
|
|
|
CTextAlign(OledOperValue.cAlignBuffer, "K2 APU");
|
|
CDrawStr(0, (Uint16)IDX_OLED_LINE_TITLE, 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, (Uint16)IDX_OLED_LINE_2, OledOperValue.cAlignBuffer);
|
|
}
|
|
|
|
static void CAddLineIndent(int8 *buffer, const int8 *str)
|
|
{
|
|
Uint16 i;
|
|
Uint16 uiSpaceNeeded = ((Uint16)TXT_MAX_LEN - 1U) - CStrLen(buffer) - CStrLen(str);
|
|
|
|
if (uiSpaceNeeded > 0U)
|
|
{
|
|
for (i = 0U; i < uiSpaceNeeded; i++)
|
|
{
|
|
CStrncat(buffer, " ", 1U);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CTextAlign(int8 *buffer, const int8 *str)
|
|
{
|
|
Uint16 uiIndent, uiLen, i, j;
|
|
|
|
uiLen = 0U;
|
|
i = 0U;
|
|
|
|
while (str[i] != ASCII_NULL) // str은 int8* 이므로, int8 타입의 널 종료 값(0) 찾음
|
|
{
|
|
uiLen++;
|
|
i++;
|
|
}
|
|
|
|
if (uiLen >= (Uint16)TXT_MAX_LEN)
|
|
{
|
|
uiIndent = 0U;
|
|
}
|
|
else
|
|
{
|
|
uiIndent = (((Uint16)TXT_MAX_LEN - 1U) - uiLen) / 2U;
|
|
}
|
|
|
|
if ((uiIndent > 0U) && (uiIndent < (Uint16)TXT_MAX_LEN)) // 리소스 과도 소비 방지
|
|
{
|
|
for (i = 0U; i < uiIndent; i++)
|
|
{
|
|
buffer[i] = ASCII_BLANK;
|
|
}
|
|
|
|
for (j = 0U; j < uiLen; j++)
|
|
{
|
|
buffer[i + j] = str[j];
|
|
}
|
|
}
|
|
|
|
buffer[i + uiLen] = ASCII_NULL;
|
|
}
|
|
|
|
static 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, (h > 0U) ? (y + h - 1U) : y); // 우측 막대
|
|
}
|
|
|
|
static void CSetDrawRegion(Uint16 x, Uint16 y)
|
|
{
|
|
if (x > OledOperValue.Point.X)
|
|
{
|
|
OledOperValue.Point.X = x;
|
|
}
|
|
if (y > OledOperValue.Point.Y)
|
|
{
|
|
OledOperValue.Point.Y = y;
|
|
}
|
|
}
|
|
|
|
static void CDrawLine(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2)
|
|
{
|
|
Uint16 uiX1 = x1;
|
|
Uint16 uiY1 = y1;
|
|
Uint16 uiX2 = x2;
|
|
Uint16 uiY2 = y2;
|
|
|
|
Uint16 tmp = 0U, x = 0U, y = 0U, dx = 0U, dy = 0U, swapxy = 0U;
|
|
Uint16 loop_end = 0U;
|
|
Uint16 minor_limit = 0U; /* 보조축(y) 한계값 */
|
|
|
|
int16 err = 0;
|
|
int16 ystep = 0;
|
|
|
|
dx = uiX2 - uiX1;
|
|
dy = (uiY1 > uiY2) ? (uiY1 - uiY2) : (uiY2 - uiY1);
|
|
|
|
if (dy > dx)
|
|
{
|
|
swapxy = 1U;
|
|
tmp = dx; dx = dy; dy = tmp;
|
|
|
|
tmp = uiX1; uiX1 = uiY1; uiY1 = tmp;
|
|
tmp = uiX2; uiX2 = uiY2; uiY2 = tmp;
|
|
|
|
loop_end = (Uint16)OLED_HEIGHT - 1U;
|
|
minor_limit = (Uint16)OLED_WIDTH - 1U;
|
|
}
|
|
else
|
|
{
|
|
loop_end = (Uint16)OLED_WIDTH - 1U;
|
|
minor_limit = (Uint16)OLED_HEIGHT - 1U;
|
|
}
|
|
|
|
if (uiX2 > loop_end)
|
|
{
|
|
uiX2 = loop_end;
|
|
}
|
|
|
|
err = (int16)((Uint16)(dx >> 1U));
|
|
ystep = (uiY2 > uiY1) ? (int16)1 : (int16)-1;
|
|
y = uiY1;
|
|
|
|
if (swapxy == 0U)
|
|
{
|
|
for (x = uiX1; x <= uiX2; x++)
|
|
{
|
|
if (y > minor_limit)
|
|
{
|
|
break;
|
|
}
|
|
|
|
CPutPixel(x, y, OledOperValue.Color.TxtColor);
|
|
|
|
err = err - (int16)dy;
|
|
if (err < 0)
|
|
{
|
|
y = (ystep > 0) ? (y + (Uint16)ystep) : (y - (Uint16)(-ystep));
|
|
err = err + (int16)dx;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (x = uiX1; x <= uiX2; x++)
|
|
{
|
|
if (y > minor_limit)
|
|
{
|
|
break;
|
|
}
|
|
|
|
CPutPixel(y, x, OledOperValue.Color.TxtColor);
|
|
|
|
err = err - (int16)dy;
|
|
if (err < 0)
|
|
{
|
|
y = (ystep > 0) ? (y + (Uint16)ystep) : (y - (Uint16)(-ystep));
|
|
err = err + (int16)dx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void CPutPixel(Uint16 x, Uint16 y, Uint16 Color)
|
|
{
|
|
Uint16 uiPage;
|
|
Uint16 uiOffset;
|
|
|
|
if ((x < (Uint16)OLED_WIDTH) && (y < (Uint16)OLED_HEIGHT))
|
|
{
|
|
uiPage = y / 8U;
|
|
uiOffset = y % 8U;
|
|
|
|
if (Color == 1U)
|
|
{
|
|
OledOperValue.uiBuff[x][uiPage] = (Uint8)(OledOperValue.uiBuff[x][uiPage] | (Uint8)(1U << uiOffset));
|
|
}
|
|
else
|
|
{
|
|
OledOperValue.uiBuff[x][uiPage] = (Uint8)(OledOperValue.uiBuff[x][uiPage] & (Uint8)(~(Uint8)(1U << uiOffset)));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CSetPageAddress(Uint16 Address)
|
|
{
|
|
COledWrite((Uint16)(Address | 0xB0U), (Uint16)MODE_COMMAND);
|
|
}
|
|
|
|
static void CSetColumnAddress(Uint16 x)
|
|
{
|
|
Uint16 HighAddress;
|
|
Uint16 LowAddress;
|
|
|
|
x += 0U; // ER_OLEDM024-1G is +2, ER_OLEDM024-2G is +0
|
|
HighAddress = ((x >> 4) & 0x0FU) | 0x10U;
|
|
LowAddress = x & 0x0FU;
|
|
|
|
COledWrite(LowAddress, (Uint16)MODE_COMMAND);
|
|
COledWrite(HighAddress, (Uint16)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 = 2;
|
|
XintfRegs.XTIMING6.bit.XWRACTIVE = 12;
|
|
XintfRegs.XTIMING6.bit.XWRTRAIL = 2;
|
|
|
|
/* Zone read timing */
|
|
XintfRegs.XTIMING6.bit.XRDLEAD = 2;
|
|
XintfRegs.XTIMING6.bit.XRDACTIVE = 12;
|
|
XintfRegs.XTIMING6.bit.XRDTRAIL = 2;
|
|
|
|
XintfRegs.XTIMING6.bit.X2TIMING = 0;
|
|
XintfRegs.XTIMING6.bit.USEREADY = 0;
|
|
XintfRegs.XTIMING6.bit.READYMODE = 0;
|
|
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;
|
|
}
|
|
|
|
static void CDrawStr(Uint16 x, Uint16 y, const int8* str)
|
|
{
|
|
Uint16 i = 0U;
|
|
|
|
if (str != NULL)
|
|
{
|
|
/* 널 문자를 만나거나 최대 한계에 도달할 때까지 그리기 수행 */
|
|
while ((str[i] != ASCII_NULL) && (i < (Uint16)TXT_MAX_LEN))
|
|
{
|
|
if (((Uint8)str[i] & 0x80U) != 0U)
|
|
{
|
|
CDrawChar(x, y, (Uint16)(((Uint16)str[i] << 8U) | (Uint16)str[i + 1U]), TXT_TYPE_ETC);
|
|
i++;
|
|
x += (TXT_ENG_WIDTH * 2U);
|
|
}
|
|
else
|
|
{
|
|
CDrawChar(x, y, (Uint16)str[i], TXT_TYPE_ENG);
|
|
x += TXT_ENG_WIDTH;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CDrawChar(Uint16 x, Uint16 y, Uint16 ch, Uint16 type)
|
|
{
|
|
// 영문 폰트 테이블 인덱스에 따른 값은 Description\font.txt 참조
|
|
static const Uint16 EngFontTable[96][9] =
|
|
{
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x41, 0x04, 0x10, 0x41, 0x00, 0x10, 0x40, 0x00 }, { 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x14, 0x57, 0xCA, 0x28, 0xAF, 0xD4, 0x51, 0x40, 0x00 }, { 0x10, 0xE5, 0x54, 0x30, 0x61, 0x45, 0x54, 0xE1, 0x00 }, { 0x25, 0x55, 0x8A, 0x10, 0x42, 0x8D, 0x55, 0x20, 0x00 },
|
|
{ 0x31, 0x24, 0x92, 0x31, 0x54, 0x92, 0x48, 0xD0, 0x00 }, { 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x08, 0x41, 0x08, 0x20, 0x82, 0x08, 0x20, 0x41, 0x02 },
|
|
{ 0x20, 0x41, 0x02, 0x08, 0x20, 0x82, 0x08, 0x41, 0x08 }, { 0x00, 0x00, 0x04, 0x11, 0xF1, 0x0A, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x04, 0x11, 0xF1, 0x04, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x00 }, { 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00 },
|
|
{ 0x04, 0x10, 0x82, 0x10, 0x42, 0x08, 0x41, 0x00, 0x00 }, { 0x39, 0x14, 0x51, 0x45, 0x14, 0x51, 0x44, 0xE0, 0x00 }, { 0x10, 0xC1, 0x04, 0x10, 0x41, 0x04, 0x10, 0x40, 0x00 },
|
|
{ 0x39, 0x14, 0x41, 0x08, 0x42, 0x10, 0x41, 0xF0, 0x00 }, { 0x39, 0x14, 0x41, 0x18, 0x10, 0x51, 0x44, 0xE0, 0x00 }, { 0x08, 0x61, 0x8A, 0x29, 0x24, 0x9F, 0x08, 0x20, 0x00 },
|
|
{ 0x7D, 0x04, 0x10, 0x79, 0x10, 0x41, 0x44, 0xE0, 0x00 }, { 0x39, 0x14, 0x10, 0x79, 0x14, 0x51, 0x44, 0xE0, 0x00 }, { 0x7D, 0x14, 0x41, 0x08, 0x21, 0x04, 0x10, 0x40, 0x00 },
|
|
{ 0x39, 0x14, 0x51, 0x39, 0x14, 0x51, 0x44, 0xE0, 0x00 }, { 0x39, 0x14, 0x51, 0x44, 0xF0, 0x41, 0x44, 0xE0, 0x00 }, { 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00 },
|
|
{ 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x10, 0x80, 0x00 }, { 0x00, 0x00, 0x42, 0x31, 0x03, 0x02, 0x04, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x7C, 0x07, 0xC0, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x04, 0x08, 0x18, 0x11, 0x88, 0x40, 0x00, 0x00 }, { 0x39, 0x14, 0x41, 0x08, 0x41, 0x00, 0x10, 0x40, 0x00 }, { 0x18, 0x94, 0xD5, 0x55, 0x55, 0x57, 0x40, 0xE0, 0x00 },
|
|
{ 0x10, 0x41, 0x0A, 0x28, 0xA7, 0xD1, 0x45, 0x10, 0x00 }, { 0x79, 0x14, 0x51, 0x79, 0x14, 0x51, 0x45, 0xE0, 0x00 }, { 0x39, 0x14, 0x50, 0x41, 0x04, 0x11, 0x44, 0xE0, 0x00 },
|
|
{ 0x79, 0x14, 0x51, 0x45, 0x14, 0x51, 0x45, 0xE0, 0x00 }, { 0x7D, 0x04, 0x10, 0x7D, 0x04, 0x10, 0x41, 0xF0, 0x00 }, { 0x7D, 0x04, 0x10, 0x79, 0x04, 0x10, 0x41, 0x00, 0x00 },
|
|
{ 0x39, 0x14, 0x50, 0x5D, 0x14, 0x51, 0x4C, 0xD0, 0x00 }, { 0x45, 0x14, 0x51, 0x7D, 0x14, 0x51, 0x45, 0x10, 0x00 }, { 0x10, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x40, 0x00 },
|
|
{ 0x08, 0x20, 0x82, 0x08, 0x20, 0x92, 0x48, 0xC0, 0x00 }, { 0x45, 0x24, 0x94, 0x61, 0x45, 0x12, 0x49, 0x10, 0x00 }, { 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x41, 0xF0, 0x00 },
|
|
{ 0x45, 0x16, 0xDB, 0x6D, 0x55, 0x55, 0x45, 0x10, 0x00 }, { 0x45, 0x16, 0x59, 0x55, 0x54, 0xD3, 0x45, 0x10, 0x00 }, { 0x39, 0x14, 0x51, 0x45, 0x14, 0x51, 0x44, 0xE0, 0x00 },
|
|
{ 0x79, 0x14, 0x51, 0x45, 0xE4, 0x10, 0x41, 0x00, 0x00 }, { 0x39, 0x14, 0x51, 0x45, 0x14, 0x51, 0x54, 0xE0, 0x40 }, { 0x79, 0x14, 0x51, 0x45, 0xE4, 0x91, 0x45, 0x10, 0x00 },
|
|
{ 0x39, 0x14, 0x48, 0x10, 0x20, 0x51, 0x44, 0xE0, 0x00 }, { 0x7C, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x40, 0x00 }, { 0x45, 0x14, 0x51, 0x45, 0x14, 0x51, 0x44, 0xE0, 0x00 },
|
|
{ 0x45, 0x14, 0x51, 0x28, 0xA2, 0x84, 0x10, 0x40, 0x00 }, { 0x55, 0x55, 0x55, 0x55, 0x55, 0x4A, 0x28, 0xA0, 0x00 }, { 0x45, 0x12, 0x8A, 0x10, 0x42, 0x8A, 0x45, 0x10, 0x00 },
|
|
{ 0x45, 0x14, 0x4A, 0x28, 0x41, 0x04, 0x10, 0x40, 0x00 }, { 0x7C, 0x10, 0x82, 0x10, 0x42, 0x08, 0x41, 0xF0, 0x00 }, { 0x30, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, 0x0C },
|
|
{ 0x55, 0x55, 0x7F, 0x55, 0x55, 0x4A, 0x28, 0xA0, 0x00 }, { 0x30, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x41, 0x0C }, { 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0 }, { 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x0C, 0x48, 0xE4, 0x92, 0x48, 0xD0, 0x00 },
|
|
{ 0x41, 0x04, 0x1E, 0x45, 0x14, 0x51, 0x45, 0xE0, 0x00 }, { 0x00, 0x00, 0x0E, 0x45, 0x04, 0x10, 0x44, 0xE0, 0x00 }, { 0x04, 0x10, 0x4F, 0x45, 0x14, 0x51, 0x44, 0xF0, 0x00 },
|
|
{ 0x00, 0x00, 0x0E, 0x45, 0x17, 0xD0, 0x44, 0xE0, 0x00 }, { 0x10, 0x82, 0x1C, 0x20, 0x82, 0x08, 0x20, 0x80, 0x00 }, { 0x00, 0x00, 0x0F, 0x45, 0x14, 0x4F, 0x05, 0x13, 0x80 },
|
|
{ 0x41, 0x04, 0x1E, 0x45, 0x14, 0x51, 0x45, 0x10, 0x00 }, { 0x10, 0x40, 0x04, 0x10, 0x41, 0x04, 0x10, 0x40, 0x00 }, { 0x10, 0x40, 0x04, 0x10, 0x41, 0x04, 0x10, 0x46, 0x00 },
|
|
{ 0x41, 0x04, 0x11, 0x49, 0x46, 0x14, 0x49, 0x10, 0x00 }, { 0x00, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x40, 0x00 }, { 0x00, 0x00, 0x1A, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00 },
|
|
{ 0x00, 0x00, 0x1E, 0x45, 0x14, 0x51, 0x45, 0x10, 0x00 }, { 0x00, 0x00, 0x0E, 0x45, 0x14, 0x51, 0x44, 0xE0, 0x00 }, { 0x00, 0x00, 0x1E, 0x45, 0x14, 0x51, 0x79, 0x04, 0x00 },
|
|
{ 0x00, 0x00, 0x0F, 0x45, 0x14, 0x51, 0x3C, 0x10, 0x40 }, { 0x00, 0x00, 0x0B, 0x30, 0x82, 0x08, 0x20, 0x80, 0x00 }, { 0x00, 0x00, 0x0E, 0x45, 0x03, 0x81, 0x44, 0xE0, 0x00 },
|
|
{ 0x00, 0x82, 0x1E, 0x20, 0x82, 0x08, 0x20, 0x60, 0x00 }, { 0x00, 0x00, 0x11, 0x45, 0x14, 0x51, 0x44, 0xF0, 0x00 }, { 0x00, 0x00, 0x11, 0x45, 0x12, 0x8A, 0x10, 0x40, 0x00 },
|
|
{ 0x00, 0x00, 0x15, 0x55, 0x55, 0x4E, 0x28, 0xA0, 0x00 }, { 0x00, 0x00, 0x11, 0x44, 0xA1, 0x0A, 0x45, 0x10, 0x00 }, { 0x00, 0x00, 0x11, 0x45, 0x12, 0x8A, 0x10, 0x46, 0x00 },
|
|
{ 0x00, 0x00, 0x1F, 0x04, 0x21, 0x08, 0x41, 0xF0, 0x00 }, { 0x08, 0x41, 0x04, 0x11, 0x81, 0x04, 0x10, 0x41, 0x02 }, { 0x10, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x41, 0x04 },
|
|
{ 0x40, 0x82, 0x08, 0x20, 0x62, 0x08, 0x20, 0x82, 0x10 }, { 0x00, 0x00, 0x00, 0x00, 0xD4, 0x80, 0x00, 0x00, 0x00 }, { 0x01, 0xE4, 0x92, 0x49, 0x24, 0x92, 0x49, 0xE0, 0x00 },
|
|
};
|
|
|
|
static const Uint16 TemperatureFont[18] = { 0x00, 0x02, 0x00, 0x53, 0x82, 0x44, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x04, 0x40, 0x38, 0x00, 0x00, 0x00 }; // ℃, A1C9
|
|
static const Uint16 uiBitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
|
const Uint16* pFontData;
|
|
Uint16 uiFontIndex = 0;
|
|
Uint16 i, j;
|
|
Uint16 uiCharWidth;
|
|
|
|
if (type == 0U) // Eng Char
|
|
{
|
|
uiCharWidth = (Uint16)TXT_ENG_WIDTH;
|
|
ch -= 0x20U; // font offset
|
|
ch = (ch > 95U) ? 0U : ch;
|
|
pFontData = EngFontTable[ch];
|
|
}
|
|
else
|
|
{
|
|
uiCharWidth = (Uint16)TXT_ENG_WIDTH * 2U;
|
|
pFontData = TemperatureFont;
|
|
}
|
|
|
|
CSetDrawRegion((x + (Uint16)TXT_ENG_WIDTH), (y + (Uint16)TXT_ENG_HEIGHT));
|
|
|
|
for(j = 0U; j < (Uint16)TXT_ENG_HEIGHT; j++)
|
|
{
|
|
for(i = 0U; i < uiCharWidth; i++)
|
|
{
|
|
if (((Uint8)pFontData[uiFontIndex / 8U] & uiBitMask[uiFontIndex % 8U]) != 0U)
|
|
{
|
|
CPutPixel((x + i), (y + j), OledOperValue.Color.TxtColor);
|
|
}
|
|
else
|
|
{
|
|
CPutPixel((x + i), (y + j), OledOperValue.Color.BgColor);
|
|
}
|
|
uiFontIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CInitOledModule(void)
|
|
{
|
|
GpioDataRegs.GPBSET.bit.GPIO37 = 1U; // GPIO_OLED_RESET
|
|
DELAY_USEC(2000);
|
|
GpioDataRegs.GPBCLEAR.bit.GPIO37 = 1U; // GPIO_OLED_RESET
|
|
DELAY_USEC(2000);
|
|
GpioDataRegs.GPBSET.bit.GPIO37 = 1U; // GPIO_OLED_RESET
|
|
DELAY_USEC(2000);
|
|
|
|
COledWrite((Uint16)0xFD, (Uint16)MODE_COMMAND); // Command Lock
|
|
COledWrite((Uint16)0x12, (Uint16)MODE_COMMAND); //
|
|
COledWrite((Uint16)0xAE, (Uint16)MODE_COMMAND); // oled off
|
|
COledWrite((Uint16)0xA1, (Uint16)MODE_COMMAND); // 1U segment column address high to low
|
|
|
|
COledWrite((Uint16)0xC8, (Uint16)MODE_COMMAND); // COM output scan from high to low
|
|
|
|
COledWrite((Uint16)0x81, (Uint16)MODE_COMMAND); // 1U contrast
|
|
COledWrite((Uint16)0xFF, (Uint16)MODE_COMMAND);
|
|
|
|
COledWrite((Uint16)0xAF, (Uint16)MODE_COMMAND); // oled on
|
|
|
|
CInitOledStructure();
|
|
OledOperValue.uiProgressValue = (Uint16)OLED_LOAD_PROGRESS_X + 1U;
|
|
}
|
|
|
|
void CDisplayAntiNoiseRefresh(void)
|
|
{
|
|
COledWrite((Uint16)0xFD, (Uint16)MODE_COMMAND);
|
|
COledWrite((Uint16)0x12, (Uint16)MODE_COMMAND);
|
|
|
|
/* 화면 방향 및 스캔 방향 재설정 (뒤집힘 방지) */
|
|
COledWrite((Uint16)0xA1, (Uint16)MODE_COMMAND); /* Segment Remap: Column Address high to low */
|
|
COledWrite((Uint16)0xC8, (Uint16)MODE_COMMAND); /* COM Output Scan: high to low */
|
|
|
|
/* 명암비(Contrast) 재설정 */
|
|
COledWrite((Uint16)0x81, (Uint16)MODE_COMMAND);
|
|
COledWrite((Uint16)0xFF, (Uint16)MODE_COMMAND);
|
|
|
|
/* Display ON 유지 확인 (노이즈로 화면이 꺼졌을 경우) */
|
|
COledWrite((Uint16)0xAF, (Uint16)MODE_COMMAND);
|
|
}
|
|
|
|
static void COledWrite(Uint16 Data, Uint16 Command)
|
|
{
|
|
if (Command == (Uint16)MODE_COMMAND)
|
|
{
|
|
CommandBus = Data;
|
|
}
|
|
else
|
|
{
|
|
DataBus = Data;
|
|
}
|
|
}
|
|
|
|
static void CInitOledStructure(void)
|
|
{
|
|
(void)memset(&OledOperValue, 0, sizeof(COledOperValue));
|
|
|
|
OledOperValue.uiResetAlarmAnswer = 1U;
|
|
}
|
|
|
|
void CInitKeyOperValue(void)
|
|
{
|
|
(void)memset(&KeyOperValue, 0, sizeof(CKeyOperValue));
|
|
}
|
|
|
|
static Uint16 CStrLen(const int8 *s)
|
|
{
|
|
Uint16 uiLen = 0U;
|
|
|
|
if (s != NULL)
|
|
{
|
|
while (s[uiLen] != ASCII_NULL)
|
|
{
|
|
uiLen++;
|
|
}
|
|
}
|
|
|
|
return uiLen;
|
|
}
|
|
static void CStrncpy(int8 *pTarget, const int8 *pSource, Uint16 Size)
|
|
{
|
|
Uint16 i;
|
|
Uint16 uiSafeLimit;
|
|
|
|
uiSafeLimit = (Size >= TXT_MAX_LEN) ? (TXT_MAX_LEN - 1U) : Size;
|
|
|
|
//for (i = 0U; i < uiSafeLimit; i++)
|
|
for (i = 0U; (i < uiSafeLimit) && (i < (TXT_MAX_LEN - 1U)); i++)
|
|
{
|
|
pTarget[i] = pSource[i];
|
|
}
|
|
|
|
pTarget[i] = ASCII_NULL;
|
|
}
|
|
|
|
static void CStrncat(int8 *pTarget, const int8 *pSource, Uint16 Size)
|
|
{
|
|
Uint16 i;
|
|
Uint16 uiTargetSize;
|
|
Uint16 uiRemainSpace;
|
|
Uint16 uiSafeLimit;
|
|
|
|
uiTargetSize = 0U;
|
|
|
|
if (pTarget != NULL)
|
|
{
|
|
/* 함수를 부르지 않고, 해당 위치에서 직접 널 문자를 찾을 때까지 카운트 (FUNCR 증가 없음) */
|
|
while (pTarget[uiTargetSize] != ASCII_NULL)
|
|
{
|
|
uiTargetSize++;
|
|
}
|
|
}
|
|
|
|
if (uiTargetSize < (Uint16)(TXT_MAX_LEN - 1U))
|
|
{
|
|
uiRemainSpace = (Uint16)((Uint16)(TXT_MAX_LEN - 1U) - uiTargetSize);
|
|
|
|
uiSafeLimit = (Size >= uiRemainSpace) ? uiRemainSpace : Size;
|
|
|
|
for (i = 0U; (i < uiSafeLimit) && ((uiTargetSize + i) < (Uint16)(TXT_MAX_LEN - 1U)); i++)
|
|
{
|
|
pTarget[uiTargetSize + i] = pSource[i];
|
|
}
|
|
|
|
pTarget[uiTargetSize + i] = ASCII_NULL;
|
|
}
|
|
}
|
|
|
|
static void CDecToString(int16 Data, int8 *Array, Uint16 ArrayLen)
|
|
{
|
|
Uint16 uiSign = 0U; // 음수 여부 플래그 (1이면 음수)
|
|
Uint16 uiSignLocate = 0U; // '-' 부호가 들어갈 배열 인덱스 위치
|
|
Uint16 i;
|
|
Uint16 x = 0U; // cTmp에 추출된 숫자의 개수 (자릿수 카운트)
|
|
Uint16 y = 0U; // 최종 문자열 Array에 값을 써넣을 인덱스
|
|
|
|
int32 lData = (int32)Data * 10;
|
|
|
|
// 추출된 각 자리의 숫자를 임시로 저장할 버퍼 (역순으로 저장됨)
|
|
int8 cTmp[6] = { ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL };
|
|
|
|
// 출력할 배열 전체를 공백(ASCII 32 = ' ')으로 초기화
|
|
for (i = 0U; (i < ArrayLen) && (i < TXT_MAX_LEN); i++)
|
|
{
|
|
Array[i] = ASCII_BLANK;
|
|
}
|
|
|
|
// 음수 판별 및 절대값(양수) 변환
|
|
if (lData < 0)
|
|
{
|
|
uiSign = 1U;
|
|
lData = -lData;
|
|
}
|
|
|
|
// 1의 자리부터 역순으로 숫자를 추출하여 ASCII 문자(ASCII 48 = '0')로 변환
|
|
while ((lData > 0) && (x < 6U))
|
|
{
|
|
cTmp[x] = (int8)((lData % 10) + 48);
|
|
x++;
|
|
lData /= 10;
|
|
}
|
|
|
|
// 추출한 숫자를 최종 배열에 배치 (우측 정렬 적용)
|
|
if (x == 0U)
|
|
{
|
|
// 수치가 0인 경우, 지정된 고정 위치(y=3)에 '0' 표시
|
|
y = 4U;
|
|
if (y < ArrayLen)
|
|
{
|
|
Array[y] = ASCII_0;
|
|
y++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (x > 0U)
|
|
{
|
|
// 앞서 '* 10'으로 부풀리며 추가되었던 최하위 숫자(0)를 버리기 위해 인덱스를 1 감소시킴
|
|
x = (Uint16)(x - 1U);
|
|
}
|
|
|
|
// 전체 폭(5칸 기준)에서 자릿수를 빼서, 문자가 쓰이기 시작할 시작 위치(y) 계산
|
|
y = (x <= 5U) ? (Uint16)(5U - x) : 0U;
|
|
|
|
// 부호('-')가 들어갈 자리 지정 (숫자가 시작되는 곳의 바로 앞 칸)
|
|
if (y < 1U)
|
|
{
|
|
uiSignLocate = 0U;
|
|
}
|
|
else if (y <= 5U)
|
|
{
|
|
uiSignLocate = (Uint16)(y - 1U);
|
|
}
|
|
else
|
|
{
|
|
uiSignLocate = 0U;
|
|
}
|
|
|
|
// 계산된 부호 위치에 '-' 또는 공백 삽입
|
|
if (uiSign == 1U)
|
|
{
|
|
if ((uiSignLocate > 0U) && (uiSignLocate < 6U) && (uiSignLocate < ArrayLen))
|
|
{
|
|
Array[uiSignLocate] = ASCII_MINUS; // '-'
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (uiSignLocate < ArrayLen)
|
|
{
|
|
Array[uiSignLocate] = ASCII_BLANK; // ' '
|
|
}
|
|
}
|
|
|
|
while ((x > 0U) && (x < 6U) && (y < ArrayLen) && (y < TXT_MAX_LEN))
|
|
{
|
|
Array[y] = cTmp[x];
|
|
y++;
|
|
x = (Uint16)(x - 1U); // 인덱스 감소
|
|
}
|
|
}
|
|
|
|
// 문자열의 끝을 알리는 널(NULL, ASCII 0) 문자 삽입하여 문자열 완성
|
|
if ((y < ArrayLen) && (y < TXT_MAX_LEN))
|
|
{
|
|
Array[y] = ASCII_NULL;
|
|
}
|
|
else
|
|
{
|
|
if (ArrayLen > 0U)
|
|
{
|
|
Array[(Uint16)(ArrayLen - 1U)] = ASCII_NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CFloatToString(float32 Data, int8 *Array, Uint16 ArrayLen)
|
|
{
|
|
int32 iTemp; // 음수 처리를 위해 signed int32 사용 (범위 확보)
|
|
Uint16 isNegative = 0U; // 음수 여부 플래그
|
|
int8 cTmp[10]; // 임시 변환 버퍼
|
|
Uint16 len = 0U; // 현재 변환된 문자 길이
|
|
Uint16 i;
|
|
Uint16 startIdx; // 최종 배열에 복사할 시작 위치
|
|
|
|
for (i = 0U; (i < ArrayLen) && (i < TXT_MAX_LEN); i++)
|
|
{
|
|
Array[i] = ASCII_BLANK; // ' '
|
|
}
|
|
|
|
// 음수 확인 및 양수 변환
|
|
if (Data < 0.0F)
|
|
{
|
|
isNegative = 1U;
|
|
Data = -Data; // 절대값으로 변환
|
|
}
|
|
|
|
// 소수점 1자리 정수로 변환 (예: 12.34 -> 123.4 -> 123)
|
|
iTemp = (int32)((float32)((Data * 10.0F) + 0.5F));
|
|
|
|
// 소수점 첫째 자리 추출
|
|
cTmp[len++] = (int8)((int8)(iTemp % 10) + ASCII_0); // '0'
|
|
iTemp /= 10;
|
|
|
|
// 소수점 문자 추가
|
|
cTmp[len++] = ASCII_DOT; // '.'
|
|
|
|
// 정수부 추출
|
|
if (iTemp == 0)
|
|
{
|
|
cTmp[len++] = ASCII_0; // 0.x 인 경우 정수부 '0' 추가
|
|
}
|
|
else
|
|
{
|
|
while (iTemp > 0)
|
|
{
|
|
cTmp[len++] = (int8)((int32)(iTemp % 10) + (int32)ASCII_0);
|
|
iTemp /= 10;
|
|
}
|
|
}
|
|
|
|
// 부호 추가
|
|
if (isNegative == 1U)
|
|
{
|
|
cTmp[len++] = ASCII_MINUS; // '-'
|
|
}
|
|
|
|
// 최종 배열에 복사 (우측 정렬, 총 6자리 제한)
|
|
|
|
// 만약 변환된 길이가 6자리를 넘으면 6자리로 자름
|
|
if (len > 6U)
|
|
{
|
|
len = 6U;
|
|
}
|
|
|
|
if (ArrayLen >= 7U) // ArrayLen 보호
|
|
{
|
|
startIdx = 6U - len;
|
|
|
|
for (i = 0U; i < len; i++)
|
|
{
|
|
Array[startIdx + i] = cTmp[len - 1U - i]; // cTmp는 역순이므로 len-1-i 로 접근
|
|
}
|
|
|
|
Array[6] = ASCII_NULL;
|
|
}
|
|
}
|
|
|
|
void CInitializePage(void)
|
|
{
|
|
CDrawLine((Uint16)(OledOperValue.uiProgressValue + 1U), (Uint16)(OLED_LOAD_PROGRESS_Y + 2U), (Uint16)(OledOperValue.uiProgressValue + 1U), (Uint16)(OLED_LOAD_PROGRESS_Y + 8U));
|
|
if (OledOperValue.uiProgressValue < (Uint16)OLED_LOAD_PROGRESS_W - 3U) // -3은 프로그래스 바의 좌우측 1픽셀 공간 줌.
|
|
{
|
|
OledOperValue.uiProgressValue++;
|
|
}
|
|
else
|
|
{
|
|
OledOperValue.uiProgressDone = 1U;
|
|
}
|
|
}
|
|
|
|
void CDisplayPostFail(void)
|
|
{
|
|
CDrawCenteredLine(IDX_OLED_LINE_TITLE, "Power On Self-Test");
|
|
CDrawCenteredLine(IDX_OLED_LINE_1, "(P:PASS F:FAIL)");
|
|
|
|
// LINE 2
|
|
CDrawPostStatusLine(IDX_OLED_ROW_2, "EHT:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_ENGINE_HEATER], "GPL:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_GLOW_PLUG], "SOL:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_SOLENOID]);
|
|
|
|
// LINE 3
|
|
CDrawPostStatusLine(IDX_OLED_ROW_3, "FUP:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_FUEL_PUMP], "CLP:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_COOLANT_PUMP], "FN1:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_FAN1]);
|
|
|
|
// LINE 4
|
|
// Only FN2
|
|
CDrawPostStatusLine(IDX_OLED_ROW_4, " FN2:", PowerOnCheckSensor[(Uint16)IDX_SENSOR_FAN2], 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;
|
|
}
|
|
}
|
|
|
|
static void CMakeVersionString(int8 Buffer[], int16 v1, int16 v2, int16 v3)
|
|
{
|
|
int16 verArray[3];
|
|
int16 i, k;
|
|
int16 num;
|
|
int8 tempArr[6] = { ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL, ASCII_NULL };
|
|
int16 tempIdx;
|
|
Uint16 currentIdx = 0U; // 함수 내부에서 0부터 시작
|
|
|
|
verArray[0] = v1;
|
|
verArray[1] = v2;
|
|
verArray[2] = v3;
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
num = verArray[i];
|
|
tempIdx = 0;
|
|
|
|
// 숫자 -> 문자 변환
|
|
if (num == 0)
|
|
{
|
|
tempArr[tempIdx++] = ASCII_0; // '0'
|
|
}
|
|
else
|
|
{
|
|
if (num < 0) { num = -num; }
|
|
while (num > 0)
|
|
{
|
|
tempArr[tempIdx++] = (int8)((num % 10) + ASCII_0); // '0'
|
|
num /= 10;
|
|
}
|
|
}
|
|
|
|
// 2. 버퍼에 기록
|
|
for (k = (tempIdx - 1); k >= 0; k--)
|
|
{
|
|
Buffer[currentIdx++] = tempArr[k];
|
|
}
|
|
|
|
// 3. 점(.) 찍기 (마지막 아닐 때만)
|
|
if (i < 2)
|
|
{
|
|
Buffer[currentIdx++] = ASCII_DOT; // '.'
|
|
}
|
|
}
|
|
|
|
// ★ 문자열 끝 처리 (함수 안으로 이동됨)
|
|
Buffer[currentIdx] = ASCII_NULL;
|
|
}
|
|
|
|
static void CHourToString(int32 num, int8 *str)
|
|
{
|
|
Uint16 i = 0U;
|
|
Uint16 end;
|
|
Uint32 temp = (Uint32)num; // 입력받은 값 (예: 1234567 -> "12345.67")
|
|
|
|
// 소수점 둘째 자리 (100분의 1)
|
|
str[i++] = (int8)((Uint32)((temp % 10U) + (Uint32)ASCII_0));
|
|
temp = temp / 10U;
|
|
|
|
// 소수점 첫째 자리 (10분의 1)
|
|
str[i++] = (int8)((Uint32)((temp % 10U) + (Uint32)ASCII_0));
|
|
temp = temp / 10U;
|
|
|
|
// 소수점 삽입
|
|
str[i++] = ASCII_DOT;
|
|
|
|
// 정수부 변환, 입력이 0이어도 최소 "0"은 찍히도록 do-while 사용
|
|
do
|
|
{
|
|
str[i++] = (int8)((Uint32)((temp % 10U) + (Uint32)ASCII_0));
|
|
temp = temp / 10U;
|
|
}
|
|
while (temp != 0U);
|
|
|
|
// 공백 채우기 (자리수 맞춤), 정수5자리 + 점1자리 + 소수2자리 = 총 8자리
|
|
while (i < 8U)
|
|
{
|
|
str[i++] = ASCII_BLANK;
|
|
}
|
|
|
|
str[i] = ASCII_NULL; // 문자열 끝
|
|
|
|
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(Uint16 idx)
|
|
{
|
|
static const int8* const strTable[] =
|
|
{
|
|
"BOOT", // 0
|
|
"INIT", // 1
|
|
"POST", // 2
|
|
"EMERGENCY", // 3
|
|
"STANDBY", // 4
|
|
"READY", // 5
|
|
"PREHEAT", // 6
|
|
"CRANKING", // 7
|
|
"", // 8: RETRY (동적 처리)
|
|
"IDLE", // 9
|
|
"GENERATING", // 10
|
|
"COOLDOWN", // 11
|
|
"STOPPING" // 12
|
|
};
|
|
|
|
static int8 strBuffer[12];
|
|
const int8* pRetVal = strTable[idx];
|
|
|
|
if (idx == (Uint16)IDX_APU_OPER_RETRY_CRANKING)
|
|
{
|
|
Uint16 count = GeneralOperValue.uiRetryCrankingCount + 1U;
|
|
|
|
strBuffer[0] = ASCII_R; // 'R'
|
|
strBuffer[1] = ASCII_E; // 'E'
|
|
strBuffer[2] = ASCII_T; // 'T'
|
|
strBuffer[3] = ASCII_R; // 'R'
|
|
strBuffer[4] = ASCII_Y; // 'Y'
|
|
strBuffer[5] = ASCII_L_PAREN; // '('
|
|
strBuffer[6] = (ASCII_0 + (int8)count);
|
|
strBuffer[7] = ASCII_R_PAREN; // ')'
|
|
strBuffer[8] = ASCII_NULL; //'\0'
|
|
|
|
pRetVal = (const int8*)strBuffer;
|
|
}
|
|
|
|
return pRetVal;
|
|
}
|
|
|
|
static void CCopyStr(int8 *pTarget, const int8 *pSource)
|
|
{
|
|
Uint16 i = 0U;
|
|
|
|
if ((pTarget != NULL) && (pSource != NULL))
|
|
{
|
|
while ((pSource[i] != ASCII_NULL) && (i < (Uint16)(TXT_MAX_LEN - 1U)))
|
|
{
|
|
pTarget[i] = pSource[i];
|
|
i++;
|
|
}
|
|
pTarget[i] = ASCII_NULL;
|
|
}
|
|
}
|
|
|
|
static void CAppendStr(int8 *pTarget, const int8 *pSource)
|
|
{
|
|
Uint16 i = 0U;
|
|
Uint16 j = 0U;
|
|
|
|
if ((pTarget != NULL) && (pSource != NULL))
|
|
{
|
|
while ((pTarget[i] != ASCII_NULL) && (i < (Uint16)(TXT_MAX_LEN - 1U)))
|
|
{
|
|
i++;
|
|
}
|
|
|
|
while ((pSource[j] != ASCII_NULL) && ((i + j) < (Uint16)(TXT_MAX_LEN - 1U)))
|
|
{
|
|
pTarget[i + j] = pSource[j];
|
|
j++;
|
|
}
|
|
pTarget[i + j] = ASCII_NULL;
|
|
}
|
|
}
|
|
|
|
static void CDrawLineText(Uint16 x, Uint16 y, const int8* str)
|
|
{
|
|
CDrawStr(x, y, str);
|
|
}
|
|
|
|
static void CDrawFaultStatusLine(Uint16 row, const int8* label1, Uint16 status1, const int8* label2, Uint16 status2)
|
|
{
|
|
CDrawTwoStatusLine(row, label1, status1, label2, status2);
|
|
}
|
|
|
|
static void CDrawSimpleLine(Uint16 row, const int8* label)
|
|
{
|
|
CDrawPageLine(row, label, NULL, NULL);
|
|
}
|
|
|
|
static void CDrawStatusTitle(const int8* title, const int8* pageNumStr)
|
|
{
|
|
CDrawPageTitle(title, pageNumStr);
|
|
}
|
|
|
|
static void CDrawSensorTitle(const int8* title, const int8* pageNumStr)
|
|
{
|
|
CDrawPageTitle(title, pageNumStr);
|
|
}
|
|
|
|
static void CDrawFaultTitle(const int8* title, const int8* pageNumStr)
|
|
{
|
|
CDrawPageTitle(title, pageNumStr);
|
|
}
|