diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h index 263737e73..03c55a873 100644 --- a/Apps/Inc/ReadCarCAN.h +++ b/Apps/Inc/ReadCarCAN.h @@ -11,8 +11,8 @@ #define SAT_BUF_LENGTH 5 // Precharge Delay times in seconds -#define PRECHARGE_MOTOR_DELAY 7 // 7 Seconds, need to change -#define PRECHARGE_ARRAY_DELAY 2 // 2 Seconds, need to change +#define PRECHARGE_MOTOR_DELAY 1 // 7 Seconds, need to change +#define PRECHARGE_ARRAY_DELAY 1 // 2 Seconds, need to change /** * Error types @@ -54,4 +54,7 @@ uint8_t SOC_Get(void); */ uint32_t SBPV_Get(void); +// Getter function for array ignition status +bool PreChargeComplete_Get(void); + #endif \ No newline at end of file diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 5564adf10..8d3f08734 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -6,6 +6,7 @@ #include "Minions.h" #include "os.h" #include "os_cfg_app.h" +#include "config.h" // Array saturation threshold is halfway between 0 and max saturation value (half of summation from one to the number of positions) #define ARRAY_SATURATION_THRESHOLD (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) @@ -44,8 +45,8 @@ static int8_t HVPlusMinusChargeMsgSaturation = 0; static uint8_t HVPlusMinusMotorOldestMsgIdx = 0; // Array ignition (IGN_1) pin status -static bool arrayContactorIgnitionStatus = false; -// Array ignition (IGN_1) pin status +static bool arrayIgnitionStatus = false; +// Array ignition (IGN_2) pin status static bool motorControllerIgnitionStatus = false; // Boolean to indicate precharge status @@ -73,7 +74,12 @@ int8_t ChargeMsgSaturation_Get(){ // Getter function for array ignition status bool ArrayIgnitionStatus_Get(void){ - return arrayContactorIgnitionStatus; + return arrayIgnitionStatus; +} + +// Getter function for array ignition status +bool PreChargeComplete_Get(void){ + return arrayBypassPrechargeComplete; } // Getter function for SOC @@ -103,12 +109,6 @@ static void updateHVPlusMinusSaturation(int8_t chargeMessage){ newSaturation += HVPlusMinusChargeMsgBuffer[(HVPlusMinusMotorOldestMsgIdx + i) % SAT_BUF_LENGTH] * (i + 1); } HVPlusMinusChargeMsgSaturation = newSaturation; - - if(chargeMessage == -1){ - chargeEnable = false; - }else if(HVPlusMinusChargeMsgSaturation >= MOTOR_SATURATION_THRESHOLD){ - chargeEnable = true; - } } /** @@ -128,6 +128,12 @@ static void updateHVArraySaturation(int8_t chargeMessage){ newSaturation += HVArrayChargeMsgBuffer[(HVArrayOldestMsgIdx + i) % SAT_BUF_LENGTH] * (i + 1); } HVArrayChargeMsgSaturation = newSaturation; + + if(chargeMessage == -1){ + chargeEnable = false; + }else if(HVArrayChargeMsgSaturation >= ARRAY_SATURATION_THRESHOLD){ + chargeEnable = true; + } } /** @@ -164,27 +170,81 @@ static void setMotorControllerBypassPrechargeComplete(void *p_tmr, void *p_arg){ static void updatePrechargeContactors(void){ Minion_Error_t Merr; - arrayContactorIgnitionStatus = Minion_Read_Pin(IGN_1, &Merr); + arrayIgnitionStatus = Minion_Read_Pin(IGN_1, &Merr); motorControllerIgnitionStatus = Minion_Read_Pin(IGN_2, &Merr); - // Array Contactor is turned off if Ignition 1 is off else - if(motorControllerIgnitionStatus == false){ - Contactors_Set(MOTOR_BYPASS_PRECHARGE_CONTACTOR, OFF, true); // need to confirm the GPIO pins. + if(arrayIgnitionStatus == true && motorControllerIgnitionStatus == false){ + if(arrayBypassPrechargeComplete == true && chargeEnable == true){ + Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, ON, true); // Turn on + UpdateDisplay_SetArray(true); + arrayBypassPrechargeComplete = false; + printf("\r\nreached ARR END\r\n"); + } + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, OFF, true); UpdateDisplay_SetMotor(false); - }else if(arrayContactorIgnitionStatus == false){ - Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, OFF, true); + + }else if(arrayIgnitionStatus == false && motorControllerIgnitionStatus == true){ + if(arrayBypassPrechargeComplete == true && chargeEnable == true){ + Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, ON, true); // Turn off + UpdateDisplay_SetArray(true); + arrayBypassPrechargeComplete = false; + } + + if(motorControllerBypassPrechargeComplete == true && HVPlusMinusChargeMsgSaturation >= MOTOR_SATURATION_THRESHOLD){ + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, ON, true); + UpdateDisplay_SetMotor(true); + } + }else if(arrayIgnitionStatus == false && motorControllerIgnitionStatus == false){ + Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, OFF, true); // Turn off UpdateDisplay_SetArray(false); + + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, OFF, true); // Turn off + UpdateDisplay_SetMotor(false); + }else{ + assertReadCarCANError(READCARCAN_ERR_MISSED_MSG); } - else if(arrayBypassPrechargeComplete == true && chargeEnable == true){ - Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, ON, false); // Turn on array contactor + + // Set precharge complete variable to false if precharge happens again + + motorControllerBypassPrechargeComplete = false; + +} + +/* + // IGNITION is set to Array AND Motor Controller -- not possible, so assert error + if(arrayIgnitionStatus == true && motorControllerIgnitionStatus == true){ + assertReadCarCANError(READCARCAN_ERR_MISSED_MSG); + return; // Return because both PBCs have been addressed + + // IGNITION SET is not set to MC, so turn off MC BPC and update display. + }else if(motorControllerIgnitionStatus == false){ + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, OFF, true); + UpdateDisplay_SetMotor(false); + + // If Ignition is not set to MC and is not set to array, then turn off array BPC + if(arrayIgnitionStatus == false){ + Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, OFF, true); + UpdateDisplay_SetMotor(false); + return; // Return because both PBCs have been addressed + } + + // IGNITION SET is set to Motor Controller + }else{ + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, OFF, true); + UpdateDisplay_SetMotor(false); + } + + // If array BPC has completed precharge and charging is enabled, then turn on contactor. + if(arrayBypassPrechargeComplete == true && chargeEnable == true){ + Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, ON, true); // Turn off UpdateDisplay_SetArray(true); - }else if(motorControllerBypassPrechargeComplete == true && HVPlusMinusChargeMsgSaturation > MOTOR_SATURATION_THRESHOLD){ - Contactors_Set(MOTOR_BYPASS_PRECHARGE_CONTACTOR, ON, false); // Turn on array contactor - UpdateDisplay_SetMotor(true); } - - arrayBypassPrechargeComplete = false; // Set precharge complete variable to false if precharge happens again -}; + + // Set precharge complete variable to false if precharge happens again + arrayBypassPrechargeComplete = false; + motorControllerBypassPrechargeComplete = false; +} +*/ /** * @brief Disables Array Precharge Bypass Contactor (APBC) by asserting an error. Also updates display for APBC to be open. @@ -204,18 +264,19 @@ static void disableArrayPrechargeBypassContactor(void){ static void updateArrayPrechargeBypassContactor(void){ OS_ERR err; - if(arrayContactorIgnitionStatus == true // Ignition is ON + if(arrayIgnitionStatus == true // Ignition is ON && HVArrayChargeMsgSaturation >= ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met - && (Contactors_Get(ARRAY_CONTACTOR)== OFF) // Array Contactor is OFF + && (Contactors_Get(ARRAY_BYPASS_PRECHARGE_CONTACTOR)== OFF) // Array Contactor is OFF && (OSTmrStateGet(&arrayBypassPrechargeDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currenetly not happening // Asserts error for OS timer start above if conditional was met assertOSError(OS_READ_CAN_LOC, err); // Wait to make sure precharge is finished and then restart array + printf("\r\nreached 273\r\n"); OSTmrStart(&arrayBypassPrechargeDlyTimer, &err); } // Asserts error for OS timer state if conditional wasn't met assertOSError(OS_READ_CAN_LOC, err); - } +} void Task_ReadCarCAN(void *p_arg){ OS_ERR err; @@ -240,7 +301,7 @@ void Task_ReadCarCAN(void *p_arg){ OSTmrCreate( &arrayBypassPrechargeDlyTimer, "Array Bypass Precharge Delay Timer", - 0, + 0, ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, OS_OPT_TMR_ONE_SHOT, setArrayBypassPrechargeComplete, @@ -277,43 +338,49 @@ void Task_ReadCarCAN(void *p_arg){ switch(dataBuf.ID){ case BPS_TRIP: { // BPS has a fault and we need to enter fault state - // Assert the error to kill contactors, display evacuation message, and enter a nonrecoverable fault assertReadCarCANError(READCARCAN_ERR_BPS_TRIP); - - } - case BPS_CONTACTOR:{ + } + case BPS_CONTACTOR:{ // Acknowledge CAN Watchdog timer OSTmrStart(&canWatchTimer, &err); assertOSError(OS_READ_CAN_LOC, err); switch (dataBuf.data[0] & 0b11){ // Masking to get last two bits - case 0b00:{ + + case 0b00:{ // HV+/- and HV Arr did not recieve enable message disableArrayPrechargeBypassContactor(); + updateHVPlusMinusSaturation(-1); break; } - case 0b01:{ + case 0b01:{ // Only HV Arr recieved enable message + updateHVArraySaturation(1); updateArrayPrechargeBypassContactor(); + updateHVPlusMinusSaturation(-1); + printf("\r\nreached ARR\r\n"); break; } - case 0b10:{ + case 0b10:{ // Only HV +/1 recieved enable message disableArrayPrechargeBypassContactor(); updateHVPlusMinusSaturation(1); break; } - case 0b11: { + case 0b11: { // Both recieved enable message + updateHVArraySaturation(1); updateArrayPrechargeBypassContactor(); updateHVPlusMinusSaturation(1); break; } - default: { // does it break for good? + default: { + // Should not be able to reach here. break; } } - + break; // End of BPS Contactor Status Updates } + case SUPPLEMENTAL_VOLTAGE: { SBPV = (*(uint16_t *) &dataBuf.data); UpdateDisplay_SetSBPV(SBPV); // Receive value in mV @@ -324,9 +391,10 @@ void Task_ReadCarCAN(void *p_arg){ UpdateDisplay_SetSOC(SOC); break; } - default: - break; - } + default: { // Unhandled CAN message IDs + break; + } + } } } diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index 3daf2f928..18580df8f 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -17,7 +17,7 @@ typedef enum { ARRAY_CONTACTOR = 0, // BPS ARRAY_BYPASS_PRECHARGE_CONTACTOR, // Controls - MOTOR_BYPASS_PRECHARGE_CONTACTOR, // Controls + MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, // Controls NUM_CONTACTORS } contactor_t; diff --git a/Drivers/Src/Contactors.c b/Drivers/Src/Contactors.c index 720f0c3cd..c98abbb68 100644 --- a/Drivers/Src/Contactors.c +++ b/Drivers/Src/Contactors.c @@ -23,7 +23,7 @@ static void setContactor(contactor_t contactor, bool state) { case ARRAY_BYPASS_PRECHARGE_CONTACTOR : BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, state); break; - case MOTOR_BYPASS_PRECHARGE_CONTACTOR : + case MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR : BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, state); break; default: @@ -70,7 +70,7 @@ bool Contactors_Get(contactor_t contactor) { case ARRAY_BYPASS_PRECHARGE_CONTACTOR : state = BSP_GPIO_Get_State(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN); break; - case MOTOR_BYPASS_PRECHARGE_CONTACTOR : + case MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR : state = BSP_GPIO_Get_State(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN); break; default: diff --git a/Drivers/Src/Minions.c b/Drivers/Src/Minions.c index c58f1ea32..dccbd1fcc 100644 --- a/Drivers/Src/Minions.c +++ b/Drivers/Src/Minions.c @@ -44,12 +44,12 @@ bool Minion_Write_Output(MinionPin_t pin, bool status, Minion_Error_t* mErr){ //if(PINS_LOOKARR[pin].direction == OUTPUT){ OSMutexPend(&OutputMutex, 0, OS_OPT_PEND_BLOCKING, ×tamp, &err); - //assertOSError(OS_MINIONS_LOC, err); + assertOSError(OS_MINIONS_LOC, err); BSP_GPIO_Write_Pin(PINS_LOOKARR[pin].port, PINS_LOOKARR[pin].pinMask, status); OSMutexPost(&OutputMutex, OS_OPT_POST_NONE, &err); - //assertOSError(OS_MINIONS_LOC, err); + assertOSError(OS_MINIONS_LOC, err); return true; // } - // *mErr = MINION_ERR_WROTE_INPUT; - // return false; + *mErr = MINION_ERR_WROTE_INPUT; + return false; } \ No newline at end of file diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 8b47892df..b3e0a6c8e 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -132,7 +132,7 @@ void OSErrorTask(void* arg) { // Helper function to see the state of the contactors static void print_Contactors() { - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_BYPASS_PRECHARGE_CONTACTOR)); + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR)); printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_BYPASS_PRECHARGE_CONTACTOR)); printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); } @@ -281,7 +281,7 @@ void Task_ManagerTask(void* arg) { // Turn on contactors so we can see if they get turned off by the error assertion Contactors_Set(ARRAY_CONTACTOR, ON, true); - Contactors_Set(MOTOR_BYPASS_PRECHARGE_CONTACTOR, ON, true); + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, ON, true); Contactors_Set(ARRAY_BYPASS_PRECHARGE_CONTACTOR, ON, true); // Although BPS has control of the precharge contactor print_Contactors(); // See the state of the contactors before we send the trip message diff --git a/Tests/Test_Ign_Cont.c b/Tests/Test_Ign_Cont.c index eda8b7cf4..7ebd98d85 100644 --- a/Tests/Test_Ign_Cont.c +++ b/Tests/Test_Ign_Cont.c @@ -40,7 +40,7 @@ void Task1(void *arg) assertOSError(OS_MAIN_LOC, err); while (1){ - printf("Array Contactor: %d, Motor Contactor: %d\n\r", Contactors_Get(ARRAY_CONTACTOR), Contactors_Get(MOTOR_BYPASS_PRECHARGE_CONTACTOR)); + printf("Array Contactor: %d, Motor Contactor: %d\n\r", Contactors_Get(ARRAY_CONTACTOR), Contactors_Get(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR)); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); } diff --git a/Tests/Test_ReadCarCANrewrite.c b/Tests/Test_ReadCarCANrewrite.c index effc42332..d95e8794f 100644 --- a/Tests/Test_ReadCarCANrewrite.c +++ b/Tests/Test_ReadCarCANrewrite.c @@ -46,8 +46,10 @@ static CPU_STK Task1_Stk[DEFAULT_STACK_SIZE]; static CANDATA_t bps_trip_msg = {.ID=BPS_TRIP, .idx=0, .data={1}}; static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; static CANDATA_t state_of_charge_msg = {.ID=STATE_OF_CHARGE, .idx=0, .data={0}}; -static CANDATA_t charge_enable_msg = {.ID=CHARGE_ENABLE, .idx=0, .data={1}}; -static CANDATA_t charge_disable_msg = {.ID=CHARGE_ENABLE, .idx=0, .data={0}}; +static CANDATA_t charge_enable_msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b01}}; +static CANDATA_t disable_msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b00}}; +static CANDATA_t all_clear_enable_msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b10}}; +static CANDATA_t enable_msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b11}}; #define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) @@ -57,24 +59,72 @@ static void infoDump(){ printf("\r\nCharge Message Saturation: %d", ChargeMsgSaturation_Get()); printf("\r\nThreshold : %s", ((ChargeMsgSaturation_Get() >= 7.5) ? "Threshold reached" : "Threshold not reached")); printf("\r\nCharge Enable : %s", (ChargeEnable_Get() ? "TRUE" : "FALSE")); - printf("\r\nArray Contactor : %s", ((Contactors_Get(ARRAY_PRECHARGE) == ON) ? "ON" : "OFF")); + printf("\r\nArray Contactor : %s", ((Contactors_Get(ARRAY_BYPASS_PRECHARGE_CONTACTOR) == ON) ? "ON" : "OFF")); + printf("\r\nPrecharge Complete? : %s", ((PreChargeComplete_Get()) ? "Yes" : "No")); + printf("\r\nMotor Contactor : %s", ((Contactors_Get(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR) == ON) ? "ON" : "OFF")); } Minion_Error_t mErr; static void turnIgnitionON(){ printf("\n\r=========== Testing: Ignition ON with Charge Enable Messages ==========="); printf("\n\r=========== Expected output: One message with Array Contactor turned ON ==========="); - Minion_Write_Output(IGN_1, true, &mErr); // Ignition ON - while(Contactors_Get(ARRAY_PRECHARGE) != ON){ + Minion_Write_Output(IGN_1, 1, &mErr); // Ignition arr ON + Minion_Write_Output(IGN_2, 0, &mErr); // Ignition motor OFF + while(Contactors_Get(ARRAY_BYPASS_PRECHARGE_CONTACTOR) != ON){ CANbus_Send(charge_enable_msg, CAN_BLOCKING, CARCAN); // Charge Enable messages + //infoDump(); } infoDump(); } + +static void turnIgnitionToMotorON(){ + printf("\n\r=========== Turn Ignition to Motor ==========="); + Minion_Write_Output(IGN_2, 1, &mErr); // Ignition motor ON + Minion_Write_Output(IGN_1, 0, &mErr); // Ignition array OFF + +} + +static void turnIgnitionToArrayON(){ + printf("\n\r=========== Turn Ignition to Array ==========="); + Minion_Write_Output(IGN_2, 0, &mErr); // Ignition motor OFF + Minion_Write_Output(IGN_1, 1, &mErr); // Ignition array ON +} + +static void turnIgnitionOFF(){ + printf("\n\r=========== Turn Ignition to OFF ==========="); + Minion_Write_Output(IGN_2, 0, &mErr); // Ignition motor OFF + Minion_Write_Output(IGN_1, 0, &mErr); // Ignition array OFF +} + + +static void sendArrayEnableMsg(){ + printf("\n\r=========== Array Enable Msg Sent ==========="); + while(Contactors_Get(ARRAY_BYPASS_PRECHARGE_CONTACTOR) != ON){ + CANbus_Send(charge_enable_msg, CAN_BLOCKING, CARCAN); // Charge Enable messages + } +} + +static void sendMotorControllerEnableMsg(){ + printf("\n\r=========== Motor Controller Enable Msg Sent ==========="); + while(Contactors_Get(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR) != ON){ + CANbus_Send(all_clear_enable_msg, CAN_BLOCKING, CARCAN); // Charge Enable messages + } +} + +static void sendDisableMsg(){ + printf("\n\r=========== Motor Controller Disable Msg Sent ==========="); + while(Contactors_Get(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR) != ON){ + CANbus_Send(disable_msg, CAN_BLOCKING, CARCAN); // Charge Enable messages + } +} + + void Task1(){ OS_ERR err; CPU_Init(); + Minion_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); Contactors_Init(); CANbus_Init(CARCAN, NULL, 0); @@ -108,7 +158,6 @@ void Task1(){ turnIgnitionON(); // Helper to turn ignition on - // Test case for when ignition is OFF but charge enable messages are read // Info dumped to show that message threshold is reached (and maxed out) but contactor is consistently off printf("\n\r"); diff --git a/Tests/Test_Telemetry.c b/Tests/Test_Telemetry.c index 3e4052049..f0ae7adf8 100644 --- a/Tests/Test_Telemetry.c +++ b/Tests/Test_Telemetry.c @@ -60,7 +60,7 @@ void Task1(void *arg) // Check contactors (HAVE NOTHING HOOKED UP TO CONTACTORS) contactorState = contactorState == OFF ? ON : OFF; - Contactors_Set(MOTOR_BYPASS_PRECHARGE_CONTACTOR, contactorState, true); + Contactors_Set(MOTOR_CONTROLLER_BYPASS_PRECHARGE_CONTACTOR, contactorState, true); Contactors_Set(ARRAY_CONTACTOR, contactorState, true); CANbus_Read(&msg, CAN_BLOCKING, CARCAN);