rusefi-1/firmware/hw_layer/hip9011_logic.cpp

110 lines
3.2 KiB
C++

/*
* @file HIP9011_logic.cpp
*
* Created on: Jan 3, 2019
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "global.h"
#include "hip9011_logic.h"
EXTERN_ENGINE;
HIP9011::HIP9011(Hip9011HardwareInterface *hardware) : rpmLookup() {
this->hardware = hardware;
}
void HIP9011::setStateAndCommand(unsigned char cmd) {
this->state = IS_SENDING_SPI_COMMAND;
hardware->sendCommand(cmd);
}
#define BAND(bore) (900 / (PIF * (bore) / 2))
/**
* @return frequency band we are interested in
*/
float getHIP9011Band(DEFINE_HIP_PARAMS) {
return GET_CONFIG_VALUE(knockBandCustom) == 0 ?
BAND(GET_CONFIG_VALUE(cylinderBore)) : GET_CONFIG_VALUE(knockBandCustom);
}
int getBandIndex(DEFINE_HIP_PARAMS) {
float freq = getHIP9011Band(FORWARD_HIP_PARAMS);
return getHip9011BandIndex(freq);
}
int getHip9011GainIndex(DEFINE_HIP_PARAMS) {
int i = GAIN_INDEX(GET_CONFIG_VALUE(hip9011Gain));
// GAIN_LOOKUP_SIZE is returned for index which is too low
return i == GAIN_LOOKUP_SIZE ? GAIN_LOOKUP_SIZE - 1 : i;
}
int getHip9011GainIndex(float gain) {
int i = GAIN_INDEX(gain);
// GAIN_LOOKUP_SIZE is returned for index which is too low
return i == GAIN_LOOKUP_SIZE ? GAIN_LOOKUP_SIZE - 1 : i;
}
/**
*
* We know the set of possible integration times, we know the knock detection window width
*/
void HIP9011::prepareHip9011RpmLookup(float angleWindowWidth) {
/**
* out binary search method needs increasing order thus the reverse order here
*/
for (int i = 0; i < INT_LOOKUP_SIZE; i++) {
rpmLookup[i] = getRpmByAngleWindowAndTimeUs(integratorValues[INT_LOOKUP_SIZE - i - 1], angleWindowWidth);
}
}
int HIP9011::getIntegrationIndexByRpm(float rpm) {
int i = findIndexMsg("getIbR", rpmLookup, INT_LOOKUP_SIZE, (rpm));
return i == -1 ? INT_LOOKUP_SIZE - 1 : INT_LOOKUP_SIZE - i - 1;
}
void HIP9011::setAngleWindowWidth(DEFINE_HIP_PARAMS) {
float angleWindowWidth = GET_CONFIG_VALUE(knockDetectionWindowEnd) - GET_CONFIG_VALUE(knockDetectionWindowStart);
if (angleWindowWidth < 0) {
#if EFI_PROD_CODE
warning(CUSTOM_KNOCK_WINDOW, "invalid knock window");
#endif
angleWindowWidth = 0;
}
// float '==' is totally appropriate here
if (this->angleWindowWidth == angleWindowWidth)
return; // exit if value has not change
this->angleWindowWidth = angleWindowWidth;
prepareHip9011RpmLookup(angleWindowWidth);
}
void HIP9011::handleValue(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS)) {
setAngleWindowWidth(FORWARD_HIP_PARAMS);
int prescalerIndex = GET_CONFIG_VALUE(hip9011PrescalerAndSDO);
int integratorIndex = getIntegrationIndexByRpm(rpm);
int gainIndex = getHip9011GainIndex(FORWARD_HIP_PARAMS);
int bandIndex = getBandIndex(FORWARD_HIP_PARAMS);
if (currentGainIndex != gainIndex) {
currentGainIndex = gainIndex;
setStateAndCommand(SET_GAIN_CMD + gainIndex);
} else if (currentIntergratorIndex != integratorIndex) {
currentIntergratorIndex = integratorIndex;
setStateAndCommand(SET_INTEGRATOR_CMD + integratorIndex);
} else if (currentBandIndex != bandIndex) {
currentBandIndex = bandIndex;
setStateAndCommand(SET_BAND_PASS_CMD + bandIndex);
} else if (currentPrescaler != prescalerIndex) {
currentPrescaler = prescalerIndex;
setStateAndCommand(SET_PRESCALER_CMD + prescalerIndex);
} else {
state = READY_TO_INTEGRATE;
}
}