diff --git a/EpsilonAuxBmsV2/Core/Inc/Tasks/ChargeContactorGatekeeperTask.h b/EpsilonAuxBmsV2/Core/Inc/Tasks/ChargeContactorGatekeeperTask.h index 4fe285cd..9466a891 100644 --- a/EpsilonAuxBmsV2/Core/Inc/Tasks/ChargeContactorGatekeeperTask.h +++ b/EpsilonAuxBmsV2/Core/Inc/Tasks/ChargeContactorGatekeeperTask.h @@ -1,7 +1,10 @@ #pragma once #include "ContactorGatekeeper.h" +#include "AuxTrip.h" extern osThreadId_t chargeContactorGatekeeperTaskHandle; +extern AuxTrip auxTrip; +extern osMutexId_t auxTripMutex; void closeChargeContactor(); void openChargeContactor(); diff --git a/EpsilonAuxBmsV2/Core/Inc/Tasks/DischargeContactorGatekeeperTask.h b/EpsilonAuxBmsV2/Core/Inc/Tasks/DischargeContactorGatekeeperTask.h index bcc74aac..8372cf5a 100644 --- a/EpsilonAuxBmsV2/Core/Inc/Tasks/DischargeContactorGatekeeperTask.h +++ b/EpsilonAuxBmsV2/Core/Inc/Tasks/DischargeContactorGatekeeperTask.h @@ -1,8 +1,11 @@ #pragma once #include "ContactorGatekeeper.h" +#include "AuxTrip.h" extern osThreadId_t dischargeContactorGatekeeperTaskHandle; extern AuxBmsContactorState auxBmsContactorState; +extern AuxTrip auxTrip; +extern osMutexId_t auxTripMutex; void dischargeContactorGatekeeperTask(void* arg); void closeDischargeContactor(); diff --git a/EpsilonAuxBmsV2/Core/Inc/Types/AuxTrip.h b/EpsilonAuxBmsV2/Core/Inc/Types/AuxTrip.h index 45a3ab74..41a4861c 100644 --- a/EpsilonAuxBmsV2/Core/Inc/Types/AuxTrip.h +++ b/EpsilonAuxBmsV2/Core/Inc/Types/AuxTrip.h @@ -11,4 +11,7 @@ typedef struct unsigned dischargeTripDueToHighTemperatureAndCurrent : 1; unsigned dischargeTripDueToPackCurrent : 1; unsigned protectionTrip : 1; + unsigned dischargeNotClosedDueToHighCurrent: 1; + unsigned chargeNotClosedDueToHighCurrent: 1; + unsigned tripDueToOrionMessageTimeout : 1; } AuxTrip; diff --git a/EpsilonAuxBmsV2/Core/Src/Tasks/ChargeContactorGatekeeperTask.c b/EpsilonAuxBmsV2/Core/Src/Tasks/ChargeContactorGatekeeperTask.c index fab3ab32..b1091cb0 100644 --- a/EpsilonAuxBmsV2/Core/Src/Tasks/ChargeContactorGatekeeperTask.c +++ b/EpsilonAuxBmsV2/Core/Src/Tasks/ChargeContactorGatekeeperTask.c @@ -37,6 +37,14 @@ void closeChargeContactor() auxBmsContactorState.chargeState = CONTACTOR_ERROR; HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, GPIO_PIN_RESET); + if (!currentLow) { //something closed that isn't supposed to be + if (osMutexAcquire(auxTripMutex, MUTEX_TIMEOUT) == osOK) + { + auxTrip.chargeNotClosedDueToHighCurrent = 1; + osMutexRelease(auxTripMutex); + } + } + if (isDischargeClosed) // Discharge closed so delay and try again { osDelay(CONTACTOR_DELAY); diff --git a/EpsilonAuxBmsV2/Core/Src/Tasks/DischargeContactorGatekeeperTask.c b/EpsilonAuxBmsV2/Core/Src/Tasks/DischargeContactorGatekeeperTask.c index 383cc263..c0376a61 100644 --- a/EpsilonAuxBmsV2/Core/Src/Tasks/DischargeContactorGatekeeperTask.c +++ b/EpsilonAuxBmsV2/Core/Src/Tasks/DischargeContactorGatekeeperTask.c @@ -38,6 +38,14 @@ void closeDischargeContactor() auxBmsContactorState.dischargeState = CONTACTOR_ERROR; HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, GPIO_PIN_RESET); + if (!currentLow) { //something closed that isn't supposed to be + if (osMutexAcquire(auxTripMutex, MUTEX_TIMEOUT) == osOK) + { + auxTrip.dischargeNotClosedDueToHighCurrent = 1; + osMutexRelease(auxTripMutex); + } + } + if (isChargeClosed) // charge contactor closed so delay then try again { osDelay(CONTACTOR_DELAY); diff --git a/EpsilonAuxBmsV2/Core/Src/Tasks/OrionFunctions/Trip.c b/EpsilonAuxBmsV2/Core/Src/Tasks/OrionFunctions/Trip.c index 0ebba6f7..2136cd76 100644 --- a/EpsilonAuxBmsV2/Core/Src/Tasks/OrionFunctions/Trip.c +++ b/EpsilonAuxBmsV2/Core/Src/Tasks/OrionFunctions/Trip.c @@ -60,29 +60,33 @@ void updateAuxTrip(OrionCanInfo* message, AuxTrip* auxTripToUpdate) } /* -Determines whether Discharge should cause a trip based on Orion CAN messages +Determines whether Discharge should cause a trip based on Orion CAN messages and current line between contactors Discharge will cause a trip due to: * the min cell voltage being lower than the Orion limit * high temperature while discharging * discharge pack current being too high + * current line between contactors not low enough to close discharge */ uint8_t checkDischargeTrip(AuxTrip auxTrip) { return auxTrip.dischargeTripDueToLowCellVoltage || auxTrip.dischargeTripDueToHighTemperatureAndCurrent || - auxTrip.dischargeTripDueToPackCurrent; + auxTrip.dischargeTripDueToPackCurrent || + auxTrip.dischargeNotClosedDueToHighCurrent; //set in discharge gatekeeper task } /* -Determines whether charge should cause a trip based on Orion CAN messages +Determines whether charge should cause a trip based on Orion CAN messages and current line between contactors Charge will cause a trip due to: * the max cell voltage being higher than the Orion limit * high temperature while charging * discharge pack current being too high (absolute value) + * current line between contactors not low enough to close charge */ uint8_t checkChargeTrip(AuxTrip auxTrip) { return auxTrip.chargeTripDueToHighCellVoltage || auxTrip.chargeTripDueToHighTemperatureAndCurrent || - auxTrip.chargeTripDueToPackCurrent; + auxTrip.chargeTripDueToPackCurrent || + auxTrip.chargeNotClosedDueToHighCurrent; //set in charge gatekeeper task } diff --git a/EpsilonAuxBmsV2/Core/Src/Tasks/OrionInterfaceTask.c b/EpsilonAuxBmsV2/Core/Src/Tasks/OrionInterfaceTask.c index 9466f6e4..e7fcbc79 100644 --- a/EpsilonAuxBmsV2/Core/Src/Tasks/OrionInterfaceTask.c +++ b/EpsilonAuxBmsV2/Core/Src/Tasks/OrionInterfaceTask.c @@ -20,7 +20,7 @@ Essentially reads inputs from Orion and gets the Aux BMS to respond accordingly. * When charge/discharge should be open or closed based on GPIO inputs coming from Orion and based on Max/Min cell voltages It will get info from the CAN Rx Interrupt parser periodically, and each time it does it will set the orionCanMessageReceivedRecently member of AuxStatus to 1 and keep track of the last time it received a message -If the waiting on the queue times out, that means that no message from Orion has been received recently, so set the orionCanMessageReceivedRecently member of AuxStatus to 0 +If the waiting on the queue times out, that means that no message from Orion has been received recently, so set the orionCanMessageReceivedRecently member of AuxStatus to 0 and trip the car. Before it finishes or triggers events to control the contactors, it updates the AuxTrip variable, and the AuxStatus variable. To update the AuxStatus variable, it must first acquire the auxStatusOrionInterfaceMutex @@ -58,6 +58,8 @@ void orionInterface(OrionCanInfo* message) if (status == osErrorTimeout) // If waiting on the queue times out { //Set orion can message recieved recently to 0 + shouldDisconnectContactors = 1; + localAuxTrip.tripDueToOrionMessageTimeout = 1; localAuxStatus.orionCanReceivedRecently = 0; } else diff --git a/EpsilonAuxBmsV2/Core/Src/Tasks/SendAuxTripTask.c b/EpsilonAuxBmsV2/Core/Src/Tasks/SendAuxTripTask.c index 9b39dc31..d649cd3c 100644 --- a/EpsilonAuxBmsV2/Core/Src/Tasks/SendAuxTripTask.c +++ b/EpsilonAuxBmsV2/Core/Src/Tasks/SendAuxTripTask.c @@ -28,14 +28,17 @@ void sendAuxTrip(CanTxGatekeeperQueueData* canQueueData, uint32_t* prevWakeTime) { canQueueData->canTxHeader = BASE_CAN_TX_HDR; canQueueData->canTxHeader.StdId = AUX_TRIP_STDID; - canQueueData->canTxHeader.DLC = 1; + canQueueData->canTxHeader.DLC = 2; canQueueData->data[0] = auxTrip.chargeTripDueToHighCellVoltage | (auxTrip.chargeTripDueToHighTemperatureAndCurrent << 1) | (auxTrip.chargeTripDueToPackCurrent << 2) | (auxTrip.dischargeTripDueToLowCellVoltage << 3) | (auxTrip.dischargeTripDueToHighTemperatureAndCurrent << 4) | (auxTrip.dischargeTripDueToPackCurrent << 5) | - (auxTrip.protectionTrip << 6); + (auxTrip.protectionTrip << 6) | + (auxTrip.tripDueToOrionMessageTimeout << 7); + canQueueData->data[1] = auxTrip.chargeNotClosedDueToHighCurrent | + (auxTrip.dischargeNotClosedDueToHighCurrent << 1); osMessageQueuePut(canTxGatekeeperQueue, canQueueData, 0, TASK_QUEUE_PUT_TIMEOUT); osMutexRelease(auxTripMutex); }