diff options
author | Vitaly Shmagun <65466721+Vitve4@users.noreply.github.com> | 2020-05-28 20:31:49 +0300 |
---|---|---|
committer | Vitaly Shmagun <65466721+Vitve4@users.noreply.github.com> | 2020-11-01 14:46:39 +0100 |
commit | 4fd3801e32fee9e25f04ae68a4cbfc95533d56df (patch) | |
tree | 27c893fbe5e13f86bb317975fb1c0a9b3806afb5 | |
parent | 58081c05e548560d3a60050bbf260ebec5d1e867 (diff) |
Improve reading ADC result
7.3.0-atmel3.6.1-arduino7 gcc fails to optimize separate reading from ADCL and ADCH. It produces additionally three eor commands or in some cases two mov commands in the assembly code (see discussion #344). These commands swap register contents before store them to data area. So they are completely unnecessary. Reading ADC result with ADC macro fixes it and gcc generates the right code..
-rw-r--r-- | cores/arduino/wiring_analog.c | 18 |
1 files changed, 5 insertions, 13 deletions
diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index e237d6d..0de64f7 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -37,7 +37,6 @@ void analogReference(uint8_t mode) int analogRead(uint8_t pin) { - uint8_t low, high; #if defined(analogPinToChannel) #if defined(__AVR_ATmega32U4__) @@ -74,27 +73,20 @@ int analogRead(uint8_t pin) // without a delay, we seem to read from the wrong channel //delay(1); -#if defined(ADCSRA) && defined(ADCL) +#if defined(ADCSRA) && defined(ADC) // start the conversion sbi(ADCSRA, ADSC); // ADSC is cleared when the conversion finishes while (bit_is_set(ADCSRA, ADSC)); - // we have to read ADCL first; doing so locks both ADCL - // and ADCH until ADCH is read. reading ADCL second would - // cause the results of each conversion to be discarded, - // as ADCL and ADCH would be locked when it completed. - low = ADCL; - high = ADCH; + // ADC macro takes care of reading ADC register. + // avr-gcc implements the proper reading order: ADCL is read first. + return ADC; #else // we dont have an ADC, return 0 - low = 0; - high = 0; + return 0; #endif - - // combine the two bytes - return (high << 8) | low; } // Right now, PWM output only works on the pins with |