This commit is contained in:
Matthew Kennedy 2023-02-20 22:29:48 -08:00
parent fd09ad7b4f
commit 666a41e496
29 changed files with 0 additions and 1649 deletions

View File

@ -3,7 +3,6 @@
*/
#include "pch.h"
#include "hip9011_logic.h"
#include "chconf_common.h"
/**
@ -26,39 +25,6 @@ static void setCanFrankensoDefaults() {
engineConfiguration->canRxPin = Gpio::B12;
}
static void setHip9011FrankensoPinout() {
/**
* SPI on PB13/14/15
*/
// engineConfiguration->hip9011CsPin = Gpio::D0; // rev 0.1
engineConfiguration->isHip9011Enabled = true;
engineConfiguration->hip9011PrescalerAndSDO = HIP_8MHZ_PRESCALER; // 8MHz chip
engineConfiguration->is_enabled_spi_2 = true;
// todo: convert this to rusEfi, hardware-independent enum
#if EFI_PROD_CODE
#ifdef EFI_HIP_CS_PIN
engineConfiguration->hip9011CsPin = EFI_HIP_CS_PIN;
#else
engineConfiguration->hip9011CsPin = Gpio::B0; // rev 0.4
#endif
engineConfiguration->hip9011CsPinMode = OM_OPENDRAIN;
engineConfiguration->hip9011IntHoldPin = Gpio::B11;
engineConfiguration->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;
if (!engineConfiguration->useTpicAdvancedMode) {
engineConfiguration->hipOutputChannel = EFI_ADC_10; // PC0
}
}
/**
* @brief Hardware board-specific default configuration (GPIO pins, ADC channels, SPI configs etc.)
*/
@ -66,10 +32,6 @@ void setBoardDefaultConfiguration() {
setDefaultFrankensoStepperIdleParameters();
setCanFrankensoDefaults();
#if EFI_HIP_9011
setHip9011FrankensoPinout();
#endif /* EFI_HIP_9011 */
// set optional subsystem configs
#if EFI_MEMS
// this would override some values from above

View File

@ -194,14 +194,6 @@ void setBoardDefaultConfiguration() {
engineConfiguration->spi3sckPin = Gpio::C10;
engineConfiguration->spi3SckMode = PO_OPENDRAIN; // 4
engineConfiguration->hip9011SpiDevice = SPI_DEVICE_3;
engineConfiguration->hip9011CsPin = is469 ? Gpio::D1 : Gpio::D2;
engineConfiguration->hip9011CsPinMode = OM_OPENDRAIN;
engineConfiguration->hip9011IntHoldPin = Gpio::C14;
engineConfiguration->hip9011IntHoldPinMode = OM_OPENDRAIN;
engineConfiguration->hipOutputChannel = EFI_ADC_10; // PC0
engineConfiguration->isHip9011Enabled = true;
engineConfiguration->canTxPin = Gpio::B9;
engineConfiguration->canRxPin = Gpio::B8;

View File

@ -169,20 +169,6 @@ void setBoardDefaultConfiguration() {
/* TODO: add settings for SPI4 */
/* Knock sensor */
/* Interface settings */
engineConfiguration->hip9011SpiDevice = SPI_DEVICE_4;
engineConfiguration->hip9011CsPin = Gpio::E11; /* SPI4_NSS1 */
engineConfiguration->hip9011CsPinMode = OM_OPENDRAIN;
engineConfiguration->hip9011IntHoldPin = Gpio::H8;
engineConfiguration->hip9011IntHoldPinMode = OM_OPENDRAIN;
engineConfiguration->hipOutputChannel = EFI_ADC_7; /* PA7 */
engineConfiguration->isHip9011Enabled = true;
/* this board has TPIC8101, that supports advanced mode */
engineConfiguration->useTpicAdvancedMode = true;
/* Chip settings */
engineConfiguration->hip9011PrescalerAndSDO = (0x6 << 1); //HIP_16MHZ_PRESCALER;
engineConfiguration->hip9011Gain = 1.0;
engineConfiguration->knockBandCustom = 0.0;
engineConfiguration->cylinderBore = 96.9;
/* Cylinder to knock bank mapping */

View File

@ -1,6 +1,5 @@
!TODO: understand this.
#define ts_show_hip9011 true
#define ts_show_egt false
#define ts_show_etb_pins true
#define ts_show_analog_divider false

View File

@ -76,7 +76,6 @@
#include "bmw_m73.h"
#include "custom_engine.h"
#include "hip9011_logic.h"
#if EFI_ELECTRONIC_THROTTLE_BODY
#include "electronic_throttle.h"

View File

@ -394,7 +394,6 @@ void setTle8888TestConfiguration() {
engineConfiguration->etbIo[0].disablePin = Gpio::F12;
#endif /* STM32_HAS_GPIOF */
engineConfiguration->etb_use_two_wires = true;
engineConfiguration->isHip9011Enabled = false;
// ETB #2
// DIS PE5

View File

@ -244,8 +244,6 @@ void setDodgeNeonNGCEngineConfiguration() {
engineConfiguration->map.sensor.type = MT_DODGE_NEON_2003;
engineConfiguration->hip9011Gain = 0.3;
engineConfiguration->cylinderBore = 87.5;
engineConfiguration->clutchDownPin = Gpio::C12;

View File

@ -258,9 +258,6 @@ void setMiataNA6_MAP_Frankenso() {
setFrankensoConfiguration();
miataNAcommonEngineSettings();
engineConfiguration->isHip9011Enabled = false;
// Frankenso middle plug 2J, W32 top <> W47 bottom "#5 Green" jumper, not OEM
engineConfiguration->map.sensor.hwChannel = EFI_ADC_4;

View File

@ -51,7 +51,6 @@
#include "mazda_miata_vvt.h"
#include "custom_engine.h"
#include "mazda_miata_base_maps.h"
#include "hip9011_logic.h"
#if HW_PROTEUS

View File

@ -26,7 +26,6 @@
#include "pch.h"
#include "status_loop.h"
#include "hip9011_logic.h"
#if EFI_LOGIC_ANALYZER
#include "logic_analyzer.h"
@ -163,7 +162,6 @@ static void printEngineSnifferPinMappings() {
extern const char *vvtNames[];
printOutPin(vvtNames[i], engineConfiguration->camInputs[i]);
}
printOutPin(PROTOCOL_HIP_NAME, engineConfiguration->hip9011IntHoldPin);
printOutPin(PROTOCOL_TACH_NAME, engineConfiguration->tachOutputPin);
#if EFI_LOGIC_ANALYZER
printOutPin(PROTOCOL_WA_CHANNEL_1, engineConfiguration->logicAnalyzerPins[0]);
@ -382,11 +380,6 @@ static CommunicationBlinkingTask communicationsBlinkingTask;
#endif /* EFI_PROD_CODE */
#if EFI_HIP_9011
extern HIP9011 instance;
#endif /* EFI_HIP_9011 */
#if EFI_TUNER_STUDIO
static void updateTempSensors() {

View File

@ -63,7 +63,6 @@ enum class PE : uint8_t {
Temporary4,
EngineSniffer,
PrepareIgnitionSchedule,
Hip9011IntHoldCallback,
GlobalLock,
GlobalUnlock,
SoftwareKnockProcess,

View File

@ -436,8 +436,6 @@ static void configureInputs() {
addChannel("MAP", engineConfiguration->map.sensor.hwChannel, ADC_FAST);
addChannel("HIP9011", engineConfiguration->hipOutputChannel, ADC_FAST);
// not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
addChannel("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel, ADC_FAST);

View File

@ -37,7 +37,6 @@
#include "AdcConfiguration.h"
#include "idle_hardware.h"
#include "mcp3208.h"
#include "hip9011.h"
#include "histogram.h"
#include "sent.h"
#include "cdm_ion_sense.h"
@ -135,7 +134,6 @@ SPIDriver * getSpiDevice(spi_device_e spiDevice) {
#if HAL_USE_ADC
static FastAdcToken fastMapSampleIndex;
static FastAdcToken hipSampleIndex;
#if HAL_TRIGGER_USE_ADC
static FastAdcToken triggerSampleIndex;
@ -185,18 +183,12 @@ void onFastAdcComplete(adcsample_t*) {
#if EFI_MAP_AVERAGING
mapAveragingAdcCallback(adcToVoltsDivided(getFastAdc(fastMapSampleIndex), engineConfiguration->map.sensor.hwChannel));
#endif /* EFI_MAP_AVERAGING */
#if EFI_HIP_9011
if (engineConfiguration->isHip9011Enabled) {
hipAdcCallback(adcToVoltsDivided(getFastAdc(hipSampleIndex), engineConfiguration->hipOutputChannel));
}
#endif /* EFI_HIP_9011 */
}
#endif /* HAL_USE_ADC */
static void calcFastAdcIndexes() {
#if HAL_USE_ADC
fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
#if HAL_TRIGGER_USE_ADC
triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
#endif /* HAL_TRIGGER_USE_ADC */
@ -536,10 +528,6 @@ void initHardware() {
turnOnTriggerInputPins();
#endif /* EFI_SHAFT_POSITION_INPUT */
#if EFI_HIP_9011
initHip9011();
#endif /* EFI_HIP_9011 */
#if EFI_MEMS
initAccelerometer();
#endif

View File

@ -21,8 +21,6 @@ HW_LAYER_EMS_CPP = \
$(PROJECT_DIR)/hw_layer/adc/adc_inputs.cpp \
$(PROJECT_DIR)/hw_layer/adc/adc_subscription.cpp \
$(PROJECT_DIR)/hw_layer/adc/ads1015.cpp \
$(PROJECT_DIR)/hw_layer/sensors/hip9011.cpp \
$(PROJECT_DIR)/hw_layer/sensors/hip9011_logic.cpp \
$(PROJECT_DIR)/hw_layer/mc33816.cpp \
$(PROJECT_DIR)/hw_layer/stepper.cpp \
$(PROJECT_DIR)/hw_layer/stepper_dual_hbridge.cpp \

View File

@ -1,680 +0,0 @@
/**
* @file HIP9011.cpp
* @brief HIP9011/TPIC8101 driver
*
* Jan 2017 status:
* 1) seems to be kind of working - reacts to parameter changes and does produce variable output
* 2) only one (first) channel is currently used
* 3) engine control does not yet react to knock since very little actual testing - no engine runs with proven knock yet
*
*
* http://rusefi.com/forum/viewtopic.php?f=4&t=400
* http://rusefi.com/forum/viewtopic.php?f=5&t=778
*
* pin1 VDD
* pin2 GND
*
* pin8 Chip Select - CS
* pin11 Slave Data Out - MISO
* pin12 Slave Data In - MOSI
* pin13 SPI clock - SCLK
*
*
* http://www.ti.com/lit/ds/symlink/tpic8101.pdf
* http://www.intersil.com/content/dam/Intersil/documents/hip9/hip9011.pdf
* http://www.intersil.com/content/dam/Intersil/documents/an97/an9770.pdf
* http://e2e.ti.com/cfs-file/__key/telligent-evolution-components-attachments/00-26-01-00-00-42-36-40/TPIC8101-Training.pdf
*
* max SPI frequency: 5MHz max
*
* @date Nov 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2020
* @Spilly
*/
#include "pch.h"
#include "hardware.h"
#include "trigger_central.h"
#include "hip9011_logic.h"
#include "hip9011.h"
#include "knock_logic.h"
#if EFI_PROD_CODE
#include "mpu_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 {
int sendSyncCommand(uint8_t command, uint8_t *rx_ptr) override;
public:
scheduling_s startTimer;
scheduling_s endTimer;
private:
int checkResponseDefMode(uint8_t tx, uint8_t rx);
int checkResponseAdvMode(uint8_t tx, uint8_t rx);
uint8_t rep_mask;
uint8_t rep_value;
};
/* TODO: include following stuff in object */
/* wake semaphore */
static semaphore_t wake;
static SPIDriver *spi;
static Hip9011Hardware hardware;
HIP9011 instance(&hardware);
#if EFI_HIP_9011_DEBUG
static float normalizedValue[HIP_INPUT_CHANNELS];
static float normalizedValueMax[HIP_INPUT_CHANNELS];
#endif
// SPI_CR1_BR_1 // 5MHz
// SPI_CR1_CPHA Clock Phase
// todo: nicer method which would mention SPI speed explicitly?
#if EFI_PROD_CODE
static SPIConfig hipSpiCfg = {
.circular = false,
.end_cb = NULL,
.ssport = NULL,
.sspad = 0,
.cr1 =
SPI_CR1_8BIT_MODE |
SPI_CR1_MSTR |
SPI_CR1_CPHA |
//SPI_CR1_BR_1 // 5MHz
SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2,
.cr2 =
SPI_CR2_8BIT_MODE
};
#endif /* EFI_PROD_CODE */
/*==========================================================================*/
/* Forward declarations */
/*==========================================================================*/
#if EFI_HIP_9011_DEBUG
static void hip_addconsoleActions();
#endif
/*==========================================================================*/
/* Local functions. */
/*==========================================================================*/
int Hip9011Hardware::checkResponseDefMode(uint8_t tx, uint8_t rx) {
/* in default SPI mode SDO is directly equals the SDI (echo function) */
if (tx == rx) {
return 0;
} else {
return -1;
}
}
int Hip9011Hardware::checkResponseAdvMode(uint8_t tx, uint8_t rx) {
int ret = 0;
/* check reply */
if ((rx & rep_mask) != rep_value)
ret = -1;
/* extract mask and value for next reply */
if ((tx & 0xe0) == SET_PRESCALER_CMD(0)){
/* D7 to D0 of digital integrator output */
rep_mask = 0x00;
rep_value = 0x00;
} else if ((tx & 0xfe) == SET_CHANNEL_CMD(0)) {
/* D9 to D8 of digital integrator output and six zeroes */
rep_mask = 0x3f;
rep_value = 0x00;
} else if ((tx & 0xc0) == SET_BAND_PASS_CMD(0)) {
rep_mask = 0xff;
rep_value = SET_BAND_PASS_REP;
} else if ((tx & 0xc0) == SET_GAIN_CMD(0)) {
rep_mask = 0xff;
rep_value = SET_GAIN_REP;
} else if ((tx & 0xe0) == SET_INTEGRATOR_CMD(0)) {
rep_mask = 0xff;
rep_value = SET_INTEGRATOR_REP;
} else if ((tx & 0xff) == SET_ADVANCED_MODE_CMD) {
rep_mask = 0xff;
rep_value = SET_ADVANCED_MODE_REP;
} else {
/* unknown */
rep_mask = 0x00;
rep_value = 0x00;
}
return ret;
}
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);
/* received data */
if (rx_ptr)
*rx_ptr = rx;
/* check response */
if (instance.adv_mode)
ret = checkResponseAdvMode(tx, rx);
else
ret = checkResponseDefMode(tx, rx);
#if EFI_HIP_9011_DEBUG
/* statistic counters */
if (ret)
instance.invalidResponsesCount++;
else
instance.correctResponsesCount++;
#endif
return ret;
}
static int hip_wake_driver()
{
/* 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);
return 0;
}
static void startIntegration(HIP9011 *hip) {
if (hip->state == READY_TO_INTEGRATE) {
/**
* SPI communication is only allowed while not integrating, so we postpone the exchange
* until we are done integrating
*/
hip->state = IS_INTEGRATING;
intHold.setHigh();
} else {
#if EFI_HIP_9011_DEBUG
hip->overrun++;
#endif
}
}
static void endIntegration(HIP9011 *hip) {
/**
* isIntegrating could be 'false' if an SPI command was pending thus we did not integrate during this
* engine cycle
*/
if (hip->state == IS_INTEGRATING) {
intHold.setLow();
hip->knockSampleTimestamp = getTimeNowNt();
if (instance.adv_mode) {
/* read value over SPI in thread mode */
hip->state = NOT_READY;
hip_wake_driver();
} else {
/* wait for ADC samples */
hip->state = WAITING_FOR_ADC_TO_SKIP;
}
}
}
void onStartKnockSampling(uint8_t /*cylinderIndex*/, float /*samplingTimeSeconds*/, uint8_t /*channelIdx*/) {
/* TODO: @dron0gus: not sure if we need the expectedCylinderNumber logic at all
Something like this might be right:
startIntegration(&instance);
efitick_t windowLength = USF2NT(1e6 * samplingTimeSeconds);
engine->executor.scheduleByTimestampNt("knock", &hardware.endTimer, getTimeNowNt() + windowLength, { endIntegration, &instance });
*/
}
/**
* Ignition callback used to start HIP integration and schedule finish
*/
void hip9011_onFireEvent(uint8_t cylinderNumber, efitick_t nowNt) {
if (!engineConfiguration->isHip9011Enabled)
return;
/* We are not checking here for READY_TO_INTEGRATE state as
* previous integration may be stil in progress, while
* we are scheduling next integration start only
* knockDetectionWindowStart from now.
* Check for correct state will be done at startIntegration () */
if (cylinderNumber == instance.expectedCylinderNumber) {
/* save currect cylinder */
instance.cylinderNumber = cylinderNumber;
/* smart books says we need to sence knock few degrees after TDC
* currently I have no idea how to hook to cylinder TDC in correct way.
* So schedule start of integration + knockDetectionWindowStart from fire event
* Keep this is mind when setting knockDetectionWindowStart */
scheduleByAngle(&hardware.startTimer, nowNt,
engineConfiguration->knockDetectionWindowStart,
{ startIntegration, &instance });
scheduleByAngle(&hardware.endTimer, nowNt,
engineConfiguration->knockDetectionWindowEnd,
{ endIntegration, &instance });
} else {
#if EFI_HIP_9011_DEBUG
/* out of sync */
if (instance.expectedCylinderNumber >= 0)
instance.unsync++;
#endif
/* save currect cylinder */
instance.cylinderNumber = cylinderNumber;
/* Skip integration, call driver task to prepare for next cylinder */
instance.state = NOT_READY;
hip_wake_driver();
}
}
void hipAdcCallback(float volts) {
/* we read in digital mode */
if (instance.adv_mode)
return;
if (instance.state == WAITING_FOR_ADC_TO_SKIP) {
instance.state = WAITING_FOR_RESULT_ADC;
} else if (instance.state == WAITING_FOR_RESULT_ADC) {
/* offload calculations to driver thread */
if (instance.channelIdx < HIP_INPUT_CHANNELS) {
/* normalize to 0..HIP9011_DIGITAL_OUTPUT_MAX */
instance.rawValue[instance.channelIdx] =
volts * HIP9011_DIGITAL_OUTPUT_MAX / HIP9011_ANALOG_OUTPUT_MAX;
}
instance.state = NOT_READY;
hip_wake_driver();
}
}
static int hip_testAdvMode() {
int ret;
uint8_t ret0, ret1, ret2;
/* do not care about configuration values, we meed replyes only.
* correct values will be uploaded later */
/* A control byte is written to the SDI and shifted with the MSB
* first. The response byte on the SDO is shifted out with the MSB
* first. The response byte corresponds to the previous command.
* Therefore, the SDI shifts in a control byte n and shifts out a
* response command byte n 1. */
ret = instance.hw->sendSyncCommand(SET_BAND_PASS_CMD(0), NULL);
if (ret)
return ret;
ret = instance.hw->sendSyncCommand(SET_GAIN_CMD(0), &ret0);
if (ret)
return ret;
ret = instance.hw->sendSyncCommand(SET_INTEGRATOR_CMD(0), &ret1);
if (ret)
return ret;
ret = instance.hw->sendSyncCommand(SET_INTEGRATOR_CMD(0), &ret2);
if (ret)
return ret;
/* magic reply bytes from DS Table 2 */
if ((ret0 == SET_BAND_PASS_REP) &&
(ret1 == SET_GAIN_REP) &&
(ret2 == SET_INTEGRATOR_REP))
return 0;
return -1;
}
static int hip_init() {
int ret;
ret = instance.hw->sendSyncCommand(SET_PRESCALER_CMD(instance.prescaler), NULL);
if (ret) {
/* NOTE: hip9011/tpic8101 can be in default or advansed mode at this point
* If we supposed not to support advanced mode this is definitely error */
if (!engineConfiguration->useTpicAdvancedMode)
return ret;
}
/* ...othervice or when no error is reported lets try to switch to advanced mode */
if (engineConfiguration->useTpicAdvancedMode) {
/* enable advanced mode */
ret = instance.hw->sendSyncCommand(SET_ADVANCED_MODE_CMD, NULL);
if (ret) {
uint8_t rx;
/* communication error is detected for default mode...
* may be we are in advanced mode already?
* Now we dont care for return value */
instance.hw->sendSyncCommand(SET_ADVANCED_MODE_CMD, &rx);
if (rx != SET_ADVANCED_MODE_REP) {
/* this is realy a communication problem */
return ret;
}
}
/* now we should be in advanced mode... if chip supports...
* set advanced mode flag now so checkResponse will switch to
* advanced mode checkig (not implemented) */
instance.adv_mode = true;
ret = hip_testAdvMode();
if (ret) {
warning(CUSTOM_OBD_KNOCK_PROCESSOR, "TPIC/HIP does not support advanced mode");
instance.adv_mode = false;
}
}
#if EFI_HIP_9011_DEBUG
/* reset error counter now */
instance.invalidResponsesCount = 0;
#endif
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 worker");
/* This strange code was here before me.
* Not sure why we need it */
#if 0
/* 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);
chThdSleepMilliseconds(100);
#endif
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(Sensor::getOrZero(SensorType::Rpm) DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));
/* in advanced more driver will set channel while reading integrator value */
if (!instance.adv_mode) {
/* switch input channel */
instance.handleChannel(DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));
}
/* State */
instance.state = READY_TO_INTEGRATE;
msg = chSemWaitTimeout(&wake, TIME_INFINITE);
if (msg == MSG_TIMEOUT) {
/* ??? */
} else {
int rawValue;
/* check now, before readValueAndHandleChannel did not overwrite expectedCylinderNumber */
bool correctCylinder = (instance.cylinderNumber == instance.expectedCylinderNumber);
/* this needs to be called in any case to set proper channel for next cycle */
if (instance.adv_mode) {
rawValue = instance.readValueAndHandleChannel(DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));
/* spi communication issue? */
if (rawValue < 0)
continue;
}
/* check that we know channel for current measurement */
int idx = instance.channelIdx;
if (!(idx < HIP_INPUT_CHANNELS))
continue;
float knockNormalized = 0.0f;
float knockVolts = 0.0f;
/* calculations */
if (instance.adv_mode) {
instance.rawValue[idx] = rawValue;
} else {
/* get value stored by callback */
rawValue = instance.rawValue[idx];
}
/* convert 10 bit integer value to 0.0 .. 1.0 float */
knockNormalized = ((float)rawValue) / HIP9011_DIGITAL_OUTPUT_MAX;
/* convert to magic volts
* TODO: remove conversion to volts */
knockVolts = knockNormalized * HIP9011_ANALOG_OUTPUT_MAX;
/* Check for correct cylinder/input */
if (correctCylinder) {
// TODO: convert knock level to dBv
engine->module<KnockController>()->onKnockSenseCompleted(instance.cylinderNumber, knockVolts, instance.knockSampleTimestamp);
#if EFI_HIP_9011_DEBUG
/* debug */
normalizedValue[idx] = knockNormalized;
normalizedValueMax[idx] = maxF(knockNormalized, normalizedValueMax[idx]);
/* counters */
instance.samples++;
#endif
} else {
/* out of sync event already calculated, nothing to do */
}
}
}
return -1;
}
/*==========================================================================*/
/* Exported functions. */
/*==========================================================================*/
void stopHip9001_pins() {
intHold.deInit();
Cs.deInit();
#if EFI_PROD_CODE
hipSpiCfg.ssport = NULL;
#endif
}
void startHip9001_pins() {
intHold.initPin("hip int/hold", engineConfiguration->hip9011IntHoldPin, &engineConfiguration->hip9011IntHoldPinMode);
Cs.initPin("hip CS", engineConfiguration->hip9011CsPin, &engineConfiguration->hip9011CsPinMode);
}
void initHip9011() {
if (!engineConfiguration->isHip9011Enabled)
return;
#if EFI_PROD_CODE
spi = getSpiDevice(engineConfiguration->hip9011SpiDevice);
if (spi == NULL) {
// error already reported
return;
}
hipSpiCfg.ssport = getHwPort("hip", engineConfiguration->hip9011CsPin);
hipSpiCfg.sspad = getHwPin("hip", engineConfiguration->hip9011CsPin);
#endif /* EFI_PROD_CODE */
startHip9001_pins();
/* load settings */
instance.prescaler = engineConfiguration->hip9011PrescalerAndSDO;
efiPrintf("Starting HIP9011/TPIC8101 driver");
/* init semaphore */
chSemObjectInit(&wake, 10);
chThdCreateStatic(hipThreadStack, sizeof(hipThreadStack), PRIO_HIP9011, (tfunc_t)(void*) hipThread, NULL);
#if EFI_HIP_9011_DEBUG
hip_addconsoleActions();
#endif
}
/*==========================================================================*/
/* Debug functions. */
/*==========================================================================*/
#if EFI_HIP_9011_DEBUG
static const char *hip_state_names[] =
{
"Not ready/calculating",
"Ready for integration",
"Integrating",
"Waiting for first ADC sample",
"Waiting for second ADC sample"
};
static void showHipInfo() {
if (!engineConfiguration->isHip9011Enabled) {
efiPrintf("hip9011 driver not active");
return;
}
efiPrintf("HIP9011: enabled %s state %s",
boolToString(engineConfiguration->isHip9011Enabled),
hip_state_names[instance.state]);
efiPrintf(" Advanced mode: enabled %d used %d",
engineConfiguration->useTpicAdvancedMode,
instance.adv_mode);
efiPrintf(" Input Ch %d (cylinder %d next %d)",
instance.channelIdx,
instance.cylinderNumber,
instance.expectedCylinderNumber);
efiPrintf(" Cyl bore %.2fmm freq %.2fkHz band idx 0x%x",
engineConfiguration->cylinderBore,
instance.getBand(PASS_HIP_PARAMS),
instance.bandIdx);
efiPrintf(" Integrator idx 0x%x",
instance.intergratorIdx);
efiPrintf(" Gain %.2f idx 0x%x",
engineConfiguration->hip9011Gain,
instance.gainIdx);
efiPrintf(" PaSDO=0x%x",
instance.prescaler);
efiPrintf(" IntHold %s (mode 0x%x)",
hwPortname(engineConfiguration->hip9011IntHoldPin),
engineConfiguration->hip9011IntHoldPinMode);
efiPrintf(" Spi %s CS %s (mode 0x%x)",
getSpi_device_e(engineConfiguration->hip9011SpiDevice),
hwPortname(engineConfiguration->hip9011CsPin),
engineConfiguration->hip9011CsPinMode);
#if EFI_PROD_CODE
printSpiConfig("hip9011", engineConfiguration->hip9011SpiDevice);
#endif /* EFI_PROD_CODE */
efiPrintf(" SPI: good response %d incorrect response %d",
instance.correctResponsesCount,
instance.invalidResponsesCount);
efiPrintf(" Counters: samples %d overruns %d sync miss %d",
instance.samples, instance.overrun, instance.unsync);
efiPrintf(" Window start %.2f end %.2f",
engineConfiguration->knockDetectionWindowStart,
engineConfiguration->knockDetectionWindowEnd);
if (!instance.adv_mode) {
efiPrintf(" Adc input %s (%.2f V)",
getAdc_channel_e(engineConfiguration->hipOutputChannel),
getVoltage("hipinfo", engineConfiguration->hipOutputChannel));
}
for (int i = 0; i < HIP_INPUT_CHANNELS; i++) {
efiPrintf(" input[%d] %d -> %.3f (max %.3f)",
i,
instance.rawValue[i],
normalizedValue[i],
normalizedValueMax[i]);
normalizedValueMax[i] = 0.0;
}
}
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() {
addConsoleAction("hipinfo", showHipInfo);
addConsoleActionF("set_gain", setHipGain);
addConsoleActionF("set_band", setHipBand);
addConsoleActionI("set_hip_prescalerandsdo", setPrescalerAndSDO);
}
#endif /* EFI_HIP_9011_DEBUG */
#endif /* EFI_HIP_9011 */

View File

@ -1,20 +0,0 @@
/**
* @file hip9011.h
* @brief HIP9011/TPIC8101 driver
*
* @date Nov 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#pragma once
#define HIP_THREAD_PERIOD 100
void initHip9011();
void startHip9001_pins();
void stopHip9001_pins();
#if HAL_USE_ADC
void hipAdcCallback(float volts);
#endif /* HAL_USE_ADC */
void hip9011_onFireEvent(uint8_t cylinderNumber, efitick_t nowNt);

View File

@ -1,256 +0,0 @@
/*
* @file HIP9011_logic.cpp
*
* Created on: Jan 3, 2019
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "pch.h"
/* getCylinderKnockBank */
#include "knock_logic.h"
#include "hip9011_logic.h"
/*==========================================================================*/
/* Local definitions. */
/*==========================================================================*/
/*==========================================================================*/
/* 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 */
/*==========================================================================*/
/*==========================================================================*/
/* Exported. */
/*==========================================================================*/
HIP9011::HIP9011(Hip9011HardwareInterface *hardware) {
this->hw = hardware;
}
int HIP9011::sendCommand(uint8_t cmd) {
return hw->sendSyncCommand(cmd, NULL);
}
int HIP9011::sendCommandGetReply(uint8_t cmd, uint8_t *reply) {
return hw->sendSyncCommand(cmd, reply);
}
/**
* @return frequency band we are interested in
*/
float HIP9011::getBand(DEFINE_HIP_PARAMS) {
return GET_CONFIG_VALUE(knockBandCustom) == 0 ?
HIP9011_BAND(GET_CONFIG_VALUE(cylinderBore)) :
GET_CONFIG_VALUE(knockBandCustom);
}
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 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;
}
/**
* '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 * CONST_PI * HIP9011_ANALOG_OUTPUT_MAX;
/**
* 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::prepareRpmLookup(void) {
/**
* 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 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
new_angleWindowWidth = 0;
}
// float '==' is totally appropriate here
if (angleWindowWidth == new_angleWindowWidth)
return; // exit if value has not change
angleWindowWidth = new_angleWindowWidth;
prepareRpmLookup();
}
void HIP9011::handleSettings(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS)) {
int ret;
setAngleWindowWidth(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 (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;
}
}
int HIP9011::cylinderToChannelIdx(int cylinder) {
/* TODO: hip9011 inputs to bank mapping? */
return getCylinderKnockBank(cylinder);
}
int HIP9011::handleChannel(DEFINE_HIP_PARAMS) {
int ret;
/* we did not receive any callback from spark logic with valid cylinder yet */
if (cylinderNumber < 0)
return -1;
/* find next firing cylinder */
/* MAGIC +1 -1, couse getNextFiringCylinderId expect cylinders to start from 1 */
expectedCylinderNumber = getNextFiringCylinderId((cylinderNumber + 1)) - 1;
int nextChannelIdx = cylinderToChannelIdx(expectedCylinderNumber);
if (nextChannelIdx == channelIdx)
return 0;
ret = sendCommand(SET_CHANNEL_CMD(nextChannelIdx));
if (ret)
return ret;
channelIdx = nextChannelIdx;
return 0;
}
int HIP9011::readValueAndHandleChannel(DEFINE_HIP_PARAMS) {
int ret;
uint8_t rx[2];
/* we did not receive any callback from spark logic with valid cylinder yet */
if (cylinderNumber < 0)
return -1;
/* find next firing cylinder */
/* MAGIC +1 -1, couse getNextFiringCylinderId expect cylinders to start from 1 */
expectedCylinderNumber = getNextFiringCylinderId((cylinderNumber + 1)) - 1;
int nextChannelIdx = cylinderToChannelIdx(expectedCylinderNumber);
/* use cached values, let handleSettings take care of settings update */
/* don't care about rx'ed data now */
ret = sendCommand(SET_PRESCALER_CMD(prescaler));
if (ret)
return ret;
/* reply from Set Prescaler CMD -> D7 to D0 of the digital integrator output */
ret = sendCommandGetReply(SET_CHANNEL_CMD(nextChannelIdx), &rx[0]);
if (ret)
return ret;
/* Same connand to get reply for previous command:
* reply from Select the channel CMD -> D9 to D8 of difital integrator output and six zeroes */
ret = sendCommandGetReply(SET_CHANNEL_CMD(nextChannelIdx), &rx[1]);
if (ret)
return ret;
channelIdx = nextChannelIdx;
/* D9..D8 in high bits */
rx[1] = (rx[1] >> 6) & 0x03;
/* return digital integrator value */
return (rx[0] | (rx[1] << 8));
}

View File

@ -1,182 +0,0 @@
/*
* @file hip9011_logic.h
*
* Created on: Jan 3, 2019
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#pragma once
#include "efifeatures.h"
#include "rusefi_enums.h"
/* enable debug by default */
#ifndef EFI_HIP_9011_DEBUG
#define EFI_HIP_9011_DEBUG EFI_HIP_9011
#endif
#define HIP9011_BAND(bore) (900 / (CONST_PI * (bore) / 2))
#define HIP9011_ANALOG_OUTPUT_MAX 5.0f
#define HIP9011_DIGITAL_OUTPUT_MAX 0x03ff /* 10 bit max value */
#define HIP_INPUT_CHANNELS 2
#define INT_LOOKUP_SIZE 32
#define GAIN_LOOKUP_SIZE 64
#define BAND_LOOKUP_SIZE 64
typedef enum {
/* initial state and state used during value read and calculations */
NOT_READY,
/* chip is configuread and ready for next integration */
READY_TO_INTEGRATE,
/* integration is in progress */
IS_INTEGRATING,
/* in default mode driver is waiting for first ADC callback */
WAITING_FOR_ADC_TO_SKIP,
/* in default mode driver is waiting for second ADC callback, saves it and switched to NOT_READY state */
WAITING_FOR_RESULT_ADC
} hip_state_e;
/**
* this interface defines hardware communication layer for HIP9011 chip
*/
class Hip9011HardwareInterface {
public:
virtual int sendSyncCommand(unsigned char command, uint8_t *rx_ptr) = 0;
};
#if EFI_PROD_CODE || EFI_SIMULATOR
#define PASS_HIP_PARAMS
#define DEFINE_HIP_PARAMS
#define GET_CONFIG_VALUE(x) engineConfiguration->x
#define FORWARD_HIP_PARAMS
#define DEFINE_PARAM_SUFFIX(x)
#else
#define PASS_HIP_PARAMS engineConfiguration->knockBandCustom, \
engineConfiguration->cylinderBore, \
engineConfiguration->hip9011Gain, \
engineConfiguration->hip9011PrescalerAndSDO, \
engineConfiguration->knockDetectionWindowStart, \
engineConfiguration->knockDetectionWindowEnd
#define FORWARD_HIP_PARAMS knockBandCustom, \
cylinderBore, \
hip9011Gain, \
hip9011PrescalerAndSDO, \
knockDetectionWindowStart, \
knockDetectionWindowEnd
#define DEFINE_HIP_PARAMS float knockBandCustom,\
float cylinderBore, \
float hip9011Gain, \
int hip9011PrescalerAndSDO, \
float knockDetectionWindowStart, \
float knockDetectionWindowEnd
#define GET_CONFIG_VALUE(x) x
#define DEFINE_PARAM_SUFFIX(x) , x
#endif
class HIP9011 {
public:
explicit HIP9011(Hip9011HardwareInterface *hardware);
int sendCommand(uint8_t cmd);
int sendCommandGetReply(uint8_t cmd, uint8_t *reply);
float getRpmByAngleWindowAndTimeUs(int timeUs, float angleWindowWidth);
void prepareRpmLookup(void);
void setAngleWindowWidth(DEFINE_HIP_PARAMS);
void handleSettings(int rpm DEFINE_PARAM_SUFFIX(DEFINE_HIP_PARAMS));
int cylinderToChannelIdx(int cylinder);
int handleChannel(DEFINE_HIP_PARAMS);
int readValueAndHandleChannel(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;
float angleWindowWidth = - 1;
Hip9011HardwareInterface *hw;
bool adv_mode = false;
/**
* Int/Hold pin is controlled from scheduler call-backs which are set according to current RPM
*
* The following state makes sure that we only have SPI communication while not integrating and that we take
* a good ADC reading after integrating.
*
* Once integration window is over, we wait for the 2nd ADC callback and then initiate SPI communication if needed
*
* hipOutput should be set to used FAST adc device
*/
hip_state_e state;
int8_t cylinderNumber = -1;
int8_t expectedCylinderNumber = -1;
int rawValue[HIP_INPUT_CHANNELS];
float rpmLookup[INT_LOOKUP_SIZE];
// Timestamp of the last sensed event
efitick_t knockSampleTimestamp = 0;
#if EFI_HIP_9011_DEBUG
/* SPI counters */
int correctResponsesCount = 0;
int invalidResponsesCount = 0;
/* counters */
int samples = 0;
int overrun = 0;
int unsync = 0;
#endif
};
// 0b010x.xxxx
#define SET_PRESCALER_CMD(v) (0x40 | ((v) & 0x1f))
// 0b1110.000x
#define SET_CHANNEL_CMD(v) (0xE0 | ((v) & 0x01))
// 0b00xx.xxxx
#define SET_BAND_PASS_CMD(v) (0x00 | ((v) & 0x3f))
/* magic replyed on SET_BAND_PASS_CMD in advanced mode */
#define SET_BAND_PASS_REP (0x01)
// 0b10xx.xxxx
#define SET_GAIN_CMD(v) (0x80 | ((v) & 0x3f))
/* magic replyed on SET_GAIN_CMD in advanced mode */
#define SET_GAIN_REP (0xe0)
// 0b110x.xxxx
#define SET_INTEGRATOR_CMD(v) (0xC0 | ((v) & 0x1f))
/* magic replyed on SET_INTEGRATOR_CMD in advanced mode */
#define SET_INTEGRATOR_REP (0x71)
// 0b0111.0001
#define SET_ADVANCED_MODE_CMD (0x71)
/* magic replyed on SET_ADVANCED_MODE_CMD in advanced mode */
#define SET_ADVANCED_MODE_REP ((~SET_ADVANCED_MODE_CMD) & 0xff)
// D[4:1] = 0000 : 4 MHz
#define HIP_4MHZ_PRESCALER (0x0 << 1)
// D[4:1] = 0001 : 5 MHz
#define HIP_5MHZ_PRESCALER (0x1 << 1)
// D[4:1] = 0010 : 6 MHz
#define HIP_6MHZ_PRESCALER (0x2 << 1)
// D[4:1] = 0011 ; 8 MHz
#define HIP_8MHZ_PRESCALER (0x3 << 1)
// D[4:1] = 0100 ; 10 MHz
#define HIP_10MHZ_PRESCALER (0x4 << 1)
// D[4:1] = 0101 ; 12 MHz
#define HIP_12MHZ_PRESCALER (0x5 << 1)
// D[4:1] = 0110 : 16 MHz
#define HIP_16MHZ_PRESCALER (0x6 << 1)
// D[4:1] = 0111 : 20 MHz
#define HIP_20MHZ_PRESCALER (0x7 << 1)
// D[4:1] = 1000 : 24 MHz
#define HIP_24MHZ_PRESCALER (0x8 << 1)

View File

@ -493,7 +493,6 @@ ThermistorConf clt;todo: merge with channel settings, use full-scale Thermistor
ThermistorConf iat;
int launchTimingRetard;;"deg", 1, 0, -180, 180, 2
int hip9011PrescalerAndSDO;value '6' for 8MHz hw osc\nread hip9011 datasheet for details\ntodo split into two bit fields;"integer", 1, 0, 0, 32, 0
float knockBandCustom;We calculate knock band based of cylinderBore\n Use this to override - kHz knock band override;"kHz", 1, 0, 0, 20, 2
struct_no_prefix specs_s
@ -588,7 +587,6 @@ trigger_config_s trigger;
float airByRpmTaper;Extra air taper amount;"%", 1, 0, 0, 50, 1
custom spi_device_e 1 bits, U08, @OFFSET@, [0:2], "Off", "SPI1", "SPI2", "SPI3", "SPI4"
spi_device_e hip9011SpiDevice;
uint8_t failedMapFallback;Single value to be used in event of a failed MAP sensor \nThis value is only used for speed density fueling calculations.;"kPa", 1, 0, 0, 100, 0
uint8_t boostControlSafeDutyCycle;Duty cycle to use in case of a sensor failure. This duty cycle should produce the minimum possible amount of boost. This duty is also used in case any of the minimum RPM/TPS/MAP conditions are not met.;"%", 1, 0, 0, 100, 0
adc_channel_e mafAdcChannel
@ -693,7 +691,6 @@ switch_input_pin_e clutchDownPin;Some cars have a switch to indicate that clutch
brain_input_pin_e[TRIGGER_INPUT_PIN_COUNT iterate] triggerInputPins;
uint16_t mc33_t_min_boost;Minimum allowed time for the boost phase. If the boost target current is reached before this time elapses, it is assumed that the injector has failed short circuit.;"us", 1, 0, 0, 10000, 0
pin_output_mode_e hip9011CsPinMode;
output_pin_e tachOutputPin;
pin_output_mode_e tachOutputPinMode;
@ -736,13 +733,11 @@ bit is_enabled_spi_2
bit isSdCardEnabled;enable sd/disable sd
bit rusefiVerbose29b,"29 bit","11 bit";Use 11 bit (standard) or 29 bit (extended) IDs for rusEFI verbose CAN format.
bit isEngineControlEnabled
bit isHip9011Enabled
bit isVerboseAlternator
bit verboseQuad
bit useStepperIdle;This setting should only be used if you have a stepper motor idle valve and a stepper motor driver installed.
bit enabledStep1Limiter
bit useTpicAdvancedMode
bit unused760b12
bit verboseTLE8888
bit enableVerboseCanTx;CAN broadcast using custom rusEFI protocol\nenable can_broadcast/disable can_broadcast
@ -766,9 +761,6 @@ bit is_enabled_spi_2
brain_input_pin_e[LOGIC_ANALYZER_CHANNEL_COUNT iterate] logicAnalyzerPins;
pin_output_mode_e mainRelayPinMode;
Gpio hip9011CsPin;
Gpio hip9011IntHoldPin;
pin_output_mode_e hip9011IntHoldPinMode;
! 536870911 = 2^29-1, the maximum valid extended ID
uint32_t verboseCanBaseAddress;;"", 1, 0, 0, 536870911, 0
@ -1350,8 +1342,6 @@ float tChargeAirDecrLimit;Maximum allowed rate of decrease allowed for the estim
custom tChargeMode_e 1 bits, U08, @OFFSET@, [0:1], @@tChargeMode_e_enum@@
tChargeMode_e tChargeMode;
float hip9011Gain;;"", 1, 0, 0, 100, 2
int16_t etb_iTermMin;iTerm min value;"", 1, 0, -30000, 30000, 0
int16_t etb_iTermMax;iTerm max value;"", 1, 0, -30000, 30000, 0
@ -2033,7 +2023,6 @@ end_struct
#define PROTOCOL_VVT2_NAME "VVT2"
#define PROTOCOL_VVT3_NAME "VVT3"
#define PROTOCOL_VVT4_NAME "VVT4"
#define PROTOCOL_HIP_NAME "HIP"
#define PROTOCOL_TACH_NAME "tach"
#define PROTOCOL_HPFP_NAME "hpfp"
@ -2120,7 +2109,6 @@ end_struct
#define PROTOCOL_INJ1_SHORT_NAME "i1"
! some board files override this value using prepend file
#define ts_show_hip9011 true
#define ts_show_vr_threshold_all true
#define ts_show_vr_threshold_2 true
#define ts_show_main_relay true

View File

@ -1860,7 +1860,6 @@ menuDialog = main
subMenu = fancyHardwareDialog, "Fancy Hardware"
subMenu = std_separator
subMenu = hipFunction, "HIP9011 settings (knock sensor) (alpha version)" @@if_ts_show_hip9011
subMenu = softwareKnock, "Software knock" @@if_ts_show_software_knock
subMenu = maxKnockRetardTbl, "Max knock retard" @@if_ts_show_software_knock
subMenu = std_separator
@ -2783,7 +2782,6 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
field = "SPI3 MOSI", spi3mosiPin, {is_enabled_spi_3 == 1} @@if_ts_show_spi
field = "SPI3 MISO", spi3misoPin, {is_enabled_spi_3 == 1} @@if_ts_show_spi
field = "SPI3 SCK", spi3sckPin, {is_enabled_spi_3 == 1} @@if_ts_show_spi
field = "hip9011CsPin", hip9011CsPin
field = "LIS302DLCsPin", LIS302DLCsPin
field = "Saab CDM knock", cdmInputPin
field = "DRV8860 CS", drv8860_cs
@ -3320,23 +3318,6 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
panel = softwareKnockLeft, West
panel = knockThresholdCurve, Center
; Engine->hip9011 Settings
dialog = hipFunction, "HIP9011 Settings (knock decoder)"
field = "Enabled", isHip9011Enabled
field = "!ECU reboot needed to apply these settings"
field = "IntHold pin (hip9011 input)", hip9011IntHoldPin, {isHip9011Enabled == 1}
field = "IntHold pin (hip9011 input) mode", hip9011IntHoldPinMode, {isHip9011Enabled == 1}
field = "ChipSelect pin", hip9011CsPin, {isHip9011Enabled == 1}
field = "ChipSelect mode", hip9011CsPinMode, {isHip9011Enabled == 1}
field = "hip Output/stm input", hipOutputChannel, {isHip9011Enabled == 1}
field = "prescaler & SDO", hip9011PrescalerAndSDO, {isHip9011Enabled == 1}
field = "knockDetectionWindowStart", knockDetectionWindowStart, {isHip9011Enabled == 1}
field = "knockDetectionWindowEnd", knockDetectionWindowEnd, {isHip9011Enabled == 1}
field = "cylinder bore (mm)", cylinderBore, {isHip9011Enabled == 1}
field = "Band Freq override", knockBandCustom, {isHip9011Enabled == 1}
field = "SPI device", hip9011SpiDevice, {isHip9011Enabled == 1}
panel = knockThresholdCurve
dialog = spiFunction, "SPI settings"
field = "!ECU reboot needed to apply these settings"
field = "SPI1 enable", is_enabled_spi_1

View File

@ -47,7 +47,6 @@ public class EnumNames {
"Temporary4",
"EngineSniffer",
"PrepareIgnitionSchedule",
"Hip9011IntHoldCallback",
"GlobalLock",
"GlobalUnlock",
"SoftwareKnockProcess",

View File

@ -86,9 +86,6 @@ public class SettingsTab {
// panel.add(UiUtils.wrap(new BitConfigField(Fields.ISSDCARDENABLED, "SD card enabled").getContent()));
// panel.add(UiUtils.wrap(new BitConfigField(Fields.USELCDSCREEN, "Use LCD").getContent()));
//
// panel.add(UiUtils.wrap(new EnumConfigField(Fields.HIP9011INTHOLDPIN, "int/hold pin").getContent()));
// panel.add(UiUtils.wrap(new EnumConfigField(Fields.HIP9011INTHOLDPINMODE, "int/hold pin mode").getContent()));
// panel.add(UiUtils.wrap(new ConfigField(Fields.HIP9011GAIN, "k gain").getContent()));
// panel.add(UiUtils.wrap(new ConfigField(Fields.KNOCKDETECTIONWINDOWSTART, "kw start").getContent()));
// panel.add(UiUtils.wrap(new ConfigField(Fields.KNOCKDETECTIONWINDOWEND, "kw end").getContent()));
//

View File

@ -1,4 +0,0 @@
cd ..
rem manually copy find.exe from cygwin to find_cygwin to avoid conflict with systen32/find
find_cygwin . -type f -print0 | xargs -0 dos2unix

View File

@ -1,5 +0,0 @@
find_cygwin . -type f -print0 | xargs -0 dos2unix
git pull
call dos2unix_all.bat
git commit -m "dos2unix nightly"
git push

View File

@ -1,243 +0,0 @@
#include "stm32f4xx.h"
/**
* SPI 2
*
* Chip Select: PD11
*
*
* http://www.ti.com/lit/ds/symlink/tpic8101.pdf
* http://www.intersil.com/content/dam/Intersil/documents/an97/an9770.pdf
* http://e2e.ti.com/cfs-file/__key/telligent-evolution-components-attachments/00-26-01-00-00-42-36-40/TPIC8101-Training.pdf
*
*/
#define NO_DATA 0x0100
#define RX_BUF_SIZE 128
#define TX_BUF_SIZE 128
uint8_t rx_buf[RX_BUF_SIZE];
uint8_t tx_buf[TX_BUF_SIZE];
volatile uint16_t rx_head;
volatile uint16_t rx_tail;
volatile uint16_t tx_head;
volatile uint16_t tx_tail;
void uart_putc(uint8_t c);
uint16_t uart_getc(void);
uint16_t spi(uint16_t data);
int main(void)
{
RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN);
RCC->APB1ENR |= (RCC_APB1ENR_SPI2EN | RCC_APB1ENR_USART3EN);
// PB11 / INT/HOLD
GPIOB->MODER |= GPIO_MODER_MODER11_0;
// open drain output
GPIOB->OTYPER |= GPIO_OTYPER_OT_11;
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11_1;
// PD11 / Chip Select
GPIOD->MODER |= GPIO_MODER_MODER11_0;
// open drain output
GPIOD->OTYPER |= GPIO_OTYPER_OT_11;
GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11_1;
// PB13 / SCK
GPIOB->MODER |= GPIO_MODER_MODER13_1;
// open drain output
GPIOB->OTYPER |= GPIO_OTYPER_OT_13;
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR13_1;
GPIOB->AFR[1] |= (0x05 << 20);
// PB14 / MISO
GPIOB->MODER |= GPIO_MODER_MODER14_1;
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR14_1;
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR14_1;
GPIOB->AFR[1] |= (0x05 << 24);
// PB15 / MOSI
GPIOB->MODER |= GPIO_MODER_MODER15_1;
// open drain output
GPIOB->OTYPER |= GPIO_OTYPER_OT_15;
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15_1;
GPIOB->AFR[1] |= (0x05 << 28);
// PD12 / LED
GPIOD->MODER |= GPIO_MODER_MODER12_0;
GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12_1;
// SPI
SPI2->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_CPHA | SPI_CR1_MSTR | (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0);
SPI2->CR1 |= SPI_CR1_SPE;
// PC10 / TX
GPIOC->MODER |= GPIO_MODER_MODER10_1;
GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10_0;
GPIOC->AFR[1] |= (0x07 << 8);
// PC11 / RX
GPIOC->MODER |= GPIO_MODER_MODER11_1;
GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR11;
GPIOC->AFR[1] |= (0x07 << 12);
// USART
USART3->BRR = 0x00D9; // 50.0 MHz / 0x00D9 = 115200
USART3->CR3 |= USART_CR3_DMAT;
USART3->CR1 |= (USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE);
USART3->CR1 |= USART_CR1_UE;
NVIC_SetPriority(USART3_IRQn, 15);
NVIC_EnableIRQ(USART3_IRQn);
__enable_irq();
volatile uint32_t i;
uint16_t data;
uart_putc(spi(0b01001100));
uart_putc(spi(0b01001100));
uart_putc(spi(0b11100001));
// SET_ADVANCED_MODE
uart_putc(spi(0b01110001));
for (;;) {
/*data = uart_getc();
if ((data & 0xFF00) == 0) {
uart_putc(spi(data));
}*/
// LED on PD12 goes LOW
GPIOD->BSRRL = GPIO_ODR_ODR_12;
// delay
for (i = 0; i < 10000; i++);
// BAND_PASS_CMD
uart_putc(spi(0b00000000 | (40 & 0x3F)));
// Set the gain
uart_putc(spi(0b10000000 | (49 & 0x3F)));
// Set the integration time constant
uart_putc(spi(0b11000000 | (31 & 0x1F)));
// SET_ADVANCED_MODE
uart_putc(spi(0b01110001));
// int/hold LOW
GPIOB->BSRRL = GPIO_ODR_ODR_11;
// LED on PD12 goes HIGH
GPIOD->BSRRH = GPIO_ODR_ODR_12;
// delay
for (i = 0; i < 10000; i++);
// int/hold HIGH
GPIOB->BSRRH = GPIO_ODR_ODR_11;
}
return 0;
}
uint16_t spi(uint16_t data)
{
volatile uint16_t i;
// Chip Select PD11 goes HIGH
GPIOD->BSRRH = GPIO_ODR_ODR_11;
for (i = 0; i < 10; i++);
SPI2->DR = data;
while (!(SPI2->SR & SPI_SR_TXE));
while (!(SPI2->SR & SPI_SR_RXNE));
while ((SPI2->SR & SPI_SR_BSY));
for (i = 0; i < 10; i++);
// Chip Select PD11 goes LOW
GPIOD->BSRRL = GPIO_ODR_ODR_11;
for (i = 0; i < 100; i++);
return SPI2->DR;
}
void uart_putc(uint8_t c)
{
uint16_t tmphead;
tmphead = (tmphead < (TX_BUF_SIZE - 1)) ? (tx_head + 1) : 0;
tx_buf[tmphead] = c;
tx_head = tmphead;
USART3->CR1 |= USART_CR1_TXEIE;
}
uint16_t uart_getc(void)
{
uint16_t data, tmptail;
if (rx_tail == rx_head)
{
data = NO_DATA;
}
else
{
tmptail = (tmptail < (RX_BUF_SIZE - 1)) ? (rx_tail + 1) : 0;
rx_tail = tmptail;
data = rx_buf[tmptail];
}
return data;
}
void USART3_IRQHandler(void)
{
if ((USART3->SR & USART_SR_RXNE))
{
uint8_t data, tmphead;
USART3->SR = ~USART_SR_RXNE;
data = USART3->DR;
tmphead = (rx_head < (RX_BUF_SIZE - 1)) ? (rx_head + 1) : 0;
if (rx_tail == tmphead)
{
// Buffer overflow
}
else
{
rx_head = tmphead;
rx_buf[tmphead] = data;
}
}
if ((USART3->SR & USART_SR_TXE))
{
uint16_t tmptail;
USART3->SR = ~USART_SR_TXE;
if (tx_tail != tx_head)
{
tmptail = (tx_tail < (TX_BUF_SIZE - 1)) ? (tx_tail + 1) : 0;
tx_tail = tmptail;
USART3->DR = tx_buf[tmptail];
}
else
{
USART3->CR1 &= ~USART_CR1_TXEIE;
}
}
}

View File

@ -1,42 +0,0 @@
echo This script should be executed from the root of rusEfi trunk SVN local copy
pwd
echo Updating from SVN
call svn update
set RUSEFI_GIT_PATH=../rusefi.github/rusefi
ls -l %RUSEFI_GIT_PATH%
rd /s /q %RUSEFI_GIT_PATH%\firmware
rd /s /q %RUSEFI_GIT_PATH%\hardware
rd /s /q %RUSEFI_GIT_PATH%\java_console
rd /s /q %RUSEFI_GIT_PATH%\unit_tests
rd /s /q %RUSEFI_GIT_PATH%\simulator
cp -r firmware %RUSEFI_GIT_PATH%
cp -r hardware %RUSEFI_GIT_PATH%
cp -r java_console %RUSEFI_GIT_PATH%
cp -r unit_tests %RUSEFI_GIT_PATH%
cp -r simulator %RUSEFI_GIT_PATH%
rm -f %RUSEFI_GIT_PATH%/readme.*
rm -f %RUSEFI_GIT_PATH%/README.*
cp -r README.* %RUSEFI_GIT_PATH%
cp -r readme.* %RUSEFI_GIT_PATH%
echo Going to git copy location
cd %RUSEFI_GIT_PATH%
git config --global user.email "russianefi@gmail.com"
git config --global user.name "rusEfi"
git pull
git add *
git commit -a -m "auto-sync"
git push --repo https://rusefi:PASSWORD@github.com/rusefi/rusefi

View File

@ -1,9 +0,0 @@
rd /s /q c:\stuff\rusefi.svn2git
mkdir -p c:\stuff\rusefi.svn2git\rusefi.svn
cd c:\stuff\rusefi.svn2git\rusefi.svn
svn co https://svn.code.sf.net/p/rusefi/code/trunk/ .
mkdir -p c:\stuff\rusefi.svn2git\rusefi.github
cd c:\stuff\rusefi.svn2git\rusefi.github
git clone https://github.com/rusefi/rusefi.git

View File

@ -1,79 +0,0 @@
/*
* @file test_hip9011.cpp
*
* Created on: Mar 22, 2018
*/
#include "pch.h"
#include "hip9011_logic.h"
using ::testing::_;
TEST(hip9011, lookup) {
HIP9011 instance(NULL);
assertEqualsM2("", 3183.1013, instance.getRpmByAngleWindowAndTimeUs(600, 360), 0.1);
assertEqualsM2("40us", 47746.5195, instance.getRpmByAngleWindowAndTimeUs(40, 360), 0.1);
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.angleWindowWidth = 50.0;
instance.prepareRpmLookup();
EXPECT_EQ(31, instance.getIntegrationIndexByRpm(1));
EXPECT_EQ(21, instance.getIntegrationIndexByRpm(1100));
EXPECT_EQ(1, instance.getIntegrationIndexByRpm(6600));
EXPECT_EQ(0, instance.getIntegrationIndexByRpm(16600));
}
TEST(hip9011, band) {
HIP9011 instance(NULL);
EXPECT_FLOAT_EQ(3, instance.getBand(/* knockBandCustom*/3, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_NEAR_M4(7.5389242, instance.getBand(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
EXPECT_EQ(42, instance.getBandIndex(/* knockBandCustom*/0, /*cylinderBore*/76, /*hip9011Gain*/NAN, 0, NAN, NAN));
}
class MockHip9011Hardware : public Hip9011HardwareInterface
{
public:
MockHip9011Hardware() { }
MOCK_METHOD2(sendSyncCommand, int(unsigned char, unsigned char *));
};
TEST(hip9011, configurationCommands) {
MockHip9011Hardware mock;
HIP9011 instance(&mock);
// want to invoke method with same parameters a few times
#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(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);
instance.handleSettings(PARAMETERS);
}

View File

@ -54,7 +54,6 @@ TESTS_SRC_CPP = \
tests/test_start_stop.cpp \
tests/test_hardware_reinit.cpp \
tests/test_ion.cpp \
tests/test_hip9011.cpp \
tests/test_engine_math.cpp \
tests/test_fasterEngineSpinningUp.cpp \
tests/test_dwell_corner_case_issue_796.cpp \