aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Shmagun <65466721+Vitve4@users.noreply.github.com>2020-05-28 20:31:49 +0300
committerVitaly Shmagun <65466721+Vitve4@users.noreply.github.com>2020-11-01 14:46:39 +0100
commit4fd3801e32fee9e25f04ae68a4cbfc95533d56df (patch)
tree27c893fbe5e13f86bb317975fb1c0a9b3806afb5
parent58081c05e548560d3a60050bbf260ebec5d1e867 (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.c18
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