// (C) Automotive Lighting Reutlingen GmbH // Tuebinger Strasse 123, 72762 Reutlingen, Germany // // Automotive Lighting Reutlingen GmbH owns all the rights to this work. // This work shall not be copied, reproduced, used, modified, transferred // or its information shall not be disclosed without the prior written // authorization of Automotive Lighting Reutlingen GmbH. //***************************************************************************** //----------------------------------------------------------------------------- /// \file CddTle94x1.c /// /// \brief SBC Infineon TLE9471/TLE9461 specific complex device driver /// /// \descr System Basic Chip /// /// \author ZHAO, Kai ALDE-RT/EES6 /// //----------------------------------------------------------------------------- //============================================================================= // Standard / system header file includes //============================================================================= #include #include #include //#if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) //#include //#endif //============================================================================= // Project-specific header file includes //============================================================================= #include #include #include #include #include //============================================================================= // Global variable //============================================================================= //#ifndef UNIT_TEST //extern uint16* ECC_RET_RAM_VAR; //#endif //============================================================================= // Local variable //============================================================================= //----------------------------------------------------------------------------- // Start definitions of non initialized structures and unions or arrays variables //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_VAR_NO_INIT_UNSPECIFIED #include <../Cfg/CddTle94x1_MemMap.h> // Structure to store the Error Flags STATIC_AL tisSbcErrorState CddTle94x1_ErrorType; // Structure to store the SPI Control and Status registers STATIC_AL tCddTle94x1_DataMirror CddTle94x1_DataMirror; #define ctadCddSbc_STOP_SEC_VAR_NO_INIT_UNSPECIFIED #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End definitions of non initialized structures and unions or arrays variables //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Start definitions of initialized structures and unions or arrays variables //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_VAR_INIT_UNSPECIFIED #include <../Cfg/CddTle94x1_MemMap.h> #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) STATIC_AL teDefaultMsgType CddSbc_eDefaultMsg = eBUS_CTRL_0; #endif #define ctadCddSbc_STOP_SEC_VAR_INIT_UNSPECIFIED #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End definitions of initialized structures and unions or arrays variables //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Start definitions of non initialized 16 bit variables //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_VAR_NO_INIT_16 #include <../Cfg/CddTle94x1_MemMap.h> #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) // Counter to track the SPI cyclic communication STATIC_AL uint16 CddTle94x1_unErrorSequenceCounter; #endif #define ctadCddSbc_STOP_SEC_VAR_NO_INIT_16 #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End definitions of non initialized 16 bit variables //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Start definitions of initialized 8 bit variables //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_VAR_INIT_8 #include <../Cfg/CddTle94x1_MemMap.h> #if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) // Variable to store the power on reset information after poweron STATIC_AL uint8 CddTle94x1_ucSUP_STAT_0_POR = 0u; // Variable to store the power on reset information after poweron STATIC_AL uint8 CddTle94x1_ucWK_STAT_0_CANWU = 0u; // Variable to store the dev status information after poweron STATIC_AL uint8 CddTle94x1_ucDEV_STAT_DEV_STAT = 0u; STATIC_AL uint8 CddTle94x1_ucTHERMO_STAT_TSD2 = 0u; STATIC_AL uint8 CddTle94x1_ucSUP_STAT_0_VCC1_UV = 0u; #endif #if (CDD_SBC_CFG_WK_INPUT == STD_ON) STATIC_AL uint8 CddTle94x1_ucWK_STAT_0_WK_WU = 0u; #endif #if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) STATIC_AL uint8 CddTle94x1_eSBCResetReason = 0u; #endif #define ctadCddSbc_STOP_SEC_VAR_INIT_8 #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End definitions of initialized 8 bit variables //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Start definitions of initialized boolean variables //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_VAR_INIT_BOOLEAN #include <../Cfg/CddTle94x1_MemMap.h> #if ((CDD_SBC_CFG_STORE_RESETREASON == STD_ON) && (CDD_SBC_CFG_WATCHDOG == STD_ON)) STATIC_AL boolean CddTle94x1_boIsWdgReset = FALSE; #endif #define ctadCddSbc_STOP_SEC_VAR_INIT_BOOLEAN #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End definitions of initialized boolean variables //----------------------------------------------------------------------------- #ifndef UNIT_TEST //volatile uint16* CddTle94x1_ECCResetReason; // PRQA S 3408 1 //volatile uint16 CddTle94x1_WdgResetReason; // PRQA S 3408 1 #else //STATIC_AL uint16* CddTle94x1_ECCResetReason; //STATIC_AL uint16 CddTle94x1_WdgResetReason; #endif //----------------------------------------------------------------------------- // Start declaration or definitions of functions //----------------------------------------------------------------------------- #define ctadCddSbc_START_SEC_CODE #include <../Cfg/CddTle94x1_MemMap.h> //============================================================================= // Prototypes //============================================================================= #if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) STATIC_AL void CddTle94x1_InitSettings(void); STATIC_AL boolean CddTle94x1_InitStatRead(void); STATIC_AL boolean CddTle94x1_Save_WK_STAT_0(void); STATIC_AL boolean CddTle94x1_Save_SUP_STAT_0(void); #endif STATIC_AL boolean CddTle94x1_WriteClearReg(uint8 ucAddress, uint16 unDataField); STATIC_AL uint16 CddTle94x1_ReadReg(uint8 ucAddress); #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) STATIC_AL void CddTle94x1_CbkGetSupState0(uint32 ulData, uint16 unSentVal); STATIC_AL void CddTle94x1_CbkGetWakeUpStatus(uint32 ulData, uint16 unSentVal); #endif #if (CDD_SBC_CFG_VCC2 == STD_ON) STATIC_AL void CddTle94x1_CbkGetThermoStat(uint32 ulData, uint16 unSentVal); #endif #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) STATIC_AL void CddTle94x1_CbkSetCanMode(uint32 ulData, uint16 unSentVal); STATIC_AL void CddTle94x1_CbkGetCanMode(uint32 ulData, uint16 unSentVal); STATIC_AL void CddTle94x1_CbkGetBusState(uint32 ulData, uint16 unSentVal); #endif STATIC_AL boolean CddTle94x1_ValidateCanMode(uint8 ucCanMode); #endif #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) STATIC_AL void CddTle94x1_ErrorSequenceCounterInc(void); STATIC_AL void CddTle94x1_ErrorSequenceCounterClear(void); #endif #if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) STATIC_AL void CddTle94x1_StoreSBCResetReason(void); #endif #if (CDD_SBC_CFG_WATCHDOG == STD_ON) STATIC_AL void CddTle94x1_SetWdgWithSingleOperation(void); #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) STATIC_AL void CddTle94x1_CbkSetWDCtrl(uint32 ulData, uint16 unSentVal); #endif #if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) STATIC_AL void CddTle94x1_GetWatchdogFlag(void); #endif #endif //============================================================================= // Function definitions //============================================================================= //#if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_Init /// /// \descr Initialize TLE9471 SBC complex device driver by using SPI Transfer Message communication. /// Preconditions: CddSpi module should be initialized first /// 1. step: Read TLE9471 Status Registers (WK_STAT_0 and SUP_STAT_0) and save wake-up reasons for later use. /// 2. step: Handle the watchdog reset reason /// 3. step: Write TLE9471 Control Registers to configure SBC. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_Init(void) { // Read and debounce TLE9471 Status Registers if (CddTle94x1_InitStatRead() != FALSE) { #if (CDD_SBC_CFG_WATCHDOG == STD_ON) // If the read and save ws successsful hanle the watchdog reset reason CddTle94x1_GetWatchdogFlag(); #endif // If the read and save was successful write the control registers CddTle94x1_InitSettings(); } else { // do nothing } #if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) //#ifndef UNIT_TEST // CddTle94x1_ECCResetReason = (volatile uint16*)&ECC_RET_RAM_VAR; //#endif CddTle94x1_StoreSBCResetReason(); #endif } //#endif //#if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_InitStatRead /// /// \descr During the initialization phase wake source signalization flags from WK_STAT_0 need to be saved in order to determin the cause of the wake-up later on. /// The power on reset flag from SUP_STAT_0 is to be read and saved after in order to detect if it was a power on reset. // The function will return FALSE if the read and save was unsuccesful and TRUE if the operation was succesful. /// /// \param void /// /// \return boolean boReturn //----------------------------------------------------------------------------- STATIC_AL boolean CddTle94x1_InitStatRead(void) { boolean boReturn = FALSE; // Tries to read and save the wake-up and supply status registers if ((CddTle94x1_Save_WK_STAT_0() == TRUE) && ((CddTle94x1_Save_SUP_STAT_0() == TRUE))) // PRQA S 3415 // if one write fails the other ones are not executed. { // Successful read and save boReturn = TRUE; // Clear the error Flag CddTle94x1_ErrorType.boInitStatRead = NO_ERROR; } else { // Set the error Flag CddTle94x1_ErrorType.boInitStatRead = ERROR_ON; } return boReturn; } //#endif //#if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_Save_WK_STAT_0 /// /// \descr During the initialization phase reads the WK_STAT_0 register by calling /// the CddTle94x1_ReadReg() function and saves the Wake-Up flag of the CAN0. /// /// \param void /// /// \return boolean boReturn //----------------------------------------------------------------------------- STATIC_AL boolean CddTle94x1_Save_WK_STAT_0(void) { boolean boReturn = FALSE; // read the spi register with the register addresse uint16 unReadReg = CddTle94x1_ReadReg(TLE94X1_WK_STAT_0_ADR); // If there were no read errors if (unReadReg != CDD_TLE94X1_ERROR) { // Store the registers content in the memory CddTle94x1_DataMirror.StatRx.WK_STAT_0_Register.Data.Word = (uint8)unReadReg; CddTle94x1_ucWK_STAT_0_CANWU = CddTle94x1_DataMirror.StatRx.WK_STAT_0_Register.Data.Bit.CAN_WU; CddTle94x1_ucWK_STAT_0_WK_WU = CddTle94x1_DataMirror.StatRx.WK_STAT_0_Register.Data.Bit.WK_WU; CddTle94x1_ErrorType.boReadWKStat_Failure = NO_ERROR; boReturn = TRUE; } else { CddTle94x1_ErrorType.boReadWKStat_Failure = ERROR_ON; } return boReturn; } //#endif //#if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_Save_SUP_STAT_0 /// /// \descr During the initialization phase reads the SUP_STAT_0 register by /// calling the CddTle94x1_ReadReg() function and saves the Power On Reset flag. /// /// \param void /// /// \return boolean boReturn //----------------------------------------------------------------------------- STATIC_AL boolean CddTle94x1_Save_SUP_STAT_0(void) { boolean boReturn = FALSE; uint16 unReadReg = CddTle94x1_ReadReg(TLE94X1_SUP_STAT_0_ADR); // If there were no read errors if (unReadReg != CDD_TLE94X1_ERROR) { // Store the registers content in the memory CddTle94x1_DataMirror.StatRx.SUP_STAT_0_Register.Data.Word = (uint8)unReadReg; CddTle94x1_ucSUP_STAT_0_POR = CddTle94x1_DataMirror.StatRx.SUP_STAT_0_Register.Data.Bit.POR; CddTle94x1_ucSUP_STAT_0_VCC1_UV = CddTle94x1_DataMirror.StatRx.SUP_STAT_0_Register.Data.Bit.VCC1_UV; CddTle94x1_ErrorType.boReadSUPStat_Failure = NO_ERROR; boReturn = TRUE; } else { CddTle94x1_ErrorType.boReadSUPStat_Failure = ERROR_ON; } // Return the status return boReturn; } //#endif #if ((CDD_SBC_CFG_WATCHDOG == STD_ON) && (CDD_SBC_CFG_STORE_RESETREASON == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_GetWatchdogFlag /// /// \descr During the initialization phase reads the DEV_STAT and THERM_STAT register by calling /// the CddTle94x1_ReadReg() function and handels the watchdog reset reason. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_GetWatchdogFlag(void) { // read the spi register with the register addresse uint16 unReadReg_DEV_STAT = CddTle94x1_ReadReg(TLE94X1_DEV_STAT_ADR); uint16 unReadReg_THERM_STAT = CddTle94x1_ReadReg(TLE94X1_THERM_STAT_ADR); // If there were no read errors if ( (unReadReg_DEV_STAT != CDD_TLE94X1_ERROR) && (unReadReg_THERM_STAT != CDD_TLE94X1_ERROR) ) { // Store the registers content in the memory CddTle94x1_DataMirror.StatRx.DEV_STAT_Register.Data.Word = (uint8)unReadReg_DEV_STAT; CddTle94x1_ucDEV_STAT_DEV_STAT = CddTle94x1_DataMirror.StatRx.DEV_STAT_Register.Data.Bit.DEV_STAT; CddTle94x1_DataMirror.StatRx.THERM_STAT_Register.Data.Word = (uint8)unReadReg_THERM_STAT; CddTle94x1_ucTHERMO_STAT_TSD2 = (uint8)CddTle94x1_DataMirror.StatRx.THERM_STAT_Register.Data.Bit.TSD2; CddTle94x1_ErrorType.boReadWdgStat_Failure = NO_ERROR; } else { CddTle94x1_ErrorType.boReadWdgStat_Failure = ERROR_ON; } if ( (CddTle94x1_ucDEV_STAT_DEV_STAT == 1u) && (CddTle94x1_ucTHERMO_STAT_TSD2 == 0u) && (CddTle94x1_ucSUP_STAT_0_VCC1_UV == 0u) ) { CddTle94x1_boIsWdgReset = TRUE; } else { CddTle94x1_boIsWdgReset = FALSE; } #ifndef UNIT_TEST //CddTle94x1_WdgResetReason = *(volatile uint16*)0x08000980; // PRQA S 303 1 // cast needed - working with actual addresses #endif //*(volatile uint16*)0x08000980 = 0UL; //CddTle94x1_boIsWdgReset = ((uint16)CddTle94x1_WdgResetReason == (uint16)ERROR_ACTIVE) ? TRUE : FALSE; } // PRQA S 5334 // not yet implemented #endif //#if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_InitSettings /// /// \descr Write configuration data to TLE9471 control registers. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_InitSettings(void) { // Clear the power on reset flag in SUP_STAT_0 Register CddTle94x1_DataMirror.StatTx.SUP_STAT_0_Register.Data.Word = CDD_TLE94X1_CLEAR_ALL; // Clear the Wake-up flag of the CAN0 in WK_STAT_0 Register CddTle94x1_DataMirror.StatTx.WK_STAT_0_Register.Data.Word = CDD_TLE94X1_CLEAR_ALL; // Clear the bus communication status DEV_STAT Register CddTle94x1_DataMirror.StatTx.DEV_STAT_Register.Data.Word = CDD_TLE94X1_CLEAR_ALL; // Update the CAN bit in the BUS_CTRL_0 register. CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Bit.CAN = CDD_SBC_CAN_CHANNEL_0_INIT_CFG; // Set the charge pump bit in the HW_CTRL_0 register.CP_EN CddTle94x1_DataMirror.CtrlTx.HW_CTRL_0_Register.Data.Bit.CP_EN = CDD_TLE94X1_ENABLE; // Set SS_MOD_FR in the HW_CTRL_2 regiester.SS_MOD_FR CddTle94x1_DataMirror.CtrlTx.HW_CTRL_2_Register.Data.Bit.SS_MOD_FR = CDD_TLE94X1_SS_MOD_FR_03; // Set the thermal shutdown threshold configuraton bit in the HW_CTRL_3 register.TSD_THR CddTle94x1_DataMirror.CtrlTx.HW_CTRL_3_Register.Data.Bit.TSD_THR = CDD_TLE94X1_TSD_THR_1; // Set the rest Delay Time Selection bit in the HW_CTRL_1 register.RSTN_DEL CddTle94x1_DataMirror.CtrlTx.HW_CTRL_1_Register.Data.Bit.RSTN_DEL = CDD_TLE94X1_RSTN_DEL_tRD2; // Set SBC to enter Restart/Fail-safe mode in case of over voltage in the M_S_CTRL register.VCC1_OV_RST CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Bit.VCC1_OV_RST = CDD_TLE94X1_VCC1_OV_RST_1; // Set VCC2_ON to normal mode in the M_S_CTRL register.VCC2_ON CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Bit.VCC2_ON = CDD_TLE94X1_VCC2_ON1; // Set SBC mode to normal mode in the M_S_CTRL register.MODE CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Bit.MODE = CDD_TLE94X1_NORMAL_MODE; // Write the data to the registers and check if it was successful or not // Write the data to the registers and check if it was successful or not if (CddTle94x1_WriteClearReg(TLE94X1_SUP_STAT_0_ADR, CddTle94x1_DataMirror.StatTx.SUP_STAT_0_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.StatRx.SUP_STAT_0_Register.Data.Word = CddTle94x1_DataMirror.StatTx.SUP_STAT_0_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_WK_STAT_0_ADR, CddTle94x1_DataMirror.StatTx.WK_STAT_0_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.StatRx.WK_STAT_0_Register.Data.Word = CddTle94x1_DataMirror.StatTx.WK_STAT_0_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_DEV_STAT_ADR, CddTle94x1_DataMirror.StatTx.DEV_STAT_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.StatRx.DEV_STAT_Register.Data.Word = CddTle94x1_DataMirror.StatTx.DEV_STAT_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_BUS_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_HW_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.HW_CTRL_0_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.HW_CTRL_0_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.HW_CTRL_0_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_HW_CTRL_2_ADR, CddTle94x1_DataMirror.CtrlTx.HW_CTRL_2_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.HW_CTRL_2_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.HW_CTRL_2_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_HW_CTRL_3_ADR, CddTle94x1_DataMirror.CtrlTx.HW_CTRL_3_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.HW_CTRL_3_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.HW_CTRL_3_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_HW_CTRL_1_ADR, CddTle94x1_DataMirror.CtrlTx.HW_CTRL_1_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.HW_CTRL_1_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.HW_CTRL_1_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_M_S_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.M_S_CTRL_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Word; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boInitCtrlWrite = ERROR_ON; } // prepare for the first SPI-Command in SPI-Cyclic Operation #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) CddSbc_InsertDefaultMessage(); #endif // PRQA S 5310 1 // compactness and readability } //#endif #if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_StoreSBCResetReason /// /// \descr Read MCU register and store the Reset Reason /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_StoreSBCResetReason(void) { if (CddTle94x1_ucSUP_STAT_0_POR == 1u) { CddTle94x1_eSBCResetReason = (uint8)ePowerOnResetSBC; } #if (CDD_SBC_CFG_WATCHDOG == STD_ON) else if (CddTle94x1_boIsWdgReset != FALSE) { CddTle94x1_eSBCResetReason = (uint8)eWatchdogReset; } #endif else if (CddTle94x1_ucWK_STAT_0_CANWU == 1u) { CddTle94x1_eSBCResetReason = (uint8)eCANWakeUpReset; } else if (CddTle94x1_ucWK_STAT_0_WK_WU == 1u) { CddTle94x1_eSBCResetReason = (uint8)eInputWakeUpReset; } else { CddTle94x1_eSBCResetReason = (uint8)eNoResetSBC; } //PRQA S 5336 1 // program architecture and readability } //----------------------------------------------------------------------------- /// \brief CddTle94x1_GetResetReason /// /// \descr Calls the hardware specific function to get the reset reason /// /// \param tieResetReason peResetReason /// /// \return void //----------------------------------------------------------------------------- uint8 CddTle94x1_GetSBCResetReason(void) { return (uint8)CddTle94x1_eSBCResetReason; } #endif #if (CDD_SBC_CFG_SLEEPMODE == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetSleepMode /// /// \descr Set SBC in Sleep Mode. /// Because Transfer Message mode is used to communicate over SPI, cyclic operation mode must be stopped, by calling SPI_Stop() before SetSleepMode operation is executed. /// Before setting the SBC to sleep mode, the wake-up and supply status registers shall to be cleared. /// Set the VCC2 output to OFF and deactiviate the Charge Pump. /// Set the CAN module to Wake Capable Mode /// Write the settings to the control registers and send the SLEEP_MODE command. /// The following error cases are handled: /// -The driver is unable to send the commands to the TLE 9471 SBC device therefore sets the /// GoToSleep_SpiFailure error flag. /// - The Sleep Mode command was successfully sent but the device is unable to reach /// Sleep Mode after waiting[MAX_WAITCNT] cycles which corresponds with 0.01[ms] /// therefore sets GoToSleep_SpiFailure error flag. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_SetSleepMode(void) { volatile uint16 unIndex; // Clear the Wake-up flag of the CAN0 in WK_STAT_0 Register CddTle94x1_DataMirror.StatTx.WK_STAT_0_Register.Data.Word = CDD_TLE94X1_CLEAR_ALL; // Clear the power on reset flag in SUP_STAT_0 Register CddTle94x1_DataMirror.StatTx.SUP_STAT_0_Register.Data.Word = CDD_TLE94X1_CLEAR_ALL; // Deactiviate the Charge Pump in the HW_CTRL_0 register.CP_EN CddTle94x1_DataMirror.CtrlTx.HW_CTRL_0_Register.Data.Bit.CP_EN = CDD_TLE94X1_DISABLE; // set CAN mode to wake capable mode in the BUS_CTRL_0 register.CAN CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Bit.CAN = CDD_TLE94X1_CAN_WAKE_ON; #if (CDD_SBC_CFG_WK_INPUT == STD_ON) // set CddTle94x1_DataMirror.CtrlTx.WK_CTRL_1_Register.Data.Bit.WK_EN = CDD_TLE94X1_ENABLE; #endif // Set VCC2_ON to off in the M_S_CTRL register.VCC2_ON CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Bit.VCC2_ON = CDD_TLE94X1_VCC2_OFF; // Set SBC mode to sleep mode in the M_S_CTRL register.MODE CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Bit.MODE = CDD_TLE94X1_SLEEP_MODE; // IMPORTANT!!! The order of the commands is important. Don't change it. // Write the data to the registers and check if it was successful or not if (CddTle94x1_WriteClearReg(TLE94X1_WK_STAT_0_ADR, CddTle94x1_DataMirror.StatTx.WK_STAT_0_Register.Data.Word) == FALSE) { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_SUP_STAT_0_ADR, CddTle94x1_DataMirror.StatTx.SUP_STAT_0_Register.Data.Word) == FALSE) { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_HW_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.HW_CTRL_0_Register.Data.Word) == FALSE) { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } if (CddTle94x1_WriteClearReg(TLE94X1_BUS_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word) == FALSE) { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } #if (CDD_SBC_CFG_WK_INPUT == STD_ON) if (CddTle94x1_WriteClearReg(TLE94X1_WK_CTRL_1_ADR, CddTle94x1_DataMirror.CtrlTx.WK_CTRL_1_Register.Data.Word) == FALSE) { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } #endif if (CddTle94x1_WriteClearReg(TLE94X1_M_S_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.M_S_CTRL_Register.Data.Word) != FALSE) { // The registers have been updated // Wait for 0.01 [ms] for (unIndex = 0u; unIndex < CDD_TLE94X1_SLEEP_WAITCNT; unIndex++) { // Do nothing. } // Set the error flag // The Sbc could not reach the sleep mode after x ms // Should not reach this point CddTle94x1_ErrorType.boGoToSleep_Failure = ERROR_ON; } else { // The commands were not sent to the SBC device, the SPI communication failed. CddTle94x1_ErrorType.boGotoSleep_SpiFailure = ERROR_ON; } }// PRQA S 5310 1 // compactness and readability #endif #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetCanMode /// /// \descr Set the specific SBC CAN transceiver to a chosen functional mode /// /// \param uint8 ucCanChannel - SBC CAN transceiver /// uint8 ucCanMode - CAN transceiver mode /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_SetCanMode(uint8 ucCanChannel, uint8 ucCanMode) { if (ucCanChannel == CAN_CH0) { if (CddTle94x1_ValidateCanMode(ucCanMode) == TRUE) { CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Bit.CAN = ucCanMode; if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { if (CddTle94x1_WriteClearReg(TLE94X1_BUS_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word; } } #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) else if (Spi_Stat_Get() == CDDSPI_STATE_CYCLIC_OPERATION) { (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_CTRL_0_ADR, CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word, CDD_TLE94X1_WRITE_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_CTRL_0_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkSetCanMode); } #endif else { // do nothing } } else { // do nothing } CddTle94x1_ErrorType.boCanChannelError = NO_ERROR; } else { CddTle94x1_ErrorType.boCanChannelError = ERROR_ON; } } #endif #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_GetCanMode /// /// \descr Set the specific SBC CAN transceiver to a chosen functional mode /// /// \param uint8 ucCanChannel - SBC CAN transceiver /// /// \return uint8 ucReturn //----------------------------------------------------------------------------- uint8 CddTle94x1_GetCanMode(uint8 ucCanChannel) { uint8 ucReturn = 0; uint16 unReadReg = 0; if (ucCanChannel == CAN_CH0) { if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { unReadReg = CddTle94x1_ReadReg(TLE94X1_BUS_CTRL_0_ADR); // If there were no read errors if (unReadReg != CDD_TLE94X1_ERROR) { // Store the registers content in the memory CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Word = (uint8)unReadReg; } } ucReturn = CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Bit.CAN; } else { // do nothing } return ucReturn; } #endif #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_GetCanUV /// /// \descr Get the undervoltage bit of CAN bus /// /// \param void /// /// \return uint8 ucReturn //----------------------------------------------------------------------------- uint8 CddTle94x1_GetCanUV(void) { uint8 ucReturn = 0; uint16 unReadReg = 0; if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { unReadReg = CddTle94x1_ReadReg(TLE94X1_BUS_STAT_ADR); // If there were no read errors if (unReadReg != CDD_TLE94X1_ERROR) { // Store the registers content in the memory CddTle94x1_DataMirror.StatRx.BUS_STAT_Register.Data.Word = (uint8)unReadReg; } } ucReturn = CddTle94x1_DataMirror.StatRx.BUS_STAT_Register.Data.Bit.VCAN_UV; return ucReturn; } #endif #if ((CDD_SBC_CFG_CAN_OPERATION == STD_ON) && (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGetCanMode /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the SUP_STAT_0_ register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkGetCanMode(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); uint8 ucAddresse = (uint8)(unSentVal & CDD_TLE94X1_ADDRESS_FIELD); if (ucAddresse == TLE94X1_BUS_CTRL_0_ADR) { // Update the register CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Word = ucRxData; } else { // do nothing } } #endif #if ((CDD_SBC_CFG_CAN_OPERATION == STD_ON) && (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGetBusState /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the BUS_STAT register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkGetBusState(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); uint8 ucAddresse = (uint8)(unSentVal & CDD_TLE94X1_ADDRESS_FIELD); if (ucAddresse == TLE94X1_BUS_STAT_ADR) { // Update the register CddTle94x1_DataMirror.StatRx.BUS_STAT_Register.Data.Word = ucRxData; } else { // do nothing } } #endif #if ((CDD_SBC_CFG_CAN_OPERATION == STD_ON) && (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkSetCanMode /// /// \descr Updates the value of the Register if the write was successful /// This callback updates the value of the BUS_CTRL_0 register in the memory if the write was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkSetCanMode(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); (void)unSentVal; // Preprocess the SentVal in order to get the Sent data //uint8 ucSentData = (uint8)(unSentVal >> 8u); // If the write wasn't successful //if (ucRxData != ucSentData) if (ucRxData != CddTle94x1_DataMirror.CtrlTx.BUS_CTRL_0_Register.Data.Word) { // Set error flag CddTle94x1_ErrorType.boCyclic_CanMode = ERROR_ON; CddTle94x1_ErrorSequenceCounterInc(); } else { CddTle94x1_ErrorSequenceCounterClear();// Reset the error counter // RESET DTC CddTle94x1_ErrorType.boCyclic_CanMode = NO_ERROR; CddTle94x1_DataMirror.CtrlRx.BUS_CTRL_0_Register.Data.Word = ucRxData; } } #endif #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_ValidateCanMode /// /// \descr Validate the CAN mode /// Checks if the received mode is a valid CAN mode /// /// \param uint8 ucCanMode - the mode to be validated /// /// \return boolean boReturn //----------------------------------------------------------------------------- STATIC_AL boolean CddTle94x1_ValidateCanMode(uint8 ucCanMode) { boolean boReturn; // If the CAN mode is valid return TRUE switch (ucCanMode) { case CDD_TLE94X1_CAN_OFF: case CDD_TLE94X1_CAN_WAKE_ON: case CDD_TLE94X1_CAN_RECEIVE_ONLY: case CDD_TLE94X1_CAN_NORMAL: { CddTle94x1_ErrorType.boCanModeError = NO_ERROR; boReturn = TRUE; } break; default: { CddTle94x1_ErrorType.boCanModeError = ERROR_ON; boReturn = FALSE; } break; } return boReturn; } #endif #if ((CDD_SBC_CFG_WATCHDOG == STD_ON) && (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGetWDCtrl /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the WD_CTRL register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkSetWDCtrl(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); (void)unSentVal; // If the write wasn't successful if (ucRxData != CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word) { // Set error flag CddTle94x1_ErrorType.boSpiWdgFailure = ERROR_ON; CddTle94x1_ErrorSequenceCounterInc(); } else { CddTle94x1_ErrorSequenceCounterClear();// Reset the error counter // RESET DTC CddTle94x1_ErrorType.boSpiWdgFailure = NO_ERROR; CddTle94x1_DataMirror.CtrlRx.WD_CTRL_Register.Data.Word = ucRxData; } } #endif #if ((CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) && (CDD_SBC_CFG_WK_INPUT == STD_ON)) //----------------------------------------------------------------------------- /// \brief CddTle94x1_GetWakeUpStatus /// /// \descr Get the WakeUp Pin Status /// /// \param void /// /// \return boolean boReturn //----------------------------------------------------------------------------- boolean CddTle94x1_GetWakeUpStatus(void) { boolean boReturn = FALSE; boReturn = (boolean)CddTle94x1_DataMirror.StatRx.WK_LVL_STAT_Register.Data.Bit.WK_LVL; return boReturn; } //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGWakeUpStatus /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the WK_LVL_STAT register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkGetWakeUpStatus(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); uint8 ucAddresse = (uint8)(unSentVal & CDD_TLE94X1_ADDRESS_FIELD); if (ucAddresse == TLE94X1_WK_LVL_STAT_ADR) { // Update the register CddTle94x1_DataMirror.StatRx.WK_LVL_STAT_Register.Data.Word = ucRxData; } else { // do nothing } } #endif //----------------------------------------------------------------------------- /// \brief CddTle94x1_WriteClearReg /// /// \descr Writes or Clears specific registers using transfer messages /// During initialization, deinitialization and setting the device into sleep mode this function is used to write and clear specific registers. /// The CddSpi_TransferMsg will be called for a maximum of CDD_SBC_MAX_WRITE_ATTEMPTS times in case of unsuccessful write. /// After a successful write CddTle94x1_ReadReg() is called to verify if the data was indeed written to the register. /// The function return FALSE if the data read from the register is not the one received as a parameter and TRUE if they are equal. /// /// \param uint8 ucAddress - the address of the register /// uint16 unDataField - data to be written into the register /// /// \return boolean boReturn //----------------------------------------------------------------------------- STATIC_AL boolean CddTle94x1_WriteClearReg(uint8 ucAddress, uint16 unDataField) { uint8 ucAddressField, ucIterationIndex = 0u; uint16 unTxData, unRxData; boolean boReturn = FALSE; // Concatenate the address field of the message ucAddressField = ucAddress | CDD_TLE94X1_WRITE_CMD; // Concatenate the address field of the message with the data field and store the obtained message in the buffer unTxData = unDataField; unTxData = unTxData << 8u; unTxData = unTxData | ucAddressField; // Try to send the data to the register for a maximum of 10 times while ((CddSpi_TransferMsg(&unTxData, &unRxData, CDD_SBC_CFG_DATA_LEN, (uint8)SEQ_Sbc) != TRUE) && (ucIterationIndex < CDD_SBC_CFG_MAX_WRITE_ATTEMPTS)) { // Increment the error counter ucIterationIndex++; } // If the write command was sent succefully via SPI if (ucIterationIndex < CDD_SBC_CFG_MAX_WRITE_ATTEMPTS) { // Read the registers value into the unRxData variable unRxData = CddTle94x1_ReadReg(ucAddress); // If the data was updated in the register if (unRxData == unDataField) { // Operation succesful => return TRUE boReturn = TRUE; } else { // do nothing } } else { // do nothing } return boReturn; } //----------------------------------------------------------------------------- /// \brief CddTle94x1_ReadReg /// /// \descr Reads specific registers using tranfser messages during the initilization /// During initialization, deinitialization and setting the device into sleep mode this function is used to read specific registers. /// The function will return the value stored in the register if the Read was succesful and CDD_TLE94X1_ERROR if the process was unsuccesful for a maximum of [MAX_READ_ATTEMPTS] times. /// /// \param uint8 ucAddress /// /// \return uint16 unReturnValue //----------------------------------------------------------------------------- STATIC_AL uint16 CddTle94x1_ReadReg(uint8 ucAddress) { uint8 ucIterationCounter = 0u; // Concatenate the message to be send in order to read out the values stored in the Sbc's register uint16 unSpiTxMsg = (uint16)ucAddress; uint16 unReturnValue = (uint16)CDD_TLE94X1_ERROR; // Try to send the Msg until is sent succesfuly and the maximum read attemps are not exceeded while ((CddSpi_TransferMsg(&unSpiTxMsg, &unSpiTxMsg, CDD_SBC_CFG_DATA_LEN, (uint8)SEQ_Sbc) != TRUE) && (ucIterationCounter < CDD_SBC_CFG_MAX_READ_ATTEMPTS)) { // Increment the error counter ucIterationCounter++; } // If the read was unsuccesful after MAX_READ_ATTEMP times if (ucIterationCounter < CDD_SBC_CFG_MAX_READ_ATTEMPTS) { // Succesful read // Store the register's content in the buffer const uint16 unSpiRxMsg = (uint8)(unSpiTxMsg >> 8u); unReturnValue = unSpiRxMsg; } else { // do nothing } return unReturnValue; } #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddSbc_InsertDefaultMessage /// /// \descr Default message will be inserted if there are no messages configured in the queue /// This default message will check cyclically the SUP_STAT_0.VCC2_UV status register /// This message will be sent only when the queue is empty and there are no more entries to be processed. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddSbc_InsertDefaultMessage(void) { // Read out the Register cyclically switch (CddSbc_eDefaultMsg) { #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) case eBUS_CTRL_0: (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_CTRL_0_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_CTRL_0_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkGetCanMode); CddSbc_eDefaultMsg = eBUS_STAT; break; case eBUS_STAT: (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_BUS_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkGetBusState); #if (CDD_SBC_CFG_WK_INPUT == STD_ON) CddSbc_eDefaultMsg = eWK_LVL_STAT; #elif (CDD_SBC_CFG_VCC2 == STD_ON) CddSbc_eDefaultMsg = eTHERM_STAT; #else CddSbc_eDefaultMsg = eSUP_STAT_0; #endif break; #endif #if (CDD_SBC_CFG_WK_INPUT == STD_ON) case eWK_LVL_STAT: (void)CddSbc_InsertNewSchedEntry(TLE94X1_WK_LVL_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_WK_LVL_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkGetWakeUpStatus); #if (CDD_SBC_CFG_VCC2 == STD_ON) CddSbc_eDefaultMsg = eTHERM_STAT; #else CddSbc_eDefaultMsg = eSUP_STAT_0; #endif break; #endif case eSUP_STAT_0: (void)CddSbc_InsertNewSchedEntry(TLE94X1_SUP_STAT_0_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_SUP_STAT_0_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkGetSupState0); #if (CDD_SBC_CFG_CAN_OPERATION == STD_ON) CddSbc_eDefaultMsg = eBUS_CTRL_0; #elif (CDD_SBC_CFG_WK_INPUT == STD_ON) CddSbc_eDefaultMsg = eWK_LVL_STAT; #elif (CDD_SBC_CFG_VCC2 == STD_ON) CddSbc_eDefaultMsg = eTHERM_STAT; #endif break; #if (CDD_SBC_CFG_VCC2 == STD_ON) case eTHERM_STAT: (void)CddSbc_InsertNewSchedEntry(TLE94X1_THERM_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_THERM_STAT_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkGetThermoStat); CddSbc_eDefaultMsg = eSUP_STAT_0; #endif default: CddSbc_eDefaultMsg = eBUS_STAT; break; } } #endif #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddSbc_ScheduleTableFull /// /// \descr Called by the CddSbc_InsertNewSchedEntry function. Sets the flag /// /// \param boolean boStatus - NO_ERROR/ERROR_ON /// /// \return void //----------------------------------------------------------------------------- void CddSbc_ScheduleTableFull(boolean boStatus) { // Set the flag with the received parameter. CddTle94x1_ErrorType.boScheduleTableFull = boStatus; } #endif #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGetSupState0 /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the SUP_STAT_0_ register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkGetSupState0(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); uint8 ucAddresse = (uint8)(unSentVal & CDD_TLE94X1_ADDRESS_FIELD); if (ucAddresse == TLE94X1_SUP_STAT_0_ADR) { // Update the register CddTle94x1_DataMirror.StatRx.SUP_STAT_0_Register.Data.Word = ucRxData; } else { // do nothing } } #endif #if (CDD_SBC_CFG_VCC2 == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_CbkGetThermoStat /// /// \descr Updates the value of the Register if the read was successful /// This callback updates the value of the THERM_STAT register in the memory if the read was succesful /// /// \param uint32 ulData - represents the data received during cyclic communication /// uint16 ucSentData - Used to store the data we just sent. Used for comparison /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_CbkGetThermoStat(uint32 ulData, uint16 unSentVal) { // Preprocess the data before checking it uint8 ucRxData = (uint8)(ulData >> 8u); uint8 ucAddresse = (uint8)(unSentVal & CDD_TLE94X1_ADDRESS_FIELD); if (ucAddresse == TLE94X1_THERM_STAT_ADR) { // Update the register CddTle94x1_DataMirror.StatRx.THERM_STAT_Register.Data.Word = ucRxData; } else { // do nothing } } #endif #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_ErrorSequenceCounterInc /// /// \descr Increment the error sequence counter of the SPI /// In this function the error sequence counter is incremented and if the counter reachs /// CDD_SBC_CFG_MAX_CYCLIC_SEQ_ERRORS, the error flag boCyclic_SPI_Communication is set /// with ERROR_ON. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_ErrorSequenceCounterInc(void) { if (CddTle94x1_unErrorSequenceCounter < CDD_SBC_CFG_MAX_CYCLIC_SEQ_ERRORS) { // Increment the sequence error counter CddTle94x1_unErrorSequenceCounter++; } else { // Set the error flag boCyclic_SPI_Communication CddTle94x1_ErrorType.boCyclic_SPI_Communication = ERROR_ON; } } #endif #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_ErrorSequenceCounterClear /// /// \descr clear the error sequence counter of the SPI /// This function cleas the error sequence counter and set the error flag /// boCyclic_SPI_Communication with NO_ERROR /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_ErrorSequenceCounterClear(void) { CddTle94x1_unErrorSequenceCounter = 0; // Set the error flag boCyclic_SPI_Communication CddTle94x1_ErrorType.boCyclic_SPI_Communication = NO_ERROR; } #endif #if (CDD_SBC_CFG_INIT_OPERATION == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_DeInit /// /// \descr Denitialize TLE9471 SBC complex device driver /// This function is a currently dummy function. /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_DeInit(void) { // dummy function // currently no requirements for A270. (void)CddTle94x1_ucSUP_STAT_0_POR; (void)CddTle94x1_ucWK_STAT_0_CANWU; (void)CddTle94x1_ErrorType; //#if (CDD_SBC_CFG_STORE_RESETREASON == STD_ON) // (void)CddSbc_eMCUResetReason; // (void)CddSbc_eSBCResetReason; // (void)CddSbc_tResetReason; //#endif } #endif #if (CDD_SBC_CFG_WATCHDOG == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetWdgWithSingleOperation /// /// \descr This function is to set the watchdog with SPI single opeartion /// /// \param void /// /// \return void //----------------------------------------------------------------------------- STATIC_AL void CddTle94x1_SetWdgWithSingleOperation(void) { if (CddTle94x1_WriteClearReg(TLE94X1_WD_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word) != FALSE) { CddTle94x1_DataMirror.CtrlRx.WD_CTRL_Register.Data.Word = CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word; CddTle94x1_ErrorType.boSpiWdgFailure = NO_ERROR; } else { // Write was unsuccessful // Set the error Flag CddTle94x1_ErrorType.boSpiWdgFailure = ERROR_ON; } } #endif #if (CDD_SBC_CFG_WATCHDOG == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetWdgWindowModeAnd10ms /// /// \descr This function is to set the watchdog with window mode and 10ms /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_SetWdgWindowModeAnd10ms(void) { // Set Watchdog Timer Periode in the WD_CTRL register.WD_TIMER CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_TIMER = CDD_TLE94X1_WD_TIMER_10ms; // Set Watchdog with Window watchdog in the WD_CTRL register.WD_WIN CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_WIN = CDD_TLE94X1_WD_Window; // Set Watchdog Checksum in the WD_CTRL register.CHECKSUM CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.CHECKSUM = CDD_TLE94X1_WD_Checksum_1; if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { CddTle94x1_SetWdgWithSingleOperation(); } #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) else if (Spi_Stat_Get() == CDDSPI_STATE_CYCLIC_OPERATION) { // Set the WD_CTRL register to trigger the watchdog (void)CddSbc_InsertNewSchedEntry(TLE94X1_WD_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word, CDD_TLE94X1_WRITE_CMD, NULL_PTR); } #endif else { // do nothing } } #endif #if (CDD_SBC_CFG_WATCHDOG == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetWdgTimeoutModeAnd200ms /// /// \descr This function is to set the watchdog with timeout mode and 200ms /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_SetWdgTimeoutModeAnd200ms(void) { // Set Watchdog Timer Periode in the WD_CTRL register.WD_TIMER CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_TIMER = CDD_TLE94X1_WD_TIMER_200ms; // Set Watchdog with Window watchdog in the WD_CTRL register.WD_WIN CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_WIN = CDD_TLE94X1_WD_TimeOut; // Set Watchdog Checksum in the WD_CTRL register.CHECKSUM CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.CHECKSUM = CDD_TLE94X1_WD_Checksum_1; if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { CddTle94x1_SetWdgWithSingleOperation(); } #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) else if (Spi_Stat_Get() == CDDSPI_STATE_CYCLIC_OPERATION) { // Set the WD_CTRL register to trigger the watchdog (void)CddSbc_InsertNewSchedEntry(TLE94X1_WD_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word, CDD_TLE94X1_WRITE_CMD, NULL_PTR); } #endif else { // do nothing } } #endif #if (CDD_SBC_CFG_WATCHDOG == STD_ON) //----------------------------------------------------------------------------- /// \brief CddTle94x1_SetWdgWindowModeAnd200ms /// /// \descr This function is to set the watchdog with window mode and 200ms /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void CddTle94x1_SetWdgWindowModeAnd200ms(void) { // Set Watchdog Timer Periode in the WD_CTRL register.WD_TIMER CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_TIMER = CDD_TLE94X1_WD_TIMER_200ms; // Set Watchdog with Window watchdog in the WD_CTRL register.WD_WIN CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_WIN = CDD_TLE94X1_WD_Window; // Set Watchdog Checksum in the WD_CTRL register.CHECKSUM CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.CHECKSUM = CDD_TLE94X1_WD_Checksum_0; if (Spi_Stat_Get() == CDDSPI_STATE_SINGLE_OPERATION) { // Set Watchdog Timer Periode in the WD_CTRL register.WD_TIMER CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_TIMER = CDD_TLE94X1_WD_TIMER_200ms; // Set Watchdog with Window watchdog in the WD_CTRL register.WD_WIN CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.WD_WIN = CDD_TLE94X1_WD_TimeOut; // Set Watchdog Checksum in the WD_CTRL register.CHECKSUM CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Bit.CHECKSUM = CDD_TLE94X1_WD_Checksum_1; CddTle94x1_SetWdgWithSingleOperation(); } #if (CDD_SBC_CFG_CYCLIC_OPERATION == STD_ON) else if (Spi_Stat_Get() == CDDSPI_STATE_CYCLIC_OPERATION) { // Set the WD_CTRL register to trigger the watchdog (void)CddSbc_InsertNewSchedEntry(TLE94X1_WD_CTRL_ADR, CddTle94x1_DataMirror.CtrlTx.WD_CTRL_Register.Data.Word, CDD_TLE94X1_WRITE_CMD, NULL_PTR); (void)CddSbc_InsertNewSchedEntry(TLE94X1_WD_CTRL_ADR, CDD_TLE94X1_CLEAR_ALL, CDD_TLE94X1_READ_CMD, CddTle94x1_CbkSetWDCtrl); } #endif else { // do nothing } } #endif /** * @brief This use case will set asynchronous as SPI_INTERRUPT_MODE and transmit data * by master synchronous and salve asynchronous. * */ boolean CddSpi_TransferMsg(uint16 *Data, uint16 *RcData, uint8 len, uint8 Cs) { uint8 tepm_data[2]; uint8 tepm_rxdata[2]; uint8 data_0; data_0 = *Data >> 8; tepm_data[0] = data_0<<7 | (data_0<<5 & 0x40) | (data_0<<3 & 0x20) | (data_0<<1 & 0x10) | (data_0>>7 & 0x01) | (data_0>>5 & 0x02) | (data_0>>3 & 0x04) | (data_0 & 0x08); data_0 = *Data; tepm_data[1] = data_0<<7 | (data_0<<5 & 0x40) | (data_0<<3 & 0x20) | (data_0<<1 & 0x10) | (data_0>>7 & 0x01) | (data_0>>5 & 0x02) | (data_0>>3 & 0x04) | (data_0 & 0x08); Spi_SetupEB(Cs, tepm_data, tepm_rxdata, len); Spi_SyncTransmit(Cs); *RcData = tepm_rxdata[0] | (tepm_rxdata[1]<<8); return TRUE; } #define ctadCddSbc_STOP_SEC_CODE #include <../Cfg/CddTle94x1_MemMap.h> //----------------------------------------------------------------------------- // End declaration or definitions of functions //----------------------------------------------------------------------------- // EOF