start allowing ADC change while running (#3100)

* allow re-register of the same sensor

* add api to unsubscribe

* do it for tps

* clear the pin

* happy test

* maybe make afr happy for now

* tests build

* happy simulator

* active configuration

* check valid

* we need vbatt now

* manage all pin init in init_sensors.cpp

* don't need that

* cleanup

* thermistors

* do two phase reinit in the right place

* config vs engine

* finally the tests are happy
This commit is contained in:
Matthew Kennedy 2021-08-24 13:41:16 -07:00 committed by GitHub
parent 879170c08b
commit a18b86a09b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 93 additions and 60 deletions

View File

@ -91,7 +91,6 @@
#include "hardware.h"
#if EFI_PROD_CODE
#include "init.h"
#include "board.h"
#endif /* EFI_PROD_CODE */
@ -174,9 +173,6 @@ void incrementGlobalConfigurationVersion(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
/**
* All these callbacks could be implemented as listeners, but these days I am saving RAM
*/
#if EFI_PROD_CODE
reconfigureSensors();
#endif /* EFI_PROD_CODE */
engine->preCalculate(PASS_ENGINE_PARAMETER_SIGNATURE);
#if EFI_ALTERNATOR_CONTROL
onConfigurationChangeAlternatorCallback(&activeConfiguration);

View File

@ -22,7 +22,6 @@ class AdcDevice {
public:
explicit AdcDevice(ADCConversionGroup* hwConfig, adcsample_t *buf, size_t buf_len);
void enableChannel(adc_channel_e hwChannelIndex);
void enableChannelAndPin(const char *msg, adc_channel_e hwChannelIndex);
adc_channel_e getAdcHardwareIndexByInternalIndex(int index) const;
uint8_t internalAdcIndexByHardwareIndex[EFI_ADC_LAST_CHANNEL];
bool isHwUsed(adc_channel_e hwChannel) const;

View File

@ -295,13 +295,6 @@ void AdcDevice::enableChannel(adc_channel_e hwChannel) {
#endif /* ADC_MAX_CHANNELS_COUNT */
}
void AdcDevice::enableChannelAndPin(const char *msg, adc_channel_e hwChannel) {
enableChannel(hwChannel);
brain_pin_e pin = getAdcChannelBrainPin(msg, hwChannel);
efiSetPadMode(msg, pin, PAL_MODE_INPUT_ANALOG);
}
adc_channel_e AdcDevice::getAdcHardwareIndexByInternalIndex(int index) const {
return hardwareIndexByIndernalAdcIndex[index];
}
@ -420,14 +413,12 @@ void addChannel(const char *name, adc_channel_e setting, adc_channel_mode_e mode
#if EFI_USE_FAST_ADC
if (mode == ADC_FAST) {
fastAdc.enableChannelAndPin(name, setting);
fastAdc.enableChannel(setting);
return;
}
#endif
// Slow ADC always samples all channels, simply set the input mode
brain_pin_e pin = getAdcChannelBrainPin(name, setting);
efiSetPadMode(name, pin, PAL_MODE_INPUT_ANALOG);
// Nothing to do for slow channels, input is mapped to analog in init_sensors.cpp
}
void removeChannel(const char *name, adc_channel_e setting) {
@ -460,8 +451,6 @@ static void configureInputs(void) {
addChannel("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel, ADC_FAST);
addChannel("AFR", engineConfiguration->afr.hwChannel, ADC_SLOW);
if (CONFIG(isCJ125Enabled)) {
addChannel("CJ125 UR", engineConfiguration->cj125ur, ADC_SLOW);
addChannel("CJ125 UA", engineConfiguration->cj125ua, ADC_SLOW);

View File

@ -76,6 +76,7 @@ static AdcSubscriptionEntry* findEntry() {
entry->VoltsPerAdcVolt = voltsPerAdcVolt;
entry->Channel = channel;
entry->Filter.configureLowpass(SLOW_ADC_RATE, lowpassCutoff);
entry->HasUpdated = false;
// Set the sensor last - it's the field we use to determine whether this entry is in use
entry->Sensor = &sensor;

View File

@ -50,6 +50,7 @@
#include "trigger_emulator_algo.h"
#include "boost_control.h"
#include "software_knock.h"
#include "init.h"
#if EFI_MC33816
#include "mc33816.h"
#endif /* EFI_MC33816 */
@ -290,6 +291,10 @@ void applyNewHardwareSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
*/
ButtonDebounce::stopConfigurationList();
#if EFI_PROD_CODE
stopSensors();
#endif // EFI_PROD_CODE
#if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
stopTriggerInputPins(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_SHAFT_POSITION_INPUT */
@ -342,6 +347,10 @@ void applyNewHardwareSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
enginePins.unregisterPins();
#if EFI_PROD_CODE
reconfigureSensors(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_PROD_CODE */
ButtonDebounce::startConfigurationList();
/*******************************************

View File

@ -9,6 +9,8 @@
// Call this once at startup to initialize, configure, and subscribe sensors
void initNewSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void stopSensors(DECLARE_CONFIG_PARAMETER_SIGNATURE);
// Call this whenever the configuration may have changed, so any sensors
// can be reconfigured with the new settings.
// Note: this may not be necessarily possible for all sensors, so some may
@ -32,9 +34,9 @@ void initAuxSensors(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void initVehicleSpeedSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE);
// Sensor reconfiguration
void reconfigureVbatt(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void reconfigureTps(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void reconfigureThermistors(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void deinitVbatt();
void deinitTps();
void deinitThermistors();
void reconfigureOilPressure(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void deInitFlexSensor();
void deInitVehicleSpeedSensor();

View File

@ -9,6 +9,46 @@
static void initSensorCli();
void initIfValid(const char* msg, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return;
}
#if EFI_PROD_CODE
brain_pin_e pin = getAdcChannelBrainPin(msg, channel);
efiSetPadMode(msg, pin, PAL_MODE_INPUT_ANALOG PASS_ENGINE_PARAMETER_SUFFIX);
#endif
}
void deInitIfValid(const char* msg, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return;
}
#if EFI_PROD_CODE
brain_pin_e pin = getAdcChannelBrainPin(msg, channel);
efiSetPadUnused(pin PASS_ENGINE_PARAMETER_SUFFIX);
#endif
}
static void initOldAnalogInputs(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
initIfValid("AFR", engineConfiguration->afr.hwChannel);
initIfValid("MAP", engineConfiguration->map.sensor.hwChannel);
initIfValid("Baro", engineConfiguration->baroSensor.hwChannel);
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
initIfValid("CJ125 UR", engineConfiguration->cj125ur);
initIfValid("CJ125 UA", engineConfiguration->cj125ua);
}
static void deInitOldAnalogInputs(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
deInitIfValid("AFR", activeConfiguration.afr.hwChannel);
deInitIfValid("MAP", activeConfiguration.map.sensor.hwChannel);
deInitIfValid("Baro", activeConfiguration.baroSensor.hwChannel);
deInitIfValid("AUXF#1", activeConfiguration.auxFastSensor1_adcChannel);
deInitIfValid("CJ125 UR", activeConfiguration.cj125ur);
deInitIfValid("CJ125 UA", activeConfiguration.cj125ua);
}
void initNewSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_CAN_SUPPORT
initCanSensors();
@ -30,19 +70,32 @@ void initNewSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
initMaf(PASS_CONFIG_PARAMETER_SIGNATURE);
#endif
initOldAnalogInputs(PASS_CONFIG_PARAMETER_SIGNATURE);
// Init CLI functionality for sensors (mocking)
initSensorCli();
}
void reconfigureSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
void stopSensors(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
deInitOldAnalogInputs(PASS_CONFIG_PARAMETER_SIGNATURE);
deinitTps();
deinitVbatt();
deinitThermistors();
deInitFlexSensor();
deInitVehicleSpeedSensor();
reconfigureVbatt(PASS_CONFIG_PARAMETER_SIGNATURE);
reconfigureTps(PASS_CONFIG_PARAMETER_SIGNATURE);
}
void reconfigureSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
reconfigureOilPressure(PASS_CONFIG_PARAMETER_SIGNATURE);
reconfigureThermistors(PASS_CONFIG_PARAMETER_SIGNATURE);
initTps(PASS_CONFIG_PARAMETER_SIGNATURE);
initVbatt(PASS_CONFIG_PARAMETER_SIGNATURE);
initThermistors(PASS_CONFIG_PARAMETER_SIGNATURE);
initFlexSensor(PASS_CONFIG_PARAMETER_SIGNATURE);
initVehicleSpeedSensor(PASS_ENGINE_PARAMETER_SIGNATURE);
initOldAnalogInputs(PASS_CONFIG_PARAMETER_SIGNATURE);
}
// Mocking/testing helpers

View File

@ -103,24 +103,9 @@ void initThermistors(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
false);
}
void reconfigureThermistors(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
configTherm(clt,
fclt,
CONFIG(clt),
CONFIG(useLinearCltSensor));
configTherm(iat,
fiat,
CONFIG(iat),
CONFIG(useLinearIatSensor));
configTherm(aux1,
faux1,
CONFIG(auxTempSensor1),
false);
configTherm(aux2,
faux2,
CONFIG(auxTempSensor2),
false);
void deinitThermistors() {
AdcSubscription::UnsubscribeSensor(clt);
AdcSubscription::UnsubscribeSensor(iat);
AdcSubscription::UnsubscribeSensor(aux1);
AdcSubscription::UnsubscribeSensor(aux2);
}

View File

@ -128,18 +128,16 @@ void initTps(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
driverIntent.Register();
}
void reconfigureTps(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
float min = CONFIG(tpsErrorDetectionTooLow);
float max = CONFIG(tpsErrorDetectionTooHigh);
void deinitTps() {
AdcSubscription::UnsubscribeSensor(tpsSens1p);
AdcSubscription::UnsubscribeSensor(tpsSens1s);
configureTps(tpsFunc1p, CONFIG(tps1_1AdcChannel), CONFIG(tpsMin), CONFIG(tpsMax), min, max, tpsSens1p.getSensorName());
configureTps(tpsFunc1s, CONFIG(tps1_2AdcChannel), CONFIG(tps1SecondaryMin), CONFIG(tps1SecondaryMax), min, max, tpsSens1s.getSensorName());
configureTps(tpsFunc2p, CONFIG(tps2_1AdcChannel), CONFIG(tps2Min), CONFIG(tps2Max), min, max, tpsSens2p.getSensorName());
configureTps(tpsFunc2s, CONFIG(tps2_2AdcChannel), CONFIG(tps2SecondaryMin), CONFIG(tps2SecondaryMax), min, max, tpsSens2s.getSensorName());
AdcSubscription::UnsubscribeSensor(tpsSens2p);
AdcSubscription::UnsubscribeSensor(tpsSens2s);
configureTps(pedalFuncPrimary, CONFIG(throttlePedalPositionAdcChannel), CONFIG(throttlePedalUpVoltage), CONFIG(throttlePedalWOTVoltage), min, max, pedalSensorPrimary.getSensorName());
configureTps(pedalFuncSecondary, CONFIG(throttlePedalPositionSecondAdcChannel), CONFIG(throttlePedalSecondaryUpVoltage), CONFIG(throttlePedalSecondaryWOTVoltage), min, max, pedalSensorSecondary.getSensorName());
AdcSubscription::UnsubscribeSensor(pedalSensorPrimary);
AdcSubscription::UnsubscribeSensor(pedalSensorSecondary);
configureTps(wastegateFunc, CONFIG(wastegatePositionSensor), CONFIG(wastegatePositionMin), CONFIG(wastegatePositionMax), min, max, wastegateSens.getSensorName());
configureTps(idlePosFunc, CONFIG(idlePositionSensor), CONFIG(idlePositionMin), CONFIG(idlePositionMax), min, max, idlePosSens.getSensorName());
AdcSubscription::UnsubscribeSensor(wastegateSens);
AdcSubscription::UnsubscribeSensor(idlePosSens);
}

View File

@ -22,6 +22,6 @@ void initVbatt(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
vbattSensor.Register();
}
void reconfigureVbatt(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
vbattFunc.configure(0, 0, 1, engineConfiguration->vbattDividerCoeff, 0, 50);
void deinitVbatt() {
AdcSubscription::UnsubscribeSensor(vbattSensor);
}

View File

@ -91,8 +91,9 @@ TEST(SensorInit, TpsValuesTooClose) {
EXPECT_NO_FATAL_ERROR(initTps(PASS_CONFIG_PARAMETER_SIGNATURE));
Sensor::resetRegistry();
// Reconfiguration should also work without error
EXPECT_NO_FATAL_ERROR(reconfigureTps(PASS_CONFIG_PARAMETER_SIGNATURE));
// de-init and re-init should also work without error
EXPECT_NO_FATAL_ERROR(deinitTps());
EXPECT_NO_FATAL_ERROR(initTps(PASS_CONFIG_PARAMETER_SIGNATURE));
}
TEST(SensorInit, Pedal) {