aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/wiring_analog.c
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 /cores/arduino/wiring_analog.c
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..
Diffstat (limited to 'cores/arduino/wiring_analog.c')
-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