* hip9011: coexistance with other spi devices

* hip9011: rework so SPI transfer is invoked from thread

also use polling spi exchange to avoid cache problems

* hip9011: move calculations from ADC callback to thread

* hip9011: big cleanup

* hip9011: simplify spi communication

* No need to set knockBandCustom if it is not custom

HIP9011 calculates knockBand from cylinderBore same way

* hip9011: make unit test happy

* hip9011: fix unit test

* hip9011: remove duplicated initialization, reorder

* hip9011: just renames and data type adjustments

* hip9011: rename BAND() to HIP9011_BAND()

* hip9011: move some code from lookup.cpp to logic.cpp

* hip9011: move initEngineNoiseTable to engine_configuration.cpp

* hip9011: move lookup tables to hip9011_logic.c

* hip9011: remove empty files

* hip9011: additional checks
This commit is contained in:
Andrey G 2021-03-30 17:56:25 +03:00 committed by GitHub
parent 523bef2eb6
commit 3d138958ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 479 additions and 422 deletions

View File

@ -110,7 +110,6 @@ void m73engine(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->cranking.baseFuel = 30;
engineConfiguration->cylinderBore = 85.0;
engineConfiguration->knockBandCustom = BAND(engineConfiguration->cylinderBore);
}

View File

@ -790,7 +790,7 @@ void setMiataNB2_ProteusEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE)
CONFIG(enableSoftwareKnock) = true;
// second harmonic (aka double) is usually quieter background noise
// 13.8
engineConfiguration->knockBandCustom = 2 * BAND(engineConfiguration->cylinderBore);
engineConfiguration->knockBandCustom = 2 * HIP9011_BAND(engineConfiguration->cylinderBore);
engineConfiguration->malfunctionIndicatorPin = GPIOB_6; // "Lowside 10" # pin 20/black35

View File

@ -637,7 +637,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
tsOutputChannels->isWarnNow = engine->engineState.warnings.isWarningNow(timeSeconds, true);
#if EFI_HIP_9011
tsOutputChannels->isKnockChipOk = (instance.invalidHip9011ResponsesCount == 0);
tsOutputChannels->isKnockChipOk = (instance.invalidResponsesCount == 0);
#endif /* EFI_HIP_9011 */
#if EFI_LAUNCH_CONTROL
@ -818,7 +818,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
case DBG_KNOCK:
// todo: maybe extract hipPostState(tsOutputChannels);
tsOutputChannels->debugIntField1 = instance.correctResponsesCount;
tsOutputChannels->debugIntField2 = instance.invalidHip9011ResponsesCount;
tsOutputChannels->debugIntField2 = instance.invalidResponsesCount;
break;
#endif /* EFI_HIP_9011 */
#if EFI_CJ125 && HAL_USE_SPI

View File

@ -32,7 +32,6 @@
#include "sensor.h"
#include "flash_main.h"
#include "hip9011_lookup.h"
#include "hip9011_logic.h"
#if EFI_MEMS
@ -658,6 +657,19 @@ void setDefaultGppwmParameters(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
}
}
void setDefaultEngineNoiseTable(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
setRpmTableBin(engineConfiguration->knockNoiseRpmBins, ENGINE_NOISE_CURVE_SIZE);
engineConfiguration->knockNoise[0] = 2; // 800
engineConfiguration->knockNoise[1] = 2; // 1700
engineConfiguration->knockNoise[2] = 2; // 2600
engineConfiguration->knockNoise[3] = 2; // 3400
engineConfiguration->knockNoise[4] = 2; // 4300
engineConfiguration->knockNoise[5] = 2; // 5200
engineConfiguration->knockNoise[6] = 2; // 6100
engineConfiguration->knockNoise[7] = 2; // 7000
}
/**
* @brief Global default engine configuration
* This method sets the global engine configuration defaults. These default values are then
@ -824,7 +836,7 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
setLinearCurve(config->fsioTable4LoadBins, 20, 120, 10);
setRpmTableBin(config->fsioTable4RpmBins, FSIO_TABLE_8);
initEngineNoiseTable(PASS_ENGINE_PARAMETER_SIGNATURE);
setDefaultEngineNoiseTable(PASS_ENGINE_PARAMETER_SIGNATURE);
engineConfiguration->clt.config = {0, 23.8889, 48.8889, 9500, 2100, 1000, 1500};
@ -972,7 +984,6 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->HD44780height = 4;
engineConfiguration->cylinderBore = 87.5;
engineConfiguration->knockBandCustom = BAND(engineConfiguration->cylinderBore);
setEgoSensor(ES_14Point7_Free PASS_CONFIG_PARAMETER_SUFFIX);

View File

@ -1,72 +0,0 @@
/**
* @file hip9011_lookup.cpp
* @brief HIP9011-specific table lookups, the other part of implementation is in HIP9011.cpp
*
* @date Jan 4, 2015
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "hip9011_lookup.h"
#include "interpolation.h"
/**
* These are HIP9011 magic values - integrator time constants in uS
*/
const int integratorValues[INT_LOOKUP_SIZE] = { 40, 45, 50, 55, 60, 65, 70, 75, 80, 90, 100, 110, 120, 130, 140, 150,
160, 180, 200, 220, 240, 260, 280, 300, 320, 360, 400, 440, 480, 520, 560, 600 };
const float gainLookupInReverseOrder[GAIN_LOOKUP_SIZE] = {
/* 00 */0.111, 0.118, 0.125, 0.129, 0.133, 0.138, 0.143, 0.148,
/* 08 */0.154, 0.160, 0.167, 0.174, 0.182, 0.190, 0.200, 0.211,
/* 16 */0.222, 0.236, 0.250, 0.258, 0.267, 0.276, 0.286, 0.296,
/* 24 */0.308, 0.320, 0.333, 0.348, 0.364, 0.381, 0.400, 0.421,
/* 32 */0.444, 0.471, 0.500, 0.548, 0.567, 0.586, 0.607, 0.630,
/* 40 */0.654, 0.680, 0.708, 0.739, 0.773, 0.810, 0.850, 0.895,
/* 48 */0.944, 1.000, 1.063, 1.143, 1.185, 1.231, 1.280, 1.333,
/* 56 */1.391, 1.455, 1.523, 1.600, 1.684, 1.778, 1.882, 2.0 };
const float bandFreqLookup[BAND_LOOKUP_SIZE] = { 1.22, 1.26, 1.31, 1.35, 1.4, 1.45, 1.51, 1.57, 1.63, 1.71, 1.78,
1.87, 1.96, 2.07, 2.18, 2.31, 2.46, 2.54, 2.62, 2.71, 2.81, 2.92, 3.03, 3.15, 3.28, 3.43, 3.59, 3.76, 3.95,
4.16, 4.39, 4.66, 4.95, 5.12, 5.29, 5.48, 5.68, 5.9, 6.12, 6.37, 6.64, 6.94, 7.27, 7.63, 8.02, 8.46, 8.95, 9.5,
10.12, 10.46, 10.83, 11.22, 11.65, 12.1, 12.6, 13.14, 13.72, 14.36, 15.07, 15.84, 16.71, 17.67, 18.76, 19.98 };
/**
* 'TC is typically TINT/(2*Pi*VOUT)'
* Knock Sensor Training TPIC8101, page 24
*/
float getRpmByAngleWindowAndTimeUs(int timeUs, float angleWindowWidth) {
/**
* TINT = TC * 2 * PI * VOUT
*/
float integrationTimeUs = timeUs * 2 * PIF * DESIRED_OUTPUT_VALUE;
/**
* rpm = 60 seconds / time
* '60000000' because revolutions per MINUTE in uS conversion
*/
float windowWidthMult = angleWindowWidth / 360.0f;
return 60000000.0f / integrationTimeUs * windowWidthMult;
}
/**
* @param frequency knock frequency, in kHz
*/
int getHip9011BandIndex(float frequency) {
return findIndexMsg("freq", bandFreqLookup, BAND_LOOKUP_SIZE, frequency);
}
EXTERN_ENGINE;
void initEngineNoiseTable(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
setRpmTableBin(engineConfiguration->knockNoiseRpmBins, ENGINE_NOISE_CURVE_SIZE);
engineConfiguration->knockNoise[0] = 2; // 800
engineConfiguration->knockNoise[1] = 2; // 1700
engineConfiguration->knockNoise[2] = 2; // 2600
engineConfiguration->knockNoise[3] = 2; // 3400
engineConfiguration->knockNoise[4] = 2; // 4300
engineConfiguration->knockNoise[5] = 2; // 5200
engineConfiguration->knockNoise[6] = 2; // 6100
engineConfiguration->knockNoise[7] = 2; // 7000
}

View File

@ -1,31 +0,0 @@
/**
* @file hip9011_lookup.h
*
* @date Jan 4, 2015
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#pragma once
#include "engine.h"
#define INT_LOOKUP_SIZE 32
#define GAIN_LOOKUP_SIZE 64
#define BAND_LOOKUP_SIZE 64
#define PIF 3.14159f
#define DESIRED_OUTPUT_VALUE 5.0f
extern const int integratorValues[INT_LOOKUP_SIZE];
extern const float gainLookupInReverseOrder[GAIN_LOOKUP_SIZE];
extern const float bandFreqLookup[BAND_LOOKUP_SIZE];
float getRpmByAngleWindowAndTimeUs(int timeUs, float angleWindowWidth);
int getHip9011BandIndex(float frequency);
#define GAIN_INDEX(gain) (GAIN_LOOKUP_SIZE - 1 - findIndexMsg("fGain", gainLookupInReverseOrder, GAIN_LOOKUP_SIZE, (gain)))
extern float rpmLookup[INT_LOOKUP_SIZE];
void initEngineNoiseTable(DECLARE_ENGINE_PARAMETER_SIGNATURE);

View File

@ -7,7 +7,6 @@ CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cp
$(PROJECT_DIR)/controllers/sensors/maf.cpp \
$(PROJECT_DIR)/controllers/sensors/tps.cpp \
$(PROJECT_DIR)/controllers/sensors/ego.cpp \
$(PROJECT_DIR)/controllers/sensors/hip9011_lookup.cpp \
$(PROJECT_DIR)/controllers/sensors/sensor.cpp \
$(PROJECT_DIR)/controllers/sensors/sensor_info_printing.cpp \
$(PROJECT_DIR)/controllers/sensors/functional_sensor.cpp \

View File

@ -39,7 +39,6 @@
#include "rpm_calculator.h"
#include "trigger_central.h"
#include "hip9011_logic.h"
#include "hip9011_lookup.h"
#include "hip9011.h"
#include "adc_inputs.h"
#include "perf_trace.h"
@ -50,28 +49,38 @@
#if EFI_PROD_CODE
#include "pin_repository.h"
#include "mpu_util.h"
#include "os_util.h"
#endif
#if EFI_HIP_9011
/*==========================================================================*/
/* Local definitions. */
/*==========================================================================*/
/*==========================================================================*/
/* Local variables and types. */
/*==========================================================================*/
static NamedOutputPin intHold(PROTOCOL_HIP_NAME);
static NamedOutputPin Cs(PROTOCOL_HIP_NAME);
class Hip9011Hardware : public Hip9011HardwareInterface {
void sendSyncCommand(unsigned char command) override;
void sendCommand(unsigned char command) override;
int sendSyncCommand(uint8_t command, uint8_t *rx_ptr) override;
};
/* TODO: include following stuff in object */
/* wake semaphore */
static semaphore_t wake;
static SPIDriver *spi;
static Hip9011Hardware hardware;
static float hipValueMax = 0;
HIP9011 instance(&hardware);
static unsigned char tx_buff[1];
static unsigned char rx_buff[1];
static scheduling_s startTimer;
static scheduling_s endTimer;
static Logging *logger;
@ -97,132 +106,77 @@ static SPIConfig hipSpiCfg = {
};
#endif /* EFI_PROD_CODE */
static void checkResponse(void) {
if (tx_buff[0] == rx_buff[0]) {
/*==========================================================================*/
/* Forward declarations */
/*==========================================================================*/
static void hip_addconsoleActions(void);
/*==========================================================================*/
/* Local functions. */
/*==========================================================================*/
static int checkResponse(uint8_t tx, uint8_t rx) {
/* TODO: implement response check for Advanced SPI mode too */
if (tx == rx) {
instance.correctResponsesCount++;
return 0;
} else {
instance.invalidHip9011ResponsesCount++;
instance.invalidResponsesCount++;
return -1;
}
}
// this macro is only used on startup
#define SPI_SYNCHRONOUS(value) \
spiSelect(driver); \
tx_buff[0] = value; \
spiExchange(driver, 1, tx_buff, rx_buff); \
spiUnselect(driver); \
checkResponse();
int Hip9011Hardware::sendSyncCommand(uint8_t tx, uint8_t *rx_ptr) {
int ret;
uint8_t rx;
/* Acquire ownership of the bus. */
spiAcquireBus(spi);
/* Setup transfer parameters. */
spiStart(spi, &hipSpiCfg);
/* Slave Select assertion. */
spiSelect(spi);
/* Transfer */
rx = spiPolledExchange(spi, tx);
/* Slave Select de-assertion. */
spiUnselect(spi);
/* Ownership release. */
spiReleaseBus(spi);
/* check response */
if (instance.adv_mode == false) {
/* only default SPI mode SDO is directly equals the SDI (echo function) */
ret = checkResponse(tx, rx);
static SPIDriver *driver;
if (ret)
return ret;
}
void Hip9011Hardware::sendSyncCommand(unsigned char command) {
SPI_SYNCHRONOUS(command);
chThdSleepMilliseconds(10);
}
if (rx_ptr) {
*rx_ptr = rx;
}
void Hip9011Hardware::sendCommand(unsigned char command) {
tx_buff[0] = command;
spiSelectI(driver);
spiStartExchangeI(driver, 1, tx_buff, rx_buff);
return 0;
}
EXTERN_ENGINE;
static void showHipInfo(void) {
if (!CONFIG(isHip9011Enabled)) {
scheduleMsg(logger, "hip9011 driver not active");
return;
static int hip_wake_driver(void)
{
/* Entering a reentrant critical zone.*/
syssts_t sts = chSysGetStatusAndLockX();
chSemSignalI(&wake);
if (!port_is_isr_context()) {
/**
* chSemSignalI above requires rescheduling
* interrupt handlers have implicit rescheduling
*/
chSchRescheduleS();
}
/* Leaving the critical zone.*/
chSysRestoreStatusX(sts);
scheduleMsg(logger, "enabled=%s state=%s",
boolToString(CONFIG(isHip9011Enabled)),
getHip_state_e(instance.state));
scheduleMsg(logger, " bore=%.2fmm freq=%.2fkHz",
engineConfiguration->cylinderBore,
getHIP9011Band(PASS_HIP_PARAMS));
scheduleMsg(logger, " band_index=%d integrator index=%d gain %.2f (%d) output=%s",
instance.currentBandIndex,
instance.currentIntergratorIndex,
engineConfiguration->hip9011Gain,
instance.currentGainIndex,
getAdc_channel_e(engineConfiguration->hipOutputChannel));
scheduleMsg(logger, " PaSDO=0x%x",
engineConfiguration->hip9011PrescalerAndSDO);
scheduleMsg(logger, " knockVThreshold=%.2f knockCount=%d maxKnockSubDeg=%.2f",
engineConfiguration->knockVThreshold,
engine->knockCount,
engineConfiguration->maxKnockSubDeg);
scheduleMsg(logger, " spi=%s IntHold@%s(0x%x) correct response=%d incorrect response=%d (%s)",
getSpi_device_e(engineConfiguration->hip9011SpiDevice),
hwPortname(CONFIG(hip9011IntHoldPin)),
CONFIG(hip9011IntHoldPinMode),
instance.correctResponsesCount,
instance.invalidHip9011ResponsesCount,
instance.invalidHip9011ResponsesCount > 0 ? "NOT GOOD" : "ok");
#if EFI_PROD_CODE
scheduleMsg(logger, "hip %.2fv/last=%.2f/max=%.2f adv=%d",
engine->knockVolts,
getVoltage("hipinfo", engineConfiguration->hipOutputChannel),
hipValueMax,
CONFIG(useTpicAdvancedMode));
scheduleMsg(logger, "hip9011 CS@%s",
hwPortname(CONFIG(hip9011CsPin)));
printSpiConfig(logger, "hip9011", CONFIG(hip9011SpiDevice));
#endif /* EFI_PROD_CODE */
scheduleMsg(logger, "start %.2f end %.2f",
engineConfiguration->knockDetectionWindowStart,
engineConfiguration->knockDetectionWindowEnd);
scheduleMsg(logger, "Status: overruns %d",
instance.overrun);
hipValueMax = 0;
engine->printKnockState();
}
void setHip9011FrankensoPinout(void) {
/**
* SPI on PB13/14/15
*/
// CONFIG(hip9011CsPin) = GPIOD_0; // rev 0.1
CONFIG(isHip9011Enabled) = true;
engineConfiguration->hip9011PrescalerAndSDO = HIP_8MHZ_PRESCALER; // 8MHz chip
CONFIG(is_enabled_spi_2) = true;
// todo: convert this to rusEfi, hardware-independent enum
#if EFI_PROD_CODE
#ifdef EFI_HIP_CS_PIN
CONFIG(hip9011CsPin) = EFI_HIP_CS_PIN;
#else
CONFIG(hip9011CsPin) = GPIOB_0; // rev 0.4
#endif
CONFIG(hip9011CsPinMode) = OM_OPENDRAIN;
CONFIG(hip9011IntHoldPin) = GPIOB_11;
CONFIG(hip9011IntHoldPinMode) = OM_OPENDRAIN;
engineConfiguration->spi2SckMode = PO_OPENDRAIN; // 4
engineConfiguration->spi2MosiMode = PO_OPENDRAIN; // 4
engineConfiguration->spi2MisoMode = PO_PULLUP; // 32
#endif /* EFI_PROD_CODE */
engineConfiguration->hip9011Gain = 1;
engineConfiguration->knockVThreshold = 4;
engineConfiguration->maxKnockSubDeg = 20;
if (!CONFIG(useTpicAdvancedMode)) {
engineConfiguration->hipOutputChannel = EFI_ADC_10; // PC0
}
return 0;
}
static void startIntegration(void *) {
@ -269,111 +223,107 @@ void hip9011_startKnockSampling(uint8_t cylinderNumber, efitick_t nowNt) {
&endIntegration);
}
void setMaxKnockSubDeg(int value) {
engineConfiguration->maxKnockSubDeg = value;
showHipInfo();
}
void setKnockThresh(float value) {
engineConfiguration->knockVThreshold = value;
showHipInfo();
}
void setPrescalerAndSDO(int value) {
engineConfiguration->hip9011PrescalerAndSDO = value;
}
void setHipBand(float value) {
engineConfiguration->knockBandCustom = value;
showHipInfo();
}
void setHipGain(float value) {
engineConfiguration->hip9011Gain = value;
showHipInfo();
}
/**
* this is the end of the non-synchronous exchange
*/
static void endOfSpiExchange(SPIDriver *spip) {
(void)spip;
spiUnselectI(driver);
instance.state = READY_TO_INTEGRATE;
checkResponse();
}
void hipAdcCallback(adcsample_t adcValue) {
if (instance.state == WAITING_FOR_ADC_TO_SKIP) {
instance.state = WAITING_FOR_RESULT_ADC;
} else if (instance.state == WAITING_FOR_RESULT_ADC) {
float knockVolts = adcValue * adcToVolts(1) * CONFIG(analogInputDividerCoefficient);
hipValueMax = maxF(knockVolts, hipValueMax);
engine->knockLogic(knockVolts);
instance.handleValue(GET_RPM() DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));
/* TunerStudio */
tsOutputChannels.knockLevels[instance.cylinderNumber] = knockVolts;
tsOutputChannels.knockLevel = knockVolts;
/* offload calculations to driver thread */
instance.raw_value = adcValue;
instance.state = NOT_READY;
hip_wake_driver();
}
}
static void hipStartupCode(void) {
instance.currentPrescaler = engineConfiguration->hip9011PrescalerAndSDO;
instance.hardware->sendSyncCommand(SET_PRESCALER_CMD(instance.currentPrescaler));
static int hip_init(void) {
int ret;
ret = instance.hw->sendSyncCommand(SET_PRESCALER_CMD(instance.prescaler), NULL);
if (ret)
return ret;
// '0' for channel #1
instance.hardware->sendSyncCommand(SET_CHANNEL_CMD(0));
// band index depends on cylinder bore
instance.hardware->sendSyncCommand(SET_BAND_PASS_CMD(instance.currentBandIndex));
if (instance.correctResponsesCount == 0) {
warning(CUSTOM_OBD_KNOCK_PROCESSOR, "TPIC/HIP does not respond");
}
ret = instance.hw->sendSyncCommand(SET_CHANNEL_CMD(instance.channelIdx), NULL);
if (ret)
return ret;
if (CONFIG(useTpicAdvancedMode)) {
// enable advanced mode for digital integrator output
instance.hardware->sendSyncCommand(SET_ADVANCED_MODE_CMD);
ret = instance.hw->sendSyncCommand(SET_ADVANCED_MODE_CMD, NULL);
if (ret)
return ret;
instance.adv_mode = true;
}
/**
* Let's restart SPI to switch it from synchronous mode into
* asynchronous mode
*/
spiStop(driver);
#if EFI_PROD_CODE
hipSpiCfg.end_cb = endOfSpiExchange;
#endif
spiStart(driver, &hipSpiCfg);
instance.state = READY_TO_INTEGRATE;
return 0;
}
static THD_WORKING_AREA(hipThreadStack, UTILITY_THREAD_STACK_SIZE);
static msg_t hipThread(void *arg) {
int ret;
UNUSED(arg);
chRegSetThreadName("hip9011 init");
chRegSetThreadName("hip9011 worker");
/* Acquire ownership of the bus. */
spiAcquireBus(spi);
// some time to let the hardware start
Cs.setValue(true);
chThdSleepMilliseconds(100);
Cs.setValue(false);
chThdSleepMilliseconds(100);
Cs.setValue(true);
/* Ownership release. */
spiReleaseBus(spi);
while (true) {
chThdSleepMilliseconds(100);
/* init semaphore */
chSemObjectInit(&wake, 10);
if (instance.needToInit) {
hipStartupCode();
instance.needToInit = false;
chThdSleepMilliseconds(100);
do {
/* retry until success */
ret = hip_init();
if (ret) {
warning(CUSTOM_OBD_KNOCK_PROCESSOR, "TPIC/HIP does not respond: %d", ret);
chThdSleepMilliseconds(10 * 1000);
}
} while (ret);
while (1) {
msg_t msg;
/* load new/updated settings */
instance.handleSettings(GET_RPM() DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));
/* State */
instance.state = READY_TO_INTEGRATE;
msg = chSemWaitTimeout(&wake, TIME_INFINITE);
if (msg == MSG_TIMEOUT) {
/* ??? */
} else {
/* TODO: check for correct cylinder/input */
if (1) {
/* calculations */
float knockVolts = instance.raw_value * adcToVolts(1) * CONFIG(analogInputDividerCoefficient);
hipValueMax = maxF(knockVolts, hipValueMax);
engine->knockLogic(knockVolts);
/* TunerStudio */
tsOutputChannels.knockLevels[instance.cylinderNumber] = knockVolts;
tsOutputChannels.knockLevel = knockVolts;
}
}
}
return -1;
}
/*==========================================================================*/
/* Exported functions. */
/*==========================================================================*/
void stopHip9001_pins() {
intHold.deInit();
Cs.deInit();
@ -389,16 +339,13 @@ void startHip9001_pins() {
void initHip9011(Logging *sharedLogger) {
logger = sharedLogger;
addConsoleAction("hipinfo", showHipInfo);
if (!CONFIG(isHip9011Enabled))
return;
instance.setAngleWindowWidth();
#if EFI_PROD_CODE
driver = getSpiDevice(engineConfiguration->hip9011SpiDevice);
if (driver == NULL) {
spi = getSpiDevice(CONFIG(hip9011SpiDevice));
if (spi == NULL) {
// error already reported
return;
}
@ -409,22 +356,151 @@ void initHip9011(Logging *sharedLogger) {
startHip9001_pins();
/* load settings */
instance.channelIdx = 0;
instance.prescaler = CONFIG(hip9011PrescalerAndSDO);
scheduleMsg(logger, "Starting HIP9011/TPIC8101 driver");
spiStart(driver, &hipSpiCfg);
instance.currentBandIndex = getBandIndex();
chThdCreateStatic(hipThreadStack, sizeof(hipThreadStack), PRIO_HIP9011, (tfunc_t)(void*) hipThread, NULL);
// MISO PB14
// palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(EFI_SPI2_AF) | PAL_STM32_PUDR_PULLUP);
// MOSI PB15
// palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(EFI_SPI2_AF) | PAL_STM32_OTYPE_OPENDRAIN);
hip_addconsoleActions();
}
/*==========================================================================*/
/* Debug functions. */
/*==========================================================================*/
static void showHipInfo(void) {
if (!CONFIG(isHip9011Enabled)) {
scheduleMsg(logger, "hip9011 driver not active");
return;
}
scheduleMsg(logger, "enabled=%s state=%s",
boolToString(CONFIG(isHip9011Enabled)),
getHip_state_e(instance.state));
scheduleMsg(logger, " bore=%.2fmm freq=%.2fkHz",
engineConfiguration->cylinderBore,
instance.getBand(PASS_HIP_PARAMS));
scheduleMsg(logger, " band idx=%d integrator idx=%d gain %.2f (idx %d) output=%s",
instance.bandIdx,
instance.intergratorIdx,
engineConfiguration->hip9011Gain,
instance.gainIdx,
getAdc_channel_e(engineConfiguration->hipOutputChannel));
scheduleMsg(logger, " PaSDO=0x%x",
instance.prescaler);
scheduleMsg(logger, " knockVThreshold=%.2f knockCount=%d maxKnockSubDeg=%.2f",
engineConfiguration->knockVThreshold,
engine->knockCount,
engineConfiguration->maxKnockSubDeg);
scheduleMsg(logger, " spi=%s IntHold@%s(0x%x) correct response=%d incorrect response=%d (%s)",
getSpi_device_e(engineConfiguration->hip9011SpiDevice),
hwPortname(CONFIG(hip9011IntHoldPin)),
CONFIG(hip9011IntHoldPinMode),
instance.correctResponsesCount,
instance.invalidResponsesCount,
instance.invalidResponsesCount > 0 ? "NOT GOOD" : "ok");
#if EFI_PROD_CODE
scheduleMsg(logger, "hip %.2fv/last=%.2f/max=%.2f adv=%d",
engine->knockVolts,
getVoltage("hipinfo", engineConfiguration->hipOutputChannel),
hipValueMax,
CONFIG(useTpicAdvancedMode));
scheduleMsg(logger, "hip9011 CS@%s",
hwPortname(CONFIG(hip9011CsPin)));
printSpiConfig(logger, "hip9011", CONFIG(hip9011SpiDevice));
#endif /* EFI_PROD_CODE */
scheduleMsg(logger, "start %.2f end %.2f",
engineConfiguration->knockDetectionWindowStart,
engineConfiguration->knockDetectionWindowEnd);
scheduleMsg(logger, "Status: overruns %d",
instance.overrun);
hipValueMax = 0;
engine->printKnockState();
}
static void setMaxKnockSubDeg(int value) {
engineConfiguration->maxKnockSubDeg = value;
showHipInfo();
}
static void setKnockThresh(float value) {
engineConfiguration->knockVThreshold = value;
showHipInfo();
}
static void setPrescalerAndSDO(int value) {
engineConfiguration->hip9011PrescalerAndSDO = value;
}
static void setHipBand(float value) {
engineConfiguration->knockBandCustom = value;
showHipInfo();
}
static void setHipGain(float value) {
engineConfiguration->hip9011Gain = value;
showHipInfo();
}
static void hip_addconsoleActions(void) {
addConsoleAction("hipinfo", showHipInfo);
addConsoleActionF("set_gain", setHipGain);
addConsoleActionF("set_band", setHipBand);
addConsoleActionI("set_hip_prescalerandsdo", setPrescalerAndSDO);
addConsoleActionF("set_knock_threshold", setKnockThresh);
addConsoleActionI("set_max_knock_sub_deg", setMaxKnockSubDeg);
chThdCreateStatic(hipThreadStack, sizeof(hipThreadStack), PRIO_HIP9011, (tfunc_t)(void*) hipThread, NULL);
}
/*==========================================================================*/
/* Boards specific functions. */
/*==========================================================================*/
/* TODO: move out oif here */
void setHip9011FrankensoPinout(void) {
/**
* SPI on PB13/14/15
*/
// CONFIG(hip9011CsPin) = GPIOD_0; // rev 0.1
CONFIG(isHip9011Enabled) = true;
engineConfiguration->hip9011PrescalerAndSDO = HIP_8MHZ_PRESCALER; // 8MHz chip
CONFIG(is_enabled_spi_2) = true;
// todo: convert this to rusEfi, hardware-independent enum
#if EFI_PROD_CODE
#ifdef EFI_HIP_CS_PIN
CONFIG(hip9011CsPin) = EFI_HIP_CS_PIN;
#else
CONFIG(hip9011CsPin) = GPIOB_0; // rev 0.4
#endif
CONFIG(hip9011CsPinMode) = OM_OPENDRAIN;
CONFIG(hip9011IntHoldPin) = GPIOB_11;
CONFIG(hip9011IntHoldPinMode) = OM_OPENDRAIN;
engineConfiguration->spi2SckMode = PO_OPENDRAIN; // 4
engineConfiguration->spi2MosiMode = PO_OPENDRAIN; // 4
engineConfiguration->spi2MisoMode = PO_PULLUP; // 32
#endif /* EFI_PROD_CODE */
engineConfiguration->hip9011Gain = 1;
engineConfiguration->knockVThreshold = 4;
engineConfiguration->maxKnockSubDeg = 20;
if (!CONFIG(useTpicAdvancedMode)) {
engineConfiguration->hipOutputChannel = EFI_ADC_10; // PC0
}
}
#endif /* EFI_HIP_9011 */

View File

@ -13,14 +13,10 @@
void initHip9011(Logging *sharedLogger);
void startHip9001_pins();
void stopHip9001_pins();
void setHip9011FrankensoPinout(void);
#if HAL_USE_ADC
void hipAdcCallback(adcsample_t value);
#endif /* HAL_USE_ADC */
void setHipGain(float value);
void setHipBand(float value);
void setPrescalerAndSDO(int value);
void setKnockThresh(float value);
void setMaxKnockSubDeg(int value);
void hip9011_startKnockSampling(uint8_t cylinderNumber, efitick_t nowNt);
void setHip9011FrankensoPinout(void);

View File

@ -6,49 +6,122 @@
*/
#include "global.h"
#include "engine.h"
#include "hip9011_logic.h"
/*==========================================================================*/
/* Local definitions. */
/*==========================================================================*/
#define DESIRED_OUTPUT_VALUE 5.0f
/*==========================================================================*/
/* Local variables and types. */
/*==========================================================================*/
/**
* These are HIP9011 magic values - integrator time constants in uS
*/
const int integratorValues[INT_LOOKUP_SIZE] = {
/* 00 */ 40, 45, 50, 55, 60, 65, 70, 75,
/* 08 */ 80, 90, 100, 110, 120, 130, 140, 150,
/* 16 */160, 180, 200, 220, 240, 260, 280, 300,
/* 24 */320, 360, 400, 440, 480, 520, 560, 600
};
const float gainLookupInReverseOrder[GAIN_LOOKUP_SIZE] = {
/* 00 */0.111, 0.118, 0.125, 0.129, 0.133, 0.138, 0.143, 0.148,
/* 08 */0.154, 0.160, 0.167, 0.174, 0.182, 0.190, 0.200, 0.211,
/* 16 */0.222, 0.236, 0.250, 0.258, 0.267, 0.276, 0.286, 0.296,
/* 24 */0.308, 0.320, 0.333, 0.348, 0.364, 0.381, 0.400, 0.421,
/* 32 */0.444, 0.471, 0.500, 0.548, 0.567, 0.586, 0.607, 0.630,
/* 40 */0.654, 0.680, 0.708, 0.739, 0.773, 0.810, 0.850, 0.895,
/* 48 */0.944, 1.000, 1.063, 1.143, 1.185, 1.231, 1.280, 1.333,
/* 56 */1.391, 1.455, 1.523, 1.600, 1.684, 1.778, 1.882, 2.000
};
const float bandFreqLookup[BAND_LOOKUP_SIZE] = {
/* 00 */ 1.22, 1.26, 1.31, 1.35, 1.40, 1.45, 1.51, 1.57,
/* 08 */ 1.63, 1.71, 1.78, 1.87, 1.96, 2.07, 2.18, 2.31,
/* 16 */ 2.46, 2.54, 2.62, 2.71, 2.81, 2.92, 3.03, 3.15,
/* 24 */ 3.28, 3.43, 3.59, 3.76, 3.95, 4.16, 4.39, 4.66,
/* 32 */ 4.95, 5.12, 5.29, 5.48, 5.68, 5.90, 6.12, 6.37,
/* 40 */ 6.64, 6.94, 7.27, 7.63, 8.02, 8.46, 8.95, 9.50,
/* 48 */10.12, 10.46, 10.83, 11.22, 11.65, 12.10, 12.60, 13.14,
/* 56 */13.72, 14.36, 15.07, 15.84, 16.71, 17.67, 18.76, 19.98
};
/*==========================================================================*/
/* Forward declarations */
/*==========================================================================*/
EXTERN_ENGINE;
HIP9011::HIP9011(Hip9011HardwareInterface *hardware) : rpmLookup() {
this->hardware = hardware;
/*==========================================================================*/
/* Exported. */
/*==========================================================================*/
HIP9011::HIP9011(Hip9011HardwareInterface *hardware) {
this->hw = hardware;
}
void HIP9011::setStateAndCommand(unsigned char cmd) {
this->state = IS_SENDING_SPI_COMMAND;
hardware->sendCommand(cmd);
int HIP9011::sendCommand(uint8_t cmd) {
return hw->sendSyncCommand(cmd, NULL);
}
/**
* @return frequency band we are interested in
*/
float getHIP9011Band(DEFINE_HIP_PARAMS) {
float HIP9011::getBand(DEFINE_HIP_PARAMS) {
return GET_CONFIG_VALUE(knockBandCustom) == 0 ?
BAND(GET_CONFIG_VALUE(cylinderBore)) : GET_CONFIG_VALUE(knockBandCustom);
HIP9011_BAND(GET_CONFIG_VALUE(cylinderBore)) :
GET_CONFIG_VALUE(knockBandCustom);
}
int getBandIndex(DEFINE_HIP_PARAMS) {
float freq = getHIP9011Band(FORWARD_HIP_PARAMS);
return getHip9011BandIndex(freq);
int HIP9011::getBandIndex(DEFINE_HIP_PARAMS) {
float freq = getBand(FORWARD_HIP_PARAMS);
int i = findIndexMsg("freq", bandFreqLookup, BAND_LOOKUP_SIZE, freq);
if (i < 0)
i = 0;
if (i > BAND_LOOKUP_SIZE - 1)
i = BAND_LOOKUP_SIZE - 1;
return i;
}
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 HIP9011::getGainIndex(DEFINE_HIP_PARAMS) {
int i = findIndexMsg("fGain", gainLookupInReverseOrder, GAIN_LOOKUP_SIZE, GET_CONFIG_VALUE(hip9011Gain));
if (i < 0)
i = 0;
if (i > GAIN_LOOKUP_SIZE - 1)
i = GAIN_LOOKUP_SIZE - 1;
/* reverse order */
return 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;
/**
* 'TC is typically TINT/(2*Pi*VOUT)'
* Knock Sensor Training TPIC8101, page 24
*/
float HIP9011::getRpmByAngleWindowAndTimeUs(int timeUs, float angleWindowWidth) {
/**
* TINT = TC * 2 * PI * VOUT
*/
float integrationTimeUs = timeUs * 2 * PIF * DESIRED_OUTPUT_VALUE;
/**
* rpm = 60 seconds / time
* '60000000' because revolutions per MINUTE in uS conversion
*/
float windowWidthMult = angleWindowWidth / 360.0f;
return 60000000.0f / integrationTimeUs * windowWidthMult;
}
/**
*
* We know the set of possible integration times, we know the knock detection window width
*/
void HIP9011::prepareHip9011RpmLookup(float angleWindowWidth) {
void HIP9011::prepareRpmLookup(void) {
/**
* out binary search method needs increasing order thus the reverse order here
*/
@ -63,44 +136,50 @@ int HIP9011::getIntegrationIndexByRpm(float rpm) {
}
void HIP9011::setAngleWindowWidth(DEFINE_HIP_PARAMS) {
float angleWindowWidth = GET_CONFIG_VALUE(knockDetectionWindowEnd) - GET_CONFIG_VALUE(knockDetectionWindowStart);
if (angleWindowWidth < 0) {
float new_angleWindowWidth =
GET_CONFIG_VALUE(knockDetectionWindowEnd) -
GET_CONFIG_VALUE(knockDetectionWindowStart);
if (new_angleWindowWidth < 0) {
#if EFI_PROD_CODE
warning(CUSTOM_KNOCK_WINDOW, "invalid knock window");
#endif
angleWindowWidth = 0;
new_angleWindowWidth = 0;
}
// float '==' is totally appropriate here
if (this->angleWindowWidth == angleWindowWidth)
if (angleWindowWidth == new_angleWindowWidth)
return; // exit if value has not change
this->angleWindowWidth = angleWindowWidth;
prepareHip9011RpmLookup(angleWindowWidth);
angleWindowWidth = new_angleWindowWidth;
prepareRpmLookup();
}
void HIP9011::handleValue(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS)) {
void HIP9011::handleSettings(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS)) {
int ret;
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);
int new_prescaler = GET_CONFIG_VALUE(hip9011PrescalerAndSDO);
int new_integratorIdx = getIntegrationIndexByRpm(rpm);
int new_gainIdx = getGainIndex(FORWARD_HIP_PARAMS);
int new_bandIdx = 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;
if (gainIdx != new_gainIdx) {
ret = sendCommand(SET_GAIN_CMD(new_gainIdx));
if (ret == 0)
gainIdx = new_gainIdx;
}
if (intergratorIdx != new_integratorIdx) {
ret = sendCommand(SET_INTEGRATOR_CMD(new_integratorIdx));
if (ret == 0)
intergratorIdx = new_integratorIdx;
}
if (bandIdx != new_bandIdx) {
ret = sendCommand(SET_BAND_PASS_CMD(new_bandIdx));
if (ret == 0)
bandIdx = new_bandIdx;
}
if (prescaler != new_prescaler) {
ret = sendCommand(SET_PRESCALER_CMD(new_prescaler));
if (ret == 0)
prescaler = new_prescaler;
}
}

View File

@ -9,17 +9,20 @@
#include "efifeatures.h"
#include "rusefi_enums.h"
#include "hip9011_lookup.h"
#define BAND(bore) (900 / (PIF * (bore) / 2))
#define PIF 3.14159f
#define HIP9011_BAND(bore) (900 / (PIF * (bore) / 2))
#define INT_LOOKUP_SIZE 32
#define GAIN_LOOKUP_SIZE 64
#define BAND_LOOKUP_SIZE 64
/**
* this interface defines hardware communication layer for HIP9011 chip
*/
class Hip9011HardwareInterface {
public:
virtual void sendSyncCommand(unsigned char command) = 0;
virtual void sendCommand(unsigned char command) = 0;
virtual int sendSyncCommand(unsigned char command, uint8_t *rx_ptr) = 0;
};
#if EFI_PROD_CODE || EFI_SIMULATOR
@ -59,26 +62,31 @@ public:
class HIP9011 {
public:
explicit HIP9011(Hip9011HardwareInterface *hardware);
void prepareHip9011RpmLookup(float angleWindowWidth);
int getIntegrationIndexByRpm(float rpm);
void setStateAndCommand(unsigned char cmd);
void setAngleWindowWidth(DEFINE_HIP_PARAMS);
void handleValue(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS));
int sendCommand(uint8_t cmd);
float getRpmByAngleWindowAndTimeUs(int timeUs, float angleWindowWidth);
void prepareRpmLookup(void);
void setAngleWindowWidth(DEFINE_HIP_PARAMS);
void handleSettings(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS));
float getBand(DEFINE_HIP_PARAMS);
int getIntegrationIndexByRpm(float rpm);
int getBandIndex(DEFINE_HIP_PARAMS);
int getGainIndex(DEFINE_HIP_PARAMS);
/* Settings loaded to chip */
uint8_t intergratorIdx = 0xff;
uint8_t bandIdx = 0xff;
uint8_t prescaler = 0xff;
uint8_t gainIdx = 0xff;
uint8_t channelIdx = 0xff;
/**
* band index is only send to HIP chip on startup
*/
int currentBandIndex = 0;
int currentGainIndex = -1;
int correctResponsesCount = 0;
int invalidHip9011ResponsesCount = 0;
int invalidResponsesCount = 0;
float angleWindowWidth = - 1;
int currentIntergratorIndex = -1;
bool needToInit = true;
int totalKnockEventsCount = 0;
int currentPrescaler = 0;
Hip9011HardwareInterface *hardware;
Hip9011HardwareInterface *hw;
bool adv_mode = false;
/**
* Int/Hold pin is controlled from scheduler call-backs which are set according to current RPM
*
@ -91,6 +99,7 @@ public:
*/
hip_state_e state;
uint8_t cylinderNumber;
int raw_value;
/* error counters */
int overrun = 0;
@ -98,10 +107,6 @@ public:
float rpmLookup[INT_LOOKUP_SIZE];
};
float getHIP9011Band(DEFINE_HIP_PARAMS);
int getBandIndex(DEFINE_HIP_PARAMS);
int getHip9011GainIndex(DEFINE_HIP_PARAMS);
// 0b010x.xxxx
#define SET_PRESCALER_CMD(v) (0x40 | ((v) & 0x1f))
// 0b1110.000x

View File

@ -38,8 +38,11 @@ typedef uint16_t adcsample_t;
#define spiExchange(x,y,w,z) {}
#define spiExchangeI(x,y,w,z) {}
#define spiStartExchangeI(x,y,w,z) {}
#define spiStartExchange(x,y,w,z) {}
#define spiUnselect(x) {}
#define spiUnselectI(x) {}
#define spiAcquireBus(x) {}
#define spiReleaseBus(x) {}
// end of mock SPI
#ifdef __cplusplus

View File

@ -5,30 +5,33 @@
*/
#include "unit_test_framework.h"
#include "hip9011_lookup.h"
#include "hip9011_logic.h"
#include "test_parameters.h"
using ::testing::_;
TEST(hip9011, lookup) {
assertEqualsM2("", 3183.1013, getRpmByAngleWindowAndTimeUs(600, 360), 0.1);
assertEqualsM2("40us", 47746.5195, getRpmByAngleWindowAndTimeUs(40, 360), 0.1);
HIP9011 instance(NULL);
assertEqualsM2("600us 50 degree", 442.0974, getRpmByAngleWindowAndTimeUs(600, 50), 0.1);
assertEqualsM2("240us 50 degree", 1105.2435, getRpmByAngleWindowAndTimeUs(240, 50), 0.1);
assertEqualsM2("240us 50 degree", 6631.4619, getRpmByAngleWindowAndTimeUs(40, 50), 0.1);
assertEqualsM2("", 3183.1013, instance.getRpmByAngleWindowAndTimeUs(600, 360), 0.1);
assertEqualsM2("40us", 47746.5195, instance.getRpmByAngleWindowAndTimeUs(40, 360), 0.1);
EXPECT_EQ(0, getHip9011GainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/3, 0, NAN, NAN));
EXPECT_EQ(0, getHip9011GainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/2, 0, NAN, NAN));
EXPECT_EQ(47, getHip9011GainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/0.234, 0, NAN, NAN));
EXPECT_EQ(63, getHip9011GainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/0.000001, 0, NAN, NAN));
assertEqualsM2("600us 50 degree", 442.0974, instance.getRpmByAngleWindowAndTimeUs(600, 50), 0.1);
assertEqualsM2("240us 50 degree", 1105.2435, instance.getRpmByAngleWindowAndTimeUs(240, 50), 0.1);
assertEqualsM2("240us 50 degree", 6631.4619, instance.getRpmByAngleWindowAndTimeUs(40, 50), 0.1);
EXPECT_EQ(0, instance.getGainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/3, 0, NAN, NAN));
EXPECT_EQ(0, instance.getGainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/2, 0, NAN, NAN));
EXPECT_EQ(47, instance.getGainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/0.234, 0, NAN, NAN));
EXPECT_EQ(63, instance.getGainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/0.000001, 0, NAN, NAN));
EXPECT_EQ(63, instance.getGainIndex(/* knockBandCustom*/NAN, /*cylinderBore*/NAN, /*hip9011Gain*/-1.0, 0, NAN, NAN));
}
TEST(hip9011, rpmLookup) {
HIP9011 instance(NULL);
instance.prepareHip9011RpmLookup(50);
instance.angleWindowWidth = 50.0;
instance.prepareRpmLookup();
EXPECT_EQ(31, instance.getIntegrationIndexByRpm(1));
EXPECT_EQ(21, instance.getIntegrationIndexByRpm(1100));
@ -37,11 +40,12 @@ TEST(hip9011, rpmLookup) {
}
TEST(hip9011, band) {
HIP9011 instance(NULL);
EXPECT_FLOAT_EQ(3, getHIP9011Band(/* knockBandCustom*/3, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_FLOAT_EQ(7.5389242, getHIP9011Band(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_FLOAT_EQ(3, instance.getBand(/* knockBandCustom*/3, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_FLOAT_EQ(7.5389242, instance.getBand(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_EQ(42, getBandIndex(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_EQ(42, instance.getBandIndex(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
}
@ -50,8 +54,7 @@ class MockHip9011Hardware : public Hip9011HardwareInterface
public:
MockHip9011Hardware() { }
MOCK_METHOD1(sendSyncCommand, void(unsigned char));
MOCK_METHOD1(sendCommand, void(unsigned char));
MOCK_METHOD2(sendSyncCommand, int(unsigned char, unsigned char *));
};
TEST(hip9011, configurationCommands) {
@ -64,24 +67,13 @@ TEST(hip9011, configurationCommands) {
#define PARAMETERS 600, /* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/1, HIP_8MHZ_PRESCALER, 0.0, 50.0
// Not making assumptions on the message send ...
EXPECT_CALL(mock, sendSyncCommand(_)).Times(0);
EXPECT_CALL(mock, sendCommand(SET_GAIN_CMD(0xE))).Times(1);
instance.handleValue(PARAMETERS);
EXPECT_CALL(mock, sendSyncCommand(_)).Times(0);
EXPECT_CALL(mock, sendCommand(SET_INTEGRATOR_CMD(0x1C))).Times(1);
instance.handleValue(PARAMETERS);
EXPECT_CALL(mock, sendSyncCommand(_)).Times(0);
EXPECT_CALL(mock, sendCommand(SET_BAND_PASS_CMD(0x2A))).Times(1);
instance.handleValue(PARAMETERS);
EXPECT_CALL(mock, sendSyncCommand(_)).Times(0);
EXPECT_CALL(mock, sendCommand(SET_PRESCALER_CMD(6))).Times(1);
instance.handleValue(PARAMETERS);
EXPECT_CALL(mock, sendSyncCommand(SET_GAIN_CMD(0xE), 0)).Times(1);
EXPECT_CALL(mock, sendSyncCommand(SET_INTEGRATOR_CMD(0x1C), 0)).Times(1);
EXPECT_CALL(mock, sendSyncCommand(SET_BAND_PASS_CMD(0x2A), 0)).Times(1);
EXPECT_CALL(mock, sendSyncCommand(SET_PRESCALER_CMD(6), 0)).Times(1);
instance.handleSettings(PARAMETERS);
// initialization is over, no commands should be sent
EXPECT_CALL(mock, sendSyncCommand(_)).Times(0);
EXPECT_CALL(mock, sendCommand(_)).Times(0);
instance.handleValue(PARAMETERS);
EXPECT_CALL(mock, sendSyncCommand(_, _)).Times(0);
instance.handleSettings(PARAMETERS);
}