2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file HIP9011.cpp
|
|
|
|
* @brief HIP9011/TPIC8101 driver
|
|
|
|
*
|
2017-01-27 09:03:05 -08:00
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*
|
2017-01-27 18:04:23 -08:00
|
|
|
* http://rusefi.com/forum/viewtopic.php?f=4&t=400
|
|
|
|
* http://rusefi.com/forum/viewtopic.php?f=5&t=778
|
|
|
|
*
|
2015-07-10 06:01:56 -07:00
|
|
|
* pin1 VDD
|
|
|
|
* pin2 GND
|
|
|
|
*
|
|
|
|
* pin8 Chip Select - CS
|
2017-01-27 09:03:05 -08:00
|
|
|
* pin11 Slave Data Out - MISO
|
2015-07-10 06:01:56 -07:00
|
|
|
* 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
|
2018-01-20 17:55:31 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2018
|
2015-07-10 06:01:56 -07:00
|
|
|
* @Spilly
|
|
|
|
*/
|
|
|
|
|
2018-09-16 19:26:57 -07:00
|
|
|
#include "global.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "engine.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "hardware.h"
|
|
|
|
#include "rpm_calculator.h"
|
|
|
|
#include "trigger_central.h"
|
2019-01-03 21:22:35 -08:00
|
|
|
#include "HIP9011_logic.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "hip9011_lookup.h"
|
|
|
|
#include "HIP9011.h"
|
|
|
|
#include "adc_inputs.h"
|
|
|
|
#include "efilib2.h"
|
|
|
|
#include "engine_controller.h"
|
|
|
|
|
2018-11-03 10:27:48 -07:00
|
|
|
#if EFI_PROD_CODE
|
|
|
|
#include "pin_repository.h"
|
|
|
|
#endif
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
#if EFI_HIP_9011 || defined(__DOXYGEN__)
|
|
|
|
|
2016-09-06 21:02:11 -07:00
|
|
|
static NamedOutputPin intHold(HIP_NAME);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
extern uint32_t lastExecutionCount;
|
2016-11-03 20:02:58 -07:00
|
|
|
extern EnginePins enginePins;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
uint32_t hipLastExecutionCount;
|
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
static float hipValueMax = 0;
|
|
|
|
|
2019-01-03 21:22:35 -08:00
|
|
|
static HIP9011 instance;
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
static unsigned char tx_buff[1];
|
|
|
|
static unsigned char rx_buff[1];
|
2017-04-09 19:07:41 -07:00
|
|
|
int correctResponsesCount = 0;
|
2018-05-30 21:15:05 -07:00
|
|
|
int invalidHip9011ResponsesCount = 0;
|
2015-07-10 06:01:56 -07:00
|
|
|
static char pinNameBuffer[16];
|
|
|
|
static float currentAngleWindowWidth;
|
|
|
|
|
|
|
|
static scheduling_s startTimer[2];
|
|
|
|
static scheduling_s endTimer[2];
|
|
|
|
|
|
|
|
static Logging *logger;
|
|
|
|
|
|
|
|
// SPI_CR1_BR_1 // 5MHz
|
|
|
|
// SPI_CR1_CPHA Clock Phase
|
|
|
|
// todo: nicer method which would mention SPI speed explicitly?
|
|
|
|
|
2018-11-03 06:44:34 -07:00
|
|
|
#if EFI_PROD_CODE
|
2016-07-17 00:01:48 -07:00
|
|
|
static SPIConfig hipSpiCfg = { NULL,
|
2015-07-10 06:01:56 -07:00
|
|
|
/* HW dependent part.*/
|
|
|
|
NULL, 0,
|
|
|
|
SPI_CR1_MSTR |
|
|
|
|
//SPI_CR1_BR_1 // 5MHz
|
|
|
|
SPI_CR1_CPHA | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 };
|
2019-01-03 19:53:34 -08:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2015-07-10 15:02:29 -07:00
|
|
|
static void checkResponse(void) {
|
|
|
|
if (tx_buff[0] == rx_buff[0]) {
|
2017-04-09 19:07:41 -07:00
|
|
|
correctResponsesCount++;
|
2015-07-10 15:02:29 -07:00
|
|
|
} else {
|
2018-05-30 21:15:05 -07:00
|
|
|
invalidHip9011ResponsesCount++;
|
2015-07-10 15:02:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// this macro is only used on startup
|
2015-07-10 06:01:56 -07:00
|
|
|
#define SPI_SYNCHRONOUS(value) \
|
|
|
|
spiSelect(driver); \
|
|
|
|
tx_buff[0] = value; \
|
|
|
|
spiExchange(driver, 1, tx_buff, rx_buff); \
|
|
|
|
spiUnselect(driver); \
|
2015-07-10 15:02:29 -07:00
|
|
|
checkResponse();
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2015-07-10 20:01:24 -07:00
|
|
|
static SPIDriver *driver;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
EXTERN_ENGINE
|
|
|
|
;
|
|
|
|
|
|
|
|
|
2017-01-28 16:03:06 -08:00
|
|
|
static char hipPinNameBuffer[16];
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
static void showHipInfo(void) {
|
|
|
|
if (!boardConfiguration->isHip9011Enabled) {
|
|
|
|
scheduleMsg(logger, "hip9011 driver not active");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
printSpiState(logger, boardConfiguration);
|
2018-05-30 21:36:46 -07:00
|
|
|
scheduleMsg(logger, "enabled=%s state=%s bore=%.2fmm freq=%.2fkHz PaSDO=%d",
|
2015-07-10 06:01:56 -07:00
|
|
|
boolToString(boardConfiguration->isHip9011Enabled),
|
2019-01-03 21:22:35 -08:00
|
|
|
getHip_state_e(instance.state),
|
2019-01-03 21:51:32 -08:00
|
|
|
engineConfiguration->cylinderBore, getHIP9011Band(PASS_HIP_PARAMS),
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->hip9011PrescalerAndSDO);
|
|
|
|
|
2017-01-28 16:03:06 -08:00
|
|
|
char *outputName = getPinNameByAdcChannel("hip", engineConfiguration->hipOutputChannel, hipPinNameBuffer);
|
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
scheduleMsg(logger, "band_index=%d gain %.2f/index=%d output=%s", instance.currentBandIndex, engineConfiguration->hip9011Gain, instance.currentGainIndex,
|
2017-01-28 16:03:06 -08:00
|
|
|
outputName);
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(logger, "integrator index=%d knockVThreshold=%.2f knockCount=%d maxKnockSubDeg=%.2f",
|
2019-01-07 20:23:50 -08:00
|
|
|
instance.currentIntergratorIndex, engineConfiguration->knockVThreshold,
|
2015-07-10 06:01:56 -07:00
|
|
|
engine->knockCount, engineConfiguration->maxKnockSubDeg);
|
|
|
|
|
2018-05-30 21:15:05 -07:00
|
|
|
const char * msg = invalidHip9011ResponsesCount > 0 ? "NOT GOOD" : "ok";
|
2017-01-28 16:03:06 -08:00
|
|
|
scheduleMsg(logger, "spi=%s IntHold@%s/%d response count=%d incorrect response=%d %s",
|
2017-05-09 15:55:25 -07:00
|
|
|
getSpi_device_e(engineConfiguration->hip9011SpiDevice),
|
2015-07-10 20:01:24 -07:00
|
|
|
hwPortname(boardConfiguration->hip9011IntHoldPin),
|
2017-01-28 16:03:06 -08:00
|
|
|
boardConfiguration->hip9011IntHoldPinMode,
|
2018-05-30 21:15:05 -07:00
|
|
|
correctResponsesCount, invalidHip9011ResponsesCount,
|
2017-01-27 08:03:45 -08:00
|
|
|
msg);
|
2019-01-07 20:23:50 -08:00
|
|
|
scheduleMsg(logger, "CS@%s updateCount=%d", hwPortname(boardConfiguration->hip9011CsPin), instance.settingUpdateCount);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2018-11-03 06:44:34 -07:00
|
|
|
#if EFI_PROD_CODE
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(logger, "hip %.2fv/last=%.2f@%s/max=%.2f adv=%d",
|
2015-07-11 13:01:31 -07:00
|
|
|
engine->knockVolts,
|
2015-07-10 06:01:56 -07:00
|
|
|
getVoltage("hipinfo", engineConfiguration->hipOutputChannel),
|
2016-12-27 11:04:04 -08:00
|
|
|
getPinNameByAdcChannel("hip", engineConfiguration->hipOutputChannel, pinNameBuffer),
|
2015-07-10 06:01:56 -07:00
|
|
|
hipValueMax,
|
2017-01-27 08:03:45 -08:00
|
|
|
boardConfiguration->useTpicAdvancedMode);
|
2017-05-09 15:55:25 -07:00
|
|
|
scheduleMsg(logger, "mosi=%s", hwPortname(getMosiPin(engineConfiguration->hip9011SpiDevice)));
|
|
|
|
scheduleMsg(logger, "miso=%s", hwPortname(getMisoPin(engineConfiguration->hip9011SpiDevice)));
|
|
|
|
scheduleMsg(logger, "sck=%s", hwPortname(getSckPin(engineConfiguration->hip9011SpiDevice)));
|
2019-01-03 19:53:34 -08:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(logger, "start %.2f end %.2f", engineConfiguration->knockDetectionWindowStart,
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->knockDetectionWindowEnd);
|
|
|
|
|
|
|
|
hipValueMax = 0;
|
|
|
|
engine->printKnockState();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setHip9011FrankensoPinout(void) {
|
|
|
|
/**
|
|
|
|
* SPI on PB13/14/15
|
|
|
|
*/
|
2015-07-13 18:01:37 -07:00
|
|
|
// boardConfiguration->hip9011CsPin = GPIOD_0; // rev 0.1
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
boardConfiguration->isHip9011Enabled = true;
|
2018-11-03 06:44:34 -07:00
|
|
|
engineConfiguration->hip9011PrescalerAndSDO = 6; // 8MHz chip
|
|
|
|
boardConfiguration->is_enabled_spi_2 = true;
|
|
|
|
// todo: convert this to rusEfi, hardware-independent enum
|
|
|
|
#if EFI_PROD_CODE
|
2015-07-13 18:01:37 -07:00
|
|
|
boardConfiguration->hip9011CsPin = GPIOB_0; // rev 0.4
|
|
|
|
boardConfiguration->hip9011CsPinMode = OM_OPENDRAIN;
|
2018-11-03 06:44:34 -07:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
boardConfiguration->hip9011IntHoldPin = GPIOB_11;
|
2015-07-12 20:01:31 -07:00
|
|
|
boardConfiguration->hip9011IntHoldPinMode = OM_OPENDRAIN;
|
2018-11-03 06:44:34 -07:00
|
|
|
|
2015-07-13 18:01:37 -07:00
|
|
|
engineConfiguration->spi2SckMode = PAL_STM32_OTYPE_OPENDRAIN; // 4
|
|
|
|
engineConfiguration->spi2MosiMode = PAL_STM32_OTYPE_OPENDRAIN; // 4
|
2017-03-21 11:58:14 -07:00
|
|
|
engineConfiguration->spi2MisoMode = PAL_STM32_PUPDR_PULLUP; // 32
|
2018-11-03 06:44:34 -07:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-01-04 14:18:43 -08:00
|
|
|
engineConfiguration->hip9011Gain = 1;
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->knockVThreshold = 4;
|
|
|
|
engineConfiguration->maxKnockSubDeg = 20;
|
|
|
|
|
|
|
|
|
|
|
|
if (!boardConfiguration->useTpicAdvancedMode) {
|
|
|
|
engineConfiguration->hipOutputChannel = EFI_ADC_10; // PC0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void startIntegration(void) {
|
2019-01-03 21:22:35 -08:00
|
|
|
if (instance.state == READY_TO_INTEGRATE) {
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* SPI communication is only allowed while not integrating, so we postpone the exchange
|
|
|
|
* until we are done integrating
|
|
|
|
*/
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = IS_INTEGRATING;
|
2017-04-21 16:23:20 -07:00
|
|
|
intHold.setHigh();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void endIntegration(void) {
|
|
|
|
/**
|
|
|
|
* isIntegrating could be 'false' if an SPI command was pending thus we did not integrate during this
|
|
|
|
* engine cycle
|
|
|
|
*/
|
2019-01-03 21:22:35 -08:00
|
|
|
if (instance.state == IS_INTEGRATING) {
|
2017-04-21 16:23:20 -07:00
|
|
|
intHold.setLow();
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = WAITING_FOR_ADC_TO_SKIP;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shaft Position callback used to start or finish HIP integration
|
|
|
|
*/
|
2017-05-15 20:33:22 -07:00
|
|
|
static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2015-07-10 06:01:56 -07:00
|
|
|
// this callback is invoked on interrupt thread
|
|
|
|
if (index != 0)
|
|
|
|
return;
|
2017-05-25 20:23:03 -07:00
|
|
|
engine->m.beforeHipCb = GET_TIMESTAMP();
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2018-07-24 16:58:32 -07:00
|
|
|
int rpm = GET_RPM();
|
2015-07-10 06:01:56 -07:00
|
|
|
if (!isValidRpm(rpm))
|
|
|
|
return;
|
|
|
|
|
|
|
|
int structIndex = getRevolutionCounter() % 2;
|
|
|
|
// todo: schedule this based on closest trigger event, same as ignition works
|
|
|
|
scheduleByAngle(rpm, &startTimer[structIndex], engineConfiguration->knockDetectionWindowStart,
|
|
|
|
(schfunc_t) &startIntegration, NULL, &engine->rpmCalculator);
|
2018-11-03 10:17:58 -07:00
|
|
|
#if EFI_PROD_CODE
|
2015-07-10 06:01:56 -07:00
|
|
|
hipLastExecutionCount = lastExecutionCount;
|
2018-11-03 10:27:48 -07:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
scheduleByAngle(rpm, &endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd,
|
|
|
|
(schfunc_t) &endIntegration,
|
|
|
|
NULL, &engine->rpmCalculator);
|
|
|
|
engine->m.hipCbTime = GET_TIMESTAMP() - engine->m.beforeHipCb;
|
|
|
|
}
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
void setMaxKnockSubDeg(int value) {
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->maxKnockSubDeg = value;
|
|
|
|
showHipInfo();
|
|
|
|
}
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
void setKnockThresh(float value) {
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->knockVThreshold = value;
|
|
|
|
showHipInfo();
|
|
|
|
}
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
void setPrescalerAndSDO(int value) {
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->hip9011PrescalerAndSDO = value;
|
|
|
|
}
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
void setHipBand(float value) {
|
2015-07-10 06:01:56 -07:00
|
|
|
engineConfiguration->knockBandCustom = value;
|
|
|
|
showHipInfo();
|
|
|
|
}
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
void setHipGain(float value) {
|
2019-01-04 14:18:43 -08:00
|
|
|
engineConfiguration->hip9011Gain = value;
|
2015-07-10 06:01:56 -07:00
|
|
|
showHipInfo();
|
|
|
|
}
|
|
|
|
|
2015-07-10 15:02:29 -07:00
|
|
|
/**
|
|
|
|
* this is the end of the non-synchronous exchange
|
|
|
|
*/
|
2015-07-10 06:01:56 -07:00
|
|
|
static void endOfSpiExchange(SPIDriver *spip) {
|
|
|
|
spiUnselectI(driver);
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = READY_TO_INTEGRATE;
|
2015-07-10 15:02:29 -07:00
|
|
|
checkResponse();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-01-03 19:53:34 -08:00
|
|
|
static void sendCommand(hip_state_e s, unsigned char cmd) {
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = s;
|
2019-01-03 19:53:34 -08:00
|
|
|
tx_buff[0] = cmd;
|
|
|
|
|
|
|
|
spiSelectI(driver);
|
|
|
|
spiStartExchangeI(driver, 1, tx_buff, rx_buff);
|
|
|
|
}
|
|
|
|
|
2018-11-03 06:44:34 -07:00
|
|
|
void hipAdcCallback(adcsample_t adcValue) {
|
2019-01-03 21:22:35 -08:00
|
|
|
if (instance.state == WAITING_FOR_ADC_TO_SKIP) {
|
|
|
|
instance.state = WAITING_FOR_RESULT_ADC;
|
|
|
|
} else if (instance.state == WAITING_FOR_RESULT_ADC) {
|
2018-11-03 06:44:34 -07:00
|
|
|
engine->knockVolts = adcValue * engine->adcToVoltageInputDividerCoefficient;
|
2015-07-11 13:01:31 -07:00
|
|
|
hipValueMax = maxF(engine->knockVolts, hipValueMax);
|
|
|
|
engine->knockLogic(engine->knockVolts);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
float angleWindowWidth =
|
|
|
|
engineConfiguration->knockDetectionWindowEnd - engineConfiguration->knockDetectionWindowStart;
|
|
|
|
|
|
|
|
if (angleWindowWidth != currentAngleWindowWidth) {
|
|
|
|
currentAngleWindowWidth = angleWindowWidth;
|
2019-01-07 20:23:50 -08:00
|
|
|
instance.prepareHip9011RpmLookup(currentAngleWindowWidth);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
int integratorIndex = instance.getIntegrationIndexByRpm(GET_RPM());
|
2019-01-04 16:20:32 -08:00
|
|
|
int gainIndex = getHip9011GainIndex(PASS_HIP_PARAMS);
|
|
|
|
int bandIndex = getBandIndex(PASS_HIP_PARAMS);
|
2015-07-10 06:01:56 -07:00
|
|
|
int prescalerIndex = engineConfiguration->hip9011PrescalerAndSDO;
|
|
|
|
|
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
if (instance.currentGainIndex != gainIndex) {
|
|
|
|
instance.currentGainIndex = gainIndex;
|
2019-01-03 19:53:34 -08:00
|
|
|
sendCommand(IS_SENDING_SPI_COMMAND, SET_GAIN_CMD + gainIndex);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
} else if (instance.currentIntergratorIndex != integratorIndex) {
|
|
|
|
instance.currentIntergratorIndex = integratorIndex;
|
2019-01-03 19:53:34 -08:00
|
|
|
sendCommand(IS_SENDING_SPI_COMMAND, SET_INTEGRATOR_CMD + integratorIndex);
|
2019-01-07 20:23:50 -08:00
|
|
|
} else if (instance.currentBandIndex != bandIndex) {
|
|
|
|
instance.currentBandIndex = bandIndex;
|
2019-01-03 19:53:34 -08:00
|
|
|
sendCommand(IS_SENDING_SPI_COMMAND, SET_BAND_PASS_CMD + bandIndex);
|
2019-01-07 20:23:50 -08:00
|
|
|
} else if (instance.currentPrescaler != prescalerIndex) {
|
|
|
|
instance.currentPrescaler = prescalerIndex;
|
2019-01-03 19:53:34 -08:00
|
|
|
sendCommand(IS_SENDING_SPI_COMMAND, SET_PRESCALER_CMD + prescalerIndex);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
} else {
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = READY_TO_INTEGRATE;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hipStartupCode(void) {
|
|
|
|
// D[4:1] = 0000 : 4 MHz
|
|
|
|
// D[4:1] = 0001 : 5 MHz
|
|
|
|
// D[4:1] = 0010 : 6 MHz
|
|
|
|
// D[4:1] = 0011 ; 8 MHz
|
|
|
|
// D[4:1] = 0100 ; 10 MHz
|
|
|
|
// D[4:1] = 0101 ; 12 MHz
|
|
|
|
// D[4:1] = 0110 : 16 MHz
|
|
|
|
// D[4:1] = 0111 : 20 MHz
|
|
|
|
// D[4:1] = 1000 : 24 MHz
|
|
|
|
|
|
|
|
|
2015-07-13 06:01:41 -07:00
|
|
|
// 0 for 4MHz
|
|
|
|
// 6 for 8 MHz
|
2019-01-07 20:23:50 -08:00
|
|
|
instance.currentPrescaler = engineConfiguration->hip9011PrescalerAndSDO;
|
|
|
|
SPI_SYNCHRONOUS(SET_PRESCALER_CMD + instance.currentPrescaler);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
|
|
|
|
// '0' for channel #1
|
|
|
|
SPI_SYNCHRONOUS(SET_CHANNEL_CMD + 0);
|
|
|
|
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
|
|
|
|
// band index depends on cylinder bore
|
2019-01-07 20:23:50 -08:00
|
|
|
SPI_SYNCHRONOUS(SET_BAND_PASS_CMD + instance.currentBandIndex);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
|
2017-04-09 19:07:41 -07:00
|
|
|
if (correctResponsesCount == 0) {
|
2017-02-07 14:04:39 -08:00
|
|
|
warning(CUSTOM_OBD_KNOCK_PROCESSOR, "TPIC/HIP does not respond");
|
2015-07-10 20:01:24 -07:00
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
if (boardConfiguration->useTpicAdvancedMode) {
|
|
|
|
// enable advanced mode for digital integrator output
|
|
|
|
SPI_SYNCHRONOUS(SET_ADVANCED_MODE);
|
|
|
|
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Let's restart SPI to switch it from synchronous mode into
|
|
|
|
* asynchronous mode
|
|
|
|
*/
|
|
|
|
spiStop(driver);
|
2018-11-03 06:44:34 -07:00
|
|
|
#if EFI_PROD_CODE
|
2016-07-17 00:01:48 -07:00
|
|
|
hipSpiCfg.end_cb = endOfSpiExchange;
|
2018-11-03 06:44:34 -07:00
|
|
|
#endif
|
2016-07-17 00:01:48 -07:00
|
|
|
spiStart(driver, &hipSpiCfg);
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.state = READY_TO_INTEGRATE;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static THD_WORKING_AREA(hipTreadStack, UTILITY_THREAD_STACK_SIZE);
|
|
|
|
|
|
|
|
static msg_t hipThread(void *arg) {
|
|
|
|
chRegSetThreadName("hip9011 init");
|
2015-07-11 12:01:54 -07:00
|
|
|
|
|
|
|
// some time to let the hardware start
|
2016-09-14 16:03:00 -07:00
|
|
|
enginePins.hipCs.setValue(true);
|
2015-07-11 12:01:54 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
2016-09-14 16:03:00 -07:00
|
|
|
enginePins.hipCs.setValue(false);
|
2015-07-11 12:01:54 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
2016-09-14 16:03:00 -07:00
|
|
|
enginePins.hipCs.setValue(true);
|
2015-07-11 12:01:54 -07:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
while (true) {
|
2015-07-11 12:01:54 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
|
|
|
|
2019-01-03 21:22:35 -08:00
|
|
|
if (instance.needToInit) {
|
2015-07-10 06:01:56 -07:00
|
|
|
hipStartupCode();
|
2019-01-03 21:22:35 -08:00
|
|
|
instance.needToInit = false;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initHip9011(Logging *sharedLogger) {
|
|
|
|
logger = sharedLogger;
|
|
|
|
addConsoleAction("hipinfo", showHipInfo);
|
|
|
|
if (!boardConfiguration->isHip9011Enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
currentAngleWindowWidth =
|
|
|
|
engineConfiguration->knockDetectionWindowEnd - engineConfiguration->knockDetectionWindowStart;
|
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
instance.prepareHip9011RpmLookup(currentAngleWindowWidth);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2018-11-03 06:44:34 -07:00
|
|
|
#if EFI_PROD_CODE
|
2016-07-17 00:01:48 -07:00
|
|
|
driver = getSpiDevice(engineConfiguration->hip9011SpiDevice);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-07-28 11:27:37 -07:00
|
|
|
hipSpiCfg.ssport = getHwPort("hip", boardConfiguration->hip9011CsPin);
|
|
|
|
hipSpiCfg.sspad = getHwPin("hip", boardConfiguration->hip9011CsPin);
|
2018-11-03 06:44:34 -07:00
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-04-21 15:11:36 -07:00
|
|
|
intHold.initPin("hip int/hold", boardConfiguration->hip9011IntHoldPin,
|
2015-07-10 06:01:56 -07:00
|
|
|
&boardConfiguration->hip9011IntHoldPinMode);
|
2017-04-21 15:11:36 -07:00
|
|
|
enginePins.hipCs.initPin("hip CS", boardConfiguration->hip9011CsPin,
|
2015-07-13 18:01:37 -07:00
|
|
|
&boardConfiguration->hip9011CsPinMode);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
scheduleMsg(logger, "Starting HIP9011/TPIC8101 driver");
|
2016-07-17 00:01:48 -07:00
|
|
|
spiStart(driver, &hipSpiCfg);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-01-07 20:23:50 -08:00
|
|
|
instance.currentBandIndex = getBandIndex();
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* this engine cycle callback would be scheduling actual integration start and end callbacks
|
|
|
|
*/
|
|
|
|
addTriggerEventListener(&intHoldCallback, "DD int/hold", engine);
|
|
|
|
|
|
|
|
// MISO PB14
|
|
|
|
// palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(EFI_SPI2_AF) | PAL_STM32_PUDR_PULLUP);
|
|
|
|
// MOSI PB15
|
|
|
|
// palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(EFI_SPI2_AF) | PAL_STM32_OTYPE_OPENDRAIN);
|
|
|
|
|
2017-01-06 14:01:28 -08:00
|
|
|
addConsoleActionF("set_gain", setHipGain);
|
|
|
|
addConsoleActionF("set_band", setHipBand);
|
2015-07-10 06:01:56 -07:00
|
|
|
addConsoleActionI("set_hip_prescalerandsdo", setPrescalerAndSDO);
|
|
|
|
addConsoleActionF("set_knock_threshold", setKnockThresh);
|
|
|
|
addConsoleActionI("set_max_knock_sub_deg", setMaxKnockSubDeg);
|
2018-12-27 06:40:40 -08:00
|
|
|
chThdCreateStatic(hipTreadStack, sizeof(hipTreadStack), NORMALPRIO, (tfunc_t)(void*) hipThread, NULL);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2017-04-09 19:07:41 -07:00
|
|
|
#endif /* EFI_HIP_9011 */
|