From eb27bcf3d6242d93325ad95561324dbfe7c6ec89 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Tue, 17 Dec 2019 05:34:56 -0800 Subject: [PATCH] Terrible ADC3 hack for Proteus vbatt support (#1066) * this is a great idea! * typo * simplify * simplify, cache coherency * enable adc3 in board file * copyright * fix tests, probably --- firmware/config/boards/proteus/adc_hack.cpp | 54 +++++++++++++++++++ firmware/config/boards/proteus/board.mk | 5 +- .../boards/proteus/board_configuration.cpp | 3 -- firmware/controllers/sensors/voltage.cpp | 5 ++ firmware/hw_layer/adc_inputs.cpp | 5 ++ .../ports/stm32/stm32_common_mpu_util.h | 3 ++ firmware/util/efilib.h | 2 + 7 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 firmware/config/boards/proteus/adc_hack.cpp diff --git a/firmware/config/boards/proteus/adc_hack.cpp b/firmware/config/boards/proteus/adc_hack.cpp new file mode 100644 index 0000000000..eeb13248fa --- /dev/null +++ b/firmware/config/boards/proteus/adc_hack.cpp @@ -0,0 +1,54 @@ +/** + * @file adc_hack.cpp + * @brief Hacky support for a single channel on adc3 + * + * @date December 17, 2019 + * @author Matthew Kennedy, (c) 2019 + */ + +#include "ch.h" +#include "hal.h" + +#include "mpu_util.h" +#include "io_pins.h" + +#include "efilib.h" + +static ADCConversionGroup adcConvGroup = { FALSE, 1, nullptr, nullptr, + 0, + ADC_CR2_SWSTART, + 0, // sample times for channels 10...18 + ADC_SMPR2_SMP_AN9(ADC_SAMPLE_56), + + 0, // htr + 0, // ltr + + 0, // sqr1 + 0, // sqr2 + ADC_SQR3_SQ1_N(ADC_CHANNEL_IN9) // sqr3 - vbatt is on pf3 = adc9 +}; + +__ALIGNED(32) adcsample_t samples[8]; + +// we use this as a hook to run near the rest of ADC init... +void setAdcChannelOverrides(void) { + efiSetPadMode("adc input", GPIOF_3, PAL_MODE_INPUT_ANALOG); + + adcStart(&ADCD3, nullptr); +} + +adcsample_t vbattSampleProteus = 0; + +void proteusAdcHack() +{ + adcConvert(&ADCD3, &adcConvGroup, samples, 8); + SCB_InvalidateDCache_by_Addr(reinterpret_cast(samples), sizeof(samples)); + + uint32_t sum = 0; + + for (int i = 0; i < 8; i++) { + sum += samples[i]; + } + + vbattSampleProteus = sum / efi::size(samples); +} diff --git a/firmware/config/boards/proteus/board.mk b/firmware/config/boards/proteus/board.mk index eb50754451..83e6d059c4 100644 --- a/firmware/config/boards/proteus/board.mk +++ b/firmware/config/boards/proteus/board.mk @@ -1,6 +1,7 @@ # List of all the board related files. BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_F767ZI/board.c -BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/proteus/board_configuration.cpp +BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/proteus/board_configuration.cpp \ + $(PROJECT_DIR)/config/boards/proteus/adc_hack.cpp # Required include directories BOARDINC = $(PROJECT_DIR)/config/boards/nucleo_f767 $(PROJECT_DIR)/config/stm32f7ems @@ -8,4 +9,4 @@ BOARDINC = $(PROJECT_DIR)/config/boards/nucleo_f767 $(PROJECT_DIR)/config/stm32f LDSCRIPT= $(PROJECT_DIR)/config/boards/nucleo_f767/STM32F76xxI.ld # Override DEFAULT_ENGINE_TYPE -DDEFS += -DSTM32F767xx -DEFI_USE_OSC=TRUE -DEFI_FATAL_ERROR_PIN=GPIOE_3 -DFIRMWARE_ID=\"proteus\" -DDEFAULT_ENGINE_TYPE=PROTEUS +DDEFS += -DSTM32F767xx -DEFI_USE_OSC=TRUE -DEFI_FATAL_ERROR_PIN=GPIOE_3 -DFIRMWARE_ID=\"proteus\" -DDEFAULT_ENGINE_TYPE=PROTEUS -DUSE_ADC3_VBATT_HACK -DSTM32_ADC_USE_ADC3=TRUE diff --git a/firmware/config/boards/proteus/board_configuration.cpp b/firmware/config/boards/proteus/board_configuration.cpp index a0bc6c067d..ac31207589 100644 --- a/firmware/config/boards/proteus/board_configuration.cpp +++ b/firmware/config/boards/proteus/board_configuration.cpp @@ -167,6 +167,3 @@ void setBoardConfigurationOverrides(void) { engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS; engineConfiguration->injectionMode = IM_SIMULTANEOUS; } - -void setAdcChannelOverrides(void) { -} diff --git a/firmware/controllers/sensors/voltage.cpp b/firmware/controllers/sensors/voltage.cpp index 994aa9f31a..e74fe6e6bc 100644 --- a/firmware/controllers/sensors/voltage.cpp +++ b/firmware/controllers/sensors/voltage.cpp @@ -24,5 +24,10 @@ bool hasVBatt(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } float getVBatt(DECLARE_ENGINE_PARAMETER_SIGNATURE) { +#ifdef USE_ADC3_VBATT_HACK + extern adcsample_t vbattSampleProteus; + return adcToVolts(vbattSampleProteus) * engineConfiguration->vbattDividerCoeff; +#else return getVoltage("vbatt", engineConfiguration->vbattAdcChannel PASS_ENGINE_PARAMETER_SUFFIX) * engineConfiguration->vbattDividerCoeff; +#endif } diff --git a/firmware/hw_layer/adc_inputs.cpp b/firmware/hw_layer/adc_inputs.cpp index 25e387076d..b317e65ca5 100644 --- a/firmware/hw_layer/adc_inputs.cpp +++ b/firmware/hw_layer/adc_inputs.cpp @@ -433,6 +433,11 @@ public: slowAdc.errorsCount++; return; } + +#ifdef USE_ADC3_VBATT_HACK + void proteusAdcHack(); + proteusAdcHack(); +#endif } { diff --git a/firmware/hw_layer/ports/stm32/stm32_common_mpu_util.h b/firmware/hw_layer/ports/stm32/stm32_common_mpu_util.h index 15b9c51a64..ef22c44ff8 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common_mpu_util.h +++ b/firmware/hw_layer/ports/stm32/stm32_common_mpu_util.h @@ -7,6 +7,9 @@ */ // burnout or 'Burn Out' + +#include "rusefi_enums.h" + typedef enum { BOR_Level_None = OB_BOR_OFF, // 0x0C=12 Supply voltage ranges from 1.62 to 2.10 V BOR_Level_1 = OB_BOR_LEVEL1, // 0x08 Supply voltage ranges from 2.10 to 2.40 V diff --git a/firmware/util/efilib.h b/firmware/util/efilib.h index 9556cd40de..79a5f3b870 100644 --- a/firmware/util/efilib.h +++ b/firmware/util/efilib.h @@ -87,6 +87,8 @@ float expf_taylor(float x); #ifdef __cplusplus } +#include + // C++ helpers go here namespace efi {