* invalidate before reading ADC

* fix degree signs

* comment

* remove unecessary alignments, add comments
This commit is contained in:
Matthew Kennedy 2019-06-23 06:21:12 -07:00 committed by rusefi
parent e044ddf974
commit ffb2429608
3 changed files with 24 additions and 3 deletions

View File

@ -22,8 +22,14 @@ public:
int conversionCount;
int errorsCount;
int getAdcValueByIndex(int internalIndex) const;
void invalidateSamplesCache();
adcsample_t samples[ADC_MAX_CHANNELS_COUNT * MAX_ADC_GRP_BUF_DEPTH];
// This must be aligned on a 32-byte boundary, and be a multiple of 32 bytes long.
// When we invalidate the cache line(s) for ADC samples, we don't want to nuke any
// adjacent data
__ALIGNED(32) adcsample_t samples[ADC_MAX_CHANNELS_COUNT * MAX_ADC_GRP_BUF_DEPTH];
// Assert multiple of 32 bytes long so we don't stomp on the data after the buffer
static_assert(sizeof(samples) % 32 == 0);
int getAdcValueByHwChannel(int hwChannel) const;

View File

@ -256,10 +256,10 @@ static void pwmpcb_fast(PWMDriver *pwmp) {
float getMCUInternalTemperature(void) {
#if defined(ADC_CHANNEL_SENSOR)
float TemperatureValue = adcToVolts(slowAdc.getAdcValueByHwChannel(ADC_CHANNEL_SENSOR));
TemperatureValue -= 0.760; // Subtract the reference voltage at 25°C
TemperatureValue -= 0.760; // Subtract the reference voltage at 25 deg C
TemperatureValue /= .0025; // Divide by slope 2.5mV
TemperatureValue += 25.0; // Add the 25°C
TemperatureValue += 25.0; // Add the 25 deg C
return TemperatureValue;
#else
return 0;
@ -342,6 +342,17 @@ int AdcDevice::getAdcValueByIndex(int internalIndex) const {
return values.adc_data[internalIndex];
}
void AdcDevice::invalidateSamplesCache() {
#if PROJECT_CPU == ARCH_STM32F7
// The STM32F7xx has a data cache
// DMA operations DO NOT invalidate cache lines, since the ARM m7 doesn't have
// anything like a CCI that maintains coherency across multiple bus masters.
// As a result, we have to manually invalidate the D-cache any time we (the CPU)
// would like to read something that somebody else wrote (ADC via DMA, in this case)
SCB_InvalidateDCache_by_Addr(reinterpret_cast<uint32_t*>(samples), sizeof(samples));
#endif
}
void AdcDevice::init(void) {
hwConfig->num_channels = size();
hwConfig->sqr1 += ADC_SQR1_NUM_CH(size());
@ -432,6 +443,9 @@ int getSlowAdcCounter() {
static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) buffer;
(void) n;
slowAdc.invalidateSamplesCache();
efiAssertVoid(CUSTOM_ERR_6671, getCurrentRemainingStack() > 128, "lowstck#9c");
/* Note, only in the ADC_COMPLETE state because the ADC driver fires
* an intermediate callback when the buffer is half full. */

View File

@ -196,6 +196,7 @@ extern AdcDevice fastAdc;
* This method is not in the adc* lower-level file because it is more business logic then hardware.
*/
void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
fastAdc.invalidateSamplesCache();
(void) buffer;
(void) n;