refactoring: reducing code duplication. Also, do we even care for critical error codes?!
This commit is contained in:
parent
54797ab559
commit
e8c45a2e7d
|
@ -92,7 +92,7 @@ float HellenBoardIdSolver::solve(float Tc1, float Tc2, float x0, float y, float
|
||||||
// since we had https://github.com/rusefi/rusefi/issues/4084 let's add paranoia check
|
// since we had https://github.com/rusefi/rusefi/issues/4084 let's add paranoia check
|
||||||
// All real cases seem to converge in <= 5 iterations, so we don't need to try more than 20.
|
// All real cases seem to converge in <= 5 iterations, so we don't need to try more than 20.
|
||||||
if (!result) {
|
if (!result) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "hellen boardID is broken");
|
criticalError("hellen boardID is broken");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ TsChannelBase::TsChannelBase(const char *name) {
|
||||||
|
|
||||||
void TsChannelBase::assertPacketSize(size_t size, bool allowLongPackets) {
|
void TsChannelBase::assertPacketSize(size_t size, bool allowLongPackets) {
|
||||||
if (isBigPacket(size) && !allowLongPackets) {
|
if (isBigPacket(size) && !allowLongPackets) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "[USE PROPER CONSOLE VERSION ] disallowed long packet of size %d", size);
|
criticalError("[USE PROPER CONSOLE VERSION ] disallowed long packet of size %d", size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void sayHello() {
|
||||||
|
|
||||||
int flashSize = TM_ID_GetFlashSize();
|
int flashSize = TM_ID_GetFlashSize();
|
||||||
if (flashSize < MIN_FLASH_SIZE) {
|
if (flashSize < MIN_FLASH_SIZE) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "rusEFI expected at least %dK of flash", MIN_FLASH_SIZE);
|
criticalError("rusEFI expected at least %dK of flash", MIN_FLASH_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: bug, at the moment we report 1MB on dual-bank F7
|
// todo: bug, at the moment we report 1MB on dual-bank F7
|
||||||
|
@ -172,7 +172,7 @@ static void cmd_threads() {
|
||||||
efiPrintf("%s\t%08x\t%lu\t%d", tp->name, tp->wabase, tp->time, freeBytes);
|
efiPrintf("%s\t%08x\t%lu\t%d", tp->name, tp->wabase, tp->time, freeBytes);
|
||||||
|
|
||||||
if (freeBytes < 100) {
|
if (freeBytes < 100) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Ran out of stack on thread %s, %d bytes remain", tp->name, freeBytes);
|
criticalError("Ran out of stack on thread %s, %d bytes remain", tp->name, freeBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
tp = chRegNextThread(tp);
|
tp = chRegNextThread(tp);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
int clampedFrequency = maxI(100, frequency);
|
int clampedFrequency = maxI(100, frequency);
|
||||||
|
|
||||||
if (clampedFrequency > ETB_HW_MAX_FREQUENCY) {
|
if (clampedFrequency > ETB_HW_MAX_FREQUENCY) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Electronic throttle frequency too high, maximum %d hz", ETB_HW_MAX_FREQUENCY);
|
criticalError("Electronic throttle frequency too high, maximum %d hz", ETB_HW_MAX_FREQUENCY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1061,7 +1061,7 @@ void doInitElectronicThrottle() {
|
||||||
if (!engineConfiguration->etb1configured && !engineConfiguration->etb2configured) {
|
if (!engineConfiguration->etb1configured && !engineConfiguration->etb2configured) {
|
||||||
// It's not valid to have a PPS without any ETBs - check that at least one ETB was enabled along with the pedal
|
// It's not valid to have a PPS without any ETBs - check that at least one ETB was enabled along with the pedal
|
||||||
if (hasPedal) {
|
if (hasPedal) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "A pedal position sensor was configured, but no electronic throttles are configured.");
|
criticalError("A pedal position sensor was configured, but no electronic throttles are configured.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ void initIdleHardware() {
|
||||||
|
|
||||||
if (engineConfiguration->isDoubleSolenoidIdle) {
|
if (engineConfiguration->isDoubleSolenoidIdle) {
|
||||||
if (!isBrainPinValid(engineConfiguration->secondSolenoidPin)) {
|
if (!isBrainPinValid(engineConfiguration->secondSolenoidPin)) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Second idle pin should be configured for double solenoid mode.");
|
criticalError("Second idle pin should be configured for double solenoid mode.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode) {
|
||||||
case VVT_MITSUBISHI_4G63:
|
case VVT_MITSUBISHI_4G63:
|
||||||
return trigger_type_e::TT_MITSU_4G63_CAM;
|
return trigger_type_e::TT_MITSU_4G63_CAM;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "getVvtTriggerType for %s", getVvt_mode_e(vvtMode));
|
criticalError("getVvtTriggerType for %s", getVvt_mode_e(vvtMode));
|
||||||
return trigger_type_e::TT_HALF_MOON; // we have to return something for the sake of -Werror=return-type
|
return trigger_type_e::TT_HALF_MOON; // we have to return something for the sake of -Werror=return-type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ void Engine::updateTriggerWaveform() {
|
||||||
#if ANALOG_HW_CHECK_MODE
|
#if ANALOG_HW_CHECK_MODE
|
||||||
static void assertCloseTo(const char* msg, float actual, float expected) {
|
static void assertCloseTo(const char* msg, float actual, float expected) {
|
||||||
if (actual < 0.95f * expected || actual > 1.05f * expected) {
|
if (actual < 0.95f * expected || actual > 1.05f * expected) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "%s validation failed actual=%f vs expected=%f", msg, actual, expected);
|
criticalError("%s validation failed actual=%f vs expected=%f", msg, actual, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ANALOG_HW_CHECK_MODE
|
#endif // ANALOG_HW_CHECK_MODE
|
||||||
|
|
|
@ -256,7 +256,7 @@ bool isLockedFromUser() {
|
||||||
int lock = engineConfiguration->tuneHidingKey;
|
int lock = engineConfiguration->tuneHidingKey;
|
||||||
bool isLocked = lock > 0;
|
bool isLocked = lock > 0;
|
||||||
if (isLocked) {
|
if (isLocked) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "password protected");
|
criticalError("password protected");
|
||||||
}
|
}
|
||||||
return isLocked;
|
return isLocked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ __attribute__((weak)) void boardOnConfigurationChange(engine_configuration_s* /*
|
||||||
void incrementGlobalConfigurationVersion(const char * msg) {
|
void incrementGlobalConfigurationVersion(const char * msg) {
|
||||||
assertStackVoid("increment", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
|
assertStackVoid("increment", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
|
||||||
if (!hasRememberedConfiguration) {
|
if (!hasRememberedConfiguration) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "too early to invoke incrementGlobalConfigurationVersion %s", msg);
|
criticalError("too early to invoke incrementGlobalConfigurationVersion %s", msg);
|
||||||
}
|
}
|
||||||
engine->globalConfigurationVersion++;
|
engine->globalConfigurationVersion++;
|
||||||
#if EFI_DEFAILED_LOGGING
|
#if EFI_DEFAILED_LOGGING
|
||||||
|
|
|
@ -63,7 +63,7 @@ expected<float> InjectorModel::getFuelDifferentialPressure() const {
|
||||||
- map.value_or(101.325);
|
- map.value_or(101.325);
|
||||||
case ICM_SensedRailPressure: {
|
case ICM_SensedRailPressure: {
|
||||||
if (!Sensor::hasSensor(SensorType::FuelPressureInjector)) {
|
if (!Sensor::hasSensor(SensorType::FuelPressureInjector)) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Fuel pressure compensation is set to use a pressure sensor, but none is configured.");
|
criticalError("Fuel pressure compensation is set to use a pressure sensor, but none is configured.");
|
||||||
return unexpected;
|
return unexpected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ float InjectorModel::getInjectorFlowRatio() {
|
||||||
|
|
||||||
if (referencePressure < 50) {
|
if (referencePressure < 50) {
|
||||||
// impossibly low fuel ref pressure
|
// impossibly low fuel ref pressure
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Impossible fuel reference pressure: %f", referencePressure);
|
criticalError("Impossible fuel reference pressure: %f", referencePressure);
|
||||||
|
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,14 @@ void GearDetector::initGearDetector() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gearCount > GEARS_COUNT) {
|
if (gearCount > GEARS_COUNT) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "too many gears");
|
criticalError("too many gears");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate gears
|
// validate gears
|
||||||
for (size_t i = 0; i < gearCount; i++) {
|
for (size_t i = 0; i < gearCount; i++) {
|
||||||
if (engineConfiguration->gearRatio[i] <= 0) {
|
if (engineConfiguration->gearRatio[i] <= 0) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Expecting positive gear ratio for #%d", i + 1);
|
criticalError("Expecting positive gear ratio for #%d", i + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ void GearDetector::initGearDetector() {
|
||||||
float gearIplusOne = engineConfiguration->gearRatio[i + 1];
|
float gearIplusOne = engineConfiguration->gearRatio[i + 1];
|
||||||
|
|
||||||
if (gearI <= gearIplusOne) {
|
if (gearI <= gearIplusOne) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Invalid gear ordering near gear #%d", i + 1);
|
criticalError("Invalid gear ordering near gear #%d", i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gearThresholds[i] = geometricMean(gearI, gearIplusOne);
|
m_gearThresholds[i] = geometricMean(gearI, gearIplusOne);
|
||||||
|
|
|
@ -331,7 +331,7 @@ static void handleBenchCategory(uint16_t index) {
|
||||||
cancelBenchTest();
|
cancelBenchTest();
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unexpected bench function %d", index);
|
criticalError("Unexpected bench function %d", index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ static void handleCommandX14(uint16_t index) {
|
||||||
sys_dual_bank();
|
sys_dual_bank();
|
||||||
rebootNow();
|
rebootNow();
|
||||||
#else
|
#else
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unexpected dbank command", index);
|
criticalError("Unexpected dbank command", index);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
case 0x15:
|
case 0x15:
|
||||||
|
@ -420,7 +420,7 @@ static void handleCommandX14(uint16_t index) {
|
||||||
#endif // EFI_PROD_CODE
|
#endif // EFI_PROD_CODE
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unexpected bench x14 %d", index);
|
criticalError("Unexpected bench x14 %d", index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ void executeTSCommand(uint16_t subsystem, uint16_t index) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unexpected bench subsystem %d %d", subsystem, index);
|
criticalError("Unexpected bench subsystem %d %d", subsystem, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1307,7 +1307,7 @@ void updateDash(CanCycle cycle) {
|
||||||
canDashboardTS(cycle);
|
canDashboardTS(cycle);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Nothing for canNbcType %s", getCan_nbc_e(engineConfiguration->canNbcType));
|
criticalError("Nothing for canNbcType %s", getCan_nbc_e(engineConfiguration->canNbcType));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ void setWidebandOffset(uint8_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!waitAck()) {
|
if (!waitAck()) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Wideband index set failed: no controller detected!");
|
criticalError("Wideband index set failed: no controller detected!");
|
||||||
}
|
}
|
||||||
|
|
||||||
waitingBootloaderThread = nullptr;
|
waitingBootloaderThread = nullptr;
|
||||||
|
|
|
@ -37,7 +37,7 @@ void checkLastBootError() {
|
||||||
case ErrorCookie::HardFault: {
|
case ErrorCookie::HardFault: {
|
||||||
efiPrintf("Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->FaultType, sramState->FaultAddress, sramState->Csfr);
|
efiPrintf("Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->FaultType, sramState->FaultAddress, sramState->Csfr);
|
||||||
if (engineConfiguration->rethrowHardFault) {
|
if (engineConfiguration->rethrowHardFault) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->FaultType, sramState->FaultAddress, sramState->Csfr);
|
criticalError("Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->FaultType, sramState->FaultAddress, sramState->Csfr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ctx = &sramState->FaultCtx;
|
auto ctx = &sramState->FaultCtx;
|
||||||
|
@ -114,7 +114,7 @@ void chDbgPanic3(const char *msg, const char * file, int line) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
#else // EFI_PROD_CODE
|
#else // EFI_PROD_CODE
|
||||||
|
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "assert fail %s %s:%d", msg, file, line);
|
criticalError("assert fail %s %s:%d", msg, file, line);
|
||||||
|
|
||||||
// If on the main thread, longjmp back to the init process so we can keep USB alive
|
// If on the main thread, longjmp back to the init process so we can keep USB alive
|
||||||
if (chThdGetSelfX()->threadId == 0) {
|
if (chThdGetSelfX()->threadId == 0) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
pin_state_t getChannelState(int channelIndex, int phaseIndex) const override {
|
pin_state_t getChannelState(int channelIndex, int phaseIndex) const override {
|
||||||
if (channelIndex >= waveCount) {
|
if (channelIndex >= waveCount) {
|
||||||
// todo: would be nice to get this asserting working
|
// todo: would be nice to get this asserting working
|
||||||
//firmwareError(ObdCode::OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
|
//criticalError("channel index %d/%d", channelIndex, waveCount);
|
||||||
}
|
}
|
||||||
return ((waveForm[phaseIndex] >> channelIndex) & 1) ? TriggerValue::RISE : TriggerValue::FALL;
|
return ((waveForm[phaseIndex] >> channelIndex) & 1) ? TriggerValue::RISE : TriggerValue::FALL;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public:
|
||||||
void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state) {
|
void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state) {
|
||||||
if (channelIndex >= waveCount) {
|
if (channelIndex >= waveCount) {
|
||||||
// todo: would be nice to get this asserting working
|
// todo: would be nice to get this asserting working
|
||||||
//firmwareError(ObdCode::OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount);
|
//criticalError("channel index %d/%d", channelIndex, waveCount);
|
||||||
}
|
}
|
||||||
uint8_t & ref = waveForm[phaseIndex];
|
uint8_t & ref = waveForm[phaseIndex];
|
||||||
ref = (ref & ~(1U << channelIndex)) | ((state == TriggerValue::RISE ? 1 : 0) << channelIndex);
|
ref = (ref & ~(1U << channelIndex)) | ((state == TriggerValue::RISE ? 1 : 0) << channelIndex);
|
||||||
|
|
|
@ -490,7 +490,7 @@ void commonInitEngineController() {
|
||||||
// Returns false if there's an obvious problem with the loaded configuration
|
// Returns false if there's an obvious problem with the loaded configuration
|
||||||
bool validateConfig() {
|
bool validateConfig() {
|
||||||
if (engineConfiguration->cylindersCount > MAX_CYLINDER_COUNT) {
|
if (engineConfiguration->cylindersCount > MAX_CYLINDER_COUNT) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Invalid cylinder count: %d", engineConfiguration->cylindersCount);
|
criticalError("Invalid cylinder count: %d", engineConfiguration->cylindersCount);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,13 +139,13 @@ int eraseAndFlashCopy(flashaddr_t storageAddress, const TStorage& data) {
|
||||||
|
|
||||||
auto err = intFlashErase(storageAddress, sizeof(TStorage));
|
auto err = intFlashErase(storageAddress, sizeof(TStorage));
|
||||||
if (FLASH_RETURN_SUCCESS != err) {
|
if (FLASH_RETURN_SUCCESS != err) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Failed to erase flash at 0x%08x: %d", storageAddress, err);
|
criticalError("Failed to erase flash at 0x%08x: %d", storageAddress, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = intFlashWrite(storageAddress, reinterpret_cast<const char*>(&data), sizeof(TStorage));
|
err = intFlashWrite(storageAddress, reinterpret_cast<const char*>(&data), sizeof(TStorage));
|
||||||
if (FLASH_RETURN_SUCCESS != err) {
|
if (FLASH_RETURN_SUCCESS != err) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Failed to write flash at 0x%08x: %d", storageAddress, err);
|
criticalError("Failed to write flash at 0x%08x: %d", storageAddress, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ void resetLuaCanRx() {
|
||||||
|
|
||||||
void addLuaCanRxFilter(int32_t eid, uint32_t mask, int bus, int callback) {
|
void addLuaCanRxFilter(int32_t eid, uint32_t mask, int bus, int callback) {
|
||||||
if (filterCount >= maxFilterCount) {
|
if (filterCount >= maxFilterCount) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Too many Lua CAN RX filters");
|
criticalError("Too many Lua CAN RX filters");
|
||||||
}
|
}
|
||||||
|
|
||||||
efiPrintf("Added Lua CAN RX filter id 0x%x mask 0x%x with%s custom function", eid, mask, (callback == -1 ? "out" : ""));
|
efiPrintf("Added Lua CAN RX filter id 0x%x mask 0x%x with%s custom function", eid, mask, (callback == -1 ? "out" : ""));
|
||||||
|
|
|
@ -168,13 +168,13 @@ static LuaHandle setupLuaState(lua_Alloc alloc) {
|
||||||
LuaHandle ls = lua_newstate(alloc, NULL);
|
LuaHandle ls = lua_newstate(alloc, NULL);
|
||||||
|
|
||||||
if (!ls) {
|
if (!ls) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Failed to start Lua interpreter");
|
criticalError("Failed to start Lua interpreter");
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_atpanic(ls, [](lua_State* l) {
|
lua_atpanic(ls, [](lua_State* l) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Lua panic: %s", lua_tostring(l, -1));
|
criticalError("Lua panic: %s", lua_tostring(l, -1));
|
||||||
|
|
||||||
// hang the lua thread
|
// hang the lua thread
|
||||||
while (true) ;
|
while (true) ;
|
||||||
|
|
|
@ -64,7 +64,7 @@ float IFuelComputer::getTChargeCoefficient(int rpm, float tps) {
|
||||||
engineConfiguration->tchargeValues
|
engineConfiguration->tchargeValues
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unexpected tChargeMode: %d", engineConfiguration->tChargeMode);
|
criticalError("Unexpected tChargeMode: %d", engineConfiguration->tChargeMode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,7 +626,7 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e
|
||||||
|
|
||||||
// Validate port
|
// Validate port
|
||||||
if (port == GPIO_NULL) {
|
if (port == GPIO_NULL) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "OutputPin::initPin got invalid port for pin idx %d", static_cast<int>(brainPin));
|
criticalError("OutputPin::initPin got invalid port for pin idx %d", static_cast<int>(brainPin));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +664,7 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e
|
||||||
#ifndef DISABLE_PIN_STATE_VALIDATION
|
#ifndef DISABLE_PIN_STATE_VALIDATION
|
||||||
// if the pin was set to logical 1, then set an error and disable the pin so that things don't catch fire
|
// if the pin was set to logical 1, then set an error and disable the pin so that things don't catch fire
|
||||||
if (logicalValue) {
|
if (logicalValue) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "HARDWARE VALIDATION FAILED %s: unexpected startup pin state %s actual value=%d logical value=%d mode=%s", msg, hwPortname(brainPin), actualValue, logicalValue, getPin_output_mode_e(outputMode));
|
criticalError("HARDWARE VALIDATION FAILED %s: unexpected startup pin state %s actual value=%d logical value=%d mode=%s", msg, hwPortname(brainPin), actualValue, logicalValue, getPin_output_mode_e(outputMode));
|
||||||
OutputPin::deInit();
|
OutputPin::deInit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,7 +79,7 @@ private:
|
||||||
chThdSleepUntilWindowed(before, before + m_period);
|
chThdSleepUntilWindowed(before, before + m_period);
|
||||||
}
|
}
|
||||||
|
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Thread died: %s", this->m_name);
|
criticalError("Thread died: %s", this->m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -103,7 +103,7 @@ void EventQueue::remove(scheduling_s* scheduling) {
|
||||||
|
|
||||||
// Walked off the end, this is an error since this *should* have been scheduled
|
// Walked off the end, this is an error since this *should* have been scheduled
|
||||||
if (!current) {
|
if (!current) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "EventQueue::remove didn't find element");
|
criticalError("EventQueue::remove didn't find element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ AngleBasedEvent * TriggerScheduler::getElementAtIndexForUnitTest(int index) {
|
||||||
return current;
|
return current;
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "getElementAtIndexForUnitText: null");
|
criticalError("getElementAtIndexForUnitText: null");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif /* EFI_UNIT_TEST */
|
#endif /* EFI_UNIT_TEST */
|
||||||
|
|
|
@ -123,7 +123,7 @@ bool TriggerWaveform::needsDisambiguation() const {
|
||||||
case TWO_STROKE:
|
case TWO_STROKE:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "bad operationMode() in needsDisambiguation");
|
criticalError("bad operationMode() in needsDisambiguation");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ static angle_t adjustCrankPhase(int camIndex) {
|
||||||
return tc->syncAndReport(crankDivider, 0);
|
return tc->syncAndReport(crankDivider, 0);
|
||||||
case VVT_HONDA_K_INTAKE:
|
case VVT_HONDA_K_INTAKE:
|
||||||
// with 4 evenly spaced tooth we cannot use this wheel for engine sync
|
// with 4 evenly spaced tooth we cannot use this wheel for engine sync
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Honda K Intake is not suitable for engine sync");
|
criticalError("Honda K Intake is not suitable for engine sync");
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case VVT_INACTIVE:
|
case VVT_INACTIVE:
|
||||||
// do nothing
|
// do nothing
|
||||||
|
@ -1145,11 +1145,11 @@ bool TriggerCentral::isTriggerConfigChanged() {
|
||||||
|
|
||||||
void validateTriggerInputs() {
|
void validateTriggerInputs() {
|
||||||
if (!isBrainPinValid(engineConfiguration->triggerInputPins[0]) && isBrainPinValid(engineConfiguration->triggerInputPins[1])) {
|
if (!isBrainPinValid(engineConfiguration->triggerInputPins[0]) && isBrainPinValid(engineConfiguration->triggerInputPins[1])) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "First trigger channel is missing");
|
criticalError("First trigger channel is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isBrainPinValid(engineConfiguration->camInputs[0]) && isBrainPinValid(engineConfiguration->camInputs[2])) {
|
if (!isBrainPinValid(engineConfiguration->camInputs[0]) && isBrainPinValid(engineConfiguration->camInputs[2])) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "First bank cam input is required if second bank specified");
|
criticalError("First bank cam input is required if second bank specified");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ static void fast_adc_callback(GPTDriver*) {
|
||||||
ADC_FAST_DEVICE.state != ADC_COMPLETE &&
|
ADC_FAST_DEVICE.state != ADC_COMPLETE &&
|
||||||
ADC_FAST_DEVICE.state != ADC_ERROR) {
|
ADC_FAST_DEVICE.state != ADC_ERROR) {
|
||||||
fastAdc.errorsCount++;
|
fastAdc.errorsCount++;
|
||||||
// todo: when? why? firmwareError(ObdCode::OBD_PCM_Processor_Fault, "ADC fast not ready?");
|
// todo: when? why? criticalError("ADC fast not ready?");
|
||||||
chSysUnlockFromISR()
|
chSysUnlockFromISR()
|
||||||
;
|
;
|
||||||
return;
|
return;
|
||||||
|
@ -253,7 +253,7 @@ bool AdcDevice::isHwUsed(adc_channel_e hwChannelIndex) const {
|
||||||
|
|
||||||
void AdcDevice::enableChannel(adc_channel_e hwChannel) {
|
void AdcDevice::enableChannel(adc_channel_e hwChannel) {
|
||||||
if ((channelCount + 1) >= ADC_MAX_CHANNELS_COUNT) {
|
if ((channelCount + 1) >= ADC_MAX_CHANNELS_COUNT) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Too many ADC channels configured");
|
criticalError("Too many ADC channels configured");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ CH_FAST_IRQ_HANDLER(VectorE0) {
|
||||||
|
|
||||||
// TODO: non-stm32 exti
|
// TODO: non-stm32 exti
|
||||||
void efiExtiInit() {
|
void efiExtiInit() {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "exti not supported");
|
criticalError("exti not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
void efiExtiEnablePin(const char *, brain_pin_e, uint32_t, ExtiCallback, void *) { }
|
void efiExtiEnablePin(const char *, brain_pin_e, uint32_t, ExtiCallback, void *) { }
|
||||||
|
|
|
@ -360,7 +360,7 @@ void initCan() {
|
||||||
|
|
||||||
// Devices can't be the same!
|
// Devices can't be the same!
|
||||||
if (device1 == device2) {
|
if (device1 == device2) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "CAN pins must be set to different devices");
|
criticalError("CAN pins must be set to different devices");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ void startSent() {
|
||||||
|
|
||||||
if (getIcuParams(sentPin, &pinAF, &icu, &cfg->channel, &baseClock) != true) {
|
if (getIcuParams(sentPin, &pinAF, &icu, &cfg->channel, &baseClock) != true) {
|
||||||
/* this pin has no ICU functionality, of ICU driver is not enabled for TIM on this pin */
|
/* this pin has no ICU functionality, of ICU driver is not enabled for TIM on this pin */
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "No ICU on selected SENT pin");
|
criticalError("No ICU on selected SENT pin");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ uint32_t backupRamLoad(backup_ram_e idx) {
|
||||||
// case DFU_JUMP_REQUESTED:
|
// case DFU_JUMP_REQUESTED:
|
||||||
// return RTCD1.rtc->BKP4R;
|
// return RTCD1.rtc->BKP4R;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Invalid backup ram idx %d", idx);
|
criticalError("Invalid backup ram idx %d", idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -43,7 +43,7 @@ void backupRamSave(backup_ram_e idx, uint32_t value) {
|
||||||
RTCD1.rtc->BKP4R = value;
|
RTCD1.rtc->BKP4R = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Invalid backup ram idx %d, value 0x08x", idx, value);
|
criticalError("Invalid backup ram idx %d, value 0x08x", idx, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* HAL_USE_RTC */
|
#endif /* HAL_USE_RTC */
|
||||||
|
|
|
@ -105,7 +105,7 @@ float getMcuTemperature() {
|
||||||
if (degrees > 150.0f || degrees < -50.0f) {
|
if (degrees > 150.0f || degrees < -50.0f) {
|
||||||
/*
|
/*
|
||||||
* we have a sporadic issue with this check todo https://github.com/rusefi/rusefi/issues/2552
|
* we have a sporadic issue with this check todo https://github.com/rusefi/rusefi/issues/2552
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Invalid CPU temperature measured %f", degrees);
|
criticalError("Invalid CPU temperature measured %f", degrees);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ adc_channel_e getAdcChannel(brain_pin_e pin) {
|
||||||
case Gpio::Unassigned:
|
case Gpio::Unassigned:
|
||||||
return EFI_ADC_NONE;
|
return EFI_ADC_NONE;
|
||||||
default:
|
default:
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "getAdcChannel %d", pin);
|
criticalError("getAdcChannel %d", pin);
|
||||||
return EFI_ADC_ERROR;
|
return EFI_ADC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ public:
|
||||||
|
|
||||||
void setDuty(float duty) override {
|
void setDuty(float duty) override {
|
||||||
if (!m_driver) {
|
if (!m_driver) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Attempted to set duty on null hard PWM device");
|
criticalError("Attempted to set duty on null hard PWM device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ stm32_hardware_pwm* getNextPwmDevice() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Run out of hardware PWM devices!");
|
criticalError("Run out of hardware PWM devices!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ static int getSpiAf(SPIDriver *driver) {
|
||||||
return EFI_SPI3_AF;
|
return EFI_SPI3_AF;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "SPI AF not available");
|
criticalError("SPI AF not available");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,7 +558,7 @@ void turnOnSpi(spi_device_e device) {
|
||||||
engineConfiguration->spi1MosiMode,
|
engineConfiguration->spi1MosiMode,
|
||||||
engineConfiguration->spi1MisoMode);
|
engineConfiguration->spi1MisoMode);
|
||||||
#else
|
#else
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "SPI1 not available in this binary");
|
criticalError("SPI1 not available in this binary");
|
||||||
#endif /* STM32_SPI_USE_SPI1 */
|
#endif /* STM32_SPI_USE_SPI1 */
|
||||||
}
|
}
|
||||||
if (device == SPI_DEVICE_2) {
|
if (device == SPI_DEVICE_2) {
|
||||||
|
@ -571,7 +571,7 @@ void turnOnSpi(spi_device_e device) {
|
||||||
engineConfiguration->spi2MosiMode,
|
engineConfiguration->spi2MosiMode,
|
||||||
engineConfiguration->spi2MisoMode);
|
engineConfiguration->spi2MisoMode);
|
||||||
#else
|
#else
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "SPI2 not available in this binary");
|
criticalError("SPI2 not available in this binary");
|
||||||
#endif /* STM32_SPI_USE_SPI2 */
|
#endif /* STM32_SPI_USE_SPI2 */
|
||||||
}
|
}
|
||||||
if (device == SPI_DEVICE_3) {
|
if (device == SPI_DEVICE_3) {
|
||||||
|
@ -584,7 +584,7 @@ void turnOnSpi(spi_device_e device) {
|
||||||
engineConfiguration->spi3MosiMode,
|
engineConfiguration->spi3MosiMode,
|
||||||
engineConfiguration->spi3MisoMode);
|
engineConfiguration->spi3MisoMode);
|
||||||
#else
|
#else
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "SPI3 not available in this binary");
|
criticalError("SPI3 not available in this binary");
|
||||||
#endif /* STM32_SPI_USE_SPI3 */
|
#endif /* STM32_SPI_USE_SPI3 */
|
||||||
}
|
}
|
||||||
if (device == SPI_DEVICE_4) {
|
if (device == SPI_DEVICE_4) {
|
||||||
|
@ -593,7 +593,7 @@ void turnOnSpi(spi_device_e device) {
|
||||||
/* there are no configuration fields for SPI4 in engineConfiguration, rely on board init code
|
/* there are no configuration fields for SPI4 in engineConfiguration, rely on board init code
|
||||||
* it should set proper functions for SPI4 pins */
|
* it should set proper functions for SPI4 pins */
|
||||||
#else
|
#else
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "SPI4 not available in this binary");
|
criticalError("SPI4 not available in this binary");
|
||||||
#endif /* STM32_SPI_USE_SPI4 */
|
#endif /* STM32_SPI_USE_SPI4 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,7 +722,7 @@ CANDriver* detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx) {
|
||||||
if (isValidCan2RxPin(pinRx) && isValidCan2TxPin(pinTx))
|
if (isValidCan2RxPin(pinRx) && isValidCan2TxPin(pinTx))
|
||||||
return &CAND2;
|
return &CAND2;
|
||||||
#endif
|
#endif
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "invalid CAN pins tx %s and rx %s", hwPortname(pinTx), hwPortname(pinRx));
|
criticalError("invalid CAN pins tx %s and rx %s", hwPortname(pinTx), hwPortname(pinRx));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,14 +39,14 @@ static DeviceType determineDevice() {
|
||||||
} else {
|
} else {
|
||||||
if (fs == 1024) {
|
if (fs == 1024) {
|
||||||
// Unsupported scenario! Not enough space for program plus two config copies
|
// Unsupported scenario! Not enough space for program plus two config copies
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "1MB single bank MCU detected: please clear nDBANK option bit and reinstall FW.");
|
criticalError("1MB single bank MCU detected: please clear nDBANK option bit and reinstall FW.");
|
||||||
return DeviceType::SingleBank1MB;
|
return DeviceType::SingleBank1MB;
|
||||||
} else if (fs == 2048) {
|
} else if (fs == 2048) {
|
||||||
return DeviceType::SingleBank2MB;
|
return DeviceType::SingleBank2MB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Unrecognized flash memory layout db=%d, size=%d", db, fs);
|
criticalError("Unrecognized flash memory layout db=%d, size=%d", db, fs);
|
||||||
return DeviceType::Unknown;
|
return DeviceType::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ void initLambda() {
|
||||||
#if EFI_CAN_SUPPORT
|
#if EFI_CAN_SUPPORT
|
||||||
if (engineConfiguration->enableAemXSeries) {
|
if (engineConfiguration->enableAemXSeries) {
|
||||||
if (!engineConfiguration->canWriteEnabled || !engineConfiguration->canReadEnabled) {
|
if (!engineConfiguration->canWriteEnabled || !engineConfiguration->canReadEnabled) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "CAN read and write are required to use CAN wideband.");
|
criticalError("CAN read and write are required to use CAN wideband.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ void deInitIfValid(const char* msg, adc_channel_e channel) {
|
||||||
|
|
||||||
static void initOldAnalogInputs() {
|
static void initOldAnalogInputs() {
|
||||||
if (isAdcChannelValid(engineConfiguration->afr.hwChannel) && engineConfiguration->enableAemXSeries) {
|
if (isAdcChannelValid(engineConfiguration->afr.hwChannel) && engineConfiguration->enableAemXSeries) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Please pick either analog AFR or CAN AFR input not both.");
|
criticalError("Please pick either analog AFR or CAN AFR input not both.");
|
||||||
}
|
}
|
||||||
initIfValid("AFR", engineConfiguration->afr.hwChannel);
|
initIfValid("AFR", engineConfiguration->afr.hwChannel);
|
||||||
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
|
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
|
||||||
|
|
|
@ -103,7 +103,7 @@ float interpolateMsg(const char *msg, float x1, float y1, float x2, float y2, fl
|
||||||
|
|
||||||
float interpolateClampedWithValidation(float x1, float y1, float x2, float y2, float x) {
|
float interpolateClampedWithValidation(float x1, float y1, float x2, float y2, float x) {
|
||||||
if (x1 >= x2) {
|
if (x1 >= x2) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "interpolateClamped %f has to be smaller than %f", x1, x2);
|
criticalError("interpolateClamped %f has to be smaller than %f", x1, x2);
|
||||||
}
|
}
|
||||||
return interpolateClamped(x1, y1, x2, y2, x);
|
return interpolateClamped(x1, y1, x2, y2, x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ void EventQueue::remove(scheduling_s* scheduling) {
|
||||||
|
|
||||||
// Walked off the end, this is an error since this *should* have been scheduled
|
// Walked off the end, this is an error since this *should* have been scheduled
|
||||||
if (!current) {
|
if (!current) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "EventQueue::remove didn't find element");
|
criticalError("EventQueue::remove didn't find element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ int getRemainingStack(thread_t*) {
|
||||||
static void assertString(const char*actual, const char *expected) {
|
static void assertString(const char*actual, const char *expected) {
|
||||||
if (strcmp(actual, expected) != 0) {
|
if (strcmp(actual, expected) != 0) {
|
||||||
printf("assertString FAILED\n");
|
printf("assertString FAILED\n");
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "chprintf test: got %s while %s", actual, expected);
|
criticalError("chprintf test: got %s while %s", actual, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ static void runToothLoggerTest() {
|
||||||
// no data yet
|
// no data yet
|
||||||
CompositeBuffer * toothBuffer = GetToothLoggerBufferNonblocking();
|
CompositeBuffer * toothBuffer = GetToothLoggerBufferNonblocking();
|
||||||
if (toothBuffer != nullptr) {
|
if (toothBuffer != nullptr) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "nullptr buffer expected");
|
criticalError("nullptr buffer expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ void CsvReader::processLine(EngineTestHelper *eth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeStampstr == nullptr) {
|
if (timeStampstr == nullptr) {
|
||||||
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "End of File");
|
criticalError("End of File");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue