rusefi-1/firmware/hw_layer/sensors/cj125_logic.cpp

169 lines
5.1 KiB
C++
Raw Normal View History

2019-02-01 20:16:34 -08:00
/*
* @file CJ125_logic.cpp
*
* @date Feb 1, 2019
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2019-02-01 20:16:34 -08:00
*/
#include "cj125_logic.h"
2019-02-01 20:16:34 -08:00
#include "engine.h"
2019-12-01 22:52:54 -08:00
#include "error_handling.h"
2019-02-01 20:16:34 -08:00
EXTERN_ENGINE;
2020-04-08 21:12:27 -07:00
#define LOW_VOLTAGE "Low Voltage"
2019-02-01 22:45:26 -08:00
CJ125::CJ125() : wboHeaterControl("wbo"),
2019-11-19 15:17:03 -08:00
heaterPid(&heaterPidConfig) {
2019-02-01 20:16:34 -08:00
}
void CJ125::SetHeater(float value DECLARE_ENGINE_PARAMETER_SUFFIX) {
// limit duty cycle for sensor safety
// todo: would be much nicer to have continuous function (vBatt)
2021-03-11 20:07:18 -08:00
float maxDuty = (Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE) > CJ125_HEATER_LIMITING_VOLTAGE) ? CJ125_HEATER_LIMITING_RATE : 1.0f;
2019-02-01 20:16:34 -08:00
heaterDuty = (value < CJ125_HEATER_MIN_DUTY) ? 0.0f : minF(maxF(value, 0.0f), maxDuty);
#ifdef CJ125_DEBUG
efiPrintf("cjSetHeater: %.2f", heaterDuty);
2019-02-01 20:16:34 -08:00
#endif
// a little trick to disable PWM if needed.
// todo: this should be moved to wboHeaterControl.setPwmDutyCycle()
// todo: is this really needed?!
wboHeaterControl.setFrequency(heaterDuty == 0.0f ? NAN : CJ125_HEATER_PWM_FREQ);
wboHeaterControl.setSimplePwmDutyCycle(heaterDuty);
}
void CJ125::SetIdleHeater(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// small preheat for faster start & moisture anti-shock therapy for the sensor
SetHeater(CJ125_HEATER_IDLE_RATE PASS_ENGINE_PARAMETER_SUFFIX);
}
bool CJ125::isWorkingState(void) const {
2019-02-01 20:16:34 -08:00
return state != CJ125_ERROR && state != CJ125_INIT && state != CJ125_IDLE;
}
2019-02-01 20:48:11 -08:00
void CJ125::StartHeaterControl(pwm_gen_callback *stateChangeCallback DECLARE_ENGINE_PARAMETER_SUFFIX) {
// todo: use custom pin state method, turn pin off while not running
startSimplePwmExt(&wboHeaterControl, "wboHeaterPin",
&engine->executor,
CONFIG(wboHeaterPin),
2019-02-01 20:48:11 -08:00
&wboHeaterPin, CJ125_HEATER_PWM_FREQ, 0.0f, stateChangeCallback);
SetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE);
}
2019-02-01 22:06:45 -08:00
2020-04-08 21:12:27 -07:00
static void printDiagCode(Logging * logging, const char *msg, int code, const char *code1message) {
switch(code & 0x3) {
case 0:
scheduleMsg(logging, "%s Short to GND", msg);
return;
case 1:
scheduleMsg(logging, "%s %s", msg, code1message);
return;
case 2:
scheduleMsg(logging, "%s Short to Vbatt", msg);
return;
2020-05-01 15:52:06 -07:00
case 3:
scheduleMsg(logging, "%s LOOKS GOOD", msg);
return;
}
}
void CJ125::printDiag() {
if (diag == CJ125_DIAG_NORM) {
efiPrintf("cj125: diag Looks great!");
2020-05-01 15:52:06 -07:00
} else {
efiPrintf("cj125: diag NOT GOOD");
2020-05-01 15:52:06 -07:00
printDiagCode(logger, "VM", diag, LOW_VOLTAGE);
printDiagCode(logger, "UN", diag >> 2, LOW_VOLTAGE);
printDiagCode(logger, "IA", diag >> 4, LOW_VOLTAGE);
printDiagCode(logger, "HR", diag >> 6, "open load");
2020-05-20 16:01:55 -07:00
/* todo: do we want to throw CRITICAL on diag start-up error? probably not?
firmwareError(CUSTOM_ERR_CJ125_DIAG, "CJ125 is not well");
*/
2020-04-08 21:12:27 -07:00
}
}
2019-12-01 22:52:54 -08:00
/**
* @return true in case of positive SPI identification
* false in case of unexpected SPI response
*/
2020-05-01 15:52:06 -07:00
bool CJ125::cjIdentify(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2019-12-01 22:52:54 -08:00
efiAssert(OBD_PCM_Processor_Fault, spi!= NULL, "No SPI pointer", false);
2019-02-01 22:06:45 -08:00
// read Ident register
int ident = spi->ReadRegister(IDENT_REG_RD) & CJ125_IDENT_MASK;
// set initial registers
spi->WriteRegister(INIT_REG1_WR, CJ125_INIT1_NORMAL_17);
spi->WriteRegister(INIT_REG2_WR, CJ125_INIT2_DIAG);
// check if regs are ok
int init1 = spi->ReadRegister(INIT_REG1_RD);
int init2 = spi->ReadRegister(INIT_REG2_RD);
diag = spi->ReadRegister(DIAG_REG_RD);
efiPrintf("cj125: Check ident=0x%x diag=0x%x init1=0x%x init2=0x%x", ident, diag, init1, init2);
2019-02-01 22:06:45 -08:00
if (ident != CJ125_IDENT) {
efiPrintf("cj125: Error! Wrong ident! Cannot communicate with CJ125!");
2020-05-01 15:52:06 -07:00
setError(CJ125_ERROR_WRONG_IDENT PASS_ENGINE_PARAMETER_SUFFIX);
2019-12-01 22:52:54 -08:00
return false;
2019-02-01 22:06:45 -08:00
}
if (init1 != CJ125_INIT1_NORMAL_17 || init2 != CJ125_INIT2_DIAG) {
efiPrintf("cj125: Error! Cannot set init registers! Cannot communicate with CJ125!");
2020-05-01 15:52:06 -07:00
setError(CJ125_ERROR_WRONG_IDENT PASS_ENGINE_PARAMETER_SUFFIX);
2019-12-01 22:52:54 -08:00
return false;
2019-02-01 22:06:45 -08:00
}
2020-05-01 15:52:06 -07:00
printDiag();
2019-12-01 22:52:54 -08:00
return true;
2019-02-01 22:06:45 -08:00
}
2019-02-01 22:45:26 -08:00
void CJ125::cjSetMode(cj125_mode_e m) {
if (mode == m)
return;
switch (m) {
case CJ125_MODE_NORMAL_8:
spi->WriteRegister(INIT_REG1_WR, CJ125_INIT1_NORMAL_8);
amplCoeff = 1.0f / 8.0f;
break;
case CJ125_MODE_NORMAL_17:
spi->WriteRegister(INIT_REG1_WR, CJ125_INIT1_NORMAL_17);
amplCoeff = 1.0f / 17.0f;
break;
case CJ125_MODE_CALIBRATION:
spi->WriteRegister(INIT_REG1_WR, CJ125_INIT1_CALBRT);
amplCoeff = 0.0f;
break;
default:
;
}
mode = m;
}
bool CJ125::isValidState() const {
2019-02-01 22:45:26 -08:00
// check if controller is functioning
if (!isWorkingState())
return false;
// check if amplification is turned on
if (amplCoeff == 0.0f)
return false;
// check if UA calibration value is valid
if (vUaCal < CJ125_UACAL_MIN || vUaCal > CJ125_UACAL_MAX)
return false;
return true;
}
void CJ125::cjInitPid(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2019-11-19 15:17:03 -08:00
if (engineConfiguration->cj125isLsu49) {
2019-02-01 22:45:26 -08:00
heaterPidConfig.pFactor = CJ125_PID_LSU49_P;
heaterPidConfig.iFactor = CJ125_PID_LSU49_I;
} else {
heaterPidConfig.pFactor = CJ125_PID_LSU42_P;
heaterPidConfig.iFactor = CJ125_PID_LSU42_I;
}
heaterPidConfig.dFactor = 0.0f;
heaterPidConfig.minValue = 0;
heaterPidConfig.maxValue = 1;
heaterPidConfig.offset = 0;
2020-05-01 14:52:25 -07:00
/**
* See hard-coded CJ125_TICK_DELAY - we run PID at 50Hz
*/
2019-02-01 22:45:26 -08:00
heaterPid.reset();
}