diff --git a/firmware/config/engines/bmw_m73.cpp b/firmware/config/engines/bmw_m73.cpp index 59f03cbeed..93a2e5328a 100644 --- a/firmware/config/engines/bmw_m73.cpp +++ b/firmware/config/engines/bmw_m73.cpp @@ -110,7 +110,6 @@ void m73engine(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->cranking.baseFuel = 30; engineConfiguration->cylinderBore = 85.0; - engineConfiguration->knockBandCustom = BAND(engineConfiguration->cylinderBore); } diff --git a/firmware/config/engines/mazda_miata_vvt.cpp b/firmware/config/engines/mazda_miata_vvt.cpp index a2cac2119e..bcb4d65b25 100644 --- a/firmware/config/engines/mazda_miata_vvt.cpp +++ b/firmware/config/engines/mazda_miata_vvt.cpp @@ -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 diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 14ae9b79f9..0e6663dcc1 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -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 diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index eeaf33c58e..05c0681d3c 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -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); diff --git a/firmware/controllers/sensors/hip9011_lookup.cpp b/firmware/controllers/sensors/hip9011_lookup.cpp deleted file mode 100644 index 49c3a9bed5..0000000000 --- a/firmware/controllers/sensors/hip9011_lookup.cpp +++ /dev/null @@ -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 - -} diff --git a/firmware/controllers/sensors/hip9011_lookup.h b/firmware/controllers/sensors/hip9011_lookup.h deleted file mode 100644 index 538bcc067e..0000000000 --- a/firmware/controllers/sensors/hip9011_lookup.h +++ /dev/null @@ -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); - diff --git a/firmware/controllers/sensors/sensors.mk b/firmware/controllers/sensors/sensors.mk index 45d4898b2c..2286c353d0 100644 --- a/firmware/controllers/sensors/sensors.mk +++ b/firmware/controllers/sensors/sensors.mk @@ -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 \ diff --git a/firmware/hw_layer/sensors/hip9011.cpp b/firmware/hw_layer/sensors/hip9011.cpp index 693bb29078..7498001296 100644 --- a/firmware/hw_layer/sensors/hip9011.cpp +++ b/firmware/hw_layer/sensors/hip9011.cpp @@ -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 */ diff --git a/firmware/hw_layer/sensors/hip9011.h b/firmware/hw_layer/sensors/hip9011.h index 5c1277b14d..e653637472 100644 --- a/firmware/hw_layer/sensors/hip9011.h +++ b/firmware/hw_layer/sensors/hip9011.h @@ -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); diff --git a/firmware/hw_layer/sensors/hip9011_logic.cpp b/firmware/hw_layer/sensors/hip9011_logic.cpp index cce9ee1a9f..6e8412aa27 100644 --- a/firmware/hw_layer/sensors/hip9011_logic.cpp +++ b/firmware/hw_layer/sensors/hip9011_logic.cpp @@ -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; } - } diff --git a/firmware/hw_layer/sensors/hip9011_logic.h b/firmware/hw_layer/sensors/hip9011_logic.h index f4421ea9d9..c5a6c4b295 100644 --- a/firmware/hw_layer/sensors/hip9011_logic.h +++ b/firmware/hw_layer/sensors/hip9011_logic.h @@ -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 diff --git a/simulator/simulator/boards.h b/simulator/simulator/boards.h index 90ddbb02d3..53e1635947 100644 --- a/simulator/simulator/boards.h +++ b/simulator/simulator/boards.h @@ -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 diff --git a/unit_tests/tests/test_hip9011.cpp b/unit_tests/tests/test_hip9011.cpp index eb5ec55cd6..ac14c7f91c 100644 --- a/unit_tests/tests/test_hip9011.cpp +++ b/unit_tests/tests/test_hip9011.cpp @@ -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); }