commit 2f07b5dd006df618d7678ec7591b6fa44b83bd9c Author: 김호수 Date: Tue Apr 14 01:03:11 2026 +0900 Upload files to "/" diff --git a/Comm.c b/Comm.c new file mode 100644 index 0000000..e2725c6 --- /dev/null +++ b/Comm.c @@ -0,0 +1,1436 @@ +/* ========================================================================= */ +/* 1. Includes */ +/* ========================================================================= */ +#include "main.h" + +/* ========================================================================= */ +/* 2. Local Macros & Constants (내부 전용 매크로 및 상수) */ +/* ========================================================================= */ + +/* ========================================================================= */ +/* 3. Local Typedefs & Structures (내부 전용 사용자 정의 자료형) */ +/* ========================================================================= */ +static CTx100 Tx100; +static CTx101 Tx101; +static CTx102 Tx102; // Command Data +static CTx103 Tx103; // Command Data +static CTx110 Tx110; +static CTx120 Tx120; +static CTx121 Tx121; +static CTx122 Tx122; +static CTx123 Tx123; +static CTx124 Tx124; + +static CTx700 Tx700; +static CTx701 Tx701; +static CTx710 Tx710; +static CTx720 Tx720; +static CTx730 Tx730; +static CTx731 Tx731; +static CTx732 Tx732; +static CTx733 Tx733; +static CTx734 Tx734; +static CTx740 Tx740; +static CTx741 Tx741; +static CTx750 Tx750; +static CTx751 Tx751; +static CTx752 Tx752; + +static CRx201 Rx201; + +/* ========================================================================= */ +/* 4. Internal Linkage Function Declarations (내부 동작용 Static 함수 선언) */ +/* ========================================================================= */ +static void CInitECanA(void); +static void CInitECanB(void); +static void CECanASetMbox(void); +static void CECanBSetMbox(void); +static void CInitECanStructure(void); +static inline Uint16 CPackBit(Uint16 data, Uint16 pos); +static inline Uint16 CPackField(Uint16 data, Uint16 mask, Uint16 pos); + +/* ========================================================================= */ +/* 5. Global Variables & Structure Initialization (전역 변수 및 구조체 초기화) */ +/* ========================================================================= */ +CCommCheck CommCheck; + +// Rx - GCU +CRx200 Rx200; +CRx210 Rx210; +CRx220 Rx220; +CRx221 Rx221; + +// Rx - ECU +CRx300 Rx300; +CRx301 Rx301; +CRx310 Rx310; +CRx320 Rx320; +CRx321 Rx321; +CRx322 Rx322; + +#ifdef AUX_TEST +// Rx - For Aux Test +CRx400 Rx400; +#endif + +/* ========================================================================= */ +/* Function Definitions */ +/* ========================================================================= */ +interrupt void CECanInterruptA(void) +{ + struct ECAN_REGS ECanShadow; + ECanShadow.CANRMP.all = ECanaRegs.CANRMP.all; + + GeneralOperValue.Conection.CarComputer = 1U; // 한번이라도 통신이 수신되었다면 해당 장치가 연결되었다고 판단. + CommCheck.CarComputer = 0U; // 송신 시 타임아웃 카운트 클리어 + + ECanaRegs.CANRMP.all = ECanShadow.CANRMP.all; +} + +static inline Uint32 CPackMboxData(Uint16 b0, Uint16 b1, Uint16 b2, Uint16 b3) +{ + return (((Uint32)b0 << 24U) | ((Uint32)b1 << 16U) | ((Uint32)b2 << 8U) | (Uint32)b3); +} + +void CSendECanDataA(void) +{ + Uint16 uiTemp = 0U; + float32 fTemp = 0.0F; + + // --------------------------------------------------------- + // [700h - MBOX0] + // --------------------------------------------------------- + Tx700.HeartBit = (Tx700.HeartBit + 1U) % 65535U; + + // BYTE 0~1(HeartBit), BYTE 2(DCUversionMajor), BYTE 3(DCUversionMinor), BYTE 4(GCUversionMajor), BYTE 5(GCUversionMinor), BYTE 6(ECUversionMajor), BYTE 7(ECUversionMinor) + ECanaMboxes.MBOX0.MDL.all = CPackMboxData((Uint16)((Tx700.HeartBit >> 0U) & 0xFFU), (Uint16)((Tx700.HeartBit >> 8U) & 0xFFU), + (Uint16)FIRMWARE_VERSION_MAJOR, (Uint16)FIRMWARE_VERSION_MINOR); + ECanaMboxes.MBOX0.MDH.all = CPackMboxData(Rx200.VersionMajor, Rx200.VersionMinor, Rx300.VersionMajor, Rx300.VersionMinor); + + // --------------------------------------------------------- + // [701h - MBOX1] + // --------------------------------------------------------- + Tx701.DcuPlayState = (Uint16)(GeneralOperValue.uiApuState & 0x7U); + + uiTemp = 0U; + uiTemp |= CPackBit(GeneralOperValue.uiFaultOccured, 0U); + uiTemp |= CPackBit(GeneralOperValue.uiEmergency, 1U); + uiTemp |= CPackBit(KeyOperValue.KeyList.MainPower, 2U); + uiTemp |= CPackBit((GPIO_FAIL_SAFE_READ() == false) ? 1U : 0U, 3U); + Tx701.DcuState = uiTemp; + + Tx701.GcuPlayState = Rx201.PlayState; + Tx701.GcuState = Rx201.State; + Tx701.EcuState = Rx301.State; + + // BYTE 0(DcuPlayState), BYTE 1(DcuState), BYTE 2(GcuPlayState), BYTE 3(GcuState), BYTE 4(EcuState), BYTE 5~7(Rsvd) + ECanaMboxes.MBOX1.MDL.all = CPackMboxData(Tx701.DcuPlayState, Tx701.DcuState, Tx701.GcuPlayState, Tx701.GcuState); + ECanaMboxes.MBOX1.MDH.all = CPackMboxData(Tx701.EcuState, 0U, 0U, 0U); + + // --------------------------------------------------------- + // [710h - MBOX5] + // --------------------------------------------------------- + Tx710.GcuWarning = Rx210.GcuWarning; + Tx710.EcuWarning = Rx310.EcuWarning; + + // BYTE 0(GcuWarning), BYTE 1(EcuWarning), BYTE 2~7(Rsvd) + ECanaMboxes.MBOX5.MDL.all = CPackMboxData(Tx710.GcuWarning, Tx710.EcuWarning, 0U, 0U); + ECanaMboxes.MBOX5.MDH.all = CPackMboxData(0U, 0U, 0U, 0U); + + // --------------------------------------------------------- + // [720h - MBOX10] + // --------------------------------------------------------- + Tx720.DcuFault0 = (Uint16)((ulDcuTotalAlarm >> 0U) & 0xFFU); + Tx720.DcuFault1 = (Uint16)((ulDcuTotalAlarm >> 8U) & 0xFFU); + Tx720.DcuFault2 = (Uint16)((ulDcuTotalAlarm >> 16U) & 0xFFU); + Tx720.DcuFault3 = (Uint16)((ulDcuTotalAlarm >> 24U) & 0xFFU); + + Tx720.GcuFault0 = (Uint16)((Rx210.GcuFault >> 0U) & 0xFFU); + Tx720.GcuFault1 = (Uint16)((Rx210.GcuFault >> 8U) & 0xFFU); + Tx720.EcuFault = Rx310.EcuFault; + + // BYTE 0~3(DcuFault0~3), BYTE 4~5(GcuFault0~1), BYTE 6(Rsvd), BYTE 7(EcuFault) + ECanaMboxes.MBOX10.MDL.all = CPackMboxData(Tx720.DcuFault0, Tx720.DcuFault1, Tx720.DcuFault2, Tx720.DcuFault3); + ECanaMboxes.MBOX10.MDH.all = CPackMboxData(Tx720.GcuFault0, Tx720.GcuFault1, 0U, Tx720.EcuFault); + + // --------------------------------------------------------- + // [730h - MBOX15] + // --------------------------------------------------------- + Tx730.AuxState = (Uint16)GET_ALL_AUX_STATUS(); + + // BYTE 0(AuxState), BYTE 1~7(Rsvd) + ECanaMboxes.MBOX15.MDL.all = CPackMboxData(Tx730.AuxState, 0U, 0U, 0U); + ECanaMboxes.MBOX15.MDH.all = CPackMboxData(0U, 0U, 0U, 0U); + + // --------------------------------------------------------- + // [731h - MBOX16] + // --------------------------------------------------------- + fTemp = Adc_EngineHeater_V.fLpfValue * 10.0F; + Tx731.EngineHeaterVoltage = (Uint16)fTemp; + + fTemp = Adc_EngineHeater_I.fLpfValue * 10.0F; + Tx731.EngineHeaterCurrent = (Uint16)fTemp; + + fTemp = Adc_GlowPlug_V.fLpfValue * 10.0F; + Tx731.GlowPlugVoltage = (Uint16)fTemp; + + fTemp = Adc_GlowPlug_I.fLpfValue * 10.0F; + Tx731.GlowPlugCurrent = (Uint16)fTemp; + + // BYTE 0~1(EngineHeaterVoltage), BYTE 2~3(EngineHeaterCurrent), BYTE 4~5(GlowPlugVoltage), BYTE 6~7(GlowPlugCurrent) + ECanaMboxes.MBOX16.MDL.all = CPackMboxData((Uint16)((Tx731.EngineHeaterVoltage >> 0U) & 0xFFU), (Uint16)((Tx731.EngineHeaterVoltage >> 8U) & 0xFFU), + (Uint16)((Tx731.EngineHeaterCurrent >> 0U) & 0xFFU), (Uint16)((Tx731.EngineHeaterCurrent >> 8U) & 0xFFU)); + ECanaMboxes.MBOX16.MDH.all = CPackMboxData((Uint16)((Tx731.GlowPlugVoltage >> 0U) & 0xFFU), (Uint16)((Tx731.GlowPlugVoltage >> 8U) & 0xFFU), + (Uint16)((Tx731.GlowPlugCurrent >> 0U) & 0xFFU), (Uint16)((Tx731.GlowPlugCurrent >> 8U) & 0xFFU)); + + // --------------------------------------------------------- + // [732h - MBOX17] + // --------------------------------------------------------- + fTemp = Adc_Solenoid_V.fLpfValue * 10.0F; + Tx732.SolenoidVoltage = (Uint16)fTemp; + + fTemp = Adc_Solenoid_I.fLpfValue * 10.0F; + Tx732.SolenoidCurrent = (Uint16)fTemp; + + fTemp = Adc_FuelPump_V.fLpfValue * 10.0F; + Tx732.FuelPumpVoltage = (Uint16)fTemp; + + fTemp = Adc_FuelPump_I.fLpfValue * 10.0F; + Tx732.FuelPumpCurrent = (Uint16)fTemp; + + // BYTE 0~1(SolenoidVoltage), BYTE 2~3(SolenoidCurrent), BYTE 4~5(FuelPumpVoltage), BYTE 6~7(FuelPumpCurrent) + ECanaMboxes.MBOX17.MDL.all = CPackMboxData((Uint16)((Tx732.SolenoidVoltage >> 0U) & 0xFFU), (Uint16)((Tx732.SolenoidVoltage >> 8U) & 0xFFU), + (Uint16)((Tx732.SolenoidCurrent >> 0U) & 0xFFU), (Uint16)((Tx732.SolenoidCurrent >> 8U) & 0xFFU)); + ECanaMboxes.MBOX17.MDH.all = CPackMboxData((Uint16)((Tx732.FuelPumpVoltage >> 0U) & 0xFFU), (Uint16)((Tx732.FuelPumpVoltage >> 8U) & 0xFFU), + (Uint16)((Tx732.FuelPumpCurrent >> 0U) & 0xFFU), (Uint16)((Tx732.FuelPumpCurrent >> 8U) & 0xFFU)); + + // --------------------------------------------------------- + // [733h - MBOX18] + // --------------------------------------------------------- + fTemp = Adc_CoolantPump_V.fLpfValue * 10.0F; + Tx733.CoolantPumpVoltage = (Uint16)fTemp; + + fTemp = Adc_CoolantPump_I.fLpfValue * 10.0F; + Tx733.CoolantPumpCurrent = (Uint16)fTemp; + + fTemp = Adc_Fan1_V.fLpfValue * 10.0F; + Tx733.Fan1Voltage = (Uint16)fTemp; + + fTemp = Adc_Fan1_I.fLpfValue * 10.0F; + Tx733.Fan1Current = (Uint16)fTemp; + + // BYTE 0~1(CoolantPumpVoltage), BYTE 2~3(CoolantPumpCurrent), BYTE 4~5(Fan1Voltage), BYTE 6~7(Fan1Current) + ECanaMboxes.MBOX18.MDL.all = CPackMboxData((Uint16)((Tx733.CoolantPumpVoltage >> 0U) & 0xFFU), (Uint16)((Tx733.CoolantPumpVoltage >> 8U) & 0xFFU), + (Uint16)((Tx733.CoolantPumpCurrent >> 0U) & 0xFFU), (Uint16)((Tx733.CoolantPumpCurrent >> 8U) & 0xFFU)); + ECanaMboxes.MBOX18.MDH.all = CPackMboxData((Uint16)((Tx733.Fan1Voltage >> 0U) & 0xFFU), (Uint16)((Tx733.Fan1Voltage >> 8U) & 0xFFU), + (Uint16)((Tx733.Fan1Current >> 0U) & 0xFFU), (Uint16)((Tx733.Fan1Current >> 8U) & 0xFFU)); + + // --------------------------------------------------------- + // [734h - MBOX19] + // --------------------------------------------------------- + fTemp = Adc_Fan2_V.fLpfValue * 10.0F; + Tx734.Fan2Voltage = (Uint16)fTemp; + + fTemp = Adc_Fan2_I.fLpfValue * 10.0F; + Tx734.Fan2Current = (Uint16)fTemp; + + // BYTE 0~1(Fan2Voltage), BYTE 2~3(Fan2Current), BYTE 4~7(Rsvd) + ECanaMboxes.MBOX19.MDL.all = CPackMboxData((Uint16)((Tx734.Fan2Voltage >> 0U) & 0xFFU), (Uint16)((Tx734.Fan2Voltage >> 8U) & 0xFFU), + (Uint16)((Tx734.Fan2Current >> 0U) & 0xFFU), (Uint16)((Tx734.Fan2Current >> 8U) & 0xFFU)); + ECanaMboxes.MBOX19.MDH.all = CPackMboxData(0U, 0U, 0U, 0U); + + // --------------------------------------------------------- + // [740h - MBOX20] + // --------------------------------------------------------- + Tx740.Voltage = Rx220.DcVoltage; + Tx740.Current = Rx220.DcCurrent; + Tx740.Rpm = Rx220.Rpm; + Tx740.Power = Rx220.Power; + + // BYTE 0~1(Voltage), BYTE 2~3(Current), BYTE 4~5(Rpm), BYTE 6~7(Power) + ECanaMboxes.MBOX20.MDL.all = CPackMboxData((Uint16)((Tx740.Voltage >> 0U) & 0xFFU), (Uint16)((Tx740.Voltage >> 8U) & 0xFFU), + (Uint16)((Tx740.Current >> 0U) & 0xFFU), (Uint16)((Tx740.Current >> 8U) & 0xFFU)); + ECanaMboxes.MBOX20.MDH.all = CPackMboxData((Uint16)((Tx740.Rpm >> 0U) & 0xFFU), (Uint16)((Tx740.Rpm >> 8U) & 0xFFU), + (Uint16)((Tx740.Power >> 0U) & 0xFFU), (Uint16)((Tx740.Power >> 8U) & 0xFFU)); + + // --------------------------------------------------------- + // [741h - MBOX21] + // --------------------------------------------------------- + Tx741.PcbTemperature = Rx221.PcbTemperature; + Tx741.FetTemperature = Rx221.FetTemperature; + Tx741.Winding1Temperature = Rx221.GenTemperature1; + Tx741.Winding2Temperature = Rx221.GenTemperature2; + + // BYTE 0(PcbTemperature), BYTE 1(FetTemperature), BYTE 2(Winding1Temperature), BYTE 3(Winding2Temperature), BYTE 4~7(Rsvd) + ECanaMboxes.MBOX21.MDL.all = CPackMboxData(Tx741.PcbTemperature, Tx741.FetTemperature, Tx741.Winding1Temperature, Tx741.Winding2Temperature); + ECanaMboxes.MBOX21.MDH.all = CPackMboxData(0U, 0U, 0U, 0U); + + // --------------------------------------------------------- + // [750h - MBOX25] + // --------------------------------------------------------- + Tx750.ActualRpm = Rx320.ActualRpm; + Tx750.SetRpm = Rx320.SetRpm; + Tx750.ActualTorque = Rx320.ActualTorque; + Tx750.SetTorque = Rx320.SetTorque; + Tx750.SystemVoltage = Rx320.SystemVoltage; + + // BYTE 0~1(ActualRpm), BYTE 2~3(SetRpm), BYTE 4(ActualTorque), BYTE 5(SetTorque), BYTE 6~7(SystemVoltage) + ECanaMboxes.MBOX25.MDL.all = CPackMboxData((Uint16)((Tx750.ActualRpm >> 0U) & 0xFFU), (Uint16)((Tx750.ActualRpm >> 8U) & 0xFFU), + (Uint16)((Tx750.SetRpm >> 0U) & 0xFFU), (Uint16)((Tx750.SetRpm >> 8U) & 0xFFU)); + ECanaMboxes.MBOX25.MDH.all = CPackMboxData(Tx750.ActualTorque, Tx750.SetTorque, + (Uint16)((Tx750.SystemVoltage >> 0U) & 0xFFU), (Uint16)((Tx750.SystemVoltage >> 8U) & 0xFFU)); + + // --------------------------------------------------------- + // [751h - MBOX26] + // --------------------------------------------------------- + Tx751.CoolantTemperature = Rx321.CoolantTemperature; + Tx751.Fan1Speed = Rx321.Fan1Speed; + Tx751.Fan2Speed = Rx321.Fan2Speed; + Tx751.CoolantPumpSpeed = Rx321.CoolantPumpSpeed; + Tx751.Barometric = Rx321.BarometricPressure; + + // BYTE 0(CoolantTemperature), BYTE 1(Fan1Speed), BYTE 2(Fan2Speed), BYTE 3(CoolantPumpSpeed), BYTE 4~5(Barometric), BYTE 6~7(Rsvd) + ECanaMboxes.MBOX26.MDL.all = CPackMboxData(Tx751.CoolantTemperature, Tx751.Fan1Speed, Tx751.Fan2Speed, Tx751.CoolantPumpSpeed); + ECanaMboxes.MBOX26.MDH.all = CPackMboxData((Uint16)((Tx751.Barometric >> 0U) & 0xFFU), (Uint16)((Tx751.Barometric >> 8U) & 0xFFU), 0U, 0U); + + // --------------------------------------------------------- + // [752h - MBOX27] + // --------------------------------------------------------- + Tx752.OperationTimeL = Rx322.TotalOperTimeL; + Tx752.OperationTimeH = Rx322.TotalOperTimeH; + + // BYTE 0~1(OperationTimeL), BYTE 2~3(OperationTimeH), BYTE 4~7(Rsvd) + ECanaMboxes.MBOX27.MDL.all = CPackMboxData((Uint16)((Tx752.OperationTimeL >> 0U) & 0xFFU), (Uint16)((Tx752.OperationTimeL >> 8U) & 0xFFU), + (Uint16)((Tx752.OperationTimeH >> 0U) & 0xFFU), (Uint16)((Tx752.OperationTimeH >> 8U) & 0xFFU)); + ECanaMboxes.MBOX27.MDH.all = CPackMboxData(0U, 0U, 0U, 0U); + + // --------------------------------------------------------- + // 송신 메일박스 마스크 설정 및 전송 트리거 + // MBOX 마스크 (0, 1, 5, 10, 15, 16, 17, 18, 19, 20, 21, 25, 26, 27) + // --------------------------------------------------------- + Uint32 ulTxMask = 0x0E3F8423UL; + + ECanaRegs.CANTRS.all = ulTxMask; + ECanaRegs.CANTA.all = ulTxMask; +} + +static void CInitECanA(void) +{ + /* Create a shadow register structure for the CAN control registers. This is + needed, since only 32-bit access is allowed to these registers. 16-bit access + to these registers could potentially corrupt the register contents or return + false data. This is especially true while writing to/reading from a bit + (or group of bits) among bits 16 - 31 */ + + struct ECAN_REGS ECanaShadow = {}; + + EALLOW; // EALLOW enables access to protected bits + + /* Enable internal pull-up for the selected CAN pins */ + // Pull-ups can be enabled or disabled by the user. + // This will enable the pullups for the specified pins. + // Comment out other unwanted lines. + + GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0x00U; // Enable pull-up CANRXA + GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0x00U; // Enable pull-up CANTXA + + /* Set qualification for selected CAN pins to asynch only */ + // Inputs are synchronized to SYSCLKOUT by default. + // This will select asynch (no qualification) for the selected pins. + + GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 0x03U; // Asynch qual for CANRXA + + /* Configure eCAN-A pins using GPIO regs*/ + // This specifies which of the possible GPIO pins will be eCAN functional pins. + + GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0x03U; // Configure CANRXA operation + GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0x03U; // Configure CANTXA operation + + /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/ + + ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all; + ECanaShadow.CANTIOC.bit.TXFUNC = 1U; + ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all; + + ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all; + ECanaShadow.CANRIOC.bit.RXFUNC = 1U; + ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all; + + /* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */ + // HECC mode also enables time-stamping feature + + ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; + ECanaShadow.CANMC.bit.SCB = 1; + ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; + + // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again + // as a matter of precaution. + + ECanaRegs.CANTA.all = 0xFFFFFFFFU; /* Clear all TAn bits */ + ECanaRegs.CANRMP.all = 0xFFFFFFFFU; /* Clear all RMPn bits */ + ECanaRegs.CANGIF0.all = 0xFFFFFFFFU; /* Clear all interrupt flag bits */ + ECanaRegs.CANGIF1.all = 0xFFFFFFFFU; + + /* Configure bit timing parameters for eCANB*/ + ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; + ECanaShadow.CANMC.bit.CCR = 1U; // Set CCR = 1 + ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; + + ECanaShadow.CANES.all = ECanaRegs.CANES.all; + + do + { + ECanaShadow.CANES.all = ECanaRegs.CANES.all; + } while(ECanaShadow.CANES.bit.CCE != 1U); // Wait for CCE bit to be set.. + + ECanaShadow.CANBTC.all = 0U; + + // 250 [Kbps] + ECanaShadow.CANBTC.bit.BRPREG = 19U; + ECanaShadow.CANBTC.bit.TSEG1REG = 10U; + ECanaShadow.CANBTC.bit.TSEG2REG = 2U; + + ECanaShadow.CANBTC.bit.SAM = 1U; + ECanaShadow.CANBTC.bit.SJWREG = 2U; + ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all; + + ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; + ECanaShadow.CANMC.bit.CCR = 0U; + ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; + + ECanaShadow.CANES.all = ECanaRegs.CANES.all; + + do + { + ECanaShadow.CANES.all = ECanaRegs.CANES.all; + } while (ECanaShadow.CANES.bit.CCE != 0U); // Wait for CCE bit to be cleared.. + + /* Disable all Mailboxes */ + ECanaRegs.CANME.all = 0U; // Required before writing the MSGIDs + + EDIS; + CECanASetMbox(); +} + +static void CECanASetMbox(void) +{ + struct ECAN_REGS ECanShadow = {}; + + /* Tx Can MBox */ + ECanaMboxes.MBOX0.MSGID.bit.IDE = 0U; // ID ECANa 식별자 - 11bit ID 스탠다드 + ECanaMboxes.MBOX0.MSGID.bit.STDMSGID = 0x700U; + ECanaMboxes.MBOX0.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX0.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX0.MDH.all = 0x00000000U; + ECanaMboxes.MBOX0.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX1.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX1.MSGID.bit.STDMSGID = 0x701U; + ECanaMboxes.MBOX1.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX1.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX1.MDH.all = 0x00000000U; + ECanaMboxes.MBOX1.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX5.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX5.MSGID.bit.STDMSGID = 0x710U; + ECanaMboxes.MBOX5.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX5.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX5.MDH.all = 0x00000000U; + ECanaMboxes.MBOX5.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX10.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX10.MSGID.bit.STDMSGID = 0x720U; + ECanaMboxes.MBOX10.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX10.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX10.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX10.MDH.all = 0x00000000U; + ECanaMboxes.MBOX10.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX15.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX15.MSGID.bit.STDMSGID = 0x730U; + ECanaMboxes.MBOX15.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX15.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX15.MDH.all = 0x00000000U; + ECanaMboxes.MBOX15.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX16.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX16.MSGID.bit.STDMSGID = 0x731U; + ECanaMboxes.MBOX16.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX16.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX16.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX16.MDH.all = 0x00000000U; + ECanaMboxes.MBOX16.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX17.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX17.MSGID.bit.STDMSGID = 0x732U; + ECanaMboxes.MBOX17.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX17.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX17.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX17.MDH.all = 0x00000000U; + ECanaMboxes.MBOX17.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX18.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX18.MSGID.bit.STDMSGID = 0x733U; + ECanaMboxes.MBOX18.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX18.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX18.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX18.MDH.all = 0x00000000U; + ECanaMboxes.MBOX18.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX19.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX19.MSGID.bit.STDMSGID = 0x734U; + ECanaMboxes.MBOX19.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX19.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX19.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX19.MDH.all = 0x00000000U; + ECanaMboxes.MBOX19.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX20.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX20.MSGID.bit.STDMSGID = 0x740U; + ECanaMboxes.MBOX20.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX20.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX20.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX20.MDH.all = 0x00000000U; + ECanaMboxes.MBOX20.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX21.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX21.MSGID.bit.STDMSGID = 0x741U; + ECanaMboxes.MBOX21.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX21.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX21.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX21.MDH.all = 0x00000000U; + ECanaMboxes.MBOX21.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX25.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX25.MSGID.bit.STDMSGID = 0x750U; + ECanaMboxes.MBOX25.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX25.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX25.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX25.MDH.all = 0x00000000U; + ECanaMboxes.MBOX25.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX26.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX26.MSGID.bit.STDMSGID = 0x751U; + ECanaMboxes.MBOX26.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX26.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX26.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX26.MDH.all = 0x00000000U; + ECanaMboxes.MBOX26.MDL.all = 0x00000000U; + + ECanaMboxes.MBOX27.MSGID.bit.IDE = 0U; + ECanaMboxes.MBOX27.MSGID.bit.STDMSGID = 0x752U; + ECanaMboxes.MBOX27.MSGID.bit.AME = 0U; + ECanaMboxes.MBOX27.MSGCTRL.bit.DLC = 8U; + ECanaMboxes.MBOX27.MSGCTRL.bit.RTR = 0U; + ECanaMboxes.MBOX27.MDH.all = 0x00000000U; + ECanaMboxes.MBOX27.MDL.all = 0x00000000U; + + // Transe, Receive, 0 is Transe, 1 is Receive + ECanShadow.CANMD.all = ECanaRegs.CANMD.all; + ECanShadow.CANMD.all = 0x0U; // USE MBOX0, MBOX1, MBOX5, MBOX10, MBOX15, MBOX16, MBOX17, MBOX18, MBOX19, MBOX20, MBOX21, MBOX25, MBOX26, MBOX27 + ECanaRegs.CANMD.all = ECanShadow.CANMD.all; + + // MailBox Enable/Disable, 0 is Disable, 1 is Enable + ECanShadow.CANME.all = ECanaRegs.CANME.all; + ECanShadow.CANME.all = 0xE3F8413UL; // USE MBOX0, MBOX1, MBOX5, MBOX10, MBOX15, MBOX16, MBOX17, MBOX18, MBOX19, MBOX20, MBOX21, MBOX25, MBOX26, MBOX27 + ECanaRegs.CANME.all = ECanShadow.CANME.all; + + EALLOW; + ECanShadow.CANMC.all = ECanaRegs.CANMC.all; + ECanShadow.CANMC.bit.STM = 0U; // '1' CAN Self-test Mode ¼³A¤ + ECanShadow.CANMC.bit.ABO = 1U; // '1' CAN Auto Bus On + ECanaRegs.CANMC.all = ECanShadow.CANMC.all; + + // Groble Interrupt + ECanShadow.CANGIM.all = ECanaRegs.CANGIM.all; + ECanShadow.CANGIM.bit.I0EN = 1U; // Line 0 Interrupt Enable + ECanShadow.CANGIM.bit.GIL = 0U; // All global interrupts are mapped to the ECAN0INT interrupt line. + ECanaRegs.CANGIM.all = ECanShadow.CANGIM.all; + EDIS; +} + +interrupt void CECanInterruptB(void) +{ + Uint32 ECanRMPbit; + Uint32 uiMBOXMdl = 0UL; + Uint32 uiMBOXMdh = 0UL; + + ECanRMPbit = ECanbRegs.CANRMP.all; + + // --------------------------------------------------------- + // MBOX15 - 200h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 15U)) != 0U) + { + GeneralOperValue.Conection.Gcu = 1U; + CommCheck.Gcu = 0U; // GCU 타임아웃 카운트 초기화 + + uiMBOXMdl = ECanbMboxes.MBOX15.MDL.all; + uiMBOXMdh = ECanbMboxes.MBOX15.MDH.all; + + Uint16 uiByte0 = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Uint16 uiByte1 = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + + Rx200.HeartBit = uiByte0 | (uiByte1 << 8U); + + Rx200.VersionMajor = (Uint16)((uiMBOXMdh >> 16U) & 0xFFU); // Byte 5 + Rx200.VersionMinor = (Uint16)((uiMBOXMdh >> 8U) & 0xFFU); // Byte 6 + Rx200.VersionPatch = (Uint16)((uiMBOXMdh >> 0U) & 0xFFU); // Byte 7 + } + + // --------------------------------------------------------- + // MBOX16 - 201h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 16U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX16.MDL.all; + + Rx201.PlayState = (Uint16)((uiMBOXMdl >> 24U) & 0x7U); + Rx201.State = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + } + // --------------------------------------------------------- + // MBOX17 - 210h (비트 필드 매핑 반전) + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 17U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX17.MDL.all; + + Rx210.GcuWarning = (Uint16)(((uiMBOXMdl >> 24U) & 0xFFU) | (((uiMBOXMdl >> 16U) & 0xFFU) << 8U)); + Rx210.GcuFault = (Uint16)(((uiMBOXMdl >> 8U) & 0xFFU) | ((uiMBOXMdl & 0xFFU) << 8U)); + } + + // --------------------------------------------------------- + // MBOX18 - 220h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 18U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX18.MDL.all; + uiMBOXMdh = ECanbMboxes.MBOX18.MDH.all; + + // [Reverse] + // Byte 0(>>24), Byte 1(>>16) + Uint16 uiVoltL = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Uint16 uiVoltH = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + Rx220.DcVoltage = uiVoltL | (uiVoltH << 8U); + + // Byte 2(>>8), Byte 3(>>0) + Uint16 uiCurrL = (Uint16)((uiMBOXMdl >> 8U) & 0xFFU); + Uint16 uiCurrH = (Uint16)((uiMBOXMdl >> 0U) & 0xFFU); + Rx220.DcCurrent = uiCurrL | (uiCurrH << 8U); + + // Byte 4(>>24), Byte 5(>>16) + Uint16 uiRpmL = (Uint16)((uiMBOXMdh >> 24U) & 0xFFU); + Uint16 uiRpmH = (Uint16)((uiMBOXMdh >> 16U) & 0xFFU); + Rx220.Rpm = uiRpmL | (uiRpmH << 8U); + + // Byte 6(>>24), Byte 7(>>16) + Uint16 uiPwrL = (Uint16)((uiMBOXMdh >> 8U) & 0xFFU); + Uint16 uiPwrH = (Uint16)((uiMBOXMdh >> 0U) & 0xFFU); + Rx220.Power = uiPwrL | (uiPwrH << 8U); + } + + // --------------------------------------------------------- + // MBOX19 - 221h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 19U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX19.MDL.all; + + // [Reverse] 0(24), 1(16), 2(8), 3(0) + Rx221.PcbTemperature = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Rx221.FetTemperature = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + Rx221.GenTemperature1 = (Uint16)((uiMBOXMdl >> 8U) & 0xFFU); + Rx221.GenTemperature2 = (Uint16)((uiMBOXMdl >> 0U) & 0xFFU); + } + + // --------------------------------------------------------- + // MBOX25 - 300h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 25U)) != 0U) + { + GeneralOperValue.Conection.Ecu = 1U; + CommCheck.Ecu = 0U; // ECU 타임아웃 카운트 초기화 + uiMBOXMdl = ECanbMboxes.MBOX25.MDL.all; + + // [Reverse] + Rx300.VersionMajor = (Uint8)((uiMBOXMdl >> 24U) & 0xFFU); + Rx300.VersionMinor = (Uint8)((uiMBOXMdl >> 16U) & 0xFFU); + Rx300.VersionPatch = (Uint8)((uiMBOXMdl >> 8U) & 0xFFU); + } + + // --------------------------------------------------------- + // MBOX26 - 301h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 26U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX26.MDL.all; + + // [Reverse] Byte 0 -> >> 24U + Rx301.State = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + } + + // --------------------------------------------------------- + // MBOX27 - 310h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 27U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX27.MDL.all; + + // [Reverse] Byte 0 -> >> 24 + Rx310.EcuWarning = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Rx310.EcuFault = (Uint16)((uiMBOXMdl >> 8U) & 0x3FU); + } + + // --------------------------------------------------------- + // MBOX28 - 320h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 28U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX28.MDL.all; + uiMBOXMdh = ECanbMboxes.MBOX28.MDH.all; + + // [Reverse] Byte 0(>>24), 1(>>16) + Uint16 uiActRpmL = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Uint16 uiActRpmH = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + Rx320.ActualRpm = uiActRpmL | (uiActRpmH << 8U); + + // [Reverse] Byte 2(>>8), 3(>>0) + Uint16 uiSetRpmL = (Uint16)((uiMBOXMdl >> 8U) & 0xFFU); + Uint16 uiSetRpmH = (Uint16)((uiMBOXMdl >> 0U) & 0xFFU); + Rx320.SetRpm = uiSetRpmL | (uiSetRpmH << 8U); + + // [Reverse] Byte 4(>>24), 5(>>16) (MDH) + Rx320.ActualTorque = (Uint16)((uiMBOXMdh >> 24U) & 0xFFU); + Rx320.SetTorque = (Uint16)((uiMBOXMdh >> 16U) & 0xFFU); + + // [Reverse] Byte 6(>>8), 7(>>0) + Uint16 uiSysVoltL = (Uint16)((uiMBOXMdh >> 8U) & 0xFFU); + Uint16 uiSysVoltH = (Uint16)((uiMBOXMdh >> 0U) & 0xFFU); + Rx320.SystemVoltage = uiSysVoltL | (uiSysVoltH << 8U); + } + + // --------------------------------------------------------- + // MBOX29 - 321h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 29U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX29.MDL.all; + uiMBOXMdh = ECanbMboxes.MBOX29.MDH.all; + + // [Reverse] + Rx321.CoolantTemperature = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Rx321.Fan1Speed = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + Rx321.Fan2Speed = (Uint16)((uiMBOXMdl >> 8U) & 0xFFU); + Rx321.CoolantPumpSpeed = (Uint16)((uiMBOXMdl >> 0U) & 0xFFU); + + // Byte 4(>>24), 5(>>16) + Uint16 uiBarL = (Uint16)((uiMBOXMdh >> 24U) & 0xFFU); + Uint16 uiBarH = (Uint16)((uiMBOXMdh >> 16U) & 0xFFU); + Rx321.BarometricPressure = uiBarL | (uiBarH << 8U); + } + + // --------------------------------------------------------- + // MBOX30 - 322h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 30U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX30.MDL.all; + + // [Reverse] Byte 0(>>24), 1(>>16) -> TimeL + Uint16 uiTimeLL = (Uint16)((uiMBOXMdl >> 24U) & 0xFFU); + Uint16 uiTimeLH = (Uint16)((uiMBOXMdl >> 16U) & 0xFFU); + Rx322.TotalOperTimeL = uiTimeLL | (uiTimeLH << 8U); + + // [Reverse] Byte 2(>>8), 3(>>0) -> TimeH + Uint16 uiTimeHL = (Uint16)((uiMBOXMdl >> 8U) & 0xFFU); + Uint16 uiTimeHH = (Uint16)((uiMBOXMdl >> 0U) & 0xFFU); + Rx322.TotalOperTimeH = uiTimeHL | (uiTimeHH << 8U); + } + +#ifdef AUX_TEST + // --------------------------------------------------------- + // MBOX31 - 400h + // --------------------------------------------------------- + if ((ECanRMPbit & (1UL << 31U)) != 0U) + { + uiMBOXMdl = ECanbMboxes.MBOX31.MDL.all; + + // [Reverse] Byte 0 -> >> 24 + Rx400.AuxControl.EngineHeater = (Uint16)((uiMBOXMdl >> 24U) & 0x1U); + Rx400.AuxControl.GlowPlug = (Uint16)((uiMBOXMdl >> 25U) & 0x1U); + Rx400.AuxControl.Solenoid = (Uint16)((uiMBOXMdl >> 26U) & 0x1U); + Rx400.AuxControl.FuelPump = (Uint16)((uiMBOXMdl >> 27U) & 0x1U); + Rx400.AuxControl.CoolantPump = (Uint16)((uiMBOXMdl >> 28U) & 0x1U); + Rx400.AuxControl.Fan1 = (Uint16)((uiMBOXMdl >> 29U) & 0x1U); + Rx400.AuxControl.Fan2 = (Uint16)((uiMBOXMdl >> 30U) & 0x1U); + Rx400.AuxControl.AuxTestStart = (Uint16)((uiMBOXMdl >> 31U) & 0x1U); + } +#endif + + ECanbRegs.CANRMP.all = ECanRMPbit; + PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; +} + +void CSendECanDataB(void) +{ + struct ECAN_REGS ECanShadow; + static Uint16 uiTxDivid = 0U; // 분산 송신 + float32 fTemp = 0.0F; + Uint16 uiTemp = 0U; + + Uint16 EmergencySig = ((GeneralOperValue.uiEmergency > 0U) || (KeyOperValue.KeyList.Emergency > 0U)) ? 1U : 0U; + + // 10ms + // [101h] + // --- BYTE 0 --- + Tx101.PlayState = GeneralOperValue.uiApuState; + + // --- BYTE 1 --- + uiTemp = 0U; + uiTemp |= CPackBit(GeneralOperValue.uiFaultOccured, 0U); + uiTemp |= CPackBit(GeneralOperValue.uiEmergency, 1U); + uiTemp |= CPackBit(KeyOperValue.KeyList.MainPower, 2U); + uiTemp |= CPackBit((GPIO_FAIL_SAFE_READ() == false) ? 1U : 0U, 3U); + Tx101.DcuState = uiTemp; + + ECanbMboxes.MBOX1.MDL.byte.BYTE0 = Tx101.PlayState; + ECanbMboxes.MBOX1.MDL.byte.BYTE1 = Tx101.DcuState; + ECanbMboxes.MBOX1.MDL.byte.BYTE2 = 0x0U; + ECanbMboxes.MBOX1.MDL.byte.BYTE3 = 0x0U; + ECanbMboxes.MBOX1.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX1.MDH.byte.BYTE5 = 0x0U; + ECanbMboxes.MBOX1.MDH.byte.BYTE6 = 0x0U; + ECanbMboxes.MBOX1.MDH.byte.BYTE7 = 0x0U; + + // [102h] + // --- BYTE 0 --- + uiTemp = 0U; + uiTemp |= CPackField(GeneralOperValue.GcuCommand.PlayCmd, 0xFU, 0U); + uiTemp |= CPackBit(GeneralOperValue.uiAlarmReset, 4U); + uiTemp |= CPackBit(EmergencySig, 5U); + Tx102.GcuCommand = uiTemp; + + ECanbMboxes.MBOX2.MDL.byte.BYTE0 = Tx102.GcuCommand; + ECanbMboxes.MBOX2.MDL.byte.BYTE1 = 0x0U; + ECanbMboxes.MBOX2.MDL.byte.BYTE2 = 0x0U; + ECanbMboxes.MBOX2.MDL.byte.BYTE3 = 0x0U; + ECanbMboxes.MBOX2.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX2.MDH.byte.BYTE5 = 0x0U; + ECanbMboxes.MBOX2.MDH.byte.BYTE6 = 0x0U; + ECanbMboxes.MBOX2.MDH.byte.BYTE7 = 0x0U; + + // [103h] + // --- BYTE 0~7 --- + uiTemp = 0U; + Tx103.EngineStart = GeneralOperValue.EcuCommand.EngineStart; + Tx103.EngineStop = GeneralOperValue.EcuCommand.EngineStop; + Tx103.FaultReset = GeneralOperValue.uiAlarmReset; + Tx103.RpmSetpoint = GeneralOperValue.EcuCommand.RpmSetPoint; + Tx103.ActiveOverride = KeyOperValue.KeyList.BattleMode; + Tx103.EmergencyStop = EmergencySig; + + ECanbMboxes.MBOX3.MDL.byte.BYTE0 = Tx103.EngineStart; + ECanbMboxes.MBOX3.MDL.byte.BYTE1 = Tx103.EngineStop; + ECanbMboxes.MBOX3.MDL.byte.BYTE2 = Tx103.FaultReset; + ECanbMboxes.MBOX3.MDL.byte.BYTE3 = 0x0U; + ECanbMboxes.MBOX3.MDH.byte.BYTE4 = ((Tx103.RpmSetpoint >> 0U) & 0xFFU); + ECanbMboxes.MBOX3.MDH.byte.BYTE5 = ((Tx103.RpmSetpoint >> 8U) & 0xFFU); + ECanbMboxes.MBOX3.MDH.byte.BYTE6 = Tx103.ActiveOverride; + ECanbMboxes.MBOX3.MDH.byte.BYTE7 = Tx103.EmergencyStop; + + ECanShadow.CANTRS.all = ECanbRegs.CANTRS.all; + ECanShadow.CANTRS.bit.TRS1 = 1U; // 101h + ECanShadow.CANTRS.bit.TRS2 = 1U; // 102h + ECanShadow.CANTRS.bit.TRS3 = 1U; // 103h + ECanbRegs.CANTRS.all = ECanShadow.CANTRS.all; + + ECanShadow.CANTA.all = ECanbRegs.CANTA.all; + ECanShadow.CANTA.bit.TA1 = 1U; // 101h + ECanShadow.CANTA.bit.TA2 = 1U; // 102h + ECanShadow.CANTA.bit.TA3 = 1U; // 103h + ECanbRegs.CANTA.all = ECanShadow.CANTA.all; + + ECanShadow.CANTRS.all = ECanbRegs.CANTRS.all; + ECanShadow.CANTA.all = ECanbRegs.CANTA.all; + + switch (uiTxDivid) + { + case 0U: + { + // [100h] + Tx100.Heartbit = (Tx100.Heartbit + 1U) % 65535U; + Tx100.VersionMajor = (Uint16)FIRMWARE_VERSION_MAJOR; + Tx100.VersionMinor = (Uint16)FIRMWARE_VERSION_MINOR; + Tx100.VersionPatch = (Uint16)FIRMWARE_VERSION_PATCH; + + ECanbMboxes.MBOX0.MDL.byte.BYTE0 = ((Tx100.Heartbit >> 0U) & 0xFFU); + ECanbMboxes.MBOX0.MDL.byte.BYTE1 = ((Tx100.Heartbit >> 8U) & 0xFFU); + ECanbMboxes.MBOX0.MDL.byte.BYTE2 = 0x0U; + ECanbMboxes.MBOX0.MDL.byte.BYTE3 = 0x0U; + ECanbMboxes.MBOX0.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX0.MDH.byte.BYTE5 = Tx100.VersionMajor; + ECanbMboxes.MBOX0.MDH.byte.BYTE6 = Tx100.VersionMinor; + ECanbMboxes.MBOX0.MDH.byte.BYTE7 = Tx100.VersionPatch; + + ECanShadow.CANTRS.bit.TRS0 = 1U; + ECanShadow.CANTA.bit.TA0 = 1U; + break; + } + case 1U: + { + // [110h] + Tx110.DcuFaultB0 = ((Uint16)(ulDcuTotalAlarm >> 0U) & 0xFFU); // Apu Fault Byte 0 + Tx110.DcuFaultB1 = ((Uint16)(ulDcuTotalAlarm >> 8U) & 0xFFU); // Apu Fault Byte 1 + Tx110.DcuFaultB2 = ((Uint16)(ulDcuTotalAlarm >> 16U) & 0xFFU); // Apu Fault Byte 2 + Tx110.DcuFaultB3 = ((Uint16)(ulDcuTotalAlarm >> 24U) & 0xFFU); // Apu Fault Byte 3 + + ECanbMboxes.MBOX4.MDL.byte.BYTE0 = Tx110.DcuFaultB0; + ECanbMboxes.MBOX4.MDL.byte.BYTE1 = Tx110.DcuFaultB1; + ECanbMboxes.MBOX4.MDL.byte.BYTE2 = Tx110.DcuFaultB2; + ECanbMboxes.MBOX4.MDL.byte.BYTE3 = Tx110.DcuFaultB3; + ECanbMboxes.MBOX4.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX4.MDH.byte.BYTE5 = 0x0U; + ECanbMboxes.MBOX4.MDH.byte.BYTE6 = 0x0U; + ECanbMboxes.MBOX4.MDH.byte.BYTE7 = 0x0U; + + ECanShadow.CANTRS.bit.TRS4 = 1U; + ECanShadow.CANTA.bit.TA4 = 1U; + break; + } + case 2U: + { + // [120h] + Tx120.AuxTotal = (Uint16)GET_ALL_AUX_STATUS(); + + ECanbMboxes.MBOX5.MDL.byte.BYTE0 = Tx120.AuxTotal; + ECanbMboxes.MBOX5.MDL.byte.BYTE1 = 0x0U; + ECanbMboxes.MBOX5.MDL.byte.BYTE2 = 0x0U; + ECanbMboxes.MBOX5.MDL.byte.BYTE3 = 0x0U; + ECanbMboxes.MBOX5.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX5.MDH.byte.BYTE5 = 0x0U; + ECanbMboxes.MBOX5.MDH.byte.BYTE6 = 0x0U; + ECanbMboxes.MBOX5.MDH.byte.BYTE7 = 0x0U; + + ECanShadow.CANTRS.bit.TRS5 = 1U; + ECanShadow.CANTA.bit.TA5 = 1U; + break; + } + case 3U: + { + // [121h] + fTemp = Adc_EngineHeater_V.fLpfValue * 10.0F; + Tx121.EngHeatVoltage = (Uint16)fTemp; + + fTemp = Adc_EngineHeater_I.fLpfValue * 10.0F; + Tx121.EngHeatCurrent = (Uint16)fTemp; + + fTemp = Adc_GlowPlug_V.fLpfValue * 10.0F; + Tx121.GlowPlugVoltage = (Uint16)fTemp; + + fTemp = Adc_GlowPlug_I.fLpfValue * 10.0F; + Tx121.GlowPlugCurrent = (Uint16)fTemp; + + ECanbMboxes.MBOX6.MDL.byte.BYTE0 = ((Tx121.EngHeatVoltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX6.MDL.byte.BYTE1 = ((Tx121.EngHeatVoltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX6.MDL.byte.BYTE2 = ((Tx121.EngHeatCurrent >> 0U) & 0xFFU); + ECanbMboxes.MBOX6.MDL.byte.BYTE3 = ((Tx121.EngHeatCurrent >> 8U) & 0xFFU); + ECanbMboxes.MBOX6.MDH.byte.BYTE4 = ((Tx121.GlowPlugVoltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX6.MDH.byte.BYTE5 = ((Tx121.GlowPlugVoltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX6.MDH.byte.BYTE6 = ((Tx121.GlowPlugCurrent >> 0U) & 0xFFU); + ECanbMboxes.MBOX6.MDH.byte.BYTE7 = ((Tx121.GlowPlugCurrent >> 8U) & 0xFFU); + + ECanShadow.CANTRS.bit.TRS6 = 1U; + ECanShadow.CANTA.bit.TA6 = 1U; + break; + } + case 4U: + { + // [122h] + fTemp = Adc_Solenoid_V.fLpfValue * 10.0F; + Tx122.SolenoidVoltage = (Uint16)fTemp; + + fTemp = Adc_Solenoid_I.fLpfValue * 10.0F; + Tx122.SolenoidCurrent = (Uint16)fTemp; + + fTemp = Adc_FuelPump_V.fLpfValue * 10.0F; + Tx122.FuelPumpVoltage = (Uint16)fTemp; + + fTemp = Adc_FuelPump_I.fLpfValue * 10.0F; + Tx122.FuelPumpCurrent = (Uint16)fTemp; + + ECanbMboxes.MBOX7.MDL.byte.BYTE0 = ((Tx122.SolenoidVoltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX7.MDL.byte.BYTE1 = ((Tx122.SolenoidVoltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX7.MDL.byte.BYTE2 = ((Tx122.SolenoidCurrent >> 0U) & 0xFFU); + ECanbMboxes.MBOX7.MDL.byte.BYTE3 = ((Tx122.SolenoidCurrent >> 8U) & 0xFFU); + ECanbMboxes.MBOX7.MDH.byte.BYTE4 = ((Tx122.FuelPumpVoltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX7.MDH.byte.BYTE5 = ((Tx122.FuelPumpVoltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX7.MDH.byte.BYTE6 = ((Tx122.FuelPumpCurrent >> 0U) & 0xFFU); + ECanbMboxes.MBOX7.MDH.byte.BYTE7 = ((Tx122.FuelPumpCurrent >> 8U) & 0xFFU); + + ECanShadow.CANTRS.bit.TRS7 = 1U; + ECanShadow.CANTA.bit.TA7 = 1U; + break; + } + case 5U: + { + // [123h] + fTemp = Adc_CoolantPump_V.fLpfValue * 10.0F; + Tx123.CoolantPumpVoltage = (Uint16)fTemp; + + fTemp = Adc_CoolantPump_I.fLpfValue * 10.0F; + Tx123.CoolantPumpCurrent = (Uint16)fTemp; + + fTemp = Adc_Fan1_V.fLpfValue * 10.0F; + Tx123.Fan1Voltage = (Uint16)fTemp; + + fTemp = Adc_Fan1_I.fLpfValue * 10.0F; + Tx123.Fan1Current = (Uint16)fTemp; + + ECanbMboxes.MBOX8.MDL.byte.BYTE0 = ((Tx123.CoolantPumpVoltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX8.MDL.byte.BYTE1 = ((Tx123.CoolantPumpVoltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX8.MDL.byte.BYTE2 = ((Tx123.CoolantPumpCurrent >> 0U) & 0xFFU); + ECanbMboxes.MBOX8.MDL.byte.BYTE3 = ((Tx123.CoolantPumpCurrent >> 8U) & 0xFFU); + ECanbMboxes.MBOX8.MDH.byte.BYTE4 = ((Tx123.Fan1Voltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX8.MDH.byte.BYTE5 = ((Tx123.Fan1Voltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX8.MDH.byte.BYTE6 = ((Tx123.Fan1Current >> 0U) & 0xFFU); + ECanbMboxes.MBOX8.MDH.byte.BYTE7 = ((Tx123.Fan1Current >> 8U) & 0xFFU); + + ECanShadow.CANTRS.bit.TRS8 = 1U; + ECanShadow.CANTA.bit.TA8 = 1U; + break; + } + default: + { + if (uiTxDivid == 6U) + { + // [124h] + fTemp = Adc_Fan2_V.fLpfValue * 10.0F; + Tx124.Fan2Voltage = (Uint16)fTemp; + + fTemp = Adc_Fan2_I.fLpfValue * 10.0F; + Tx124.Fan2Current = (Uint16)fTemp; + + ECanbMboxes.MBOX9.MDL.byte.BYTE0 = ((Tx124.Fan2Voltage >> 0U) & 0xFFU); + ECanbMboxes.MBOX9.MDL.byte.BYTE1 = ((Tx124.Fan2Voltage >> 8U) & 0xFFU); + ECanbMboxes.MBOX9.MDL.byte.BYTE2 = ((Tx124.Fan2Current >> 0U) & 0xFFU); + ECanbMboxes.MBOX9.MDL.byte.BYTE3 = ((Tx124.Fan2Current >> 8U) & 0xFFU); + ECanbMboxes.MBOX9.MDH.byte.BYTE4 = 0x0U; + ECanbMboxes.MBOX9.MDH.byte.BYTE5 = 0x0U; + ECanbMboxes.MBOX9.MDH.byte.BYTE6 = 0x0U; + ECanbMboxes.MBOX9.MDH.byte.BYTE7 = 0x0U; + + ECanShadow.CANTRS.bit.TRS9 = 1U; + ECanShadow.CANTA.bit.TA9 = 1U; + } + break; + } + } + ECanbRegs.CANTRS.all = ECanShadow.CANTRS.all; + ECanbRegs.CANTA.all = ECanShadow.CANTA.all; + + uiTxDivid = (uiTxDivid + 1U) % 10U; +} + +static void CInitECanB(void) +{ + /* Create a shadow register structure for the CAN control registers. This is + needed, since only 32-bit access is allowed to these registers. 16-bit access + to these registers could potentially corrupt the register contents or return + false data. This is especially true while writing to/reading from a bit + (or group of bits) among bits 16 - 31 */ + + struct ECAN_REGS ECanbShadow = {}; + + EALLOW; // EALLOW enables access to protected bits + + /* Enable internal pull-up for the selected CAN pins */ + // Pull-ups can be enabled or disabled by the user. + // This will enable the pullups for the specified pins. + // Comment out other unwanted lines. + + GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0x00U; // Enable pull-up CANTXB + GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0x00U; // Enable pull-up CANRXB + + /* Set qualification for selected CAN pins to asynch only */ + // Inputs are synchronized to SYSCLKOUT by default. + // This will select asynch (no qualification) for the selected pins. + + GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0x03U; // Asynch qual for CANRXB + + /* Configure eCAN-A pins using GPIO regs*/ + // This specifies which of the possible GPIO pins will be eCAN functional pins. + + GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0x03U; // Configure CANTXB operation + GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0x03U; // Configure CANRXB operation + + /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/ + + ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all; + ECanbShadow.CANTIOC.bit.TXFUNC = 1U; + ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all; + + ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all; + ECanbShadow.CANRIOC.bit.RXFUNC = 1U; + ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all; + + /* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */ + // HECC mode also enables time-stamping feature + + ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; + ECanbShadow.CANMC.bit.SCB = 1; + ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; + + // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again + // as a matter of precaution. + + ECanbRegs.CANTA.all = 0xFFFFFFFFU; /* Clear all TAn bits */ + ECanbRegs.CANRMP.all = 0xFFFFFFFFU; /* Clear all RMPn bits */ + ECanbRegs.CANGIF0.all = 0xFFFFFFFFU; /* Clear all interrupt flag bits */ + ECanbRegs.CANGIF1.all = 0xFFFFFFFFU; + + /* Configure bit timing parameters for eCANB*/ + ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; + ECanbShadow.CANMC.bit.CCR = 1U; // Set CCR = 1 + ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; + + ECanbShadow.CANES.all = ECanbRegs.CANES.all; + + do + { + ECanbShadow.CANES.all = ECanbRegs.CANES.all; + } while(ECanbShadow.CANES.bit.CCE != 1U); // Wait for CCE bit to be set.. + + ECanbShadow.CANBTC.all = 0U; + + // 250 [kbps] + ECanbShadow.CANBTC.bit.BRPREG = 19U; + ECanbShadow.CANBTC.bit.TSEG1REG = 10U; + ECanbShadow.CANBTC.bit.TSEG2REG = 2U; + + ECanbShadow.CANBTC.bit.SAM = 1U; + ECanbShadow.CANBTC.bit.SJWREG = 2U; + ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all; + + ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; + ECanbShadow.CANMC.bit.CCR = 0U; + ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; + + ECanbShadow.CANES.all = ECanbRegs.CANES.all; + + do + { + ECanbShadow.CANES.all = ECanbRegs.CANES.all; + } while (ECanbShadow.CANES.bit.CCE != 0U); // Wait for CCE bit to be cleared.. + + /* Disable all Mailboxes */ + ECanbRegs.CANME.all = 0U; // Required before writing the MSGIDs + + EDIS; + CECanBSetMbox(); +} + +static void CECanBSetMbox(void) +{ + struct ECAN_REGS ECanShadow = {}; + + /* Tx Can MBox */ + ECanbMboxes.MBOX0.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX0.MSGID.bit.STDMSGID = 0x100U; + ECanbMboxes.MBOX0.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX0.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX0.MDH.all = 0x00000000U; + ECanbMboxes.MBOX0.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX1.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX1.MSGID.bit.STDMSGID = 0x101U; + ECanbMboxes.MBOX1.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX1.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX1.MDH.all = 0x00000000U; + ECanbMboxes.MBOX1.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX2.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX2.MSGID.bit.STDMSGID = 0x102U; + ECanbMboxes.MBOX2.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX2.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX2.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX2.MDH.all = 0x00000000U; + ECanbMboxes.MBOX2.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX3.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX3.MSGID.bit.STDMSGID = 0x103U; + ECanbMboxes.MBOX3.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX3.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX3.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX3.MDH.all = 0x00000000U; + ECanbMboxes.MBOX3.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX4.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX4.MSGID.bit.STDMSGID = 0x110U; + ECanbMboxes.MBOX4.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX4.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX4.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX4.MDH.all = 0x00000000U; + ECanbMboxes.MBOX4.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX5.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX5.MSGID.bit.STDMSGID = 0x120U; + ECanbMboxes.MBOX5.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX5.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX5.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX5.MDH.all = 0x00000000U; + ECanbMboxes.MBOX5.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX6.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX6.MSGID.bit.STDMSGID = 0x121U; + ECanbMboxes.MBOX6.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX6.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX6.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX6.MDH.all = 0x00000000U; + ECanbMboxes.MBOX6.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX7.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX7.MSGID.bit.STDMSGID = 0x122U; + ECanbMboxes.MBOX7.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX7.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX7.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX7.MDH.all = 0x00000000U; + ECanbMboxes.MBOX7.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX8.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX8.MSGID.bit.STDMSGID = 0x123U; + ECanbMboxes.MBOX8.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX8.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX8.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX8.MDH.all = 0x00000000U; + ECanbMboxes.MBOX8.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX9.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX9.MSGID.bit.STDMSGID = 0x124U; + ECanbMboxes.MBOX9.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX9.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX9.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX9.MDH.all = 0x00000000U; + ECanbMboxes.MBOX9.MDL.all = 0x00000000U; + + /* Rx Can MBox(GCU)*/ + ECanbMboxes.MBOX15.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX15.MSGID.bit.STDMSGID = 0x200U; + ECanbMboxes.MBOX15.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX15.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX15.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX15.MDH.all = 0x00000000U; + ECanbMboxes.MBOX15.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX16.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX16.MSGID.bit.STDMSGID = 0x201U; + ECanbMboxes.MBOX16.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX16.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX16.MDH.all = 0x00000000U; + ECanbMboxes.MBOX16.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX17.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX17.MSGID.bit.STDMSGID = 0x210U; + ECanbMboxes.MBOX17.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX17.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX17.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX17.MDH.all = 0x00000000U; + ECanbMboxes.MBOX17.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX18.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX18.MSGID.bit.STDMSGID = 0x220U; + ECanbMboxes.MBOX18.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX18.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX18.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX18.MDH.all = 0x00000000U; + ECanbMboxes.MBOX18.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX19.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX19.MSGID.bit.STDMSGID = 0x221U; + ECanbMboxes.MBOX19.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX19.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX19.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX19.MDH.all = 0x00000000U; + ECanbMboxes.MBOX19.MDL.all = 0x00000000U; + + /* Rx Can MBox(ECU)*/ + ECanbMboxes.MBOX25.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX25.MSGID.bit.STDMSGID = 0x300U; + ECanbMboxes.MBOX25.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX25.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX25.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX25.MDH.all = 0x00000000U; + ECanbMboxes.MBOX25.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX26.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX26.MSGID.bit.STDMSGID = 0x301U; + ECanbMboxes.MBOX26.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX26.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX26.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX26.MDH.all = 0x00000000U; + ECanbMboxes.MBOX26.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX27.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX27.MSGID.bit.STDMSGID = 0x310U; + ECanbMboxes.MBOX27.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX27.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX27.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX27.MDH.all = 0x00000000U; + ECanbMboxes.MBOX27.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX28.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX28.MSGID.bit.STDMSGID = 0x320U; + ECanbMboxes.MBOX28.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX28.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX28.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX28.MDH.all = 0x00000000U; + ECanbMboxes.MBOX28.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX29.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX29.MSGID.bit.STDMSGID = 0x321U; + ECanbMboxes.MBOX29.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX29.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX29.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX29.MDH.all = 0x00000000U; + ECanbMboxes.MBOX29.MDL.all = 0x00000000U; + + ECanbMboxes.MBOX30.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX30.MSGID.bit.STDMSGID = 0x322U; + ECanbMboxes.MBOX30.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX30.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX30.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX30.MDH.all = 0x00000000U; + ECanbMboxes.MBOX30.MDL.all = 0x00000000U; +#ifdef AUX_TEST // ! Auxiliary Test + ECanbMboxes.MBOX31.MSGID.bit.IDE = 0U; + ECanbMboxes.MBOX31.MSGID.bit.STDMSGID = 0x400U; + ECanbMboxes.MBOX31.MSGID.bit.AME = 0U; + ECanbMboxes.MBOX31.MSGCTRL.bit.DLC = 8U; + ECanbMboxes.MBOX31.MSGCTRL.bit.RTR = 0U; + ECanbMboxes.MBOX31.MDH.all = 0x00000000U; + ECanbMboxes.MBOX31.MDL.all = 0x00000000U; +#endif + + //0 is Transe, 1 is Receive + ECanShadow.CANMD.all = ECanbRegs.CANMD.all; + ECanShadow.CANMD.all = 0x7E0F8000UL; // USE MBOX15~19, 25~30 (31 제외) +#ifdef AUX_TEST // ! Auxiliary Test + ECanShadow.CANMD.bit.MD31 = 1U; +#endif + ECanbRegs.CANMD.all = ECanShadow.CANMD.all; + + // MailBox Enable/Disable, 0 is Disable, 1 is Enable + ECanShadow.CANME.all = ECanbRegs.CANME.all; + ECanShadow.CANME.all = 0x7E0F83FFUL; // USE MBOX0~9, 15~19, 25~30 (31 제외) +#ifdef AUX_TEST // ! Auxiliary Test + ECanShadow.CANME.bit.ME31 = 1U; +#endif + ECanbRegs.CANME.all = ECanShadow.CANME.all; + + EALLOW; + ECanShadow.CANMC.all = ECanbRegs.CANMC.all; + ECanShadow.CANMC.bit.STM = 0U; // '1' CAN Self-test Mode ¼³A¤ + ECanShadow.CANMC.bit.ABO = 1U; // '1' CAN Auto Bus On + ECanbRegs.CANMC.all = ECanShadow.CANMC.all; + + // Interrupt Enable(Receive Interrupt), 0 is Disable, 1 is Enable + ECanShadow.CANMIM.all = ECanbRegs.CANMIM.all; + ECanShadow.CANMIM.bit.MIM15 = 1U; + ECanShadow.CANMIM.bit.MIM16 = 1U; + ECanShadow.CANMIM.bit.MIM17 = 1U; + ECanShadow.CANMIM.bit.MIM18 = 1U; + ECanShadow.CANMIM.bit.MIM19 = 1U; + ECanShadow.CANMIM.bit.MIM25 = 1U; + ECanShadow.CANMIM.bit.MIM26 = 1U; + ECanShadow.CANMIM.bit.MIM27 = 1U; + ECanShadow.CANMIM.bit.MIM28 = 1U; + ECanShadow.CANMIM.bit.MIM29 = 1U; + ECanShadow.CANMIM.bit.MIM30 = 1U; +#ifdef AUX_TEST // ! Auxiliary Test + ECanShadow.CANMIM.bit.MIM31 = 1U; +#endif + ECanbRegs.CANMIM.all = ECanShadow.CANMIM.all; + + // Groble Interrupt + ECanShadow.CANGIM.all = ECanbRegs.CANGIM.all; + ECanShadow.CANGIM.bit.I0EN = 1U; // Line 0 Interrupt Enable + ECanShadow.CANGIM.bit.GIL = 0U; // All global interrupts are mapped to the ECAN0INT interrupt line. + ECanbRegs.CANGIM.all = ECanShadow.CANGIM.all; + EDIS; +} + +void CInitEcan(void) +{ + CInitECanA(); + CInitECanB(); + + CInitECanStructure(); +} + +static void CInitECanStructure(void) +{ + // Tx + (void)memset(&Tx100, 0, sizeof(CTx100)); + (void)memset(&Tx101, 0, sizeof(CTx101)); + (void)memset(&Tx102, 0, sizeof(CTx102)); + (void)memset(&Tx103, 0, sizeof(CTx103)); + (void)memset(&Tx110, 0, sizeof(CTx110)); + (void)memset(&Tx120, 0, sizeof(CTx120)); + (void)memset(&Tx121, 0, sizeof(CTx121)); + (void)memset(&Tx122, 0, sizeof(CTx122)); + (void)memset(&Tx123, 0, sizeof(CTx123)); + (void)memset(&Tx124, 0, sizeof(CTx124)); + + (void)memset(&Tx700, 0, sizeof(CTx700)); + (void)memset(&Tx701, 0, sizeof(CTx701)); + (void)memset(&Tx710, 0, sizeof(CTx710)); + (void)memset(&Tx720, 0, sizeof(CTx720)); + (void)memset(&Tx730, 0, sizeof(CTx730)); + (void)memset(&Tx731, 0, sizeof(CTx731)); + (void)memset(&Tx732, 0, sizeof(CTx732)); + (void)memset(&Tx733, 0, sizeof(CTx733)); + (void)memset(&Tx734, 0, sizeof(CTx734)); + (void)memset(&Tx740, 0, sizeof(CTx740)); + (void)memset(&Tx741, 0, sizeof(CTx741)); + (void)memset(&Tx750, 0, sizeof(CTx750)); + (void)memset(&Tx751, 0, sizeof(CTx751)); + (void)memset(&Tx752, 0, sizeof(CTx752)); + + // Rx - GCU + (void)memset(&Rx200, 0, sizeof(CRx200)); + (void)memset(&Rx201, 0, sizeof(CRx201)); + (void)memset(&Rx210, 0, sizeof(CRx210)); + (void)memset(&Rx220, 0, sizeof(CRx220)); + (void)memset(&Rx221, 0, sizeof(CRx221)); + + // Rx - ECU + (void)memset(&Rx300, 0, sizeof(CRx300)); + (void)memset(&Rx301, 0, sizeof(CRx301)); + (void)memset(&Rx310, 0, sizeof(CRx310)); + (void)memset(&Rx320, 0, sizeof(CRx320)); + (void)memset(&Rx321, 0, sizeof(CRx321)); + (void)memset(&Rx322, 0, sizeof(CRx322)); + +#ifdef AUX_TEST // ! Auxiliary Test + // Rx - Auxiliary Test + (void)memset(&Rx400, 0, sizeof(CRx400)); +#endif +} + +static inline Uint16 CPackBit(Uint16 data, Uint16 pos) +{ + Uint16 result = (data != 0U) ? 1U : 0U; + + return result << pos; +} + +static inline Uint16 CPackField(Uint16 data, Uint16 mask, Uint16 pos) +{ + return ((data & mask) << pos); +} diff --git a/Comm.h b/Comm.h new file mode 100644 index 0000000..5fcdbd5 --- /dev/null +++ b/Comm.h @@ -0,0 +1,696 @@ +#ifndef SOURCE_COMM_H_ +#define SOURCE_COMM_H_ + +typedef struct ClassCommCheck +{ + Uint16 CarComputer; + Uint16 Gcu; + Uint16 Ecu; +} CCommCheck; + +typedef struct ClassTx100 +{ + /* BYTE 0~1 */ + Uint16 Heartbit; + + /* BYTE 2~4 Reserved */ + + /* BYTE 5 */ + Uint16 VersionMajor; + + /* BYTE 6 */ + Uint16 VersionMinor; + + /* BYTE 7 */ + Uint16 VersionPatch; +} CTx100; + +typedef struct ClassTx101 +{ + /* BYTE 0 */ + Uint16 PlayState; // 0~3 bit + + /* BYTE 1 */ + Uint16 DcuState; // bit 0:AlarmOccured, 1:Emergency, 2:PowerSwitch, 3:EcuFailSafe + + /* BYTE 2~7 Reserved */ + +} CTx101; + +typedef struct ClassTx102 +{ + /* BYTE 0 */ + Uint16 GcuCommand; // bit 0~3:PlayCommand, 4:FaultReset, 5:Emergency + + /* BYTE 1~7 Reserved */ + +} CTx102; + + +typedef struct ClassTx103 +{ + /* BYTE 0 */ + Uint16 EngineStart; + + /* BYTE 1 */ + Uint16 EngineStop; + + /* BYTE 2 */ + Uint16 FaultReset; + + /* BYTE 3 Reserved */ + + /* BYTE 4~5 */ + Uint16 RpmSetpoint; + + /* BYTE 6 */ + Uint16 ActiveOverride; + + /* BYTE 7 */ + Uint16 EmergencyStop; + +} CTx103; + +typedef struct ClassTx110 +{ + /* BYTE 0~3 */ + Uint16 DcuFaultB0; + Uint16 DcuFaultB1; + Uint16 DcuFaultB2; + Uint16 DcuFaultB3; + + /* BYTE 4~7 - Reserved */ + +} CTx110; + +typedef struct ClassTx120 +{ + /* BYTE 0 */ + Uint16 AuxTotal; // bit 0:EngineHeater, 1:GlowPlug, 2:Solenoid, 3:FuelPump, 4:CoolantPump, 5:Fan1, 6:Fan2 + + /* BYTE 1~7 - Reserved */ + +} CTx120; + +typedef struct ClassTx121 +{ + /* BYTE 0~1 */ + Uint16 EngHeatVoltage; + + /* BYTE 2~3 */ + Uint16 EngHeatCurrent; + + /* BYTE 4~5 */ + Uint16 GlowPlugVoltage; + + /* BYTE 6~7 */ + Uint16 GlowPlugCurrent; +} CTx121; + +typedef struct ClassTx122 +{ + /* BYTE 0~1 */ + Uint16 SolenoidVoltage; + + /* BYTE 2~3 */ + Uint16 SolenoidCurrent; + + /* BYTE 4~5 */ + Uint16 FuelPumpVoltage; + + /* BYTE 6~7 */ + Uint16 FuelPumpCurrent; +} CTx122; + +typedef struct ClassTx123 +{ + /* BYTE 0~1 */ + Uint16 CoolantPumpVoltage; + + /* BYTE 2~3 */ + Uint16 CoolantPumpCurrent; + + /* BYTE 4~5 */ + Uint16 Fan1Voltage; + + /* BYTE 6~7 */ + Uint16 Fan1Current; +} CTx123; + +typedef struct ClassTx124 +{ + /* BYTE 0~1 */ + Uint16 Fan2Voltage; + + /* BYTE 2~3 */ + Uint16 Fan2Current; + + /* BYTE 4~7 - Reserved */ + +} CTx124; + +typedef struct ClassRx200 +{ + /* BYTE 0~1 */ + Uint16 HeartBit; + + /* BYTE 2~4 - Reserved */ + + /* BYTE 5 */ + Uint16 VersionMajor; + + /* BYTE 6 */ + Uint16 VersionMinor; + + /* BYTE 7 */ + Uint16 VersionPatch; +} CRx200; + +typedef struct ClassRx201 +{ + /* BYTE 0 */ + Uint16 PlayState; // 0:3 bit PlayState + + /* BYTE 1 */ + Uint16 State; // bit 0:AlarmOccured, 1:Shutdown + + /* BYTE 2~7 - Reserved */ + +} CRx201; + +typedef struct ClassRx210 +{ + /* BYTE 0~1 */ + /* + * bit description + * 0:PcbOverHeat + * 1:FetOverHeat + * 2:GenOverHeat1 + * 3:GenOverHeat2 + */ + Uint16 GcuWarning; + + /* BYTE 2~3 */ + /* + * bit description + * 0:HwTrip + * 1:HwIgbt + * 2:HwDc + * 3:GenOverCurrentU + * 4:GenOverCurrentV + * 5:GenOverCurrentW + * 6:DcOverVoltage + * 7:DcOverCurrent + * + * 8:CrankningOverCurrent + * 9:PcbOverHeat + * 10:FetOverHeat + * 11:GenTempOverHeat1 + * 12:GenTempOverHeat2 + * 13:GenOverSpeed + * 14:ResolverIC + * 15:ResolverParity + */ + Uint16 GcuFault; + + /* BYTE 4~7 - Reserved*/ + +} CRx210; + +typedef struct ClassRx220 +{ + /* BYTE 0~1 */ + Uint16 DcVoltage; + + /* BYTE 2~3 */ + Uint16 DcCurrent; + + /* BYTE 4~5 */ + Uint16 Rpm; + + /* BYTE 6~7 */ + Uint16 Power; +} CRx220; + +typedef struct ClassRx221 +{ + /* BYTE 0 */ + Uint16 PcbTemperature; + + /* BYTE 1 */ + Uint16 FetTemperature; + + /* BYTE 2 */ + Uint16 GenTemperature1; + + /* BYTE 3 */ + Uint16 GenTemperature2; + + /* BYTE 4~7 - Reserved */ + +} CRx221; + +typedef struct ClassRx300 +{ + /* BYTE 0 */ + Uint16 VersionMajor; + + /* BYTE 1 */ + Uint16 VersionMinor; + + /* BYTE 2 */ + Uint16 VersionPatch; + + /* BYTE 3~7 - Reserved */ + +} CRx300; + +typedef struct ClassRx301 +{ + + /* BYTE 0 */ + /* + * bit description + * 0:AlarmOccured + * 1~3:PlayState + * 4:OverrideActive + * 5:GlowPlugActive + * 6:HeaterActive + * 7:OilPressureMissing + */ + Uint16 State; + + /* BYTE 1~7 - Reserved */ + +} CRx301; + +typedef struct ClassRx310 +{ + /* BYTE 0 */ + /* + * bit description + * 0:EngineOverHeat + * 1:Reserved + * 2:LoOilPressure + * 3:IntakeOverHeat + * 4:IntakeLoPressure + * 5:EngineLoTemperature + * 6:EngineSensor + * 7:DefaltValueActive + */ + Uint16 EcuWarning; + + /* BYTE 1 - Reserved */ + + /* BYTE 2 */ + /* + * bit description + * 0:OilPressureMissing + * 1:IntakeOverHeat + * 2:EngineOverHeat + * 3:Actuator + * 4:RpmSignal + * 5:EngineStartFail + * 6:Reserved + * 7:Reserved + */ + Uint16 EcuFault; + + /* BYTE 3~7 - Reserved */ + +} CRx310; + +typedef struct ClassRx320 +{ + /* BYTE 0~1 */ + Uint16 ActualRpm; + + /* BYTE 2~3 */ + Uint16 SetRpm; + + /* BYTE 4 */ + Uint16 ActualTorque; + + /* BYTE 5 */ + Uint16 SetTorque; + + /* BYTE 6~7 */ + Uint16 SystemVoltage; +} CRx320; + +typedef struct ClassRx321 +{ + /* BYTE 0 */ + Uint16 CoolantTemperature; + + /* BYTE 1 */ + Uint16 Fan1Speed; + + /* BYTE 2 */ + Uint16 Fan2Speed; + + /* BYTE 3 */ + Uint16 CoolantPumpSpeed; + + /* BYTE 4~5 */ + Uint16 BarometricPressure; + + /* BYTE 6~7 - Reserved */ + +} CRx321; + +typedef struct ClassRx322 +{ + /* BYTE 0~1 */ + Uint16 TotalOperTimeL : 16; + + /* BYTE 2~3 */ + Uint16 TotalOperTimeH : 16; + + /* BYTE 4~7 - Reserved*/ + +} CRx322; + +typedef struct ClassTx700 +{ + /* BYTE 0~1 */ + Uint16 HeartBit; + + /* BYTE 2 */ + Uint16 DCUversionMajor; + + /* BYTE 3 */ + Uint16 DCUversionMinor; + + /* BYTE 4 */ + Uint16 GCUversionMajor; + + /* BYTE 5 */ + Uint16 GCUversionMinor; + + /* BYTE 6 */ + Uint16 ECUversionMajor; + + /* BYTE 7 */ + Uint16 ECUversionMinor; +} CTx700; + +typedef struct ClassTx701 +{ + /* BYTE 0 */ + Uint16 DcuPlayState; // bit 0~3:PlayState + + /* BYTE 1 */ + /* + * bit description + * 0:DcuAlarmOccured + * 1:DcuEmergencyStop + * 2:PowerSwitchPush + * 3:EcuFailSafe + */ + Uint16 DcuState; + + /* BYTE 2 */ + Uint16 GcuPlayState; // bit 0~2:GcuPlayState + + /* BYTE 3 */ + /* + * bit description + * 0:GcuAlarmOccured + * 1:GcuShutdown + */ + Uint16 GcuState; + + /* BYTE 4 */ + /* + * bit description + * 0:EcuAlarmOccured + * 1~3:EcuPlayState + * 4:ActiveOverride + * 5:ActiveGlowPlug + * 6:ActiveEngHeater + * 7:OilPressureMissing + */ + Uint16 EcuState; + + /* BYTE 5~7 - Reserved */ + +} CTx701; + +typedef struct ClassTx710 +{ + /* BYTE 0 - GCU Warning */ + /* + * bit description + * 0:PcbOverHeat + * 1:FetOverHeat + * 2:Winding1OverHeat + * 3:Winding2OverHeat + */ + Uint16 GcuWarning; + + /* BYTE 1 - ECU Warning */ + /* + * bit description + * 0:EngineOverHeat + * 1:Reserved + * 2:LoOilPressure + * 3:IntakeOverHeat + * 4:IntakeLoPressure + * 5:EngineLoTemperature + * 6:EngineSensorFault + * 7:DefaultValueActive + */ + Uint16 EcuWarning; + + /* BYTE 2~7 - Reserved */ + +} CTx710; + +typedef struct ClassTx720 +{ + /* BYTE 0~3 - DCU Fault */ + Uint16 DcuFault0; + Uint16 DcuFault1; + Uint16 DcuFault2; + Uint16 DcuFault3; + + /* BYTE 4~5 - GCU Fault */ + Uint16 GcuFault0; + Uint16 GcuFault1; + + /* BYTE 6 - Reserved */ + + /* BYTE 7 */ + Uint16 EcuFault; +} CTx720; + +typedef struct ClassTx730 +{ + /* BYTE 0 */ + /* + * bit description + * 0:EngineHeater + * 1:GlowPlug + * 2:Solenoid + * 3:FuelPump + * 4:CoolantPump + * 5:Fan1 + * 6:Fan2 + * 7:Reserved + */ + Uint16 AuxState; + + /* BYTE 1~7 - Reserved */ + +} CTx730; + +typedef struct ClassTx731 +{ + /* BYTE 0~1 */ + Uint16 EngineHeaterVoltage; + + /* BYTE 2~3 */ + Uint16 EngineHeaterCurrent; + + /* BYTE 4~5 */ + Uint16 GlowPlugVoltage; + + /* BYTE 6~7 */ + Uint16 GlowPlugCurrent; +} CTx731; + +typedef struct ClassTx732 +{ + /* BYTE 0~1 */ + Uint16 SolenoidVoltage; + + /* BYTE 2~3 */ + Uint16 SolenoidCurrent; + + /* BYTE 4~5 */ + Uint16 FuelPumpVoltage; + + /* BYTE 6~7 */ + Uint16 FuelPumpCurrent; +} CTx732; + +typedef struct ClassTx733 +{ + /* BYTE 0~1 */ + Uint16 CoolantPumpVoltage; + + /* BYTE 2~3 */ + Uint16 CoolantPumpCurrent; + + /* BYTE 4~5 */ + Uint16 Fan1Voltage; + + /* BYTE 6~7 */ + Uint16 Fan1Current; +} CTx733; + +typedef struct ClassTx734 +{ + /* BYTE 0~1 */ + Uint16 Fan2Voltage; + + /* BYTE 2~3 */ + Uint16 Fan2Current; + + /* BYTE 4~7 - Reserved */ + +} CTx734; + +typedef struct ClassTx740 +{ + /* BYTE 0~1 */ + Uint16 Voltage; + + /* BYTE 2~3 */ + Uint16 Current; + + /* BYTE 4~5 */ + Uint16 Rpm; + + /* BYTE 6~7 */ + Uint16 Power; +} CTx740; + +typedef struct ClassTx741 +{ + /* BYTE 0 */ + Uint16 PcbTemperature; + + /* BYTE 1 */ + Uint16 FetTemperature; + + /* BYTE 2 */ + Uint16 Winding1Temperature; + + /* BYTE 3 */ + Uint16 Winding2Temperature; + + /* BYTE 4~7 - Reserved */ + +} CTx741; + +typedef struct ClassTx750 +{ + /* BYTE 0~1 */ + Uint16 ActualRpm; + + /* BYTE 2~3 */ + Uint16 SetRpm; + + /* BYTE 4 */ + Uint16 ActualTorque; + + /* BYTE 5 */ + Uint16 SetTorque; + + /* BYTE 6~7 */ + Uint16 SystemVoltage; +} CTx750; + +typedef struct ClassTx751 +{ + /* BYTE 0 */ + Uint16 CoolantTemperature; + + /* BYTE 1 */ + Uint16 Fan1Speed; + + /* BYTE 2 */ + Uint16 Fan2Speed; + + /* BYTE 3 */ + Uint16 CoolantPumpSpeed; + + /* BYTE 4~5 */ + Uint16 Barometric; + + /* BYTE 6~7 - Reserved */ + +} CTx751; + +typedef struct ClassTx752 +{ + /* BYTE 0~1 */ + Uint16 OperationTimeL; + + /* BYTE 2~3 */ + Uint16 OperationTimeH; + + /* BYTE 4~7 - Reserved */ + +} CTx752; + +interrupt void CECanInterruptA(void); +interrupt void CECanInterruptB(void); +void CSendECanDataA(void); +void CSendECanDataB(void); +void CInitEcan(void); + +extern CCommCheck CommCheck; +extern CRx200 Rx200; +extern CRx210 Rx210; +extern CRx220 Rx220; +extern CRx221 Rx221; +extern CRx300 Rx300; +extern CRx301 Rx301; +extern CRx310 Rx310; +extern CRx320 Rx320; +extern CRx321 Rx321; +extern CRx322 Rx322; + +typedef struct ClassRx400 +{ + struct + { + Uint16 BYTE0 : 8; + Uint16 BYTE1 : 8; + Uint16 BYTE2 : 8; + Uint16 BYTE3 : 8; + Uint16 BYTE4 : 8; + Uint16 BYTE5 : 8; + Uint16 BYTE6 : 8; + Uint16 BYTE7 : 8; + } Bytes; + struct + { + Uint16 EngineHeater : 1; + Uint16 GlowPlug : 1; + Uint16 Solenoid : 1; + Uint16 FuelPump : 1; + Uint16 CoolantPump : 1; + Uint16 Fan1 : 1; + Uint16 Fan2 : 1; + Uint16 AuxTestStart : 1; + Uint16 rsvd_padding : 8; + } AuxControl; +} CRx400; + +extern CRx400 Rx400; + +#endif /* SOURCE_COMM_H_ */ diff --git a/Display.c b/Display.c new file mode 100644 index 0000000..72f3250 --- /dev/null +++ b/Display.c @@ -0,0 +1,1979 @@ +/* ========================================================================= */ +/* 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; + Uint16 uiCh = ch; + + if (type == 0U) // Eng Char + { + uiCharWidth = (Uint16)TXT_ENG_WIDTH; + uiCh -= 0x20U; // font offset + uiCh = (uiCh > 95U) ? 0U : uiCh; + pFontData = EngFontTable[uiCh]; + } + 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); +} diff --git a/Display.h b/Display.h new file mode 100644 index 0000000..3cdec6d --- /dev/null +++ b/Display.h @@ -0,0 +1,156 @@ +#ifndef SOURCE_DISPLAY_H_ +#define SOURCE_DISPLAY_H_ + +#define ZONE6_DAT *(volatile Uint16*)0x00100001 +#define ZONE6_COM *(volatile Uint16*)0x00100000 + +#define OLED_WIDTH (128U) // ER-OLEDM024 Vertical Pixel 0~127 +#define OLED_HEIGHT (64U) +#define OLED_PAGE (8U) // ER-OLEDM024 Page 0~7 + +#define TXT_ENG_WIDTH (6U) +#define TXT_ENG_HEIGHT (12U) + +#define TXT_TYPE_ENG (0U) +#define TXT_TYPE_ETC (1U) + +#define TXT_MAX_LEN (22U) +#define TXT_LINE_LEN (5U) + +#define OLED_LOAD_PROGRESS_X (14U) +#define OLED_LOAD_PROGRESS_Y (52U) +#define OLED_LOAD_PROGRESS_W (114U) +#define OLED_LOAD_PROGRESS_H (10U) + +#define MODE_COMMAND (0U) +#define MODE_DATA (1U) + +#define DIR_UP (1U) +#define DIR_DOWN (0U) + +typedef signed char int8; +typedef unsigned char Uint8; + +typedef enum +{ + IDX_OLED_LINE_TITLE = 0U, + IDX_OLED_LINE_1 = 14U, + IDX_OLED_LINE_2 = 27U, + IDX_OLED_LINE_3 = 40U, + IDX_OLED_LINE_4 = 53U +} E_IDX_OLED_LINE; + +typedef enum +{ + IDX_OLED_ROW_0 = 0U, + IDX_OLED_ROW_1, + IDX_OLED_ROW_2, + IDX_OLED_ROW_3, + IDX_OLED_ROW_4 +} E_IDX_OLED_ROW; + +typedef enum +{ + IDX_OLED_PASS_DIGIT_1 = 0U, + IDX_OLED_PASS_DIGIT_2, + IDX_OLED_PASS_DIGIT_3, + IDX_OLED_PASS_DIGIT_4 +} E_IDX_OLED_PASS; + +typedef enum +{ + IDX_OLED_PAGE_APU1 = 0U, // 0 + IDX_OLED_PAGE_APU2, // 1 + IDX_OLED_PAGE_MENU1, // 2 + IDX_OLED_PAGE_MENU2, // 3 + IDX_OLED_PAGE_TEMP, // 4 + IDX_OLED_PAGE_SENSOR1, // 5 + IDX_OLED_PAGE_SENSOR2, // 6 + IDX_OLED_PAGE_SENSOR3, // 7 + IDX_OLED_PAGE_SENSOR4, // 8 + IDX_OLED_PAGE_WARNING1, // 9 + IDX_OLED_PAGE_WARNING2, // 10 + IDX_OLED_PAGE_FAULT1, // 11 + IDX_OLED_PAGE_FAULT2, // 12 + IDX_OLED_PAGE_FAULT3, // 13 + IDX_OLED_PAGE_FAULT4, // 14 + IDX_OLED_PAGE_FAULT5, // 15 + IDX_OLED_PAGE_FAULT6, // 16 + IDX_OLED_PAGE_FAULT7, // 17 + IDX_OLED_PAGE_RESET_ALARM, // 18 + IDX_OLED_PAGE_PASSWORD, // 19 + IDX_OLED_PAGE_MAINTENANCE, // 20 + IDX_OLED_PAGE_VERSION, // 21 + IDX_OLED_PAGE_KEY_TEST, // 21 + IDX_OLED_PAGE_SHUTDOWN, // 23 + IDX_OLED_PAGE_MAX +} E_IDX_OLED_PAGE; + +typedef enum +{ + IDX_OLED_MENU_APU = 0U, // 0 + IDX_OLED_MENU_TEMP, // 1 + IDX_OLED_MENU_SENSOR, // 2 + IDX_OLED_MENU_WARNING, // 3 +} E_IDX_OLED_MENU1; + +typedef enum +{ + IDX_OLED_MENU_FAULT = 0U, // 0 + IDX_OLED_MENU_RESET, // 1 + IDX_OLED_MENU_DEBUG // 2 +} E_IDX_OLED_MENU2; + +typedef enum +{ + IDX_OLED_LINE_FOCUS_1 = 0U, + IDX_OLED_LINE_FOCUS_2, + IDX_OLED_LINE_FOCUS_3, + IDX_OLED_LINE_FOCUS_4 +} E_IDX_OLED_LINE_FOCUS; + +typedef struct ClassPageHandler +{ + Uint16 uiPage; + void (*pAction) (void); // PageTable 참조 +} CPageHandler; + +typedef struct ClassOledOperValue +{ + Uint16 uiBuff[OLED_WIDTH][OLED_PAGE]; + Uint16 uiPageNum; + Uint16 uiOldPageNum; + Uint16 uiFocusLine; + Uint16 uiPrevFocusLine; + Uint16 uiFocusDigit; + Uint16 uiProgressValue; + Uint16 uiProgressDone; + Uint16 uiResetAlarmAnswer; + Uint16 uiResetHourAnswer; + int8 cStrBuff[TXT_LINE_LEN][TXT_MAX_LEN]; + int8 cAlignBuffer[TXT_MAX_LEN]; + struct + { + Uint16 TxtColor; + Uint16 BgColor; + } Color; + struct + { + Uint16 X; + Uint16 Y; + } Point; +} COledOperValue; + +void CInitXintf(void); +void CInitOled(void); +void COledReflash(Uint16 x, Uint16 y, Uint16 width, Uint16 height); +void CDisplayPostFail(void); +void CSetPage(Uint16 PageNum); +void CInitKeyOperValue(void); +void CInitializePage(void); +void COledBufferReset(void); +void CDisplayAntiNoiseRefresh(void); + +extern COledOperValue OledOperValue; + +#endif /* SOURCE_DISPLAY_H_ */ diff --git a/ci.ini b/ci.ini new file mode 100644 index 0000000..fb0274a --- /dev/null +++ b/ci.ini @@ -0,0 +1,140 @@ +; +; +; PA Դϴ. +; +;------------------------------------------------------------------------- +[PA] +; PA ÿ ̺ ڵ带 PA ˴ϴ. +; default N Դϴ. +CLEAN_MODE=N +;UTF-8 ڵ ϵ ν ϵ ϴ ɼԴϴ. +; default N Դϴ. +AUTO_ENCODING_UTF8=N + +; Ʈ DB ʱȭ +INIT_QUERY=PRAGMA mmap_size=2147418112; + +; ڵ带 CFG Դϴ. +; ʱ 'N' Դϴ. +DISABLE_LAMBDA_CFG=N + + +; Ƽ ȯ濡 refined 丮 ϰ +; ʱ 'Y' Դϴ. +MAKE_UNIQUE_REFINED_DIR=Y +; +;------------------------------------------------------------------------- +;Violation ̺ violation ε ϰ Ŀ ٽ ε մϴ. +;default Y Դϴ. +[CI] +REINDEX_MODE=Y + +; +; +; DFA Դϴ. +; +;------------------------------------------------------------------------- +[DFA] +DFA_ENABLE=Y +SCFG_OUT=N +LIMIT_ITER=N +RESULT_OUT=N +ITER_OUT=N +TRANSFER_OUT=N +FYCYC_ITER=40 +; +; +; Abstract Interpreter +;------------------------------------------------------------------------- +[ABSINT] +; ENABLE WHEN CI +ABSINT_ENABLE=Y +; MUST | MAY +ABSINT_STRATEGY=MUST + + +;------------------------------------------------------------------------- +; +; ExtendedDeclarations db մϴ. +; db linking time ˴ϴ. +; default Y Դϴ(Y or N). +; +;------------------------------------------------------------------------- +[ExtendedDeclaration] +SAVE_TO_PROJECT_REPOSITORY=Y + +;------------------------------------------------------------------------- +; +; Report ÿ ũ Ǵ ý ũθ մϴ. +; SKIP_SYSTEM_MACRO, SKIP_ALL_MACRO, SKIP_NONE, SKIP_DEFINED_IN_FILE ɼ մϴ. +; MACRO_SKIP_MODE=SKIP_DEFINED_IN_FILE:.*_Math\.h +; default SKIP_SYSTEM_MACRO Դϴ. +; +;------------------------------------------------------------------------- +[REPORT] +MACRO_SKIP_MODE=SKIP_SYSTEM_MACRO + +;------------------------------------------------------------------------- +; ó Ľ ÿ Ǵ , +; ó . +; ó ϴ key ϰ ׻ . +; default Y̰, Ư (뷮 ) ƴ ̻ ׻ . +; key 쿡 Y . +GEN_PP_OUTPUT=Y + +;------------------------------------------------------------------------- +; +; Ʒ FunctionUnit 鿡 ɼǵԴϴ. +; Ư 찡 ƴ϶ Ʒ ɼǵ ձ ʿմϴ^^. +; +; +;------------------------------------------------------------------------- +[FunctionMapBuilder] +SYMBOL_MAPPER=default +;SYMBOL_MAPPER=physical +; default +; physical ( ϳ static Լ , Translation Unit ޶ ó) + + +;------------------------------------------------------------------------- +[CFGWriter] +; debugging purpose - Լ GML ǥ Working Directory մϴ. yEd ̿Ͽ ֽϴ. +GML_OUT=N + +;------------------------------------------------------------------------- +[MetricGenerator] +; FUNCR ο Դϴ. ⺻ N +PHYSICAL_FUNCR=N + +;------------------------------------------------------------------------- +[TestValidator] +; debugging purpose - Database ڵ Ἲ Ȯմϴ. +CHECK_ALL=N +CHECK_FUNCTION_MAP=N +CHECK_CFG=N +CHECK_FUNCTION_INFO=N +CHECK_TYPE_INFO=N +CHECK_USE_DEF=N +TYPE_INFO_GML_OUT=N +;------------------------------------------------------------------------- +[ANALYSIS] +; RTE annoatation Դϴ. ʱ 'Y' Դϴ. +ANNOTATION=Y +; psionic Դϴ. ʱ 'Y' Դϴ. +RUN_PSIONIC=Y +; м⿡ type ̸ ª ɼԴϴ. +OPTIMIZE=Y +; ý ڵ带 ڵ常 ȯϴ ɼԴϴ. ʱ 'N' Դϴ. +USER_CODE_ONLY=N +; CAL ó⸦ ؼ CAL  Դϴ. +RUN_PREPROC=Y +; Ư ̺귯 Over-Approximation մϴ. +; ';' ڷ ׸ Է ֽϴ. +OVER_APPROXIMATION=std::vector +;------------------------------------------------------------------------- +[ASTFactory] +; AST lambda unknown expression +; ʱ 'N' Դϴ. +ENABLE_LAMBDA_AS_UNKNOWN=N + +; IniLoader װ ־ ʽϴ. ݵ ٿ ֽ߰ñ ٶϴ.