rusefi/firmware/hw_layer/sensors/hip9011_logic.h

182 lines
5.2 KiB
C++

/*
* @file hip9011_logic.h
*
* Created on: Jan 3, 2019
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#pragma once
#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)