Skip to content

Commit

Permalink
add MREC fault types for EvseManager and bsp interface
Browse files Browse the repository at this point in the history
Signed-off-by: Cornelius Claussen <[email protected]>
  • Loading branch information
corneliusclaussen committed Oct 16, 2023
1 parent 0e59c4e commit 5b9e418
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 123 deletions.
96 changes: 62 additions & 34 deletions modules/EvseManager/Charger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,15 +617,6 @@ void Charger::processEvent(CPEvent cp_event) {
case CPEvent::EFtoBCD:
session_log.car(false, fmt::format("Event {}", cpevent_to_string(cp_event)));
break;
case CPEvent::ErrorOverCurrent:
case CPEvent::ErrorRelais:
case CPEvent::ErrorVentilationNotAvailable:
case CPEvent::PermanentFault:
case CPEvent::PowerOff:
case CPEvent::PowerOn:
case CPEvent::EvseReplugStarted:
case CPEvent::EvseReplugFinished:

default:
session_log.evse(false, fmt::format("Event {}", cpevent_to_string(cp_event)));
break;
Expand Down Expand Up @@ -742,53 +733,90 @@ void Charger::processCPEventsIndependent(CPEvent cp_event) {
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::CarDiodeFault;
break;
case CPEvent::ErrorRelais:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::Relais;
break;

case CPEvent::ErrorVentilationNotAvailable:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::VentilationNotAvailable;
break;
case CPEvent::ErrorOverCurrent:

case CPEvent::ErrorBrownOut:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::OverCurrent;
errorState = types::evse_manager::ErrorEnum::BrownOut;
break;
case CPEvent::ErrorOverVoltage:

case CPEvent::ErrorEnergyManagement:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::OverVoltage;
errorState = types::evse_manager::ErrorEnum::EnergyManagement;
break;
case CPEvent::ErrorUnderVoltage:

case CPEvent::MREC_1_ConnectorLockFailure:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::UnderVoltage;
errorState = types::evse_manager::ErrorEnum::MREC_1_ConnectorLockFailure;
break;
case CPEvent::ErrorMotorLock:
case CPEvent::MREC_3_HighTemperature:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MotorLock;
errorState = types::evse_manager::ErrorEnum::MREC_3_HighTemperature;
break;
case CPEvent::ErrorOverTemperature:
case CPEvent::MREC_4_OverCurrentFailure:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::OverTemperature;
errorState = types::evse_manager::ErrorEnum::MREC_4_OverCurrentFailure;
break;
case CPEvent::ErrorBrownOut:
case CPEvent::MREC_5_OverVoltage:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::BrownOut;
errorState = types::evse_manager::ErrorEnum::MREC_5_OverVoltage;
break;
case CPEvent::ErrorCablePP:
case CPEvent::MREC_6_UnderVoltage:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::CablePP;
errorState = types::evse_manager::ErrorEnum::MREC_6_UnderVoltage;
break;
case CPEvent::ErrorEnergyManagement:
case CPEvent::MREC_8_EmergencyStop:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::EnergyManagement;
errorState = types::evse_manager::ErrorEnum::MREC_8_EmergencyStop;
break;

case CPEvent::MREC_10_InvalidVehicleMode:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_10_InvalidVehicleMode;
break;
case CPEvent::MREC_14_PilotFault:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_14_PilotFault;
break;
case CPEvent::MREC_15_PowerLoss:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_15_PowerLoss;
break;
case CPEvent::MREC_17_EVSEContactorFault:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_17_EVSEContactorFault;
break;
case CPEvent::MREC_18_CableOverTempDerate:
// This is a non fatal error, issue a warning with the new fault handling
errorState = types::evse_manager::ErrorEnum::MREC_18_CableOverTempDerate;
break;
case CPEvent::MREC_19_CableOverTempStop:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_19_CableOverTempStop;
break;
case CPEvent::MREC_20_PartialInsertion:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_20_PartialInsertion;
break;
case CPEvent::MREC_23_ProximityFault:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_23_ProximityFault;
break;
case CPEvent::MREC_24_ConnectorVoltageHigh:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::MREC_24_ConnectorVoltageHigh;
break;
case CPEvent::ErrorNeutralPEN:
case CPEvent::MREC_25_BrokenLatch:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::NeutralPEN;
errorState = types::evse_manager::ErrorEnum::MREC_25_BrokenLatch;
break;
case CPEvent::ErrorCpDriver:
case CPEvent::MREC_26_CutCable:
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::CpDriver;
errorState = types::evse_manager::ErrorEnum::MREC_26_CutCable;
break;
default:
break;
Expand Down Expand Up @@ -1282,7 +1310,7 @@ void Charger::checkSoftOverCurrent() {
currentDrawnByVehicle[0], currentDrawnByVehicle[1],
currentDrawnByVehicle[2], limit));
currentState = EvseState::Error;
errorState = types::evse_manager::ErrorEnum::OverCurrent;
errorState = types::evse_manager::ErrorEnum::MREC_4_OverCurrentFailure;
}
}

Expand Down
18 changes: 12 additions & 6 deletions modules/EvseManager/EvseManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,6 @@ void EvseManager::ready() {
}

bsp->signal_event.connect([this](const CPEvent event) {

// Forward events from BSP to SLAC module before we process the events in the charger
if (slac_enabled) {
if (event == CPEvent::EFtoBCD) {
Expand Down Expand Up @@ -578,18 +577,25 @@ void EvseManager::ready() {
}
}

if (event == CPEvent::ErrorRelais) {
if (event == CPEvent::MREC_17_EVSEContactorFault) {
session_log.evse(false, "Error Relais");
r_hlc[0]->call_set_FAILED_ContactorError(true);
}

if (event == CPEvent::PermanentFault) {
session_log.evse(false, "Error Permanent Fault");
if (event == CPEvent::PermanentFault || event == CPEvent::MREC_26_CutCable ||
event == CPEvent::MREC_25_BrokenLatch) {
session_log.evse(false, "Error Permanent Fault: " + cpevent_to_string(event));
r_hlc[0]->call_set_EVSE_Malfunction(true);
}

if (event == CPEvent::ErrorOverCurrent) {
session_log.evse(false, "Error Over Current");
if (event == CPEvent::MREC_2_GroundFailure || event == CPEvent::MREC_4_OverCurrentFailure ||
event == CPEvent::MREC_5_OverVoltage || event == CPEvent::MREC_6_UnderVoltage ||
event == CPEvent::MREC_8_EmergencyStop || event == CPEvent::MREC_19_CableOverTempStop ||
event == CPEvent::MREC_10_InvalidVehicleMode || event == CPEvent::MREC_14_PilotFault ||
event == CPEvent::MREC_15_PowerLoss || event == CPEvent::MREC_17_EVSEContactorFault ||
event == CPEvent::MREC_19_CableOverTempStop || event == CPEvent::MREC_20_PartialInsertion ||
event == CPEvent::MREC_23_ProximityFault || event == CPEvent::MREC_24_ConnectorVoltageHigh) {
session_log.evse(false, "Fatal error, emergency stop: " + cpevent_to_string(event));
r_hlc[0]->call_set_EVSE_EmergencyShutdown(true);
}

Expand Down
127 changes: 78 additions & 49 deletions modules/EvseManager/IECStateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,54 @@ static std::variant<RawCPState, CPEvent> from_bsp_event(types::board_support_com
return CPEvent::PowerOff;
case types::board_support_common::Event::ErrorDF:
return CPEvent::ErrorDF;
case types::board_support_common::Event::ErrorRelais:
return CPEvent::ErrorRelais;
case types::board_support_common::Event::ErrorVentilationNotAvailable:
return CPEvent::ErrorVentilationNotAvailable;
case types::board_support_common::Event::ErrorOverCurrent:
return CPEvent::ErrorOverCurrent;
case types::board_support_common::Event::ErrorOverVoltage:
return CPEvent::ErrorOverVoltage;
case types::board_support_common::Event::ErrorUnderVoltage:
return CPEvent::ErrorUnderVoltage;
case types::board_support_common::Event::ErrorMotorLock:
return CPEvent::ErrorMotorLock;
case types::board_support_common::Event::ErrorOverTemperature:
return CPEvent::ErrorOverTemperature;
case types::board_support_common::Event::ErrorBrownOut:
return CPEvent::ErrorBrownOut;
case types::board_support_common::Event::ErrorCablePP:
return CPEvent::ErrorCablePP;
case types::board_support_common::Event::ErrorEnergyManagement:
return CPEvent::ErrorEnergyManagement;
case types::board_support_common::Event::ErrorNeutralPEN:
return CPEvent::ErrorNeutralPEN;
case types::board_support_common::Event::ErrorCpDriver:
return CPEvent::ErrorCpDriver;
case types::board_support_common::Event::PermanentFault:
return CPEvent::PermanentFault;
case types::board_support_common::Event::EvseReplugStarted:
return CPEvent::EvseReplugStarted;
case types::board_support_common::Event::EvseReplugFinished:
return CPEvent::EvseReplugFinished;
case types::board_support_common::Event::EmergencyStopButtonPressed:
return CPEvent::EmergencyStopButtonPressed;

case types::board_support_common::Event::MREC_1_ConnectorLockFailure:
return CPEvent::MREC_1_ConnectorLockFailure;
case types::board_support_common::Event::MREC_2_GroundFailure:
return CPEvent::MREC_2_GroundFailure;
case types::board_support_common::Event::MREC_3_HighTemperature:
return CPEvent::MREC_3_HighTemperature;
case types::board_support_common::Event::MREC_4_OverCurrentFailure:
return CPEvent::MREC_4_OverCurrentFailure;
case types::board_support_common::Event::MREC_5_OverVoltage:
return CPEvent::MREC_5_OverVoltage;
case types::board_support_common::Event::MREC_6_UnderVoltage:
return CPEvent::MREC_6_UnderVoltage;
case types::board_support_common::Event::MREC_8_EmergencyStop:
return CPEvent::MREC_8_EmergencyStop;
case types::board_support_common::Event::MREC_10_InvalidVehicleMode:
return CPEvent::MREC_10_InvalidVehicleMode;
case types::board_support_common::Event::MREC_14_PilotFault:
return CPEvent::MREC_14_PilotFault;
case types::board_support_common::Event::MREC_15_PowerLoss:
return CPEvent::MREC_15_PowerLoss;
case types::board_support_common::Event::MREC_17_EVSEContactorFault:
return CPEvent::MREC_17_EVSEContactorFault;
case types::board_support_common::Event::MREC_18_CableOverTempDerate:
return CPEvent::MREC_18_CableOverTempDerate;
case types::board_support_common::Event::MREC_19_CableOverTempStop:
return CPEvent::MREC_19_CableOverTempStop;
case types::board_support_common::Event::MREC_20_PartialInsertion:
return CPEvent::MREC_20_PartialInsertion;
case types::board_support_common::Event::MREC_23_ProximityFault:
return CPEvent::MREC_23_ProximityFault;
case types::board_support_common::Event::MREC_24_ConnectorVoltageHigh:
return CPEvent::MREC_24_ConnectorVoltageHigh;
case types::board_support_common::Event::MREC_25_BrokenLatch:
return CPEvent::MREC_25_BrokenLatch;
case types::board_support_common::Event::MREC_26_CutCable:
return CPEvent::MREC_26_CutCable;
default:
return RawCPState::Disabled;
}
Expand All @@ -93,30 +108,12 @@ const std::string cpevent_to_string(CPEvent e) {
return "ErrorE";
case CPEvent::ErrorDF:
return "ErrorDF";
case CPEvent::ErrorRelais:
return "ErrorRelais";
case CPEvent::ErrorVentilationNotAvailable:
return "ErrorVentilationNotAvailable";
case CPEvent::ErrorOverCurrent:
return "ErrorOverCurrent";
case CPEvent::ErrorOverVoltage:
return "ErrorOverVoltage";
case CPEvent::ErrorUnderVoltage:
return "ErrorUnderVoltage";
case CPEvent::ErrorMotorLock:
return "ErrorMotorLock";
case CPEvent::ErrorOverTemperature:
return "ErrorOverTemperature";
case CPEvent::ErrorBrownOut:
return "ErrorBrownOut";
case CPEvent::ErrorCablePP:
return "ErrorCablePP";
case CPEvent::ErrorEnergyManagement:
return "ErrorEnergyManagement";
case CPEvent::ErrorNeutralPEN:
return "ErrorNeutralPEN";
case CPEvent::ErrorCpDriver:
return "ErrorCpDriver";
case CPEvent::EFtoBCD:
return "EFtoBCD";
case CPEvent::BCDtoEF:
Expand All @@ -127,8 +124,40 @@ const std::string cpevent_to_string(CPEvent e) {
return "EvseReplugStarted";
case CPEvent::EvseReplugFinished:
return "EvseReplugFinished";
case CPEvent::MREC_1_ConnectorLockFailure:
return "MREC_1_ConnectorLockFailure";
case CPEvent::MREC_2_GroundFailure:
return "MREC_2_GroundFailure";
case CPEvent::MREC_3_HighTemperature:
return "MREC_3_HighTemperature";
case CPEvent::MREC_4_OverCurrentFailure:
return "MREC_4_OverCurrentFailure";
case CPEvent::MREC_5_OverVoltage:
return "MREC_5_OverVoltage";
case CPEvent::MREC_6_UnderVoltage:
return "MREC_6_UnderVoltage";
case CPEvent::MREC_8_EmergencyStop:
return "MREC_8_EmergencyStop";
case CPEvent::MREC_15_PowerLoss:
return "MREC_15_PowerLoss";
case CPEvent::MREC_17_EVSEContactorFault:
return "MREC_17_EVSEContactorFault";
case CPEvent::MREC_18_CableOverTempDerate:
return "MREC_18_CableOverTempDerate";
case CPEvent::MREC_19_CableOverTempStop:
return "MREC_19_CableOverTempStop";
case CPEvent::MREC_20_PartialInsertion:
return "MREC_20_PartialInsertion";
return "MREC_19_CableOverTempStop";
case CPEvent::MREC_23_ProximityFault:
return "MREC_23_ProximityFault";
case CPEvent::MREC_24_ConnectorVoltageHigh:
return "MREC_24_ConnectorVoltageHigh";
case CPEvent::MREC_25_BrokenLatch:
return "MREC_25_BrokenLatch";
case CPEvent::MREC_26_CutCable:
return "MREC_26_CutCable";
}

throw std::out_of_range("No known string conversion for provided enum of type CPEvent");
}

Expand Down Expand Up @@ -369,8 +398,8 @@ void IECStateMachine::call_allow_power_on_bsp(bool value) {
}

// High level state machine requests reading PP ampacity value.
// We forware this request to the BSP driver. The high level state machine will never call this if it is not used (e.g.
// in DC or AC tethered charging)
// We forware this request to the BSP driver. The high level state machine will never call this if it is not used
// (e.g. in DC or AC tethered charging)
double IECStateMachine::read_pp_ampacity() {
auto a = r_bsp->call_ac_read_pp_ampacity();
switch (a.ampacity) {
Expand All @@ -392,8 +421,8 @@ void IECStateMachine::evse_replug(int ms) {
r_bsp->call_evse_replug(ms);
}

// Forward special request to switch the number of phases during charging. BSP will need to implement a special sequence
// to not destroy cars.
// Forward special request to switch the number of phases during charging. BSP will need to implement a special
// sequence to not destroy cars.
void IECStateMachine::switch_three_phases_while_charging(bool n) {
r_bsp->call_ac_switch_three_phases_while_charging(n);
}
Expand All @@ -404,8 +433,8 @@ void IECStateMachine::setup(bool three_phases, bool has_ventilation, std::string
this->has_ventilation = has_ventilation;
}

// Force an unlock now. This can be sent from OCPP. As locking/unlocking is handled in the BSP the BSP MCU will need to
// decide how and when to fulfill this request in a safe manner.
// Force an unlock now. This can be sent from OCPP. As locking/unlocking is handled in the BSP the BSP MCU will need
// to decide how and when to fulfill this request in a safe manner.
bool IECStateMachine::force_unlock() {
return r_bsp->call_force_unlock();
}
Expand All @@ -415,9 +444,9 @@ void IECStateMachine::enable(bool en) {
r_bsp->call_enable(en);
}

// Forward the over current detection limit to the BSP. Many BSP MCUs monitor the charge current and trigger a fault in
// case of over current. This sets the target charging current value to be used in OC detection. It cannot be derived
// from the PWM duty cycle, use this value instead.
// Forward the over current detection limit to the BSP. Many BSP MCUs monitor the charge current and trigger a fault
// in case of over current. This sets the target charging current value to be used in OC detection. It cannot be
// derived from the PWM duty cycle, use this value instead.
void IECStateMachine::set_overcurrent_limit(double amps) {
if (amps != last_amps) {
r_bsp->call_ac_set_overcurrent_limit_A(amps);
Expand Down
Loading

0 comments on commit 5b9e418

Please sign in to comment.