Add support for analog transmission range sensors

This commit is contained in:
David Holdeman 2024-04-06 11:40:17 -05:00 committed by rusefillc
parent 4270e554fa
commit b3a23daa2c
9 changed files with 120 additions and 25 deletions

View File

@ -113,6 +113,13 @@ enum class SensorType : unsigned char {
DetectedGear,
RangeInput1,
RangeInput2,
RangeInput3,
RangeInput4,
RangeInput5,
RangeInput6,
// analog voltage inputs for Lua
AuxAnalog1,
AuxAnalog2,

View File

@ -1,5 +1,6 @@
#include "pch.h"
#include "math.h"
#include "gc_generic.h"
#if EFI_TCU
@ -18,6 +19,21 @@ void GenericGearController::init() {
GearControllerBase::init();
}
SensorType GenericGearController::getAnalogSensorType(int zeroBasedSensorIndex) {
return static_cast<SensorType>(zeroBasedSensorIndex + static_cast<int>(SensorType::RangeInput1));
}
bool GenericGearController::isNearest(float value, int pinIndex, float* rangeStates) {
float distance = fabs(rangeStates[pinIndex] - value);
for (int i = 1; i <= TCU_RANGE_COUNT; i++) {
float pinDistance = fabs(getRangeStateArray(i)[pinIndex] - value);
if (pinDistance < distance) {
return false;
}
}
return true;
}
void GenericGearController::update() {
SelectedGear gear = SelectedGear::Invalid;
// Loop through possible range states
@ -27,19 +43,30 @@ void GenericGearController::update() {
// Loop through inputs
for (size_t p = 0; p < efi::size(engineConfiguration->tcu_rangeInput); p++) {
float cellState = rangeStates[p];
// If the pin isn't configured and it matters, or if we've locked out this range with 3 in a cell
if ((!isBrainPinValid(engineConfiguration->tcu_rangeInput[p]) && cellState != 2) || cellState == 3) {
gear = SelectedGear::Invalid;
break;
}
bool pinState = efiReadPin(engineConfiguration->tcu_rangeInput[p]);
// If the pin doesn't matter, and it matches the cellState
if (cellState == 2 || (pinState && cellState == 1) || (!pinState && cellState == 0)) {
// Set the gear to the one we're checking, and continue to the next pin
gear = static_cast<SelectedGear>(i);
} else {
// This possibility doesn't match, set to invalid
gear = SelectedGear::Invalid;
if (isAdcChannelValid(engineConfiguration->tcu_rangeAnalogInput[p])) {
float pinState = Sensor::getOrZero(getAnalogSensorType(p));
if (isNearest(pinState, p, rangeStates)) {
// Set the gear to the one we're checking, and continue to the next pin
gear = static_cast<SelectedGear>(i);
} else {
// This possibility doesn't match, set to invalid
gear = SelectedGear::Invalid;
}
} else if (isBrainPinValid(engineConfiguration->tcu_rangeInput[p])) {
// If we've locked out this range with 3 in a cell
if (cellState == 3) {
gear = SelectedGear::Invalid;
break;
}
bool pinState = efiReadPin(engineConfiguration->tcu_rangeInput[p]);
// If the pin doesn't matter, or if it matches the cellState
if (cellState == 2 || (pinState && cellState == 1) || (!pinState && cellState == 0)) {
// Set the gear to the one we're checking, and continue to the next pin
gear = static_cast<SelectedGear>(i);
} else {
// This possibility doesn't match, set to invalid
gear = SelectedGear::Invalid;
}
}
}
// If we didn't find it, try the next range

View File

@ -12,6 +12,9 @@ public:
GearControllerMode getMode() const {
return GearControllerMode::Generic;
}
private:
bool isNearest(float value, int pinIndex, float* rangeStates);
SensorType getAnalogSensorType(int zeroBasedSensorIndex);
};
GenericGearController* getGenericGearController();

View File

@ -37,6 +37,7 @@ void initVehicleSpeedSensor();
void initTurbochargerSpeedSensor();
void initAuxSpeedSensors();
void initInputShaftSpeedSensor();
void initRangeSensors();
// Sensor reconfiguration
void deinitVbatt();

View File

@ -16,4 +16,5 @@ INIT_SRC_CPP = $(PROJECT_DIR)/init/sensor/init_sensors.cpp \
$(PROJECT_DIR)/init/sensor/init_vehicle_speed_sensor.cpp \
$(PROJECT_DIR)/init/sensor/init_aux_speed_sensor.cpp \
$(PROJECT_DIR)/init/sensor/init_turbocharger_speed_sensor.cpp \
$(PROJECT_DIR)/init/sensor/init_input_shaft_speed_sensor.cpp
$(PROJECT_DIR)/init/sensor/init_input_shaft_speed_sensor.cpp \
$(PROJECT_DIR)/init/sensor/init_range.cpp

View File

@ -0,0 +1,44 @@
#include "pch.h"
#include "init.h"
#include "adc_subscription.h"
#include "functional_sensor.h"
#include "resistance_func.h"
#if EFI_TCU
// These aux sensors just read voltage - so the converter function has nothing to do
static FunctionalSensor rangeSensors[] = {
{ SensorType::RangeInput1, MS2NT(50) },
{ SensorType::RangeInput2, MS2NT(50) },
{ SensorType::RangeInput3, MS2NT(50) },
{ SensorType::RangeInput4, MS2NT(50) },
{ SensorType::RangeInput5, MS2NT(50) },
{ SensorType::RangeInput6, MS2NT(50) },
};
static ResistanceFunc rangeFuncs[RANGE_INPUT_COUNT];
static_assert(efi::size(rangeSensors) == RANGE_INPUT_COUNT);
void initRangeSensors() {
for (size_t i = 0; i < efi::size(engineConfiguration->tcu_rangeAnalogInput); i++) {
auto channel = engineConfiguration->tcu_rangeAnalogInput[i];
// Skip unconfigured channels
if (!isAdcChannelValid(channel)) {
continue;
}
rangeFuncs[i].configure(5.0f, engineConfiguration->tcu_rangeSensorBiasResistor, engineConfiguration->tcu_rangeSensorPulldown);
auto& sensor = rangeSensors[i];
sensor.setFunction(rangeFuncs[i]);
sensor.Register();
AdcSubscription::SubscribeSensor(sensor, channel, 10);
}
}
#endif

View File

@ -100,6 +100,9 @@ static void sensorStartUpOrReconfiguration(bool isFirstTime) {
initAuxSensors();
initAuxSpeedSensors();
initInputShaftSpeedSensor();
#if EFI_TCU
initRangeSensors();
#endif
initFlexSensor(isFirstTime);
}

View File

@ -1162,7 +1162,7 @@ int16_t tps2Max;Full throttle#2. tpsMax value as 10 bit ADC value. Not Voltage!\
bit is_enabled_spi_6
bit enableAemXSeriesEgt;AEM X-Series EGT gauge kit or rusEFI EGT sensor from Wideband controller
bit startRequestPinInverted,"Inverted","Normal"
bit unusedBit_503_17
bit tcu_rangeSensorPulldown
bit skipBoardCanDash
bit unusedBit_503_19
bit devBit0
@ -1646,7 +1646,10 @@ pin_output_mode_e camSimulatorPinMode
int anotherCiTest
uint32_t[3 iterate] device_uid
uint8_t[214] unusedOftenChangesDuringFirmwareUpdate;;"units", 1, 0, 0, 1, 0
adc_channel_e[RANGE_INPUT_COUNT iterate] tcu_rangeAnalogInput;
float tcu_rangeSensorBiasResistor;;"Ohm", 1, 0, 0, 200000, 1
uint8_t[204] unusedOftenChangesDuringFirmwareUpdate;;"units", 1, 0, 0, 1, 0
! end of engine_configuration_s
end_struct

View File

@ -4345,14 +4345,20 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
field = "Tooth Count", tcuInputSpeedSensorTeeth
dialog = rangeMatrixInputPanel, "Range Selector Inputs"
field = "Input 1 Pin", tcu_rangeInput1, { tcuEnabled }
field = "Input 1 Pin Mode", tcu_rangeInputMode1, { tcuEnabled }
field = "Input 2 Pin", tcu_rangeInput2, { tcuEnabled }
field = "Input 2 Pin Mode", tcu_rangeInputMode2, { tcuEnabled }
field = "Input 3 Pin", tcu_rangeInput3, { tcuEnabled }
field = "Input 3 Pin Mode", tcu_rangeInputMode3, { tcuEnabled }
field = "Input 4 Pin", tcu_rangeInput4, { tcuEnabled }
field = "Input 4 Pin Mode", tcu_rangeInputMode4, { tcuEnabled }
field = "Analog Bias Resistor", tcu_rangeSensorBiasResistor, { tcuEnabled }
field = "Pulldown?", tcu_rangeSensorPulldown, { tcuEnabled }
field = "Analog Pin 1", tcu_rangeAnalogInput1, { tcuEnabled && tcu_rangeInput1 == 0 }
field = "Digital Pin 1", tcu_rangeInput1, { tcuEnabled && tcu_rangeAnalogInput1 == @@ADC_CHANNEL_NONE@@ }
field = "Digital Pin 1 Mode", tcu_rangeInputMode1, { tcuEnabled && tcu_rangeInput1 != 0 && tcu_rangeAnalogInput1 == @@ADC_CHANNEL_NONE@@ }
field = "Analog Pin 2", tcu_rangeAnalogInput2, { tcuEnabled && tcu_rangeInput2 == 0 }
field = "Digital Pin 2", tcu_rangeInput2, { tcuEnabled && tcu_rangeAnalogInput2 == @@ADC_CHANNEL_NONE@@ }
field = "Digital Pin 2 Mode", tcu_rangeInputMode2, { tcuEnabled && tcu_rangeInput2 != 0 && tcu_rangeAnalogInput2 == @@ADC_CHANNEL_NONE@@ }
field = "Analog Pin 3", tcu_rangeAnalogInput3, { tcuEnabled && tcu_rangeInput3 == 0 }
field = "Digital Pin 3", tcu_rangeInput3, { tcuEnabled && tcu_rangeAnalogInput3 == @@ADC_CHANNEL_NONE@@ }
field = "Digital Pin 3 Mode", tcu_rangeInputMode3, { tcuEnabled && tcu_rangeInput3 != 0 && tcu_rangeAnalogInput3 == @@ADC_CHANNEL_NONE@@ }
field = "Analog Pin 4", tcu_rangeAnalogInput4, { tcuEnabled && tcu_rangeInput4 == 0 }
field = "Digital Pin 4", tcu_rangeInput4, { tcuEnabled && tcu_rangeAnalogInput4 == @@ADC_CHANNEL_NONE@@ }
field = "Digital Pin 4 Mode", tcu_rangeInputMode4, { tcuEnabled && tcu_rangeInput4 != 0 && tcu_rangeAnalogInput4 == @@ADC_CHANNEL_NONE@@ }
dialog = tcuControls, "Transmission Settings"
panel = transmissionPanel
@ -4382,7 +4388,7 @@ dialog = tcuControls, "Transmission Settings"
dialog = 32Dialog, "3-2 Shift Solenoid Percent by Speed"
panel = 32Curve
dialog = rangeMatrixDocumentation, "Cell Values"
dialog = rangeMatrixDocumentation, "Digital Cell Values"
field = "0 = this pin must be low to reach this state"
field = "1 = this pin must be high to reach this state"
field = "2 = this pin is ignored for reaching this state"