2021-08-03 19:05:01 -07:00
|
|
|
#include "pch.h"
|
|
|
|
|
2019-09-21 11:33:38 -07:00
|
|
|
#include "adc_subscription.h"
|
2019-09-24 18:11:41 -07:00
|
|
|
|
2020-08-21 16:47:12 -07:00
|
|
|
#include "biquad.h"
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2020-04-05 06:10:08 -07:00
|
|
|
#if EFI_UNIT_TEST
|
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
/*static*/ void AdcSubscription::SubscribeSensor(FunctionalSensor&, adc_channel_e, float, float) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void AdcSubscription::UnsubscribeSensor(FunctionalSensor&) {
|
2020-04-05 06:10:08 -07:00
|
|
|
}
|
|
|
|
|
2023-01-06 05:09:17 -08:00
|
|
|
/*static*/ void AdcSubscription::UnsubscribeSensor(FunctionalSensor&, adc_channel_e) {
|
|
|
|
}
|
|
|
|
|
2020-04-05 06:10:08 -07:00
|
|
|
#else
|
2019-09-21 11:33:38 -07:00
|
|
|
|
|
|
|
struct AdcSubscriptionEntry {
|
2019-09-25 04:26:56 -07:00
|
|
|
FunctionalSensor *Sensor;
|
2019-09-21 11:33:38 -07:00
|
|
|
float VoltsPerAdcVolt;
|
2021-08-26 23:32:31 -07:00
|
|
|
Biquad Filter;
|
2021-08-27 03:18:05 -07:00
|
|
|
adc_channel_e Channel;
|
2020-08-31 18:05:04 -07:00
|
|
|
bool HasUpdated = false;
|
2019-09-21 11:33:38 -07:00
|
|
|
};
|
|
|
|
|
2021-05-09 11:36:11 -07:00
|
|
|
static AdcSubscriptionEntry s_entries[16];
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
static AdcSubscriptionEntry* findEntry(FunctionalSensor* sensor) {
|
|
|
|
for (size_t i = 0; i < efi::size(s_entries); i++) {
|
|
|
|
if (s_entries[i].Sensor == sensor) {
|
|
|
|
return &s_entries[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static AdcSubscriptionEntry* findEntry() {
|
|
|
|
// Find an entry with no sensor set
|
|
|
|
return findEntry(nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void AdcSubscription::SubscribeSensor(FunctionalSensor &sensor,
|
2019-09-24 18:11:41 -07:00
|
|
|
adc_channel_e channel,
|
2020-08-21 16:47:12 -07:00
|
|
|
float lowpassCutoff,
|
2019-09-24 18:11:41 -07:00
|
|
|
float voltsPerAdcVolt /*= 0.0f*/) {
|
2019-09-21 11:33:38 -07:00
|
|
|
// Don't subscribe null channels
|
2021-01-05 13:02:20 -08:00
|
|
|
if (!isAdcChannelValid(channel)) {
|
2019-09-21 11:33:38 -07:00
|
|
|
return;
|
|
|
|
}
|
2019-09-24 18:11:41 -07:00
|
|
|
|
2023-01-06 05:09:17 -08:00
|
|
|
// If you passed the same sensor again, resubscribe it with the new parameters
|
|
|
|
auto entry = findEntry(&sensor);
|
|
|
|
|
|
|
|
if (entry) {
|
|
|
|
// If the channel didn't change, we're already set
|
|
|
|
if (entry->Channel == channel) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// avoid updates to this while we're mucking with the configuration
|
|
|
|
entry->Sensor = nullptr;
|
|
|
|
} else {
|
|
|
|
// If not already registered, get an empty (new) entry
|
|
|
|
entry = findEntry();
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2023-01-06 05:09:17 -08:00
|
|
|
const char* name = sensor.getSensorName();
|
2021-08-14 05:41:27 -07:00
|
|
|
|
|
|
|
// Ensure that a free entry was found
|
|
|
|
if (!entry) {
|
2023-04-11 17:01:34 -07:00
|
|
|
firmwareError(ObdCode::CUSTOM_INVALID_ADC, "too many ADC subscriptions subscribing %s", name);
|
2021-05-09 11:36:11 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-05-23 21:13:07 -07:00
|
|
|
#if EFI_PROD_CODE && HAL_USE_ADC
|
2021-05-09 11:36:11 -07:00
|
|
|
// Enable the input pin
|
2023-01-07 18:56:12 -08:00
|
|
|
/**
|
|
|
|
TODO: this code is similar to initIfValid, what is the plan? shall we extract helper method or else?
|
|
|
|
*/
|
2023-01-07 19:09:43 -08:00
|
|
|
brain_pin_e pin = getAdcChannelBrainPin(name, channel);
|
2023-01-07 18:56:12 -08:00
|
|
|
if (pin != Gpio::Invalid) {
|
|
|
|
// todo: external muxes for internal ADC #3350
|
|
|
|
efiSetPadMode(name, pin, PAL_MODE_INPUT_ANALOG);
|
|
|
|
}
|
2021-05-09 11:36:11 -07:00
|
|
|
|
2023-01-08 14:29:29 -08:00
|
|
|
// if 0, default to the board's divider coefficient for given channel
|
2019-09-21 11:33:38 -07:00
|
|
|
if (voltsPerAdcVolt == 0) {
|
2023-01-08 14:29:29 -08:00
|
|
|
voltsPerAdcVolt = getAnalogInputDividerCoefficient(channel);
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
2023-05-23 21:13:07 -07:00
|
|
|
#endif /* EFI_PROD_CODE && HAL_USE_ADC */
|
2019-09-21 11:33:38 -07:00
|
|
|
// Populate the entry
|
2021-08-14 05:41:27 -07:00
|
|
|
entry->VoltsPerAdcVolt = voltsPerAdcVolt;
|
|
|
|
entry->Channel = channel;
|
|
|
|
entry->Filter.configureLowpass(SLOW_ADC_RATE, lowpassCutoff);
|
2021-08-24 13:41:16 -07:00
|
|
|
entry->HasUpdated = false;
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
// Set the sensor last - it's the field we use to determine whether this entry is in use
|
|
|
|
entry->Sensor = &sensor;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void AdcSubscription::UnsubscribeSensor(FunctionalSensor& sensor) {
|
|
|
|
auto entry = findEntry(&sensor);
|
|
|
|
|
|
|
|
if (!entry) {
|
|
|
|
// This sensor wasn't configured, skip it
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-05-23 21:39:56 -07:00
|
|
|
#if EFI_PROD_CODE && HAL_USE_ADC
|
2021-08-14 05:41:27 -07:00
|
|
|
// Release the pin
|
|
|
|
efiSetPadUnused(getAdcChannelBrainPin("adc unsubscribe", entry->Channel));
|
2023-05-23 21:39:56 -07:00
|
|
|
#endif // EFI_PROD_CODE && HAL_USE_ADC
|
2021-08-14 05:41:27 -07:00
|
|
|
|
2022-10-20 06:33:27 -07:00
|
|
|
sensor.unregister();
|
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
// clear the sensor first to mark this entry not in use
|
|
|
|
entry->Sensor = nullptr;
|
|
|
|
|
|
|
|
entry->VoltsPerAdcVolt = 0;
|
|
|
|
entry->Channel = EFI_ADC_NONE;
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2023-01-06 05:09:17 -08:00
|
|
|
/*static*/ void AdcSubscription::UnsubscribeSensor(FunctionalSensor& sensor, adc_channel_e channel) {
|
|
|
|
// Find the old sensor
|
|
|
|
auto entry = findEntry(&sensor);
|
|
|
|
|
|
|
|
// if the channel changed, unsubscribe!
|
|
|
|
if (entry && entry->Channel != channel) {
|
|
|
|
AdcSubscription::UnsubscribeSensor(sensor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-08 14:48:15 -08:00
|
|
|
void AdcSubscription::UpdateSubscribers(efitick_t nowNt) {
|
2019-10-11 17:43:21 -07:00
|
|
|
ScopePerf perf(PE::AdcSubscriptionUpdateSubscribers);
|
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
for (size_t i = 0; i < efi::size(s_entries); i++) {
|
2019-09-24 18:11:41 -07:00
|
|
|
auto &entry = s_entries[i];
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2021-08-14 05:41:27 -07:00
|
|
|
if (!entry.Sensor) {
|
|
|
|
// Skip unconfigured entries
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-09-21 11:33:38 -07:00
|
|
|
float mcuVolts = getVoltage("sensor", entry.Channel);
|
|
|
|
float sensorVolts = mcuVolts * entry.VoltsPerAdcVolt;
|
|
|
|
|
2020-08-31 18:05:04 -07:00
|
|
|
// On the very first update, preload the filter as if we've been
|
|
|
|
// seeing this value for a long time. This prevents a slow ramp-up
|
|
|
|
// towards the correct value just after startup
|
|
|
|
if (!entry.HasUpdated) {
|
|
|
|
entry.Filter.cookSteadyState(sensorVolts);
|
|
|
|
entry.HasUpdated = true;
|
|
|
|
}
|
|
|
|
|
2020-08-21 16:47:12 -07:00
|
|
|
float filtered = entry.Filter.filter(sensorVolts);
|
|
|
|
|
|
|
|
entry.Sensor->postRawValue(filtered, nowNt);
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-23 21:13:07 -07:00
|
|
|
#if EFI_PROD_CODE && HAL_USE_ADC
|
2022-10-10 04:44:20 -07:00
|
|
|
void AdcSubscription::PrintInfo() {
|
|
|
|
for (size_t i = 0; i < efi::size(s_entries); i++) {
|
|
|
|
auto& entry = s_entries[i];
|
|
|
|
|
|
|
|
if (!entry.Sensor) {
|
|
|
|
// Skip unconfigured entries
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto name = entry.Sensor->getSensorName();
|
|
|
|
float mcuVolts = getVoltage("sensor", entry.Channel);
|
|
|
|
float sensorVolts = mcuVolts * entry.VoltsPerAdcVolt;
|
|
|
|
auto channel = entry.Channel;
|
|
|
|
|
|
|
|
char pinNameBuffer[16];
|
|
|
|
|
|
|
|
efiPrintf(
|
|
|
|
"%s ADC%d m=%d %s adc=%.2f/input=%.2fv/divider=%.2f",
|
|
|
|
name,
|
|
|
|
channel,
|
|
|
|
getAdcMode(channel),
|
|
|
|
getPinNameByAdcChannel(name, channel, pinNameBuffer),
|
|
|
|
mcuVolts, sensorVolts, entry.VoltsPerAdcVolt
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2023-05-23 21:13:07 -07:00
|
|
|
#endif // EFI_PROD_CODE && HAL_USE_ADC
|
2022-10-10 04:44:20 -07:00
|
|
|
|
2019-09-24 18:11:41 -07:00
|
|
|
#endif // !EFI_UNIT_TEST
|