From 047e4135df711b34737fa87b33322db5fc4d692d Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 2 Jan 2025 18:23:43 -0800 Subject: [PATCH 1/3] set up ADC dual mode --- .../hw_layer/ports/stm32/stm32_adc_v4.cpp | 87 +++++++++++++++---- .../ports/stm32/stm32h7/cfg/mcuconf.h | 2 +- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp index b279658522..ca8b87a491 100644 --- a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp @@ -71,8 +71,8 @@ static void adc_callback(ADCDriver *adcp) { // (25 * 64) / 25MHz -> 64 microseconds to sample all channels #define ADC_SAMPLING_SLOW ADC_SMPR_SMP_16P5 -// Sample the 16 channels that line up with the STM32F4/F7 -constexpr size_t slowChannelCount = 16; +// Sample the 16 channels that line up with the STM32F4/F7, plus PF11/12/13/14 +constexpr size_t slowChannelCount = 20; // Conversion group for slow channels // This simply samples every channel in sequence @@ -89,8 +89,7 @@ static constexpr ADCConversionGroup convGroupSlow = { .pcsel = 0xFFFFFFFF, // enable analog switches on all channels // Thresholds aren't used .ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0, - .awd2cr = 0, - .awd3cr = 0, + .awd2cr = 0, .awd3cr = 0, .smpr = { // Configure all channels to use ADC_SAMPLING_SLOW time ADC_SMPR1_SMP_AN0(ADC_SAMPLING_SLOW) | @@ -115,27 +114,71 @@ static constexpr ADCConversionGroup convGroupSlow = { ADC_SMPR2_SMP_AN19(ADC_SAMPLING_SLOW) }, .sqr = { - // The seemingly insane values here exist to put the values - // in the buffer in the same order as the ADCv2 (F4/F7) ADC + // ADC1 samples the first 10 channels: PA0-5, PB0-1, PF11-12 ADC_SQR1_SQ1_N(16) | // PA0 (aka PA0_C) ADC_SQR1_SQ2_N(17) | // PA1 (aka PA1_C) ADC_SQR1_SQ3_N(14) | // PA2 ADC_SQR1_SQ4_N(15), // PA3 ADC_SQR2_SQ5_N(18) | // PA4 ADC_SQR2_SQ6_N(19) | // PA5 - ADC_SQR2_SQ7_N(3) | // PA6 - ADC_SQR2_SQ8_N(7) | // PA7 - ADC_SQR2_SQ9_N(9), // PB0 - ADC_SQR3_SQ10_N(5) | // PB1 - ADC_SQR3_SQ11_N(10) | // PC0 - ADC_SQR3_SQ12_N(11) | // PC1 - ADC_SQR3_SQ13_N(12) | // PC2 (aka PC2_C) - ADC_SQR3_SQ14_N(13), // PC3 (aka PC3_C) - ADC_SQR4_SQ15_N(4) | // PC4 - ADC_SQR4_SQ16_N(8) // PC5 + ADC_SQR2_SQ7_N(9) | // PB0 + ADC_SQR2_SQ8_N(5) | // PB1 + ADC_SQR2_SQ9_N(2), // PF11 + ADC_SQR3_SQ10_N(6), // PF12 + 0 + }, + + // Thresholds aren't used + .sltr1 = 0, .shtr1 = 0, .sltr2 = 0, .shtr2 = 0, .sltr3 = 0, .shtr3 = 0, + .sawd2cr = 0, .sawd3cr = 0, + .ssmpr = { + // Configure all channels to use ADC_SAMPLING_SLOW time + ADC_SMPR1_SMP_AN0(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN1(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN2(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN3(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN4(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN5(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN6(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN7(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN8(ADC_SAMPLING_SLOW) | + ADC_SMPR1_SMP_AN9(ADC_SAMPLING_SLOW), + ADC_SMPR2_SMP_AN10(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN11(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN12(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN13(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN14(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN15(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN16(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN17(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN18(ADC_SAMPLING_SLOW) | + ADC_SMPR2_SMP_AN19(ADC_SAMPLING_SLOW) + }, + .ssqr = { + // ADC2 samples the second 10 channels: PA6-7, PC0-5, PF11-14 + ADC_SQR1_SQ1_N(3) | // PA6 (aka PA0_C) + ADC_SQR1_SQ2_N(7) | // PA7 (aka PA1_C) + ADC_SQR1_SQ3_N(10) | // PC0 + ADC_SQR1_SQ4_N(11), // PC1 + ADC_SQR2_SQ5_N(12) | // PC2 + ADC_SQR2_SQ6_N(13) | // PC3 + ADC_SQR2_SQ7_N(4) | // PC4 + ADC_SQR2_SQ8_N(8) | // PC5 + ADC_SQR2_SQ9_N(2), // PF13 + ADC_SQR3_SQ10_N(6), // PF14 + 0 }, }; +static const uint8_t adcChannelScramble[20] = { + 0, 1, 2, 3, 4, 5, // ADC1: PA0-5 + 10, 11, // ADC2: PA6/7 + 6, 7, // ADC1: PB0/1 + 12, 13, 14, 15, 16, 17, // ADC2: PC0-5 + 8, 9, // ADC1: PF11/12 + 18, 19 // ADC2: PF13/14 +}; + static bool didStart = false; bool readSlowAnalogInputs(adcsample_t* convertedSamples) { @@ -251,6 +294,12 @@ static const ADCConversionGroup adcConvGroupCh1 = { 0, 0 }, + + // Dual mode isn't used on knock ADC, so all zeroes + .sltr1 = 0, .shtr1 = 0, .sltr2 = 0, .shtr2 = 0, .sltr3 = 0, .shtr3 = 0, + .sawd2cr = 0, .sawd3cr = 0, + .ssmpr = {0, 0}, + .ssqr = {0, 0, 0, 0}, }; // Not all boards have a second channel - configure it if it exists @@ -276,6 +325,12 @@ static const ADCConversionGroup adcConvGroupCh2 = { 0, 0 }, + + // Dual mode isn't used on knock ADC, so all zeroes + .sltr1 = 0, .shtr1 = 0, .sltr2 = 0, .shtr2 = 0, .sltr3 = 0, .shtr3 = 0, + .sawd2cr = 0, .sawd3cr = 0, + .ssmpr = {0, 0}, + .ssqr = {0, 0, 0, 0}, }; #endif // KNOCK_HAS_CH2 diff --git a/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h b/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h index 2231726750..739a27a3f8 100644 --- a/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h +++ b/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h @@ -251,7 +251,7 @@ /* * ADC driver system settings. */ -#define STM32_ADC_DUAL_MODE FALSE +#define STM32_ADC_DUAL_MODE TRUE #define STM32_ADC_COMPACT_SAMPLES FALSE #define STM32_ADC_USE_ADC12 TRUE From a52f57eeb04bfa633ea0a5a3c67c8d4a1ba09aff Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 2 Jan 2025 18:23:49 -0800 Subject: [PATCH 2/3] new pins --- firmware/hw_layer/ports/stm32/stm32_common.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/firmware/hw_layer/ports/stm32/stm32_common.cpp b/firmware/hw_layer/ports/stm32/stm32_common.cpp index fa12f9d738..5da03a32a0 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_common.cpp @@ -89,6 +89,16 @@ brain_pin_e getAdcChannelBrainPin(const char*, adc_channel_e hwChannel) { return Gpio::C4; case EFI_ADC_15: return Gpio::C5; +#ifdef STM32H7XX + case EFI_ADC_16: + return Gpio::F11; + case EFI_ADC_17: + return Gpio::F12; + case EFI_ADC_18: + return Gpio::F13; + case EFI_ADC_19: + return Gpio::F14; +#endif // STM32H7xx default: /* todo: what is upper range ADC is used while lower range ADC is not used? how do we still mark pin used? external muxes for internal ADC #3350 From 62fcece9bfc8d2a134990c36a95caf420d375fe2 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 2 Jan 2025 18:33:45 -0800 Subject: [PATCH 3/3] adc channel scrambler --- firmware/hw_layer/adc/adc_inputs.cpp | 4 ++-- firmware/hw_layer/adc/adc_subscription.cpp | 2 +- firmware/hw_layer/ports/mpu_util.h | 3 +++ firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp | 4 ++++ firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/firmware/hw_layer/adc/adc_inputs.cpp b/firmware/hw_layer/adc/adc_inputs.cpp index 2f81834db8..a8c1f43f95 100644 --- a/firmware/hw_layer/adc/adc_inputs.cpp +++ b/firmware/hw_layer/adc/adc_inputs.cpp @@ -22,7 +22,7 @@ #include "pch.h" float __attribute__((weak)) getAnalogInputDividerCoefficient(adc_channel_e) { - return engineConfiguration->analogInputDividerCoefficient; + return engineConfiguration->analogInputDividerCoefficient; } #if HAL_USE_ADC @@ -109,7 +109,7 @@ int getInternalAdcValue(const char *msg, adc_channel_e hwChannel) { } #endif // EFI_USE_FAST_ADC - return slowAdcSamples[hwChannel - EFI_ADC_0]; + return slowAdcSamples[indexForSlowAdcChannel(hwChannel)]; } #if EFI_USE_FAST_ADC diff --git a/firmware/hw_layer/adc/adc_subscription.cpp b/firmware/hw_layer/adc/adc_subscription.cpp index 9d88f72489..9717715186 100644 --- a/firmware/hw_layer/adc/adc_subscription.cpp +++ b/firmware/hw_layer/adc/adc_subscription.cpp @@ -83,7 +83,7 @@ TODO: this code is similar to initIfValid, what is the plan? shall we extract he brain_pin_e pin = getAdcChannelBrainPin(name, channel); if (pin != Gpio::Invalid) { // todo: external muxes for internal ADC #3350 - efiSetPadMode(name, pin, PAL_MODE_INPUT_ANALOG); + efiSetPadMode(name, pin, PAL_MODE_INPUT_ANALOG); } // if 0, default to the board's divider coefficient for given channel diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index b89cadd42b..0fb106d897 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -25,6 +25,9 @@ void portInitAdc(); float getMcuTemperature(); // Convert all slow ADC inputs. Returns true if the conversion succeeded, false if a failure occured. bool readSlowAnalogInputs(adcsample_t* convertedSamples); + +// Get the position of samples for this channel in the sample buffer +size_t indexForSlowAdcChannel(adc_channel_e channel); #endif // CAN bus diff --git a/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp b/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp index 68de8cc234..da11ca93e3 100644 --- a/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp @@ -211,6 +211,10 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) { return result; } +size_t indexForSlowAdcChannel(adc_channel_e channel) { + return channel - EFI_ADC_0; +} + #if EFI_USE_FAST_ADC #include "AdcConfiguration.h" diff --git a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp index ca8b87a491..d9261e7978 100644 --- a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp @@ -179,6 +179,10 @@ static const uint8_t adcChannelScramble[20] = { 18, 19 // ADC2: PF13/14 }; +size_t indexForSlowAdcChannel(adc_channel_e channel) { + return adcChannelScramble[channel - EFI_ADC_0]; +} + static bool didStart = false; bool readSlowAnalogInputs(adcsample_t* convertedSamples) {