I noticed some pretty bad ADC results and tracked them down to the fact that the prescaler was not set correctly. The prescaler is set inside ADCInit(), but after setting it, it is cleared by the following sequence of function calls:
- Call to NutRegisterIrqHandler passing sig_adc
- Call to AvrAdcIrqCtl (pointed by a field inside sig_adc) passing NUT_IRQ_CTL_INIT
I think there is a bug in AVRAdcIrqCtl (nut/arch/avr/dev/ih_adc.c) because instead of modifying just the ADIF bit in ADCSR, the function is blasting the entire register.
/* Clear any pending interrupt. */
outb(ADCSR, _BV(ADIF));
From a quick look this bug may apply to other AVR peripherals but I have not verified that.