rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions | Variables
stm32_adc_v4.cpp File Reference

Detailed Description

Port implementation for the STM32 "v4" ADC found on the STM32H7.

Date
February 25, 2021
Author
Matthew Kennedy, (c) 2021

Definition in file stm32_adc_v4.cpp.

Functions

static constexpr size_t log2_int (size_t x)
 
void portInitAdc ()
 
float getMcuTemperature ()
 
float getMcuVrefVoltage ()
 
float getMcuVbatVoltage ()
 
static void adc_callback (ADCDriver *adcp)
 
bool readSlowAnalogInputs (adcsample_t *convertedSamples)
 
AdcToken enableFastAdcChannel (const char *, adc_channel_e channel)
 
adcsample_t getFastAdc (AdcToken token)
 
static void knockCompletionCallback (ADCDriver *adcp)
 
static void knockErrorCallback (ADCDriver *, adcerror_t)
 
const ADCConversionGroup * getKnockConversionGroup (uint8_t channelIdx)
 

Variables

static constexpr int H7_ADC_SHIFT_BITS = log2_int(H7_ADC_OVERSAMPLE)
 
adcsample_tfastSampleBuffer
 
constexpr size_t slowChannelCount = 16
 
static constexpr ADCConversionGroup convGroupSlow
 
static bool didStart = false
 
static constexpr int H7_KNOCK_ADC_SHIFT_BITS = log2_int(H7_KNOCK_OVERSAMPLE)
 
static const uint32_t smpr1
 
static const uint32_t smpr2
 
static const ADCConversionGroup adcConvGroupCh1
 
static const ADCConversionGroup adcConvGroupCh2
 

Function Documentation

◆ adc_callback()

static void adc_callback ( ADCDriver *  adcp)
static

Definition at line 74 of file stm32_adc_v4.cpp.

74 {
75 // State may not be complete if we get a callback for "half done"
76 if (adcIsBufferComplete(adcp)) {
77 // here we invoke 'fast' from slow ADC due to https://github.com/rusefi/rusefi/issues/3301
78 onFastAdcComplete(adcp->samples);
79 }
80
81 assertInterruptPriority(__func__, EFI_IRQ_ADC_PRIORITY);
82}
void onFastAdcComplete(adcsample_t *)
Definition hardware.cpp:278
void assertInterruptPriority(const char *func, uint8_t expectedPrio)
Here is the call graph for this function:

◆ enableFastAdcChannel()

AdcToken enableFastAdcChannel ( const char msg,
adc_channel_e  channel 
)

Definition at line 191 of file stm32_adc_v4.cpp.

191 {
193 return invalidAdcToken;
194 }
195
196 // H7 always samples all fast channels, nothing to do here but compute index
197 return channel - EFI_ADC_0;
198}
static constexpr AdcToken invalidAdcToken
Definition adc_inputs.h:110
bool isAdcChannelValid(adc_channel_e hwChannel)
Definition adc_inputs.h:23
uint16_t channel
Definition adc_inputs.h:104

Referenced by calcFastAdcIndexes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getFastAdc()

adcsample_t getFastAdc ( AdcToken  token)

Definition at line 200 of file stm32_adc_v4.cpp.

200 {
201 if (token == invalidAdcToken) {
202 return 0;
203 }
204
205 return fastSampleBuffer[token];
206}
adcsample_t * fastSampleBuffer

Referenced by onFastAdcComplete().

Here is the caller graph for this function:

◆ getKnockConversionGroup()

const ADCConversionGroup * getKnockConversionGroup ( uint8_t  channelIdx)

Definition at line 298 of file stm32_adc_v4.cpp.

298 {
299#if KNOCK_HAS_CH2
300 if (channelIdx == 1) {
301 return &adcConvGroupCh2;
302 }
303#else
304 (void)channelIdx;
305#endif // KNOCK_HAS_CH2
306
307 return &adcConvGroupCh1;
308}
float uint8_t channelIdx
static const ADCConversionGroup adcConvGroupCh2
static const ADCConversionGroup adcConvGroupCh1

Referenced by onStartKnockSampling().

Here is the caller graph for this function:

◆ getMcuTemperature()

float getMcuTemperature ( )

Definition at line 57 of file stm32_adc_v4.cpp.

57 {
58 // Ugh, internal temp sensor is wired to ADC3, which makes it nearly useless on the H7.
59 return 0;
60}

◆ getMcuVbatVoltage()

float getMcuVbatVoltage ( )

Definition at line 67 of file stm32_adc_v4.cpp.

67 {
68 // TODO: implement me!
69 return 0;
70}

◆ getMcuVrefVoltage()

float getMcuVrefVoltage ( )

Definition at line 62 of file stm32_adc_v4.cpp.

62 {
63 // TODO: implement me!
65}
static constexpr engine_configuration_s * engineConfiguration

◆ knockCompletionCallback()

static void knockCompletionCallback ( ADCDriver *  adcp)
static

Definition at line 214 of file stm32_adc_v4.cpp.

214 {
215 if (adcIsBufferComplete(adcp)) {
217 }
218
219 assertInterruptPriority(__func__, EFI_IRQ_ADC_PRIORITY);
220}
void onKnockSamplingComplete()
Here is the call graph for this function:

◆ knockErrorCallback()

static void knockErrorCallback ( ADCDriver *  ,
adcerror_t   
)
static

Definition at line 222 of file stm32_adc_v4.cpp.

222 {
223}

◆ log2_int()

static constexpr size_t log2_int ( size_t  x)
staticconstexpr

Definition at line 30 of file stm32_adc_v4.cpp.

30 {
31 size_t result = 0;
32 while (x >>= 1) result++;
33 return result;
34}

◆ portInitAdc()

void portInitAdc ( )

Definition at line 43 of file stm32_adc_v4.cpp.

43 {
44 // Init slow ADC
45 adcStart(&ADCD1, NULL);
46
47#if STM32_ADC_USE_ADC3
48 // Knock/trigger scope ADC
49 adcStart(&ADCD3, nullptr);
50#endif // STM32_ADC_USE_ADC3
51
52 // Connect the analog switches between {PA0_C, PA1_C, PC2_C, PC3_C} and their non-C counterparts
53 // This lets us use normal (non-direct) analog on those channels
54 SYSCFG->PMCR &= ~(SYSCFG_PMCR_PA0SO | SYSCFG_PMCR_PA1SO | SYSCFG_PMCR_PC2SO | SYSCFG_PMCR_PC3SO);
55}
ADCDriver ADCD3
ADC3 driver identifier.
Definition hal_adc_lld.c:54
ADCDriver ADCD1
ADC1 driver identifier.
Definition hal_adc_lld.c:44

◆ readSlowAnalogInputs()

bool readSlowAnalogInputs ( adcsample_t convertedSamples)

Definition at line 157 of file stm32_adc_v4.cpp.

157 {
158 // This only needs to happen once, as the timer will continue firing the ADC and writing to the buffer without our help
159 if (didStart) {
160 return true;
161 }
162 didStart = true;
163
164 fastSampleBuffer = convertedSamples;
165
166 {
167 chibios_rt::CriticalSectionLocker csl;
168 // Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
169 adcStartConversionI(&ADCD1, &convGroupSlow, convertedSamples, 1);
170 }
171
172 constexpr uint32_t samplingRate = H7_ADC_SPEED;
173 constexpr uint32_t timerCountFrequency = samplingRate * 10;
174 constexpr uint32_t timerPeriod = timerCountFrequency / samplingRate;
175
176 static constexpr GPTConfig gptCfg = {
177 timerCountFrequency,
178 nullptr,
179 TIM_CR2_MMS_1, // TRGO on update event
180 0
181 };
182
183 // Start timer
184 gptStart(&GPTD3, &gptCfg);
185 gptStartContinuous(&GPTD3, timerPeriod);
186
187 // Return true if OK
188 return true;
189}
GPTDriver GPTD3
GPTD3 driver identifier.
Definition hal_gpt_lld.c:59
static constexpr ADCConversionGroup convGroupSlow
static bool didStart
Driver configuration structure.

Variable Documentation

◆ adcConvGroupCh1

const ADCConversionGroup adcConvGroupCh1
static
Initial value:
= {
.circular = FALSE,
.num_channels = 1,
.error_cb = &knockErrorCallback,
.cfgr = 0,
.cfgr2 = (H7_KNOCK_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos |
H7_KNOCK_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos |
ADC_CFGR2_ROVSE,
.ccr = 0,
.pcsel = 0xFFFFFFFF,
.ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0,
.awd2cr = 0,
.awd3cr = 0,
.smpr = {smpr1, smpr2},
.sqr = {
ADC_SQR1_SQ1_N(KNOCK_ADC_CH1),
0,
0
},
}
static const uint32_t smpr1
static void knockCompletionCallback(ADCDriver *adcp)
static const uint32_t smpr2
static void knockErrorCallback(ADCDriver *, adcerror_t)
static constexpr int H7_KNOCK_ADC_SHIFT_BITS

Definition at line 249 of file stm32_adc_v4.cpp.

249 {
250 .circular = FALSE,
251 .num_channels = 1,
252 .end_cb = &knockCompletionCallback,
253 .error_cb = &knockErrorCallback,
254 .cfgr = 0,
255 .cfgr2 = (H7_KNOCK_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos | // Oversample by Nx (register contains N-1)
256 H7_KNOCK_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos | // shift the result right log2(N) bits to make a 16 bit result out of the internal oversample sum
257 ADC_CFGR2_ROVSE, // Enable oversampling
258 .ccr = 0,
259 .pcsel = 0xFFFFFFFF, // enable analog switches on all channels
260 // Thresholds aren't used
261 .ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0,
262 .awd2cr = 0,
263 .awd3cr = 0,
264 .smpr = {smpr1, smpr2},
265 .sqr = {
266 ADC_SQR1_SQ1_N(KNOCK_ADC_CH1),
267 0,
268 0
269 },
270};

Referenced by getKnockConversionGroup().

◆ adcConvGroupCh2

const ADCConversionGroup adcConvGroupCh2
static
Initial value:
= {
.circular = FALSE,
.num_channels = 1,
.error_cb = &knockErrorCallback,
.cfgr = 0,
.cfgr2 = (H7_ADC_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos |
H7_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos |
ADC_CFGR2_ROVSE,
.ccr = 0,
.pcsel = 0xFFFFFFFF,
.ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0,
.awd2cr = 0,
.awd3cr = 0,
.smpr = {smpr1, smpr2},
.sqr = {
ADC_SQR1_SQ1_N(KNOCK_ADC_CH2),
0,
0
},
}
static constexpr int H7_ADC_SHIFT_BITS

Definition at line 274 of file stm32_adc_v4.cpp.

274 {
275 .circular = FALSE,
276 .num_channels = 1,
277 .end_cb = &knockCompletionCallback,
278 .error_cb = &knockErrorCallback,
279 .cfgr = 0,
280 .cfgr2 = (H7_ADC_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos | // Oversample by Nx (register contains N-1)
281 H7_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos | // shift the result right log2(N) bits to make a 16 bit result out of the internal oversample sum
282 ADC_CFGR2_ROVSE, // Enable oversampling
283 .ccr = 0,
284 .pcsel = 0xFFFFFFFF, // enable analog switches on all channels
285 // Thresholds aren't used
286 .ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0,
287 .awd2cr = 0,
288 .awd3cr = 0,
289 .smpr = {smpr1, smpr2},
290 .sqr = {
291 ADC_SQR1_SQ1_N(KNOCK_ADC_CH2),
292 0,
293 0
294 },
295};

Referenced by getKnockConversionGroup().

◆ convGroupSlow

constexpr ADCConversionGroup convGroupSlow
staticconstexpr

Definition at line 95 of file stm32_adc_v4.cpp.

95 {
96 .circular = true, // Continuous mode means we will auto re-trigger on every timer event
97 .num_channels = slowChannelCount,
98 .end_cb = adc_callback,
99 .error_cb = nullptr,
100 .cfgr = ADC_CFGR_EXTEN_0 | (4 << ADC_CFGR_EXTSEL_Pos), // External trigger ch4, rising edge: TIM3 TRGO
101 .cfgr2 = (H7_ADC_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos | // Oversample by Nx (register contains N-1)
102 H7_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos | // shift the result right log2(N) bits to make a 16 bit result out of the internal oversample sum
103 ADC_CFGR2_ROVSE, // Enable oversampling
104 .ccr = 0,
105 .pcsel = 0xFFFFFFFF, // enable analog switches on all channels
106 // Thresholds aren't used
107 .ltr1 = 0, .htr1 = 0, .ltr2 = 0, .htr2 = 0, .ltr3 = 0, .htr3 = 0,
108 .awd2cr = 0,
109 .awd3cr = 0,
110 .smpr = {
111 // Configure all channels to use ADC_SAMPLING_SLOW time
112 ADC_SMPR1_SMP_AN0(ADC_SAMPLING_SLOW) |
113 ADC_SMPR1_SMP_AN1(ADC_SAMPLING_SLOW) |
114 ADC_SMPR1_SMP_AN2(ADC_SAMPLING_SLOW) |
115 ADC_SMPR1_SMP_AN3(ADC_SAMPLING_SLOW) |
116 ADC_SMPR1_SMP_AN4(ADC_SAMPLING_SLOW) |
117 ADC_SMPR1_SMP_AN5(ADC_SAMPLING_SLOW) |
118 ADC_SMPR1_SMP_AN6(ADC_SAMPLING_SLOW) |
119 ADC_SMPR1_SMP_AN7(ADC_SAMPLING_SLOW) |
120 ADC_SMPR1_SMP_AN8(ADC_SAMPLING_SLOW) |
121 ADC_SMPR1_SMP_AN9(ADC_SAMPLING_SLOW),
122 ADC_SMPR2_SMP_AN10(ADC_SAMPLING_SLOW) |
123 ADC_SMPR2_SMP_AN11(ADC_SAMPLING_SLOW) |
124 ADC_SMPR2_SMP_AN12(ADC_SAMPLING_SLOW) |
125 ADC_SMPR2_SMP_AN13(ADC_SAMPLING_SLOW) |
126 ADC_SMPR2_SMP_AN14(ADC_SAMPLING_SLOW) |
127 ADC_SMPR2_SMP_AN15(ADC_SAMPLING_SLOW) |
128 ADC_SMPR2_SMP_AN16(ADC_SAMPLING_SLOW) |
129 ADC_SMPR2_SMP_AN17(ADC_SAMPLING_SLOW) |
130 ADC_SMPR2_SMP_AN18(ADC_SAMPLING_SLOW) |
131 ADC_SMPR2_SMP_AN19(ADC_SAMPLING_SLOW)
132 },
133 .sqr = {
134 // The seemingly insane values here exist to put the values
135 // in the buffer in the same order as the ADCv2 (F4/F7) ADC
136 ADC_SQR1_SQ1_N(16) | // PA0 (aka PA0_C)
137 ADC_SQR1_SQ2_N(17) | // PA1 (aka PA1_C)
138 ADC_SQR1_SQ3_N(14) | // PA2
139 ADC_SQR1_SQ4_N(15), // PA3
140 ADC_SQR2_SQ5_N(18) | // PA4
141 ADC_SQR2_SQ6_N(19) | // PA5
142 ADC_SQR2_SQ7_N(3) | // PA6
143 ADC_SQR2_SQ8_N(7) | // PA7
144 ADC_SQR2_SQ9_N(9), // PB0
145 ADC_SQR3_SQ10_N(5) | // PB1
146 ADC_SQR3_SQ11_N(10) | // PC0
147 ADC_SQR3_SQ12_N(11) | // PC1
148 ADC_SQR3_SQ13_N(12) | // PC2 (aka PC2_C)
149 ADC_SQR3_SQ14_N(13), // PC3 (aka PC3_C)
150 ADC_SQR4_SQ15_N(4) | // PC4
151 ADC_SQR4_SQ16_N(8) // PC5
152 },
153};
static void adc_callback(ADCDriver *adcp)
constexpr size_t slowChannelCount

Referenced by readSlowAnalogInputs().

◆ didStart

bool didStart = false
static

Definition at line 155 of file stm32_adc_v4.cpp.

Referenced by readSlowAnalogInputs().

◆ fastSampleBuffer

adcsample_t* fastSampleBuffer

Definition at line 72 of file stm32_adc_v4.cpp.

Referenced by getFastAdc(), and readSlowAnalogInputs().

◆ H7_ADC_SHIFT_BITS

constexpr int H7_ADC_SHIFT_BITS = log2_int(H7_ADC_OVERSAMPLE)
staticconstexpr

Definition at line 41 of file stm32_adc_v4.cpp.

◆ H7_KNOCK_ADC_SHIFT_BITS

constexpr int H7_KNOCK_ADC_SHIFT_BITS = log2_int(H7_KNOCK_OVERSAMPLE)
staticconstexpr

Definition at line 212 of file stm32_adc_v4.cpp.

◆ slowChannelCount

constexpr size_t slowChannelCount = 16
constexpr

Definition at line 91 of file stm32_adc_v4.cpp.

◆ smpr1

const uint32_t smpr1
static
Initial value:
=
ADC_SMPR1_SMP_AN0(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN1(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN2(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN3(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN4(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN5(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN6(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN7(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN8(KNOCK_SAMPLE_TIME) |
ADC_SMPR1_SMP_AN9(KNOCK_SAMPLE_TIME)

Definition at line 225 of file stm32_adc_v4.cpp.

◆ smpr2

const uint32_t smpr2
static
Initial value:
=
ADC_SMPR2_SMP_AN10(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN11(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN12(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN13(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN14(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN15(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN16(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN17(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN18(KNOCK_SAMPLE_TIME) |
ADC_SMPR2_SMP_AN19(KNOCK_SAMPLE_TIME)

Definition at line 237 of file stm32_adc_v4.cpp.

Go to the source code of this file.