rusefi/firmware/hw_layer/adc/adc_inputs.h

118 lines
3.3 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file adc_inputs.h
2017-11-24 14:40:20 -08:00
* @brief Low level internal ADC code
2015-07-10 06:01:56 -07:00
*
* @date Jan 14, 2013
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*/
2020-02-18 05:16:19 -08:00
#pragma once
2015-07-10 06:01:56 -07:00
2018-09-16 19:26:57 -07:00
#include "global.h"
2019-01-31 08:57:15 -08:00
#include "adc_math.h"
2015-07-10 06:01:56 -07:00
#ifndef SLOW_ADC_RATE
#define SLOW_ADC_RATE 500
#endif
float getAnalogInputDividerCoefficient(adc_channel_e);
inline bool isAdcChannelValid(adc_channel_e hwChannel) {
2024-05-05 05:34:46 -07:00
/* Compiler will optimize, keep following if as a reminder */
if (hwChannel >= EFI_ADC_TOTAL_CHANNELS) {
/* this should not happen!
* if we have enum out of range somewhere in settings
* that means something goes terribly wrong
* TODO: should we say something?
*/
return false;
}
2024-05-05 05:34:46 -07:00
return ((hwChannel > EFI_ADC_NONE) && (hwChannel < EFI_ADC_TOTAL_CHANNELS));
}
2024-05-05 05:55:03 -07:00
inline bool isAdcChannelOnChip(adc_channel_e hwChannel) {
return (isAdcChannelValid(hwChannel) && (hwChannel <= EFI_ADC_ONCHIP_LAST));
}
inline bool isAdcChannelOffChip(adc_channel_e hwChannel) {
return (isAdcChannelValid(hwChannel) && (hwChannel > EFI_ADC_ONCHIP_LAST));
}
2023-05-31 20:36:30 -07:00
#if !defined(GPT_FREQ_FAST) || !defined(GPT_PERIOD_FAST)
2024-06-25 13:31:04 -07:00
/*
2023-05-31 20:36:30 -07:00
* 8000 RPM is 133Hz
2024-06-25 13:31:04 -07:00
* If we want to sample MAP once per 5 degrees we need 133Hz * (360 / 5) = 9576Hz of fast ADC ~= 10 KHz
*/
/*
* TODO: migrate to continuous ADC mode? probably not - we cannot afford the callback in continuous mode.
* TODO: look into other options
* TODO: ADC convertion can be triggered directly from timer, with no SW intervention
2023-05-31 20:36:30 -07:00
*/
2024-06-25 13:31:04 -07:00
/* PWM clock frequency. Timer clock = 100 KHz */
#define GPT_FREQ_FAST 100000
/* PWM period (in PWM ticks), 100 KHz / 10 = 10KHz callback rate */
#define GPT_PERIOD_FAST 10
/*
* We have 1 / (GPT_FREQ_FAST / GPT_PERIOD_FAST) to finish conversion = 100 uS
* With ADC_SAMPLING_FAST = 28 ADC clock @ 21 MHz (F4) -> one channel conversion takes 1.33(3) uS
* Oversampling is ADC_BUF_DEPTH_FAST = 4
* We can do up-to 100 / (1.33(3) * 4) = 18.75 channels conversions
* So we can enable ALL channels for fast ADC.
* This will increase bus load with more DMA transfers, but who cares?
*/
2023-05-31 20:36:30 -07:00
#endif /* GPT_FREQ_FAST GPT_PERIOD_FAST */
2020-08-21 19:07:55 -07:00
#if HAL_USE_ADC
2024-07-22 16:47:57 -07:00
enum class AdcChannelMode : char {
Off,
Slow,
Fast
};
2024-07-22 16:47:57 -07:00
AdcChannelMode getAdcMode(adc_channel_e hwChannel);
void initAdcInputs();
2017-04-21 17:07:17 -07:00
// wait until at least 1 slowADC sampling is complete
void waitForSlowAdc(uint32_t lastAdcCounter = 1);
void printFullAdcReportIfNeeded(void);
2015-07-10 06:01:56 -07:00
int getInternalAdcValue(const char *msg, adc_channel_e index);
2016-07-19 19:03:16 -07:00
float getMCUInternalTemperature(void);
2015-07-10 06:01:56 -07:00
void addFastAdcChannel(const char *name, adc_channel_e hwChannel);
2024-05-05 08:51:47 -07:00
void removeChannel(const char *name, adc_channel_e hwChannel);
2015-07-10 06:01:56 -07:00
#define getAdcValue(msg, hwChannel) getInternalAdcValue(msg, hwChannel)
#define adcToVoltsDivided(adc, hwChannel) (adcToVolts(adc) * getAnalogInputDividerCoefficient(hwChannel))
2015-07-10 06:01:56 -07:00
// This callback is called by the ADC driver when a new fast ADC sample is ready
void onFastAdcComplete(adcsample_t* samples);
2024-06-20 03:00:27 -07:00
using AdcToken = uint32_t;
using AdcTockenInternal = union {
AdcToken token;
struct {
uint16_t adc;
uint16_t channel;
} __attribute__((packed));
};
static_assert(sizeof(AdcTockenInternal) == sizeof(AdcToken));
2024-05-12 09:08:01 -07:00
static constexpr AdcToken invalidAdcToken = (AdcToken)(-1);
2024-05-12 09:08:01 -07:00
AdcToken enableFastAdcChannel(const char* msg, adc_channel_e channel);
adcsample_t getFastAdc(AdcToken token);
#endif // HAL_USE_ADC
void printFullAdcReport(void);