rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
adc_inputs.h
Go to the documentation of this file.
1/**
2 * @file adc_inputs.h
3 * @brief Low level internal ADC code
4 *
5 * @date Jan 14, 2013
6 * @author Andrey Belomutskiy, (c) 2012-2020
7 */
8
9#pragma once
10
11#include "global.h"
12#include "adc_math.h"
13
14#ifndef SLOW_ADC_RATE
15#define SLOW_ADC_RATE 500
16#endif
17
19float boardAdjustVoltage(float voltage, adc_channel_e hwChannel);
20/* optional, checks if measured voltage is valid */
22
23inline bool isAdcChannelValid(adc_channel_e hwChannel) {
24 /* Compiler will optimize, keep following if as a reminder */
25 if (hwChannel >= EFI_ADC_TOTAL_CHANNELS) {
26 /* this should not happen!
27 * if we have enum out of range somewhere in settings
28 * that means something goes terribly wrong
29 * TODO: should we say something?
30 */
31 return false;
32 }
33 return ((hwChannel > EFI_ADC_NONE) && (hwChannel < EFI_ADC_TOTAL_CHANNELS));
34}
35
36inline bool isAdcChannelOnChip(adc_channel_e hwChannel) {
37 return (isAdcChannelValid(hwChannel) && (hwChannel <= EFI_ADC_ONCHIP_LAST));
38}
39
40inline bool isAdcChannelOffChip(adc_channel_e hwChannel) {
41 return (isAdcChannelValid(hwChannel) && (hwChannel > EFI_ADC_ONCHIP_LAST));
42}
43
45
46#if !defined(GPT_FREQ_FAST) || !defined(GPT_PERIOD_FAST)
47
48/*
49 * 8000 RPM is 133Hz
50 * If we want to sample MAP once per 5 degrees we need 133Hz * (360 / 5) = 9576Hz of fast ADC ~= 10 KHz
51 */
52
53/*
54 * TODO: migrate to continuous ADC mode? probably not - we cannot afford the callback in continuous mode.
55 * TODO: look into other options
56 * TODO: ADC convertion can be triggered directly from timer, with no SW intervention
57 */
58
59/* PWM clock frequency. Timer clock = 100 KHz */
60#define GPT_FREQ_FAST 100000
61/* PWM period (in PWM ticks), 100 KHz / 10 = 10KHz callback rate */
62#define GPT_PERIOD_FAST 10
63
64/*
65 * We have 1 / (GPT_FREQ_FAST / GPT_PERIOD_FAST) to finish conversion = 100 uS
66 * With ADC_SAMPLING_FAST = 28 ADC clock @ 21 MHz (F4)
67 * One channel conversion takes 28 + 12 = 40 clocks
68 * One channel conversion takes 1 / 21`000`000 * 40 = 1.904 uS
69 * Oversampling is ADC_BUF_DEPTH_FAST = 4
70 * We can do up-to 100 / (1.904 * 4) = 13.125 channels conversions
71 */
72
73#endif /* GPT_FREQ_FAST GPT_PERIOD_FAST */
74
75#if HAL_USE_ADC
76
77enum class AdcChannelMode : char {
78 Off,
79 Slow,
80 Fast
81};
82
83void adcInputsUpdateSubscribers(efitick_t nowNt);
84
86void initAdcInputs();
87
89int getInternalAdcValue(const char *msg, adc_channel_e index);
90
91void addFastAdcChannel(const char *name, adc_channel_e hwChannel);
92void removeChannel(const char *name, adc_channel_e hwChannel);
93
94#define adcGetRawValue(msg, hwChannel) getInternalAdcValue(msg, hwChannel)
95
96#define adcRawValueToScaledVoltage(adc, hwChannel) (adcRawValueToRawVoltage(adc) * getAnalogInputDividerCoefficient(hwChannel))
97
98using AdcToken = uint32_t;
99
100using AdcTockenInternal = union {
101 AdcToken token;
102 struct {
103 uint16_t adc;
104 uint16_t channel;
105 } __attribute__((packed));
106};
107
108static_assert(sizeof(AdcTockenInternal) == sizeof(AdcToken));
109
110static constexpr AdcToken invalidAdcToken = (AdcToken)(-1);
111
114const ADCConversionGroup* getKnockConversionGroup(uint8_t channelIdx);
116
117// Slow ADC stuff
118float getMCUInternalTemperature(void);
119float getMCUVref(void);
120// wait until at least 1 slowADC sampling is complete
121void waitForSlowAdc(uint32_t lastAdcCounter = 1);
122
123#endif // HAL_USE_ADC
124
125void printFullAdcReport(void);
const ADCConversionGroup * getKnockConversionGroup(uint8_t channelIdx)
void adcInputsUpdateSubscribers(efitick_t nowNt)
void initAdcInputs()
void removeChannel(const char *name, adc_channel_e hwChannel)
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
int boardGetAnalogInputDiagnostic(adc_channel_e, float voltage)
AdcToken enableFastAdcChannel(const char *msg, adc_channel_e channel)
Definition mpu_util.cpp:279
float getMCUInternalTemperature(void)
bool isAdcChannelOnChip(adc_channel_e hwChannel)
Definition adc_inputs.h:36
AdcChannelMode
Definition adc_inputs.h:77
adcsample_t getFastAdc(AdcToken token)
Definition mpu_util.cpp:288
AdcChannelMode getAdcMode(adc_channel_e hwChannel)
float boardAdjustVoltage(float voltage, adc_channel_e hwChannel)
void waitForSlowAdc(uint32_t lastAdcCounter=1)
bool isAdcChannelOffChip(adc_channel_e hwChannel)
Definition adc_inputs.h:40
ObdCode analogGetDiagnostic()
void onKnockSamplingComplete()
void printFullAdcReportIfNeeded(void)
uint16_t adc
Definition adc_inputs.h:103
float getMCUVref(void)
void addFastAdcChannel(const char *name, adc_channel_e hwChannel)
union { AdcToken token AdcTockenInternal
Definition adc_inputs.h:101
int getInternalAdcValue(const char *msg, adc_channel_e index)
void printFullAdcReport(void)
float getAnalogInputDividerCoefficient(adc_channel_e)
uint32_t AdcToken
Definition adc_inputs.h:98
typedef __attribute__
Ignition Mode.
uint16_t adcsample_t
ADC sample data type.
float uint8_t channelIdx
ObdCode