rusEFI
The most advanced open source ECU
Functions | Variables
adc_inputs.cpp File Reference

Detailed Description

Low level ADC code.

rusEfi uses two ADC devices on the same 16 pins at the moment. Two ADC devices are used in orde to distinguish between fast and slow devices. The idea is that but only having few channels in 'fast' mode we can sample those faster?

At the moment rusEfi does not allow to have more than 16 ADC channels combined. At the moment there is no flexibility to use any ADC pins, only the hardcoded choice of 16 pins.

Slow ADC group is used for IAT, CLT, AFR, VBATT etc - this one is currently sampled at 500Hz

Fast ADC group is used for MAP, MAF HIP - this one is currently sampled at 10KHz We need frequent MAP for map_averaging.cpp

10KHz equals one measurement every 3.6 degrees at 6000 RPM

Date
Jan 14, 2013
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file adc_inputs.cpp.

Functions

float __attribute__ ((weak)) getAnalogInputDividerCoefficient(adc_channel_e)
 
float getVoltageDivided (const char *msg, adc_channel_e hwChannel)
 
float getVoltage (const char *msg, adc_channel_e hwChannel)
 
static adcsample_t getAvgAdcValue (int index, adcsample_t *samples, int bufDepth, int numChannels)
 
static void adc_callback_fast (ADCDriver *adcp)
 
AdcDevice fastAdcadcgrpcfgFast (fastAdcSampleBuf)
 
static void fast_adc_callback (GPTDriver *)
 
float getMCUInternalTemperature ()
 
int getInternalAdcValue (const char *msg, adc_channel_e hwChannel)
 
adc_channel_mode_e getAdcMode (adc_channel_e hwChannel)
 
static void printAdcValue (int channel)
 
void printFullAdcReport (void)
 
static void setAdcDebugReporting (int value)
 
void waitForSlowAdc (uint32_t lastAdcCounter)
 
int getSlowAdcCounter ()
 
void addChannel (const char *, adc_channel_e setting, adc_channel_mode_e mode)
 
void removeChannel (const char *name, adc_channel_e setting)
 
static void configureInputs ()
 
void initAdcInputs ()
 
void printFullAdcReportIfNeeded (void)
 

Variables

static NO_CACHE adcsample_t slowAdcSamples [SLOW_ADC_CHANNEL_COUNT]
 
static adc_channel_mode_e adcHwChannelEnabled [HW_MAX_ADC_INDEX]
 
static uint32_t slowAdcCounter = 0
 
static int adcDebugReporting = false
 
static ADCConversionGroup adcgrpcfgFast
 
static NO_CACHE adcsample_t fastAdcSampleBuf [ADC_BUF_DEPTH_FAST *ADC_MAX_CHANNELS_COUNT]
 
static float mcuTemperature
 
static GPTConfig fast_adc_config
 
static uint32_t slowAdcConversionCount = 0
 
static uint32_t slowAdcErrorsCount = 0
 
static SlowAdcController slowAdcController
 
 adc_channel_e
 

Function Documentation

◆ __attribute__()

float __attribute__ ( (weak)  )

Definition at line 24 of file adc_inputs.cpp.

24  {
26 }
engine_configuration_s * engineConfiguration

◆ adc_callback_fast()

static void adc_callback_fast ( ADCDriver *  adcp)
static

Definition at line 115 of file adc_inputs.cpp.

115  {
116  // State may not be complete if we get a callback for "half done"
117  if (adcp->state == ADC_COMPLETE) {
118  onFastAdcComplete(adcp->samples);
119  }
120 }
void onFastAdcComplete(adcsample_t *samples)
Definition: hardware.cpp:279
Here is the call graph for this function:

◆ adcgrpcfgFast()

AdcDevice fastAdc& adcgrpcfgFast ( fastAdcSampleBuf  )

Referenced by portInitAdc().

Here is the caller graph for this function:

◆ addChannel()

void addChannel ( const char *  name,
adc_channel_e  setting,
adc_channel_mode_e  mode 
)

Definition at line 402 of file adc_inputs.cpp.

402  {
403  if (!isAdcChannelValid(setting)) {
404  return;
405  }
406 
407  adcHwChannelEnabled[setting] = mode;
408 
409 #if EFI_USE_FAST_ADC
410  if (mode == ADC_FAST) {
411  fastAdc.enableChannel(setting);
412  return;
413  }
414 #endif
415 
416  // Nothing to do for slow channels, input is mapped to analog in init_sensors.cpp
417 }
static adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX]
Definition: adc_inputs.cpp:43
bool isAdcChannelValid(adc_channel_e hwChannel)
Definition: adc_inputs.h:20
@ ADC_FAST
Definition: adc_inputs.h:51
void enableChannel(adc_channel_e hwChannelIndex)
Definition: adc_inputs.cpp:268
AdcDevice fastAdc

Referenced by addAdcChannelForTrigger(), configureInputs(), and setAdcChannelOverrides().

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

◆ configureInputs()

static void configureInputs ( )
static

order of analog channels here is totally random and has no meaning we also have some weird implementation with internal indices - that all has no meaning, it's just a random implementation which does not mean anything.

Definition at line 430 of file adc_inputs.cpp.

430  {
431  memset(adcHwChannelEnabled, 0, sizeof(adcHwChannelEnabled));
432 
433  /**
434  * order of analog channels here is totally random and has no meaning
435  * we also have some weird implementation with internal indices - that all has no meaning, it's just a random implementation
436  * which does not mean anything.
437  */
438 
440 
442 
443  // not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
444 
446 
448 }
void addChannel(const char *, adc_channel_e setting, adc_channel_mode_e mode)
Definition: adc_inputs.cpp:402
void setAdcChannelOverrides()

Referenced by initAdcInputs().

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

◆ fast_adc_callback()

static void fast_adc_callback ( GPTDriver )
static

Definition at line 169 of file adc_inputs.cpp.

169  {
170 #if EFI_INTERNAL_ADC
171  /*
172  * Starts an asynchronous ADC conversion operation, the conversion
173  * will be executed in parallel to the current PWM cycle and will
174  * terminate before the next PWM cycle.
175  */
176  chSysLockFromISR()
177  ;
178  if (ADC_FAST_DEVICE.state != ADC_READY &&
179  ADC_FAST_DEVICE.state != ADC_COMPLETE &&
180  ADC_FAST_DEVICE.state != ADC_ERROR) {
182  // todo: when? why? criticalError("ADC fast not ready?");
183  // see notes at https://github.com/rusefi/rusefi/issues/6399
184  chSysUnlockFromISR();
185  return;
186  }
187 
188  adcStartConversionI(&ADC_FAST_DEVICE, &adcgrpcfgFast, fastAdc.samples, ADC_BUF_DEPTH_FAST);
189  chSysUnlockFromISR();
191 #endif /* EFI_INTERNAL_ADC */
192 }
static ADCConversionGroup adcgrpcfgFast
Definition: adc_inputs.cpp:122
uint32_t conversionCount
adcsample_t * samples
TunerStudioOutputChannels outputChannels
Definition: engine.h:96
Engine * engine

◆ getAdcMode()

adc_channel_mode_e getAdcMode ( adc_channel_e  hwChannel)

Definition at line 228 of file adc_inputs.cpp.

228  {
229 #if EFI_USE_FAST_ADC
230  if (fastAdc.isHwUsed(hwChannel)) {
231  return ADC_FAST;
232  }
233 #endif // EFI_USE_FAST_ADC
234 
235  return ADC_SLOW;
236 }
@ ADC_SLOW
Definition: adc_inputs.h:50
bool isHwUsed(adc_channel_e hwChannel) const
Definition: adc_inputs.cpp:259

Referenced by AdcSubscription::PrintInfo().

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

◆ getAvgAdcValue()

static adcsample_t getAvgAdcValue ( int  index,
adcsample_t samples,
int  bufDepth,
int  numChannels 
)
static

Definition at line 85 of file adc_inputs.cpp.

85  {
86  uint32_t result = 0;
87  for (int i = 0; i < bufDepth; i++) {
88  adcsample_t sample = samples[index];
89 // if (sample > 0x1FFF) {
90 // // 12bit ADC expected right now, make this configurable one day
91 // criticalError("fast ADC unexpected sample %d", sample);
92 // } else
93  if (sample > 0xFFF) {
95  criticalError("fast ADC unexpected sample %d. Please report and use skipADC12bitAssert to disable", sample);
96  }
98  sample = sample & 0xFFF; // sad hack which works around https://github.com/rusefi/rusefi/issues/6376 which we do not understand
100  }
101  result += sample;
102  index += numChannels;
103  }
104 
105  // this truncation is guaranteed to not be lossy - the average can't be larger than adcsample_t
106  return static_cast<adcsample_t>(result / bufDepth);
107 }
uint16_t adcsample_t
ADC sample data type.
Definition: hal_adc_lld.h:190
static adcsample_t samples[oversample]

Referenced by getInternalAdcValue(), and printFullAdcReport().

Here is the caller graph for this function:

◆ getInternalAdcValue()

int getInternalAdcValue ( const char *  msg,
adc_channel_e  hwChannel 
)

Definition at line 201 of file adc_inputs.cpp.

201  {
202  if (!isAdcChannelValid(hwChannel)) {
203  warning(ObdCode::CUSTOM_OBD_ANALOG_INPUT_NOT_CONFIGURED, "ADC: %s input is not configured", msg);
204  return -1;
205  }
206 
207 #if EFI_USE_FAST_ADC
208  if (adcHwChannelEnabled[hwChannel] == ADC_FAST) {
209  int internalIndex = fastAdc.internalAdcIndexByHardwareIndex[hwChannel];
210 // todo if ADC_BUF_DEPTH_FAST EQ 1
211 // return fastAdc.samples[internalIndex];
212  int value = getAvgAdcValue(internalIndex, fastAdc.samples, ADC_BUF_DEPTH_FAST, fastAdc.size());
213  return value;
214  }
215 #endif // EFI_USE_FAST_ADC
216 
217  return slowAdcSamples[hwChannel - EFI_ADC_0];
218 }
static NO_CACHE adcsample_t slowAdcSamples[SLOW_ADC_CHANNEL_COUNT]
Definition: adc_inputs.cpp:41
static adcsample_t getAvgAdcValue(int index, adcsample_t *samples, int bufDepth, int numChannels)
Definition: adc_inputs.cpp:85
uint8_t internalAdcIndexByHardwareIndex[EFI_ADC_LAST_CHANNEL]
int size() const
Definition: adc_inputs.cpp:240
bool warning(ObdCode code, const char *fmt,...)
@ CUSTOM_OBD_ANALOG_INPUT_NOT_CONFIGURED
Here is the call graph for this function:

◆ getMCUInternalTemperature()

float getMCUInternalTemperature ( void  )

Definition at line 197 of file adc_inputs.cpp.

197  {
198  return mcuTemperature;
199 }
static float mcuTemperature
Definition: adc_inputs.cpp:195

Referenced by populateFrame(), and updateMiscSensors().

Here is the caller graph for this function:

◆ getSlowAdcCounter()

int getSlowAdcCounter ( )

Definition at line 364 of file adc_inputs.cpp.

364  {
365  return slowAdcCounter;
366 }
static uint32_t slowAdcCounter
Definition: adc_inputs.cpp:79

◆ getVoltage()

float getVoltage ( const char *  msg,
adc_channel_e  hwChannel 
)

Definition at line 51 of file adc_inputs.cpp.

51  {
52  return adcToVolts(getAdcValue(msg, hwChannel));
53 }

Referenced by getVoltageDivided(), AdcSubscription::PrintInfo(), printMAPInfo(), showHipInfo(), and AdcSubscription::UpdateSubscribers().

Here is the caller graph for this function:

◆ getVoltageDivided()

float getVoltageDivided ( const char *  msg,
adc_channel_e  hwChannel 
)

Definition at line 46 of file adc_inputs.cpp.

46  {
47  return getVoltage(msg, hwChannel) * getAnalogInputDividerCoefficient(hwChannel);
48 }
float getVoltage(const char *msg, adc_channel_e hwChannel)
Definition: adc_inputs.cpp:51
float getAnalogInputDividerCoefficient(adc_channel_e hwChannel)

Referenced by getAfr(), and updateRawSensors().

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

◆ initAdcInputs()

void initAdcInputs ( )

Definition at line 452 of file adc_inputs.cpp.

452  {
453  efiPrintf("initAdcInputs()");
454 
455  configureInputs();
456 
457  // migrate to 'enable adcdebug'
459 
460 #if EFI_INTERNAL_ADC
461  portInitAdc();
462 
463  // Start the slow ADC thread
464  slowAdcController.start();
465 
466 #if EFI_USE_FAST_ADC
467  fastAdc.init();
468 
469  gptStart(EFI_INTERNAL_FAST_ADC_GPT, &fast_adc_config);
470  gptStartContinuous(EFI_INTERNAL_FAST_ADC_GPT, GPT_PERIOD_FAST);
471 #endif // EFI_USE_FAST_ADC
472 
474 #else
475  efiPrintf("ADC disabled");
476 #endif
477 }
static GPTConfig fast_adc_config
Definition: adc_inputs.cpp:221
static void setAdcDebugReporting(int value)
Definition: adc_inputs.cpp:351
static void printAdcValue(int channel)
Definition: adc_inputs.cpp:306
static void configureInputs()
Definition: adc_inputs.cpp:430
static SlowAdcController slowAdcController
Definition: adc_inputs.cpp:450
void init(void)
Definition: adc_inputs.cpp:253
void addConsoleActionI(const char *token, VoidInt callback)
Register a console command with one Integer parameter.
void(* VoidInt)(int)
Definition: cli_registry.h:54
void portInitAdc()
Definition: mpu_util.cpp:238

Referenced by initHardware().

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

◆ printAdcValue()

static void printAdcValue ( int  channel)
static

Definition at line 306 of file adc_inputs.cpp.

306  {
307  int value = getAdcValue("print", (adc_channel_e)channel);
308  float volts = adcToVoltsDivided(value, (adc_channel_e)channel);
309  efiPrintf("adc voltage : %.2f", volts);
310 }
adc_channel_e
Definition: adc_inputs.cpp:487

Referenced by initAdcInputs().

Here is the caller graph for this function:

◆ printFullAdcReport()

void printFullAdcReport ( void  )

Definition at line 315 of file adc_inputs.cpp.

315  {
316 #if EFI_USE_FAST_ADC
317  efiPrintf("fast %d samples", fastAdc.conversionCount);
318 
319  for (int internalIndex = 0; internalIndex < fastAdc.size(); internalIndex++) {
321 
322  if (isAdcChannelValid(hwIndex)) {
323  ioportid_t port = getAdcChannelPort("print", hwIndex);
324  int pin = getAdcChannelPin(hwIndex);
325  int adcValue = getAvgAdcValue(internalIndex, fastAdc.samples, ADC_BUF_DEPTH_FAST, fastAdc.size());
326  float volts = adcToVolts(adcValue);
327  /* Human index starts from 1 */
328  efiPrintf(" F ch[%2d] @ %s%d ADC%d 12bit=%4d %.2fV",
329  internalIndex, portname(port), pin, hwIndex - EFI_ADC_0 + 1, adcValue, volts);
330  }
331  }
332 #endif // EFI_USE_FAST_ADC
333  efiPrintf("slow %d samples", slowAdcConversionCount);
334 
335  /* we assume that all slow ADC channels are enabled */
336  for (int internalIndex = 0; internalIndex < ADC_MAX_CHANNELS_COUNT; internalIndex++) {
337  adc_channel_e hwIndex = static_cast<adc_channel_e>(internalIndex + EFI_ADC_0);
338 
339  if (isAdcChannelValid(hwIndex)) {
340  ioportid_t port = getAdcChannelPort("print", hwIndex);
341  int pin = getAdcChannelPin(hwIndex);
342  int adcValue = slowAdcSamples[internalIndex];
343  float volts = adcToVolts(adcValue);
344  /* Human index starts from 1 */
345  efiPrintf(" S ch[%2d] @ %s%d ADC%d 12bit=%4d %.2fV",
346  internalIndex, portname(port), pin, hwIndex - EFI_ADC_0 + 1, adcValue, volts);
347  }
348  }
349 }
static uint32_t slowAdcConversionCount
Definition: adc_inputs.cpp:312
adc_channel_e getAdcHardwareIndexByInternalIndex(int index) const
Definition: adc_inputs.cpp:300
int getAdcChannelPin(adc_channel_e hwChannel)
ioportid_t getAdcChannelPort(const char *msg, adc_channel_e hwChannel)
const char * portname(ioportid_t GPIOx)
GPIO_TypeDef * ioportid_t
Port Identifier.
Definition: hal_pal_lld.h:102

Referenced by initSettings(), and printFullAdcReportIfNeeded().

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

◆ printFullAdcReportIfNeeded()

void printFullAdcReportIfNeeded ( void  )

Definition at line 479 of file adc_inputs.cpp.

479  {
480  if (!adcDebugReporting)
481  return;
483 }
static int adcDebugReporting
Definition: adc_inputs.cpp:82
void printFullAdcReport(void)
Definition: adc_inputs.cpp:315

Referenced by updateDevConsoleState().

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

◆ removeChannel()

void removeChannel ( const char *  name,
adc_channel_e  setting 
)

Definition at line 419 of file adc_inputs.cpp.

419  {
420  (void)name;
421  if (!isAdcChannelValid(setting)) {
422  return;
423  }
424  adcHwChannelEnabled[setting] = ADC_OFF;
425 }
@ ADC_OFF
Definition: adc_inputs.h:49

Referenced by setAdcChannelOverrides().

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

◆ setAdcDebugReporting()

static void setAdcDebugReporting ( int  value)
static

Definition at line 351 of file adc_inputs.cpp.

351  {
352  adcDebugReporting = value;
353  efiPrintf("adcDebug=%d", adcDebugReporting);
354 }

Referenced by initAdcInputs().

Here is the caller graph for this function:

◆ waitForSlowAdc()

void waitForSlowAdc ( uint32_t  lastAdcCounter)

Definition at line 356 of file adc_inputs.cpp.

356  {
357  // we use slowAdcCounter instead of slowAdc.conversionCount because we need ADC_COMPLETE state
358  // todo: use sync.objects?
359  while (slowAdcCounter <= lastAdcCounter) {
360  chThdSleepMilliseconds(1);
361  }
362 }

Referenced by initHardware(), and StepperMotorBase::setInitialPosition().

Here is the caller graph for this function:

Variable Documentation

◆ adc_channel_e

adc_channel_e
Initial value:
{
return 0

Definition at line 487 of file adc_inputs.cpp.

Referenced by printAdcValue(), and printFullAdcReport().

◆ adcDebugReporting

int adcDebugReporting = false
static

Definition at line 82 of file adc_inputs.cpp.

Referenced by printFullAdcReportIfNeeded(), and setAdcDebugReporting().

◆ adcgrpcfgFast

ADCConversionGroup adcgrpcfgFast
static

Definition at line 122 of file adc_inputs.cpp.

Referenced by fast_adc_callback().

◆ adcHwChannelEnabled

adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX]
static

Definition at line 43 of file adc_inputs.cpp.

Referenced by addChannel(), configureInputs(), getInternalAdcValue(), and removeChannel().

◆ fast_adc_config

GPTConfig fast_adc_config
static
Initial value:
= {
GPT_FREQ_FAST,
0, 0
}
static void fast_adc_callback(GPTDriver *)
Definition: adc_inputs.cpp:169

Definition at line 221 of file adc_inputs.cpp.

Referenced by initAdcInputs().

◆ fastAdcSampleBuf

NO_CACHE adcsample_t fastAdcSampleBuf[ADC_BUF_DEPTH_FAST *ADC_MAX_CHANNELS_COUNT]
static

Definition at line 166 of file adc_inputs.cpp.

◆ mcuTemperature

float mcuTemperature
static

Definition at line 195 of file adc_inputs.cpp.

Referenced by getMCUInternalTemperature().

◆ slowAdcController

SlowAdcController slowAdcController
static

Definition at line 450 of file adc_inputs.cpp.

Referenced by initAdcInputs().

◆ slowAdcConversionCount

uint32_t slowAdcConversionCount = 0
static

Definition at line 312 of file adc_inputs.cpp.

Referenced by printFullAdcReport().

◆ slowAdcCounter

uint32_t slowAdcCounter = 0
static

Definition at line 79 of file adc_inputs.cpp.

Referenced by getSlowAdcCounter(), and waitForSlowAdc().

◆ slowAdcErrorsCount

uint32_t slowAdcErrorsCount = 0
static

Definition at line 313 of file adc_inputs.cpp.

◆ slowAdcSamples

NO_CACHE adcsample_t slowAdcSamples[SLOW_ADC_CHANNEL_COUNT]
static

Definition at line 41 of file adc_inputs.cpp.

Referenced by getInternalAdcValue(), and printFullAdcReport().

Go to the source code of this file.