//***************************************************************************** // (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 Bmg.c /// /// \brief Functions for AL- specific initialization: /// - mounting side LEFT /RIGHT /// - EFT entry condition --> Normal Mode or "WaitForRAMAppl" /// /// \descr /// /// Additional information can be found in the design description (Link: /// MDDD) /// /// \author Cosmin Cojocaru (f11501c) /// mailTo:constantin-cosmin.cojocaru(at)marelli.com //----------------------------------------------------------------------------- #include "Bmg.h" #include "ShaData.h" #include #include #ifdef BMG_DETECT_MOUNTING_SIDE static uint8 Bmg_MountingSideLeftCounter = 0U; static uint8 Bmg_MountingSideRightCounter = 0U; static uint8 Bmg_MountingSideUnknown = 0U; #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION static uint8 Bmg_WaitForRAMApplCounter = 0U; #endif //BMG_DETECT_ENTRY_CONDITION static TIMER Bmg_SampeRateTimer; //function prototypes #ifdef BMG_DETECT_ENTRY_CONDITION static void Bmg_CheckWaitForRAMAppl(uint16 adcRawVal1, uint16 adcRawVal2, uint16 adcRawVal3); #ifndef BMG_IS_ENTRY_COND_VAL1 #error BMG_IS_ENTRY_COND_VAL1 must be set in BmgCgf.h #endif //BMG_IS_ENTRY_COND_VAL1 #ifndef BMG_IS_ENTRY_COND_VAL2 #define BMG_IS_ENTRY_COND_VAL2(x) (1U) #endif //BMG_IS_ENTRY_COND_VAL2 #ifndef BMG_IS_ENTRY_COND_VAL3 #define BMG_IS_ENTRY_COND_VAL3(x) (1U) #endif //BMG_IS_ENTRY_COND_VAL3 #endif //BMG_DETECT_ENTRY_CONDITION #ifdef BMG_DETECT_MOUNTING_SIDE static void Bmg_CheckMountingSide(uint16 adcRawVal, uint16 adcRawValKl30); #endif //BMG_DETECT_MOUNTING_SIDE //----------------------------------------------------------------------------- /// \brief Bmg_BootStatus_detection /// /// \descr Function which is performing the reading of ADC channels for mounting side and EFT entry condition /// and increments it's specific counter according to the voltage tresholds /// /// \param void /// /// \return void //----------------------------------------------------------------------------- static void Bmg_BootStatus_detection(void) { uint8 u8_Index; #ifdef BMG_DETECT_MOUNTING_SIDE uint16 u16_RawMoutingSide = 0U; #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION uint16 u16_RawEntryCondVal1 = 0U; uint16 u16_RawEntryCondVal2 = 0U; uint16 u16_RawEntryCondVal3 = 0U; #endif //BMG_DETECT_ENTRY_CONDITION #ifdef BMG_DETECT_MOUNTING_SIDE Bmg_MountingSideLeftCounter = 0U; Bmg_MountingSideRightCounter = 0U; Bmg_MountingSideUnknown = 0U; #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION Bmg_WaitForRAMApplCounter = 0U; #endif //BMG_DETECT_ENTRY_CONDITION for( u8_Index = (uint8)0; u8_Index < BMG_NR_SAMPES; u8_Index++ ) { //set sample rate time Bmg_SampeRateTimer = TimerStart( BMG_SAMPLE_RATE ); #ifdef BMG_DETECT_MOUNTING_SIDE (void)Adc_ReadGroup(BMG_MOUNTING_SIDE_ADC_INDEX, &u16_RawMoutingSide); #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION #ifdef BMG_ENTRY_COND_PIN_VAL1_INDEX (void)Adc_ReadGroup(BMG_ENTRY_COND_PIN_VAL1_INDEX, &u16_RawEntryCondVal1); #else #error BMG_ENTRY_COND_PIN_VAL1_INDEX must be set in BmgCgf.h #endif //BMG_ENTRY_COND_PIN_VAL1_INDEX #ifdef BMG_ENTRY_COND_PIN_VAL2_INDEX (void)Adc_ReadGroup(BMG_ENTRY_COND_PIN_VAL2_INDEX, &u16_RawEntryCondVal2); #endif //BMG_ENTRY_COND_PIN_VAL2_INDEX #ifdef BMG_ENTRY_COND_PIN_VAL3_INDEX (void)Adc_ReadGroup(BMG_ENTRY_COND_PIN_VAL3_INDEX, &u16_RawEntryCondVal3); #endif //BMG_ENTRY_COND_PIN_VAL3_INDEX #endif //BMG_DETECT_ENTRY_CONDITION //check results #ifdef BMG_DETECT_MOUNTING_SIDE Bmg_CheckMountingSide(u16_RawMoutingSide, u16_RawMoutingSide); #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION Bmg_CheckWaitForRAMAppl(u16_RawEntryCondVal1, u16_RawEntryCondVal2, u16_RawEntryCondVal3); #endif //BMG_DETECT_ENTRY_CONDITION //wait for sample rate timing while ( TimerTimeout( Bmg_SampeRateTimer ) == 0u ) {;} } } #ifdef BMG_DETECT_MOUNTING_SIDE //----------------------------------------------------------------------------- /// \brief Bmg_CheckMountingSide /// /// \descr Function used to perform the increment of mounting side specific counters based on voltage tresholds /// /// \param adcRawVal: RAW ADC conversion value for LR detection assigned channel /// \param adcRawValKl30: RAW ADC conversion value for KL30 assigned channel(parameter not used) /// /// \return void //----------------------------------------------------------------------------- static void Bmg_CheckMountingSide(uint16 adcRawVal, uint16 adcRawValKl30) { // if value under the detection threshold left side is detected if( BMG_IS_MOUNTING_SIDE_LEFT(adcRawVal)) { Bmg_MountingSideLeftCounter++; } else if(BMG_IS_MOUNTING_SIDE_RIGHT(adcRawVal)) { Bmg_MountingSideRightCounter++; } else { Bmg_MountingSideUnknown++; } (void)adcRawValKl30; // parameter is unused, avoid any warnings } //----------------------------------------------------------------------------- /// \brief Bmg_BootStatus_isMountingSideLeft /// /// \descr Function which detects Left mounting side based on it's counter value /// /// \param void /// /// \return boolean: TRUE - indicates that mounting side is on Left /// FALSE - indicates that mounting side is on different side than Left(Righ or Unknown) /// //----------------------------------------------------------------------------- static boolean Bmg_BootStatus_isMountingSideLeft(void) { //if most of the samples match the condition returns true return ( (Bmg_MountingSideLeftCounter > BMG_MAJORITY_OF_COUNTS_CHECKS) ? TRUE : FALSE ); } //----------------------------------------------------------------------------- /// \brief Bmg_BootStatus_isMountingSideRight /// /// \descr Function which detects Right mounting side based on it's counter value /// /// \param void /// /// \return boolean: TRUE - indicates that mounting side is on Right /// FALSE - indicates that mounting side is on different side than Right(Left or Unknown) /// //----------------------------------------------------------------------------- static boolean Bmg_BootStatus_isMountingSideRight(void) { //if most of the samples match the condition returns true return ( (Bmg_MountingSideRightCounter > BMG_MAJORITY_OF_COUNTS_CHECKS) ? TRUE : FALSE ); } #endif //BMG_DETECT_MOUNTING_SIDE #ifdef BMG_DETECT_ENTRY_CONDITION //----------------------------------------------------------------------------- /// \brief Bmg_CheckWaitForRAMAppl /// /// \descr Function used to perform the increment of EFT entry condition specific counter based on voltage tresholds /// /// \param adcRawVal1: RAW ADC conversion value for NTC0 assigned channel /// \param adcRawVal2: RAW ADC conversion value for NTC1 assigned channel /// \param adcRawVal3: RAW ADC conversion value for NTC2 assigned channel /// /// \return void //----------------------------------------------------------------------------- static void Bmg_CheckWaitForRAMAppl(uint16 adcRawVal1, uint16 adcRawVal2, uint16 adcRawVal3) { // all three defined condition must match to detect the entry condititon if ( ( BMG_IS_ENTRY_COND_VAL1( adcRawVal1 ) ) && ( BMG_IS_ENTRY_COND_VAL2( adcRawVal2 ) ) && ( BMG_IS_ENTRY_COND_VAL3( adcRawVal3 ) ) ) { Bmg_WaitForRAMApplCounter++; } else { // no valid voltage value to met the EFT entry condition, skip incrementing the counter } } //----------------------------------------------------------------------------- /// \brief Bmg_BootStatus_waitForRAMAppl /// /// \descr Function which detects EFT operating mode based on it's counter value /// /// \param void /// /// \return boolean: TRUE - indicates that PBL is running in EFT operating mode /// FALSE - indicates that PBL is running in normal operating mode //----------------------------------------------------------------------------- static boolean Bmg_BootStatus_waitForRAMAppl(void) { //if most of the samples match the condition returns true return ( (Bmg_WaitForRAMApplCounter > BMG_MAJORITY_OF_COUNTS_CHECKS) ? TRUE : FALSE ); } //----------------------------------------------------------------------------- /// \brief start_app /// /// \descr Function used to modify the CPU program counter to start executing instructions from a designated address /// /// \param void /// /// \return void //----------------------------------------------------------------------------- static void __attribute__((naked)) start_app(uint32 pc, uint32 sp) // PRQA S 3206 1 // pc and sp params are actually used through assembly instructions { __asm(" \n\ msr msp, r1 /* load r1 into MSP */\n\ bx r0 /* branch to the address at r0 */\n\ "); }// PRQA S 5334 3 // function not empty, assembly section code is used inside it //----------------------------------------------------------------------------- /// \brief Bmg_JumpToApplication /// /// \descr Function used to jump to FBL start vector. This function will be called after execution of PBL SW, passing the handle to other SW applications /// /// \param void /// /// \return void //----------------------------------------------------------------------------- static void Bmg_JumpToApplication(void) { //Chage value of CM0P_SCS_VTOR //PRQA S 306 1 //used as an adress uint32* CM4_SCS_VTOR = (uint32*)((uint32)0xE000ED08UL); const volatile uint32* FBL_VALID_PTR = (const volatile uint32*)((uint32)BMG_FBL_VALID_FLAG_ADDR); /* Check if FBL flag is valid */ if (*FBL_VALID_PTR == BMG_FBL_VALID_FLAG_VALUE) { *CM4_SCS_VTOR = BMG_FBL_START_ADDR; } else /* No valid FBL flag detected, jump in FBL updater */ { *CM4_SCS_VTOR = BMG_FBL_UPDATER_START_ADDR; } // PRQA S 306 1 //correct cast const uint32* pc = (uint32*)(*CM4_SCS_VTOR + 4U); // PRQA S 306 1 //correct cast const uint32* sp = (uint32*)(*CM4_SCS_VTOR); start_app(*pc, *sp); } //----------------------------------------------------------------------------- /// \brief Bmg_Run /// /// \descr Function which sets the mounting side pattern values in the shared data memory and detects the operating mode of PBL SW /// /// \param void /// /// \return void //----------------------------------------------------------------------------- void Bmg_Run(void) { //Initialize Mounting side with UNKNOWN ShaData.MountingSide = EcuMountingSide_UNKNOWN.Code; //perform the reading of ADC channels and increment the mounting side and enty condition counters according to voltage tresholds Bmg_BootStatus_detection(); //check if mounting side is Left and write to shared data if (Bmg_BootStatus_isMountingSideLeft() != 0u) { ShaData.MountingSide = EcuMountingSide_LEFT.Code; } //check if mounting side is Right and write to shared data else if (Bmg_BootStatus_isMountingSideRight() != 0u) { ShaData.MountingSide = EcuMountingSide_RIGHT.Code; } //no Left or Right side detected, write unknown to shared data else { ShaData.MountingSide = EcuMountingSide_UNKNOWN.Code; } //check for EFT entry condition if (Bmg_BootStatus_waitForRAMAppl() != 0u) { //start OS and wait for can messages to load AL flash software into memory OsSchedulerStartOs(); } else { //jump in APP if EFT entry condition is not satisfied Bmg_JumpToApplication(); } //this code should not be reached while (1) { ; } } #endif //BMG_DETECT_ENTRY_CONDITION // EOF