While analogRead is waiting for the ADC conversion to complete, what happens if there is an interrupt? I know ISRs preserve registers, but I would think the timing would be messed up and the value would be garbled if the conversion is interrupted? Even worse would be if the ISR tried to start it's on analogRead (which I know is a bad practice given how long analog reads take).
Am I just missing it, or why doesn't analogRead disable global interrupts while it is waiting for the ADSC bit to clear? (I know there's an alternate method where it doesn't have to block, instead specifically asking for an interrupt to be called when ADIF is set, but I don't understand what happens in that case either if a timer goes off, etc.)
i.e. Shouldn't the code below be preceded by sei(); and followed by SREG = oldSreg;? Or is there no need / reason to do this?
// high 2 bits are AREF mode, next bit is ADLAR (0 for right justified), next reserved, bottom four are channel
ADMUX = (ADMUX & 0b11000000) | pin;
// start the conversion
// ADSC is cleared when the conversion finishes (if using free running / interrupt mode, check for ADIF to be set instead)
while (bit_is_set(ADCSRA, ADSC))
If there were an interrupt while waiting for conversion to finish, how would that garble the conversion? The ADC is hardware. The ADC happily runs along doing its thing while the interrupt gets serviced. If the interrupt takes too long and the conversion finishes while you're off servicing the interrupt, then the value on the ADC will just be there waiting on you when you get back.
The ADC unit is separate hardware from the processor - it simply runs to completion and sets a flag in the relevant register (and optionally generates an interrupt). What the processor does during this process is not going to interfere so long as it doesn't reset the state of the ADC hardware...
Well, actually the running processor does cause some noise on the power rails so there can be slight sub-LSB effects via signal crosstalk, but that's another level of interference... IIRC the datasheets suggests halting the processor while the ADC is running for the least noise on the ADC readings.
The Arduino libraries rightly treat interrupts as a higher prority than ADC readings since the latter take 110us or so, much longer than is acceptable for various interrupts to be delayed.
Makes a lot of sense. Thank you both! (I was mistakenly thinking the ADC was suspended during the ISR.)