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)
 
adc_channel_mode_e getAdcMode (adc_channel_e hwChannel)
 
float getVoltageDivided (const char *msg, adc_channel_e hwChannel)
 
float getVoltage (const char *msg, adc_channel_e hwChannel)
 
static void fastAdcDoneCB (ADCDriver *adcp)
 
static void fastAdcErrorCB (ADCDriver *, adcerror_t err)
 
static void fastAdcTrigger (GPTDriver *)
 
float getMCUInternalTemperature ()
 
int getInternalAdcValue (const char *msg, adc_channel_e hwChannel)
 
static void printAdcValue (int channel)
 
static void printAdcChannedReport (const char *prefix, int internalIndex, adc_channel_e hwChannel)
 
void printFullAdcReport (void)
 
static void setAdcDebugReporting (int value)
 
void waitForSlowAdc (uint32_t lastAdcCounter)
 
void addChannel (const char *, adc_channel_e hwChannel, adc_channel_mode_e mode)
 
void removeChannel (const char *, adc_channel_e hwChannel)
 
static void configureInputs ()
 
void initAdcInputs ()
 
void printFullAdcReportIfNeeded (void)
 

Variables

static volatile NO_CACHE adcsample_t slowAdcSamples [SLOW_ADC_CHANNEL_COUNT]
 
static adc_channel_mode_e adcHwChannelMode [HW_MAX_ADC_INDEX]
 
static int adcDebugReporting = false
 
static ADCConversionGroup adcgrpcfgFast
 
static volatile NO_CACHE adcsample_t fastAdcSampleBuf [ADC_BUF_DEPTH_FAST *ADC_MAX_CHANNELS_COUNT]
 
static volatile adcerror_t fastAdcLastError
 
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

◆ addChannel()

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

Definition at line 391 of file adc_inputs.cpp.

391  {
392  if (!isAdcChannelValid(hwChannel)) {
393  return;
394  }
395 
396 #if EFI_USE_FAST_ADC
397  if (mode == ADC_FAST) {
398  fastAdc.enableChannel(hwChannel);
399  }
400 #endif
401 
402  adcHwChannelMode[hwChannel] = mode;
403  // Nothing to do for slow channels, input is mapped to analog in init_sensors.cpp
404 }
static adc_channel_mode_e adcHwChannelMode[HW_MAX_ADC_INDEX]
Definition: adc_inputs.cpp:38
bool isAdcChannelValid(adc_channel_e hwChannel)
Definition: adc_inputs.h:20
@ ADC_FAST
Definition: adc_inputs.h:58
void enableChannel(adc_channel_e hwChannel)
Definition: adc_inputs.cpp:222
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 423 of file adc_inputs.cpp.

423  {
424  memset(adcHwChannelMode, ADC_OFF, sizeof(adcHwChannelMode));
425 
426  /**
427  * order of analog channels here is totally random and has no meaning
428  * we also have some weird implementation with internal indices - that all has no meaning, it's just a random implementation
429  * which does not mean anything.
430  */
431 
433 
435 
436  // not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
437 
439 
441 }
void addChannel(const char *, adc_channel_e hwChannel, adc_channel_mode_e mode)
Definition: adc_inputs.cpp:391
@ ADC_OFF
Definition: adc_inputs.h:56
void setAdcChannelOverrides()

Referenced by initAdcInputs().

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

◆ fastAdcDoneCB()

static void fastAdcDoneCB ( ADCDriver *  adcp)
static

Definition at line 143 of file adc_inputs.cpp.

143  {
144  // State may not be complete if we get a callback for "half done"
145  if (adcp->state == ADC_COMPLETE) {
147  onFastAdcComplete(adcp->samples);
148  }
149 }
void onFastAdcComplete(adcsample_t *samples)
Definition: hardware.cpp:278
uint32_t conversionCount
Here is the call graph for this function:

◆ fastAdcErrorCB()

static void fastAdcErrorCB ( ADCDriver *  ,
adcerror_t  err 
)
static

Definition at line 153 of file adc_inputs.cpp.

154 {
155  fastAdcLastError = err;
156 }
static volatile adcerror_t fastAdcLastError
Definition: adc_inputs.cpp:151

◆ fastAdcTrigger()

static void fastAdcTrigger ( GPTDriver )
static

Definition at line 158 of file adc_inputs.cpp.

158  {
159 #if EFI_INTERNAL_ADC
160  /*
161  * Starts an asynchronous ADC conversion operation, the conversion
162  * will be executed in parallel to the current PWM cycle and will
163  * terminate before the next PWM cycle.
164  */
165  chSysLockFromISR();
166  if ((ADC_FAST_DEVICE.state != ADC_READY) &&
167  (ADC_FAST_DEVICE.state != ADC_COMPLETE) &&
168  (ADC_FAST_DEVICE.state != ADC_ERROR)) {
170  // todo: when? why? criticalError("ADC fast not ready?");
171  // see notes at https://github.com/rusefi/rusefi/issues/6399
172  } else {
173  /* drop volatile type qualifier - this is safe */
174  adcStartConversionI(&ADC_FAST_DEVICE, &adcgrpcfgFast, (adcsample_t *)fastAdc.samples, ADC_BUF_DEPTH_FAST);
175  }
176  chSysUnlockFromISR();
177 #endif /* EFI_INTERNAL_ADC */
178 }
static ADCConversionGroup adcgrpcfgFast
Definition: adc_inputs.cpp:95
volatile adcsample_t * samples
TunerStudioOutputChannels outputChannels
Definition: engine.h:99
Engine * engine
uint16_t adcsample_t
ADC sample data type.
Definition: hal_adc_lld.h:190

◆ getAdcMode()

adc_channel_mode_e getAdcMode ( adc_channel_e  hwChannel)

Definition at line 40 of file adc_inputs.cpp.

40  {
41  return adcHwChannelMode[hwChannel];
42 }

Referenced by AdcSubscription::PrintInfo().

Here is the caller graph for this function:

◆ getInternalAdcValue()

int getInternalAdcValue ( const char *  msg,
adc_channel_e  hwChannel 
)

Definition at line 187 of file adc_inputs.cpp.

187  {
188  if (!isAdcChannelValid(hwChannel)) {
189  warning(ObdCode::CUSTOM_OBD_ANALOG_INPUT_NOT_CONFIGURED, "ADC: %s input is not configured", msg);
190  return -1;
191  }
192 
193 #if EFI_USE_FAST_ADC
194  if (adcHwChannelMode[hwChannel] == ADC_FAST) {
195  /* todo if ADC_BUF_DEPTH_FAST EQ 1
196  * return fastAdc.samples[internalIndex]; */
197  return fastAdc.getAvgAdcValue(hwChannel, ADC_BUF_DEPTH_FAST);
198  }
199 #endif // EFI_USE_FAST_ADC
200 
201  return slowAdcSamples[hwChannel - EFI_ADC_0];
202 }
static volatile NO_CACHE adcsample_t slowAdcSamples[SLOW_ADC_CHANNEL_COUNT]
Definition: adc_inputs.cpp:36
adcsample_t getAvgAdcValue(adc_channel_e hwChannel, size_t bufDepth)
Definition: adc_inputs.cpp:253
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 183 of file adc_inputs.cpp.

183  {
184  return mcuTemperature;
185 }
static float mcuTemperature
Definition: adc_inputs.cpp:181

Referenced by populateFrame(), and updateMiscSensors().

Here is the caller graph for this function:

◆ getVoltage()

float getVoltage ( const char *  msg,
adc_channel_e  hwChannel 
)

Definition at line 50 of file adc_inputs.cpp.

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

Referenced by getVoltageDivided(), printAdcChannedReport(), 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 45 of file adc_inputs.cpp.

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

Referenced by getAfr(), printAdcChannedReport(), and updateRawSensors().

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

◆ initAdcInputs()

void initAdcInputs ( )

Definition at line 445 of file adc_inputs.cpp.

445  {
446  efiPrintf("initAdcInputs()");
447 
448  configureInputs();
449 
450  // migrate to 'enable adcdebug'
452 
453 #if EFI_INTERNAL_ADC
454  portInitAdc();
455 
456  // Start the slow ADC thread
457  slowAdcController.start();
458 
459 #if EFI_USE_FAST_ADC
460  fastAdc.init();
461 
462  gptStart(EFI_INTERNAL_FAST_ADC_GPT, &fast_adc_config);
463  gptStartContinuous(EFI_INTERNAL_FAST_ADC_GPT, GPT_PERIOD_FAST);
464 #endif // EFI_USE_FAST_ADC
465 
467 #else
468  efiPrintf("ADC disabled");
469 #endif
470 }
static GPTConfig fast_adc_config
Definition: adc_inputs.cpp:205
static void setAdcDebugReporting(int value)
Definition: adc_inputs.cpp:346
static void printAdcValue(int channel)
Definition: adc_inputs.cpp:299
static void configureInputs()
Definition: adc_inputs.cpp:423
static SlowAdcController slowAdcController
Definition: adc_inputs.cpp:443
void init(void)
Definition: adc_inputs.cpp:216
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:

◆ printAdcChannedReport()

static void printAdcChannedReport ( const char *  prefix,
int  internalIndex,
adc_channel_e  hwChannel 
)
static

Definition at line 310 of file adc_inputs.cpp.

311 {
312  if (isAdcChannelValid(hwChannel)) {
313  ioportid_t port = getAdcChannelPort("print", hwChannel);
314  int pin = getAdcChannelPin(hwChannel);
315  int adcValue = getAdcValue("print", hwChannel);
316  float volts = getVoltage("print", hwChannel);
317  float voltsDivided = getVoltageDivided("print", hwChannel);
318  /* Human index starts from 1 */
319  efiPrintf(" %s ch[%2d] @ %s%d ADC%d 12bit=%4d %.3fV (input %.3fV)",
320  prefix, internalIndex, portname(port), pin,
321  /* TODO: */ hwChannel - EFI_ADC_0 + 1,
322  adcValue, volts, voltsDivided);
323  }
324 }
float getVoltageDivided(const char *msg, adc_channel_e hwChannel)
Definition: adc_inputs.cpp:45
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
brain_pin_e pin
Definition: stm32_adc.cpp:15

Referenced by printFullAdcReport().

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 299 of file adc_inputs.cpp.

299  {
300  /* Do this check before conversion to adc_channel_e that is uint8_t based */
301  if ((channel < EFI_ADC_NONE) || (channel >= EFI_ADC_TOTAL_CHANNELS)) {
302  efiPrintf("Invalid ADC channel %d", channel);
303  return;
304  }
305  int value = getAdcValue("print", (adc_channel_e)channel);
306  float volts = adcToVoltsDivided(value, (adc_channel_e)channel);
307  efiPrintf("adc %d voltage : %.3f", channel, volts);
308 }
adc_channel_e
Definition: adc_inputs.cpp:480

Referenced by initAdcInputs().

Here is the caller graph for this function:

◆ printFullAdcReport()

void printFullAdcReport ( void  )

Definition at line 326 of file adc_inputs.cpp.

326  {
327 #if EFI_USE_FAST_ADC
328  efiPrintf("fast %lu samples", fastAdc.conversionCount);
329 
330  for (int internalIndex = 0; internalIndex < fastAdc.size(); internalIndex++) {
331  adc_channel_e hwChannel = fastAdc.getAdcChannelByInternalIndex(internalIndex);
332 
333  printAdcChannedReport("F", internalIndex, hwChannel);
334  }
335 #endif // EFI_USE_FAST_ADC
336  efiPrintf("slow %lu samples", slowAdcConversionCount);
337 
338  /* we assume that all slow ADC channels are enabled */
339  for (int internalIndex = 0; internalIndex < ADC_MAX_CHANNELS_COUNT; internalIndex++) {
340  adc_channel_e hwChannel = static_cast<adc_channel_e>(internalIndex + EFI_ADC_0);
341 
342  printAdcChannedReport("S", internalIndex, hwChannel);
343  }
344 }
static uint32_t slowAdcConversionCount
Definition: adc_inputs.cpp:296
static void printAdcChannedReport(const char *prefix, int internalIndex, adc_channel_e hwChannel)
Definition: adc_inputs.cpp:310
int size() const
Definition: adc_inputs.cpp:212
adc_channel_e getAdcChannelByInternalIndex(int index) const
Definition: adc_inputs.cpp:281

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 472 of file adc_inputs.cpp.

472  {
473  if (!adcDebugReporting)
474  return;
476 }
static int adcDebugReporting
Definition: adc_inputs.cpp:83
void printFullAdcReport(void)
Definition: adc_inputs.cpp:326

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  hwChannel 
)

Definition at line 406 of file adc_inputs.cpp.

406  {
407  if (!isAdcChannelValid(hwChannel)) {
408  return;
409  }
410 #if EFI_USE_FAST_ADC
411  if (adcHwChannelMode[hwChannel] == ADC_FAST) {
412  /* TODO: */
413  //fastAdc.disableChannel(hwChannel);
414  }
415 #endif
416 
417  adcHwChannelMode[hwChannel] = ADC_OFF;
418 }

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 346 of file adc_inputs.cpp.

346  {
347  adcDebugReporting = value;
348  efiPrintf("adcDebug=%d", adcDebugReporting);
349 }

Referenced by initAdcInputs().

Here is the caller graph for this function:

◆ waitForSlowAdc()

void waitForSlowAdc ( uint32_t  lastAdcCounter)

Definition at line 351 of file adc_inputs.cpp.

351  {
352  // todo: use sync.objects?
353  while (slowAdcConversionCount <= lastAdcCounter) {
354  chThdSleepMilliseconds(1);
355  }
356 }

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 480 of file adc_inputs.cpp.

Referenced by AdcDevice::getAdcChannelByInternalIndex(), printAdcValue(), and printFullAdcReport().

◆ adcDebugReporting

int adcDebugReporting = false
static

Definition at line 83 of file adc_inputs.cpp.

Referenced by printFullAdcReportIfNeeded(), and setAdcDebugReporting().

◆ adcgrpcfgFast

AdcDevice fastAdc & adcgrpcfgFast
static

Definition at line 95 of file adc_inputs.cpp.

Referenced by fastAdcTrigger(), and portInitAdc().

◆ adcHwChannelMode

adc_channel_mode_e adcHwChannelMode[HW_MAX_ADC_INDEX]
static

◆ fast_adc_config

GPTConfig fast_adc_config
static
Initial value:
= {
.frequency = GPT_FREQ_FAST,
.callback = fastAdcTrigger,
.cr2 = 0,
.dier = 0,
}
static void fastAdcTrigger(GPTDriver *)
Definition: adc_inputs.cpp:158

Definition at line 205 of file adc_inputs.cpp.

Referenced by initAdcInputs().

◆ fastAdcLastError

volatile adcerror_t fastAdcLastError
static

Definition at line 151 of file adc_inputs.cpp.

Referenced by fastAdcErrorCB().

◆ fastAdcSampleBuf

volatile NO_CACHE adcsample_t fastAdcSampleBuf[ADC_BUF_DEPTH_FAST *ADC_MAX_CHANNELS_COUNT]
static

Definition at line 139 of file adc_inputs.cpp.

◆ mcuTemperature

float mcuTemperature
static

Definition at line 181 of file adc_inputs.cpp.

Referenced by getMCUInternalTemperature().

◆ slowAdcController

SlowAdcController slowAdcController
static

Definition at line 443 of file adc_inputs.cpp.

Referenced by initAdcInputs().

◆ slowAdcConversionCount

uint32_t slowAdcConversionCount = 0
static

Definition at line 296 of file adc_inputs.cpp.

Referenced by printFullAdcReport(), and waitForSlowAdc().

◆ slowAdcErrorsCount

uint32_t slowAdcErrorsCount = 0
static

Definition at line 297 of file adc_inputs.cpp.

◆ slowAdcSamples

volatile NO_CACHE adcsample_t slowAdcSamples[SLOW_ADC_CHANNEL_COUNT]
static

Definition at line 36 of file adc_inputs.cpp.

Referenced by getInternalAdcValue().

Go to the source code of this file.