CJ125 unit-tests coverage #617

This commit is contained in:
rusefi 2019-02-01 23:16:34 -05:00
parent cb559a3259
commit 6992480f74
10 changed files with 180 additions and 166 deletions

View File

@ -814,11 +814,11 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
tsOutputChannels->debugIntField2 = instance.invalidHip9011ResponsesCount;
break;
#endif /* EFI_HIP_9011 */
#if EFI_CJ125 || defined(__DOXYGEN__)
#if (EFI_CJ125 && HAL_USE_SPI) || defined(__DOXYGEN__)
case DBG_CJ125:
cjPostState(tsOutputChannels);
break;
#endif /* EFI_CJ125 */
#endif /* EFI_CJ125 && HAL_USE_SPI */
#if EFI_MAP_AVERAGING
case DBG_MAP:
postMapState(tsOutputChannels);

View File

@ -92,20 +92,20 @@ void initEgoAveraging(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#endif
bool hasAfrSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_CJ125 || defined(__DOXYGEN__)
#if (EFI_CJ125 && HAL_USE_SPI) || defined(__DOXYGEN__)
if (CONFIGB(isCJ125Enabled)) {
return cjHasAfrSensor(PASS_ENGINE_PARAMETER_SIGNATURE);
}
#endif /* EFI_CJ125 */
#endif /* EFI_CJ125 && HAL_USE_SPI */
return engineConfiguration->afr.hwChannel != EFI_ADC_NONE;
}
float getAfr(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_CJ125 || defined(__DOXYGEN__)
#if (EFI_CJ125 && HAL_USE_SPI) || defined(__DOXYGEN__)
if (CONFIGB(isCJ125Enabled)) {
return cjGetAfr(PASS_ENGINE_PARAMETER_SIGNATURE);
}
#endif /* EFI_CJ125 */
#endif /* EFI_CJ125 && HAL_USE_SPI */
afr_sensor_s * sensor = &CONFIG(afr);
float volts = getVoltageDivided("ego", sensor->hwChannel);

View File

@ -12,7 +12,7 @@
#include "rpm_calculator.h"
#include "pid.h"
#if EFI_CJ125 || defined(__DOXYGEN__)
#if (EFI_CJ125 && HAL_USE_SPI) || defined(__DOXYGEN__)
// looks like 3v range should be enough, divider not needed
#define EFI_CJ125_DIRECTLY_CONNECTED_UR TRUE
@ -24,19 +24,11 @@
EXTERN_ENGINE;
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
#include "hardware.h"
#include "backup_ram.h"
#include "pin_repository.h"
extern TunerStudioOutputChannels tsOutputChannels;
#endif
struct CJ125_state {
efitick_t startHeatingNt;
efitick_t prevNt;
};
static SimplePwm wboHeaterControl("wbo");
static OutputPin wboHeaterPin;
static OutputPin cj125Cs;
static Logging *logger;
@ -45,30 +37,18 @@ static unsigned char rx_buff[1];
static pid_s heaterPidConfig;
static Pid heaterPid(&heaterPidConfig);
static float heaterDuty = 0.0f;
// todo: only define this variable in EIF_PROD
static CJ125 globalInstance;
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
static THD_WORKING_AREA(cjThreadStack, UTILITY_THREAD_STACK_SIZE);
static SPIDriver *driver;
#if EFI_PROD_CODE
static SPIConfig cj125spicfg = { NULL,
/* HW dependent part.*/
NULL, 0, SPI_CR1_MSTR | SPI_CR1_CPHA | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 };
#endif /* EFI_PROD_CODE */
#endif /* EFI_UNIT_TEST */
CJ125::CJ125() {
state = CJ125_IDLE;
errorCode = CJ125_ERROR_NONE;
}
// Chip diagnostics register contents
static volatile int diag = 0;
@ -134,7 +114,6 @@ static int cjReadRegister(unsigned char regAddr) {
static void cjWriteRegister(unsigned char regAddr, unsigned char regValue) {
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
#ifdef CJ125_DEBUG_SPI
scheduleMsg(logger, "cjWriteRegister: addr=%d value=%d", regAddr, regValue);
#endif /* CJ125_DEBUG_SPI */
@ -143,7 +122,6 @@ static void cjWriteRegister(unsigned char regAddr, unsigned char regValue) {
tx_buff[1] = regValue;
spiSend(driver, 2, tx_buff);
spiUnselect(driver);
#endif /* EFI_UNIT_TEST */
}
static float getUr() {
@ -373,51 +351,26 @@ static void cjStart(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#endif
}
static void cjSetHeater(float value DECLARE_ENGINE_PARAMETER_SUFFIX) {
// limit duty cycle for sensor safety
float maxDuty = (engine->sensors.vBatt > CJ125_HEATER_LIMITING_VOLTAGE) ? CJ125_HEATER_LIMITING_RATE : 1.0f;
heaterDuty = (value < CJ125_HEATER_MIN_DUTY) ? 0.0f : minF(maxF(value, 0.0f), maxDuty);
#ifdef CJ125_DEBUG
scheduleMsg(logger, "cjSetHeater: %.2f", heaterDuty);
#endif
// a little trick to disable PWM if needed.
// todo: this should be moved to wboHeaterControl.setPwmDutyCycle()
wboHeaterControl.setFrequency(heaterDuty == 0.0f ? NAN : CJ125_HEATER_PWM_FREQ);
wboHeaterControl.setSimplePwmDutyCycle(heaterDuty);
}
static void cjSetIdleHeater(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// small preheat for faster start & moisture anti-shock therapy for the sensor
cjSetHeater(CJ125_HEATER_IDLE_RATE PASS_ENGINE_PARAMETER_SUFFIX);
}
static void cjStartHeaterControl(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if (CONFIGB(wboHeaterPin) != GPIO_UNASSIGNED) {
scheduleMsg(logger, "cj125: Starting heater control");
// todo: use custom pin state method, turn pin off while not running
startSimplePwmExt(&wboHeaterControl, "wboHeaterPin",
startSimplePwmExt(&globalInstance.wboHeaterControl, "wboHeaterPin",
&engine->executor,
CONFIGB(wboHeaterPin),
&wboHeaterPin, CJ125_HEATER_PWM_FREQ, 0.0f, applyPinState);
cjSetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE);
}
}
void CJ125::cjSetError(cj125_error_e errCode DECLARE_ENGINE_PARAMETER_SUFFIX) {
void CJ125::setError(cj125_error_e errCode DECLARE_ENGINE_PARAMETER_SUFFIX) {
errorCode = errCode;
state = CJ125_ERROR;
cjPrintErrorCode(errorCode);
// This is for safety:
scheduleMsg(logger, "cj125: Controller Shutdown!");
cjSetHeater(0 PASS_ENGINE_PARAMETER_SUFFIX);
SetHeater(0 PASS_ENGINE_PARAMETER_SUFFIX);
// Software-reset of CJ125
cjWriteRegister(INIT_REG2_WR, CJ125_INIT2_RESET);
}
bool CJ125::cjIsWorkingState(void) {
return state != CJ125_ERROR && state != CJ125_INIT && state != CJ125_IDLE;
}
static void cjInitPid(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if(engineConfiguration->cj125isLsu49) {
heaterPidConfig.pFactor = CJ125_PID_LSU49_P;
@ -475,7 +428,7 @@ static void cjStartSpi(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
/**
* @return true if currently in IDLE or ERROR state
*/
static bool cj125periodic(CJ125 *instance, CJ125_state *anotherState DECLARE_ENGINE_PARAMETER_SUFFIX) {
static bool cj125periodic(CJ125 *instance DECLARE_ENGINE_PARAMETER_SUFFIX) {
{
efitick_t nowNt = getTimeNowNt();
bool isStopped = engine->rpmCalculator.isStopped(PASS_ENGINE_PARAMETER_SIGNATURE);
@ -497,12 +450,12 @@ static bool cj125periodic(CJ125 *instance, CJ125_state *anotherState DECLARE_ENG
diag = cjReadRegister(DIAG_REG_RD);
// check heater state
if (vUr > CJ125_UR_PREHEAT_THR || heaterDuty < CJ125_PREHEAT_MIN_DUTY) {
if (vUr > CJ125_UR_PREHEAT_THR || instance->heaterDuty < CJ125_PREHEAT_MIN_DUTY) {
// Check if RPM>0 and it's time to start pre-heating
if (instance->state == CJ125_INIT && !isStopped) {
// start preheating
instance->state = CJ125_PREHEAT;
anotherState->startHeatingNt = anotherState->prevNt = getTimeNowNt();
instance->startHeatingNt = instance->prevNt = getTimeNowNt();
cjSetMode(CJ125_MODE_NORMAL_17);
}
} else if (vUr > CJ125_UR_GOOD_THR) {
@ -514,9 +467,9 @@ static bool cj125periodic(CJ125 *instance, CJ125_state *anotherState DECLARE_ENG
instance->state = CJ125_READY;
}
if (isStopped && instance->cjIsWorkingState()) {
if (isStopped && instance->isWorkingState()) {
instance->state = CJ125_INIT;
cjSetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE);
instance->SetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE);
}
#if 0
@ -527,38 +480,38 @@ static bool cj125periodic(CJ125 *instance, CJ125_state *anotherState DECLARE_ENG
switch (instance->state) {
case CJ125_PREHEAT:
// use constant-speed startup heat-up
if (nowNt - anotherState->prevNt >= CJ125_HEATER_PREHEAT_PERIOD) {
float periodSecs = (float)(nowNt - anotherState->prevNt) / US2NT(US_PER_SECOND_LL);
if (nowNt - instance->prevNt >= CJ125_HEATER_PREHEAT_PERIOD) {
float periodSecs = (float)(nowNt - instance->prevNt) / US2NT(US_PER_SECOND_LL);
// maintain speed at ~0.4V/sec
float preheatDuty = heaterDuty + periodSecs * CJ125_HEATER_PREHEAT_RATE;
cjSetHeater(preheatDuty PASS_ENGINE_PARAMETER_SUFFIX);
float preheatDuty = instance->heaterDuty + periodSecs * CJ125_HEATER_PREHEAT_RATE;
instance->SetHeater(preheatDuty PASS_ENGINE_PARAMETER_SUFFIX);
// If we are heating too long, and there's still no result, then something is wrong...
if (nowNt - anotherState->startHeatingNt > US2NT(US_PER_SECOND_LL) * CJ125_PREHEAT_TIMEOUT) {
instance->cjSetError(CJ125_ERROR_HEATER_MALFUNCTION PASS_ENGINE_PARAMETER_SUFFIX);
if (nowNt - instance->startHeatingNt > US2NT(US_PER_SECOND_LL) * CJ125_PREHEAT_TIMEOUT) {
instance->setError(CJ125_ERROR_HEATER_MALFUNCTION PASS_ENGINE_PARAMETER_SUFFIX);
}
cjPrintData();
anotherState->prevNt = nowNt;
instance->prevNt = nowNt;
}
break;
case CJ125_HEAT_UP:
case CJ125_READY:
// use PID for normal heater control
if (nowNt - anotherState->prevNt >= CJ125_HEATER_CONTROL_PERIOD) {
if (nowNt - instance->prevNt >= CJ125_HEATER_CONTROL_PERIOD) {
/* PID doesn't care about the target or the input, it knows only the
* error value as the difference of (target - input). and if we swap them we'll just get a sign inversion. If target=vUrCal, and input=vUr, then error=vUrCal-vUr, i.e. if vUr<vUrCal then the error will cause the heater to increase it's duty cycle. But it's not exactly what we want! Lesser vUr means HOTTER cell. That's why we even have this safety check for overheating: (vUr < CJ125_UR_OVERHEAT_THR)...
* So the simple trick is to inverse the error by swapping the target and input values.
*/
float duty = heaterPid.getValue(vUr, vUrCal);
heaterPid.showPidStatus(logger, "cj");
cjSetHeater(duty PASS_ENGINE_PARAMETER_SUFFIX);
instance->SetHeater(duty PASS_ENGINE_PARAMETER_SUFFIX);
cjPrintData();
anotherState->prevNt = nowNt;
instance->prevNt = nowNt;
}
break;
case CJ125_OVERHEAT:
if (nowNt - anotherState->prevNt >= CJ125_HEATER_OVERHEAT_PERIOD) {
instance->cjSetError(CJ125_ERROR_OVERHEAT PASS_ENGINE_PARAMETER_SUFFIX);
anotherState->prevNt = nowNt;
if (nowNt - instance->prevNt >= CJ125_HEATER_OVERHEAT_PERIOD) {
instance->setError(CJ125_ERROR_OVERHEAT PASS_ENGINE_PARAMETER_SUFFIX);
instance->prevNt = nowNt;
}
default:
;
@ -567,25 +520,20 @@ static bool cj125periodic(CJ125 *instance, CJ125_state *anotherState DECLARE_ENG
return false;
}
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
static CJ125_state globalStateInstance;
static msg_t cjThread(void)
{
chRegSetThreadName("cj125");
chThdSleepMilliseconds(500);
globalStateInstance.startHeatingNt = 0;
globalStateInstance.prevNt = getTimeNowNt();
globalInstance.startHeatingNt = 0;
globalInstance.prevNt = getTimeNowNt();
while (1) {
bool needIdleSleep = cj125periodic(&globalInstance, &globalStateInstance PASS_ENGINE_PARAMETER_SUFFIX);
bool needIdleSleep = cj125periodic(&globalInstance PASS_ENGINE_PARAMETER_SUFFIX);
chThdSleepMilliseconds(needIdleSleep ? CJ125_IDLE_TICK_DELAY : CJ125_TICK_DELAY);
}
return -1;
}
#endif /* EFI_UNIT_TEST */
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
static bool cjCheckConfig(void) {
@ -599,7 +547,7 @@ static bool cjCheckConfig(void) {
static void cjStartCalibration(void) {
if (!cjCheckConfig())
return;
if (globalInstance.cjIsWorkingState()) {
if (globalInstance.isWorkingState()) {
// todo: change this later for the normal thread operation (auto pre-heating)
scheduleMsg(logger, "cj125: Cannot start calibration. Please restart the board and make sure that your sensor is not heating");
return;
@ -649,7 +597,7 @@ bool cjHasAfrSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
return false;
#if ! EFI_UNIT_TEST
// check if controller is functioning
if (!globalInstance.cjIsWorkingState())
if (!globalInstance.isWorkingState())
return false;
#endif /* EFI_UNIT_TEST */
// check if amplification is turned on
@ -664,7 +612,7 @@ bool cjHasAfrSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
// used by DBG_CJ125
void cjPostState(TunerStudioOutputChannels *tsOutputChannels) {
tsOutputChannels->debugFloatField1 = heaterDuty;
tsOutputChannels->debugFloatField1 = globalInstance.heaterDuty;
tsOutputChannels->debugFloatField2 = heaterPid.getIntegration();
tsOutputChannels->debugFloatField3 = heaterPid.getPrevError();
tsOutputChannels->debugFloatField4 = vUa;
@ -695,24 +643,19 @@ void initCJ125(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
cjInitPid(PASS_ENGINE_PARAMETER_SIGNATURE);
cjStartSpi(PASS_ENGINE_PARAMETER_SIGNATURE);
cjStartHeaterControl(PASS_ENGINE_PARAMETER_SIGNATURE);
globalInstance.SetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE);
cjStart(PASS_ENGINE_PARAMETER_SIGNATURE);
#if 1
globalInstance.state = CJ125_INIT;
#endif
#ifdef CJ125_DEBUG
addConsoleActionF("cj125_heater", cjSetHeater);
// addConsoleActionF("cj125_heater", cjConsoleSetHeater);
addConsoleActionI("cj125_set_init1", cjSetInit1);
addConsoleActionI("cj125_set_init2", cjSetInit2);
#endif /* CJ125_DEBUG */
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
addConsoleAction("cj125", cjStartTest);
addConsoleAction("cj125_calibrate", cjStartCalibration);
chThdCreateStatic(cjThreadStack, sizeof(cjThreadStack), LOWPRIO, (tfunc_t)(void*) cjThread, NULL);
#endif /* EFI_UNIT_TEST */
}
#endif /* EFI_CJ125 */
#endif /* EFI_CJ125 && HAL_USE_SPI */

View File

@ -8,7 +8,7 @@
#ifndef HW_LAYER_SENSORS_CJ125_H_
#define HW_LAYER_SENSORS_CJ125_H_
#include "engine_configuration.h"
#include "CJ125_logic.h"
// CJ125 SPI Registers
#define IDENT_REG_RD 0x48 // Read Identity Register
@ -98,18 +98,6 @@
#define CJ125_TICK_DELAY 20 // 20 ms
#define CJ125_IDLE_TICK_DELAY 1000 // 1 sec
// Heater params for Idle(cold), Preheating and Control stages
// See http://www.waltech.com/wideband-files/boschsensordatasheet.htm
#define CJ125_HEATER_IDLE_RATE 0.15f // for a very cold sensor (presumably), we allow 15% duty max.
#define CJ125_HEATER_PREHEAT_PERIOD 300 // 300 ms
#define CJ125_HEATER_CONTROL_PERIOD 180 // 180 ms
#define CJ125_HEATER_OVERHEAT_PERIOD 500 // 500 ms
#define CJ125_HEATER_PWM_FREQ 100 // 100 Hz
#define CJ125_HEATER_PREHEAT_RATE (0.4f/14.0f) // Assuming that dutycycle=1.0 equals to 14V, and max.allowed heater rate is 0.4V/sec
#define CJ125_HEATER_LIMITING_VOLTAGE 12.0f // Do not allow more than 90% heating for high battery voltage (>12V).
#define CJ125_HEATER_LIMITING_RATE 0.92f // This prevents sensor overheating.
#define CJ125_CALIBRATE_NUM_SAMPLES 10
#define CJ125_UR_PREHEAT_THR 2.0f // Ur > 2.0 Volts is too cold to control with PID
@ -119,7 +107,6 @@
#define CJ125_UACAL_MIN 1.0f // Calibration UA values range
#define CJ125_UACAL_MAX 2.0f
#define CJ125_HEATER_MIN_DUTY 0.1f
#define CJ125_PREHEAT_MIN_DUTY 0.9f
//#define CJ125_PREHEAT_TIMEOUT 90 // 90 secs
@ -141,54 +128,6 @@
// Returned if there's no valid measurement
#define CJ125_AFR_NAN 0.0f
typedef enum {
CJ125_IDLE,
CJ125_INIT,
CJ125_CALIBRATION,
CJ125_PREHEAT,
CJ125_HEAT_UP,
CJ125_READY,
CJ125_OVERHEAT,
CJ125_ERROR,
} cj125_state_e;
typedef enum {
CJ125_ERROR_NONE = 0,
CJ125_ERROR_HEATER_MALFUNCTION = 1,
CJ125_ERROR_OVERHEAT = 2,
CJ125_ERROR_WRONG_IDENT = 3,
CJ125_ERROR_WRONG_INIT = 4,
} cj125_error_e;
typedef enum {
CJ125_MODE_NONE,
CJ125_MODE_NORMAL_8,
CJ125_MODE_NORMAL_17,
CJ125_MODE_CALIBRATION,
} cj125_mode_e;
typedef enum {
CJ125_LSU_42 = 0,
CJ125_LSU_49 = 1,
} cj125_sensor_type_e;
class CJ125 {
public:
CJ125();
// Used by CJ125 driver state machine
volatile cj125_state_e state;
// Last Error code
volatile cj125_error_e errorCode;
void cjSetError(cj125_error_e errCode DECLARE_ENGINE_PARAMETER_SUFFIX);
bool cjIsWorkingState(void);
};
#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)
void cjPostState(TunerStudioOutputChannels *tsOutputChannels);

View File

@ -0,0 +1,38 @@
/*
* @file CJ125_logic.cpp
*
* @date Feb 1, 2019
* @author Andrey Belomutskiy, (c) 2012-2019
*/
#include "CJ125_logic.h"
#include "engine.h"
EXTERN_ENGINE;
CJ125::CJ125() : wboHeaterControl("wbo") {
}
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)
float maxDuty = (engine->sensors.vBatt > CJ125_HEATER_LIMITING_VOLTAGE) ? CJ125_HEATER_LIMITING_RATE : 1.0f;
heaterDuty = (value < CJ125_HEATER_MIN_DUTY) ? 0.0f : minF(maxF(value, 0.0f), maxDuty);
#ifdef CJ125_DEBUG
scheduleMsg(logger, "cjSetHeater: %.2f", heaterDuty);
#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) {
return state != CJ125_ERROR && state != CJ125_INIT && state != CJ125_IDLE;
}

View File

@ -0,0 +1,83 @@
/*
* @file CJ125_logic.h
*
* @date Feb 1, 2019
* @author Andrey Belomutskiy, (c) 2012-2019
*/
#ifndef HW_LAYER_SENSORS_CJ125_LOGIC_H_
#define HW_LAYER_SENSORS_CJ125_LOGIC_H_
#include "engine_configuration.h"
#include "pwm_generator_logic.h"
typedef enum {
CJ125_LSU_42 = 0,
CJ125_LSU_49 = 1,
} cj125_sensor_type_e;
typedef enum {
CJ125_INIT,
CJ125_IDLE,
CJ125_CALIBRATION,
CJ125_PREHEAT,
CJ125_HEAT_UP,
CJ125_READY,
CJ125_OVERHEAT,
CJ125_ERROR,
} cj125_state_e;
typedef enum {
CJ125_ERROR_NONE = 0,
CJ125_ERROR_HEATER_MALFUNCTION = 1,
CJ125_ERROR_OVERHEAT = 2,
CJ125_ERROR_WRONG_IDENT = 3,
CJ125_ERROR_WRONG_INIT = 4,
} cj125_error_e;
typedef enum {
CJ125_MODE_NONE,
CJ125_MODE_NORMAL_8,
CJ125_MODE_NORMAL_17,
CJ125_MODE_CALIBRATION,
} cj125_mode_e;
class CJ125 {
public:
CJ125();
SimplePwm wboHeaterControl;
efitick_t startHeatingNt;
efitick_t prevNt;
float heaterDuty = 0.0f;
// Used by CJ125 driver state machine
volatile cj125_state_e state = CJ125_INIT;
// Last Error code
volatile cj125_error_e errorCode = CJ125_ERROR_NONE;
void setError(cj125_error_e errCode DECLARE_ENGINE_PARAMETER_SUFFIX);
bool isWorkingState(void);
void SetHeater(float value DECLARE_ENGINE_PARAMETER_SUFFIX);
void SetIdleHeater(DECLARE_ENGINE_PARAMETER_SIGNATURE);
};
// Heater params for Idle(cold), Preheating and Control stages
// See http://www.waltech.com/wideband-files/boschsensordatasheet.htm
#define CJ125_HEATER_IDLE_RATE 0.15f // for a very cold sensor (presumably), we allow 15% duty max.
#define CJ125_HEATER_PREHEAT_PERIOD 300 // 300 ms
#define CJ125_HEATER_CONTROL_PERIOD 180 // 180 ms
#define CJ125_HEATER_OVERHEAT_PERIOD 500 // 500 ms
#define CJ125_HEATER_PREHEAT_RATE (0.4f/14.0f) // Assuming that dutycycle=1.0 equals to 14V, and max.allowed heater rate is 0.4V/sec
#define CJ125_HEATER_MIN_DUTY 0.1f
#define CJ125_HEATER_PWM_FREQ 100 // 100 Hz
#define CJ125_HEATER_LIMITING_VOLTAGE 12.0f // Do not allow more than 90% heating for high battery voltage (>12V).
#define CJ125_HEATER_LIMITING_RATE 0.92f // This prevents sensor overheating.
#endif /* HW_LAYER_SENSORS_CJ125_LOGIC_H_ */

View File

@ -1,2 +1,3 @@
HW_SENSORS_SRC = $(PROJECT_DIR)/hw_layer/sensors/CJ125.cpp \
$(PROJECT_DIR)/hw_layer/CJ125_logic.cpp \
$(PROJECT_DIR)/hw_layer/sensors/yaw_rate_sensor.cpp

View File

@ -1,5 +1,5 @@
// This file was generated by Version2Header
// Fri Jan 11 08:48:17 EST 2019
// Fri Feb 01 18:26:44 EST 2019
#ifndef VCS_VERSION
#define VCS_VERSION "16346"
#define VCS_VERSION "16581"
#endif

View File

@ -89,6 +89,7 @@ include $(PROJECT_DIR)/controllers/system/system.mk
include $(PROJECT_DIR)/controllers/sensors/sensors.mk
include $(PROJECT_DIR)/controllers/trigger/trigger.mk
include $(PROJECT_DIR)/hw_layer/hw_layer.mk
include $(PROJECT_DIR)/hw_layer/sensors/sensors.mk
include test.mk
# Define linker script file here
@ -120,7 +121,7 @@ CPPSRC = $(UTILSRC_CPP) \
$(SYSTEMSRC_CPP) \
$(PROJECT_DIR)/controllers/error_handling.cpp \
$(HW_LAYER_EMS_CPP) \
$(PROJECT_DIR)/hw_layer/sensors/CJ125.cpp \
$(HW_SENSORS_SRC) \
$(TRIGGER_SRC_CPP) \
main.cpp

View File

@ -6,9 +6,18 @@
*/
#include "gtest/gtest.h"
#include "CJ125_logic.h"
#include "engine_test_helper.h"
TEST(testCJ125, testInitialState) {
CJ125 cj;
ASSERT_EQ(cj.state, CJ125_INIT);
ASSERT_FALSE(cj.isWorkingState());
WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996);
ASSERT_EQ(engine->sensors.vBatt, 0);
TEST(testCJ125, todo) {
EXPECT_EQ(1, 2 - 1);
}