mirror of https://github.com/FOME-Tech/fome-fw.git
hip9011
This commit is contained in:
parent
fd09ad7b4f
commit
666a41e496
|
@ -3,7 +3,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "hip9011_logic.h"
|
|
||||||
#include "chconf_common.h"
|
#include "chconf_common.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,39 +25,6 @@ static void setCanFrankensoDefaults() {
|
||||||
engineConfiguration->canRxPin = Gpio::B12;
|
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.)
|
* @brief Hardware board-specific default configuration (GPIO pins, ADC channels, SPI configs etc.)
|
||||||
*/
|
*/
|
||||||
|
@ -66,10 +32,6 @@ void setBoardDefaultConfiguration() {
|
||||||
setDefaultFrankensoStepperIdleParameters();
|
setDefaultFrankensoStepperIdleParameters();
|
||||||
setCanFrankensoDefaults();
|
setCanFrankensoDefaults();
|
||||||
|
|
||||||
#if EFI_HIP_9011
|
|
||||||
setHip9011FrankensoPinout();
|
|
||||||
#endif /* EFI_HIP_9011 */
|
|
||||||
|
|
||||||
// set optional subsystem configs
|
// set optional subsystem configs
|
||||||
#if EFI_MEMS
|
#if EFI_MEMS
|
||||||
// this would override some values from above
|
// this would override some values from above
|
||||||
|
|
|
@ -194,14 +194,6 @@ void setBoardDefaultConfiguration() {
|
||||||
engineConfiguration->spi3sckPin = Gpio::C10;
|
engineConfiguration->spi3sckPin = Gpio::C10;
|
||||||
engineConfiguration->spi3SckMode = PO_OPENDRAIN; // 4
|
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->canTxPin = Gpio::B9;
|
||||||
engineConfiguration->canRxPin = Gpio::B8;
|
engineConfiguration->canRxPin = Gpio::B8;
|
||||||
|
|
||||||
|
|
|
@ -169,20 +169,6 @@ void setBoardDefaultConfiguration() {
|
||||||
/* TODO: add settings for SPI4 */
|
/* TODO: add settings for SPI4 */
|
||||||
|
|
||||||
/* Knock sensor */
|
/* 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;
|
engineConfiguration->cylinderBore = 96.9;
|
||||||
|
|
||||||
/* Cylinder to knock bank mapping */
|
/* Cylinder to knock bank mapping */
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
!TODO: understand this.
|
!TODO: understand this.
|
||||||
|
|
||||||
#define ts_show_hip9011 true
|
|
||||||
#define ts_show_egt false
|
#define ts_show_egt false
|
||||||
#define ts_show_etb_pins true
|
#define ts_show_etb_pins true
|
||||||
#define ts_show_analog_divider false
|
#define ts_show_analog_divider false
|
||||||
|
|
|
@ -76,7 +76,6 @@
|
||||||
|
|
||||||
#include "bmw_m73.h"
|
#include "bmw_m73.h"
|
||||||
#include "custom_engine.h"
|
#include "custom_engine.h"
|
||||||
#include "hip9011_logic.h"
|
|
||||||
|
|
||||||
#if EFI_ELECTRONIC_THROTTLE_BODY
|
#if EFI_ELECTRONIC_THROTTLE_BODY
|
||||||
#include "electronic_throttle.h"
|
#include "electronic_throttle.h"
|
||||||
|
|
|
@ -394,7 +394,6 @@ void setTle8888TestConfiguration() {
|
||||||
engineConfiguration->etbIo[0].disablePin = Gpio::F12;
|
engineConfiguration->etbIo[0].disablePin = Gpio::F12;
|
||||||
#endif /* STM32_HAS_GPIOF */
|
#endif /* STM32_HAS_GPIOF */
|
||||||
engineConfiguration->etb_use_two_wires = true;
|
engineConfiguration->etb_use_two_wires = true;
|
||||||
engineConfiguration->isHip9011Enabled = false;
|
|
||||||
|
|
||||||
// ETB #2
|
// ETB #2
|
||||||
// DIS PE5
|
// DIS PE5
|
||||||
|
|
|
@ -244,8 +244,6 @@ void setDodgeNeonNGCEngineConfiguration() {
|
||||||
|
|
||||||
engineConfiguration->map.sensor.type = MT_DODGE_NEON_2003;
|
engineConfiguration->map.sensor.type = MT_DODGE_NEON_2003;
|
||||||
|
|
||||||
engineConfiguration->hip9011Gain = 0.3;
|
|
||||||
|
|
||||||
engineConfiguration->cylinderBore = 87.5;
|
engineConfiguration->cylinderBore = 87.5;
|
||||||
|
|
||||||
engineConfiguration->clutchDownPin = Gpio::C12;
|
engineConfiguration->clutchDownPin = Gpio::C12;
|
||||||
|
|
|
@ -258,9 +258,6 @@ void setMiataNA6_MAP_Frankenso() {
|
||||||
setFrankensoConfiguration();
|
setFrankensoConfiguration();
|
||||||
miataNAcommonEngineSettings();
|
miataNAcommonEngineSettings();
|
||||||
|
|
||||||
|
|
||||||
engineConfiguration->isHip9011Enabled = false;
|
|
||||||
|
|
||||||
// Frankenso middle plug 2J, W32 top <> W47 bottom "#5 Green" jumper, not OEM
|
// Frankenso middle plug 2J, W32 top <> W47 bottom "#5 Green" jumper, not OEM
|
||||||
engineConfiguration->map.sensor.hwChannel = EFI_ADC_4;
|
engineConfiguration->map.sensor.hwChannel = EFI_ADC_4;
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include "mazda_miata_vvt.h"
|
#include "mazda_miata_vvt.h"
|
||||||
#include "custom_engine.h"
|
#include "custom_engine.h"
|
||||||
#include "mazda_miata_base_maps.h"
|
#include "mazda_miata_base_maps.h"
|
||||||
#include "hip9011_logic.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if HW_PROTEUS
|
#if HW_PROTEUS
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "status_loop.h"
|
#include "status_loop.h"
|
||||||
#include "hip9011_logic.h"
|
|
||||||
|
|
||||||
#if EFI_LOGIC_ANALYZER
|
#if EFI_LOGIC_ANALYZER
|
||||||
#include "logic_analyzer.h"
|
#include "logic_analyzer.h"
|
||||||
|
@ -163,7 +162,6 @@ static void printEngineSnifferPinMappings() {
|
||||||
extern const char *vvtNames[];
|
extern const char *vvtNames[];
|
||||||
printOutPin(vvtNames[i], engineConfiguration->camInputs[i]);
|
printOutPin(vvtNames[i], engineConfiguration->camInputs[i]);
|
||||||
}
|
}
|
||||||
printOutPin(PROTOCOL_HIP_NAME, engineConfiguration->hip9011IntHoldPin);
|
|
||||||
printOutPin(PROTOCOL_TACH_NAME, engineConfiguration->tachOutputPin);
|
printOutPin(PROTOCOL_TACH_NAME, engineConfiguration->tachOutputPin);
|
||||||
#if EFI_LOGIC_ANALYZER
|
#if EFI_LOGIC_ANALYZER
|
||||||
printOutPin(PROTOCOL_WA_CHANNEL_1, engineConfiguration->logicAnalyzerPins[0]);
|
printOutPin(PROTOCOL_WA_CHANNEL_1, engineConfiguration->logicAnalyzerPins[0]);
|
||||||
|
@ -382,11 +380,6 @@ static CommunicationBlinkingTask communicationsBlinkingTask;
|
||||||
|
|
||||||
#endif /* EFI_PROD_CODE */
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
||||||
#if EFI_HIP_9011
|
|
||||||
extern HIP9011 instance;
|
|
||||||
#endif /* EFI_HIP_9011 */
|
|
||||||
|
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
|
|
||||||
static void updateTempSensors() {
|
static void updateTempSensors() {
|
||||||
|
|
|
@ -63,7 +63,6 @@ enum class PE : uint8_t {
|
||||||
Temporary4,
|
Temporary4,
|
||||||
EngineSniffer,
|
EngineSniffer,
|
||||||
PrepareIgnitionSchedule,
|
PrepareIgnitionSchedule,
|
||||||
Hip9011IntHoldCallback,
|
|
||||||
GlobalLock,
|
GlobalLock,
|
||||||
GlobalUnlock,
|
GlobalUnlock,
|
||||||
SoftwareKnockProcess,
|
SoftwareKnockProcess,
|
||||||
|
|
|
@ -436,8 +436,6 @@ static void configureInputs() {
|
||||||
|
|
||||||
addChannel("MAP", engineConfiguration->map.sensor.hwChannel, ADC_FAST);
|
addChannel("MAP", engineConfiguration->map.sensor.hwChannel, ADC_FAST);
|
||||||
|
|
||||||
addChannel("HIP9011", engineConfiguration->hipOutputChannel, ADC_FAST);
|
|
||||||
|
|
||||||
// not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
|
// not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
|
||||||
|
|
||||||
addChannel("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel, ADC_FAST);
|
addChannel("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel, ADC_FAST);
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "AdcConfiguration.h"
|
#include "AdcConfiguration.h"
|
||||||
#include "idle_hardware.h"
|
#include "idle_hardware.h"
|
||||||
#include "mcp3208.h"
|
#include "mcp3208.h"
|
||||||
#include "hip9011.h"
|
|
||||||
#include "histogram.h"
|
#include "histogram.h"
|
||||||
#include "sent.h"
|
#include "sent.h"
|
||||||
#include "cdm_ion_sense.h"
|
#include "cdm_ion_sense.h"
|
||||||
|
@ -135,7 +134,6 @@ SPIDriver * getSpiDevice(spi_device_e spiDevice) {
|
||||||
#if HAL_USE_ADC
|
#if HAL_USE_ADC
|
||||||
|
|
||||||
static FastAdcToken fastMapSampleIndex;
|
static FastAdcToken fastMapSampleIndex;
|
||||||
static FastAdcToken hipSampleIndex;
|
|
||||||
|
|
||||||
#if HAL_TRIGGER_USE_ADC
|
#if HAL_TRIGGER_USE_ADC
|
||||||
static FastAdcToken triggerSampleIndex;
|
static FastAdcToken triggerSampleIndex;
|
||||||
|
@ -185,18 +183,12 @@ void onFastAdcComplete(adcsample_t*) {
|
||||||
#if EFI_MAP_AVERAGING
|
#if EFI_MAP_AVERAGING
|
||||||
mapAveragingAdcCallback(adcToVoltsDivided(getFastAdc(fastMapSampleIndex), engineConfiguration->map.sensor.hwChannel));
|
mapAveragingAdcCallback(adcToVoltsDivided(getFastAdc(fastMapSampleIndex), engineConfiguration->map.sensor.hwChannel));
|
||||||
#endif /* EFI_MAP_AVERAGING */
|
#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 */
|
#endif /* HAL_USE_ADC */
|
||||||
|
|
||||||
static void calcFastAdcIndexes() {
|
static void calcFastAdcIndexes() {
|
||||||
#if HAL_USE_ADC
|
#if HAL_USE_ADC
|
||||||
fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
|
fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
|
||||||
hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
|
|
||||||
#if HAL_TRIGGER_USE_ADC
|
#if HAL_TRIGGER_USE_ADC
|
||||||
triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
|
triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
|
||||||
#endif /* HAL_TRIGGER_USE_ADC */
|
#endif /* HAL_TRIGGER_USE_ADC */
|
||||||
|
@ -536,10 +528,6 @@ void initHardware() {
|
||||||
turnOnTriggerInputPins();
|
turnOnTriggerInputPins();
|
||||||
#endif /* EFI_SHAFT_POSITION_INPUT */
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||||
|
|
||||||
#if EFI_HIP_9011
|
|
||||||
initHip9011();
|
|
||||||
#endif /* EFI_HIP_9011 */
|
|
||||||
|
|
||||||
#if EFI_MEMS
|
#if EFI_MEMS
|
||||||
initAccelerometer();
|
initAccelerometer();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,8 +21,6 @@ HW_LAYER_EMS_CPP = \
|
||||||
$(PROJECT_DIR)/hw_layer/adc/adc_inputs.cpp \
|
$(PROJECT_DIR)/hw_layer/adc/adc_inputs.cpp \
|
||||||
$(PROJECT_DIR)/hw_layer/adc/adc_subscription.cpp \
|
$(PROJECT_DIR)/hw_layer/adc/adc_subscription.cpp \
|
||||||
$(PROJECT_DIR)/hw_layer/adc/ads1015.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/mc33816.cpp \
|
||||||
$(PROJECT_DIR)/hw_layer/stepper.cpp \
|
$(PROJECT_DIR)/hw_layer/stepper.cpp \
|
||||||
$(PROJECT_DIR)/hw_layer/stepper_dual_hbridge.cpp \
|
$(PROJECT_DIR)/hw_layer/stepper_dual_hbridge.cpp \
|
||||||
|
|
|
@ -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 */
|
|
|
@ -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);
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -493,7 +493,6 @@ ThermistorConf clt;todo: merge with channel settings, use full-scale Thermistor
|
||||||
ThermistorConf iat;
|
ThermistorConf iat;
|
||||||
|
|
||||||
int launchTimingRetard;;"deg", 1, 0, -180, 180, 2
|
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
|
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
|
struct_no_prefix specs_s
|
||||||
|
@ -588,7 +587,6 @@ trigger_config_s trigger;
|
||||||
float airByRpmTaper;Extra air taper amount;"%", 1, 0, 0, 50, 1
|
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"
|
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 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
|
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
|
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;
|
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
|
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;
|
output_pin_e tachOutputPin;
|
||||||
pin_output_mode_e tachOutputPinMode;
|
pin_output_mode_e tachOutputPinMode;
|
||||||
|
|
||||||
|
@ -736,13 +733,11 @@ bit is_enabled_spi_2
|
||||||
bit isSdCardEnabled;enable sd/disable sd
|
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 rusefiVerbose29b,"29 bit","11 bit";Use 11 bit (standard) or 29 bit (extended) IDs for rusEFI verbose CAN format.
|
||||||
bit isEngineControlEnabled
|
bit isEngineControlEnabled
|
||||||
bit isHip9011Enabled
|
|
||||||
bit isVerboseAlternator
|
bit isVerboseAlternator
|
||||||
bit verboseQuad
|
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 useStepperIdle;This setting should only be used if you have a stepper motor idle valve and a stepper motor driver installed.
|
||||||
|
|
||||||
bit enabledStep1Limiter
|
bit enabledStep1Limiter
|
||||||
bit useTpicAdvancedMode
|
|
||||||
bit unused760b12
|
bit unused760b12
|
||||||
bit verboseTLE8888
|
bit verboseTLE8888
|
||||||
bit enableVerboseCanTx;CAN broadcast using custom rusEFI protocol\nenable can_broadcast/disable can_broadcast
|
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;
|
brain_input_pin_e[LOGIC_ANALYZER_CHANNEL_COUNT iterate] logicAnalyzerPins;
|
||||||
pin_output_mode_e mainRelayPinMode;
|
pin_output_mode_e mainRelayPinMode;
|
||||||
Gpio hip9011CsPin;
|
|
||||||
Gpio hip9011IntHoldPin;
|
|
||||||
pin_output_mode_e hip9011IntHoldPinMode;
|
|
||||||
|
|
||||||
! 536870911 = 2^29-1, the maximum valid extended ID
|
! 536870911 = 2^29-1, the maximum valid extended ID
|
||||||
uint32_t verboseCanBaseAddress;;"", 1, 0, 0, 536870911, 0
|
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@@
|
custom tChargeMode_e 1 bits, U08, @OFFSET@, [0:1], @@tChargeMode_e_enum@@
|
||||||
tChargeMode_e tChargeMode;
|
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_iTermMin;iTerm min value;"", 1, 0, -30000, 30000, 0
|
||||||
int16_t etb_iTermMax;iTerm max 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_VVT2_NAME "VVT2"
|
||||||
#define PROTOCOL_VVT3_NAME "VVT3"
|
#define PROTOCOL_VVT3_NAME "VVT3"
|
||||||
#define PROTOCOL_VVT4_NAME "VVT4"
|
#define PROTOCOL_VVT4_NAME "VVT4"
|
||||||
#define PROTOCOL_HIP_NAME "HIP"
|
|
||||||
#define PROTOCOL_TACH_NAME "tach"
|
#define PROTOCOL_TACH_NAME "tach"
|
||||||
#define PROTOCOL_HPFP_NAME "hpfp"
|
#define PROTOCOL_HPFP_NAME "hpfp"
|
||||||
|
|
||||||
|
@ -2120,7 +2109,6 @@ end_struct
|
||||||
#define PROTOCOL_INJ1_SHORT_NAME "i1"
|
#define PROTOCOL_INJ1_SHORT_NAME "i1"
|
||||||
|
|
||||||
! some board files override this value using prepend file
|
! 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_all true
|
||||||
#define ts_show_vr_threshold_2 true
|
#define ts_show_vr_threshold_2 true
|
||||||
#define ts_show_main_relay true
|
#define ts_show_main_relay true
|
||||||
|
|
|
@ -1860,7 +1860,6 @@ menuDialog = main
|
||||||
subMenu = fancyHardwareDialog, "Fancy Hardware"
|
subMenu = fancyHardwareDialog, "Fancy Hardware"
|
||||||
subMenu = std_separator
|
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 = softwareKnock, "Software knock" @@if_ts_show_software_knock
|
||||||
subMenu = maxKnockRetardTbl, "Max knock retard" @@if_ts_show_software_knock
|
subMenu = maxKnockRetardTbl, "Max knock retard" @@if_ts_show_software_knock
|
||||||
subMenu = std_separator
|
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 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 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 = "SPI3 SCK", spi3sckPin, {is_enabled_spi_3 == 1} @@if_ts_show_spi
|
||||||
field = "hip9011CsPin", hip9011CsPin
|
|
||||||
field = "LIS302DLCsPin", LIS302DLCsPin
|
field = "LIS302DLCsPin", LIS302DLCsPin
|
||||||
field = "Saab CDM knock", cdmInputPin
|
field = "Saab CDM knock", cdmInputPin
|
||||||
field = "DRV8860 CS", drv8860_cs
|
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 = softwareKnockLeft, West
|
||||||
panel = knockThresholdCurve, Center
|
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"
|
dialog = spiFunction, "SPI settings"
|
||||||
field = "!ECU reboot needed to apply these settings"
|
field = "!ECU reboot needed to apply these settings"
|
||||||
field = "SPI1 enable", is_enabled_spi_1
|
field = "SPI1 enable", is_enabled_spi_1
|
||||||
|
|
|
@ -47,7 +47,6 @@ public class EnumNames {
|
||||||
"Temporary4",
|
"Temporary4",
|
||||||
"EngineSniffer",
|
"EngineSniffer",
|
||||||
"PrepareIgnitionSchedule",
|
"PrepareIgnitionSchedule",
|
||||||
"Hip9011IntHoldCallback",
|
|
||||||
"GlobalLock",
|
"GlobalLock",
|
||||||
"GlobalUnlock",
|
"GlobalUnlock",
|
||||||
"SoftwareKnockProcess",
|
"SoftwareKnockProcess",
|
||||||
|
|
|
@ -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.ISSDCARDENABLED, "SD card enabled").getContent()));
|
||||||
// panel.add(UiUtils.wrap(new BitConfigField(Fields.USELCDSCREEN, "Use LCD").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.KNOCKDETECTIONWINDOWSTART, "kw start").getContent()));
|
||||||
// panel.add(UiUtils.wrap(new ConfigField(Fields.KNOCKDETECTIONWINDOWEND, "kw end").getContent()));
|
// panel.add(UiUtils.wrap(new ConfigField(Fields.KNOCKDETECTIONWINDOWEND, "kw end").getContent()));
|
||||||
//
|
//
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -54,7 +54,6 @@ TESTS_SRC_CPP = \
|
||||||
tests/test_start_stop.cpp \
|
tests/test_start_stop.cpp \
|
||||||
tests/test_hardware_reinit.cpp \
|
tests/test_hardware_reinit.cpp \
|
||||||
tests/test_ion.cpp \
|
tests/test_ion.cpp \
|
||||||
tests/test_hip9011.cpp \
|
|
||||||
tests/test_engine_math.cpp \
|
tests/test_engine_math.cpp \
|
||||||
tests/test_fasterEngineSpinningUp.cpp \
|
tests/test_fasterEngineSpinningUp.cpp \
|
||||||
tests/test_dwell_corner_case_issue_796.cpp \
|
tests/test_dwell_corner_case_issue_796.cpp \
|
||||||
|
|
Loading…
Reference in New Issue