/*! \brief Main loop. * * Most of the action is interrupt driven. This loop only detects USB suspension. * * @return Never exits */ void main(void) { init(); for(;;){ wait100us(); suspend_timer++; if (suspend_timer>=SUSPEND_TIME) { /* host is not sending keepalive signals, time to suspend all operation */ /* BDM is in idle mode when not communicating, so nothing to do there */ U16 i; /* Acknowledge any pending interrupt and disable KBD interrupts; */ /* This will prevent RESET activity waking us up out of stop */ KBSCR = KBSCR_IMASKK_MASK | KBSCR_ACKK_MASK; led_state=LED_OFF; /* switch the LED off */ GREEN_LED_OFF(); /* do it now, the interrupt which would do it normally is not going to come */ UIR0_SUSPND=1; /* suspend USB */ while (suspend_timer) asm(STOP); /* go to sleep, wait for USB resume or reset */ for (i=0;i<RESUME_RECOVERY;i++) wait100us(); /* wait for host to recover */ led_state=LED_ON; /* Switch the LED back on */ (void)bdm_init(); /* Reinitialise the BDM after wake-up as the device might */ /* have been disconected in the meantime; assume nothing */ } }
unsigned int ReadADC(uint8_t Probe) { unsigned int U; /* return value (mV) */ uint8_t samples; /* loop counter */ unsigned long Value; /* ADC value */ uint8_t StartADCmsk; /* Bit mask to start the ADC */ Probe |= (1 << REFS0); /* use internal reference anyway */ #ifdef AUTOSCALE_ADC sample: #endif ADMUX = Probe; /* set input channel and U reference */ #ifdef AUTOSCALE_ADC /* if voltage reference changes, wait for voltage stabilization */ samples = (Probe & (1 << REFS1)); // get REFS1 bit flag if (samples != ADCconfig.RefFlag) { ADCconfig.RefFlag = samples; // update flag // switch to 1.1V Reference #ifdef NO_AREF_CAP wait100us(); /* time for voltage stabilization */ #else wait_about10ms(); /* time for voltage stabilization */ #endif // always do one dummy read of ADC, 112us StartADCwait(); /* start ADC and wait */ } #endif /* sample ADC readings */ Value = 0UL; /* reset sampling variable */ samples = 0; /* number of samples to take */ while (samples < ADCconfig.Samples) /* take samples */ { StartADCwait(); /* start ADC and wait */ Value += ADCW; /* add ADC reading */ #ifdef AUTOSCALE_ADC /* auto-switch voltage reference for low readings */ if ((samples == 4) && (ADCconfig.U_Bandgap > 255) && ((uint16_t)Value < 1024) && !(Probe & (1 << REFS1))) { Probe |= (1 << REFS1); /* select internal bandgap reference */ #if (PROCESSOR_TYP == 644) || (PROCESSOR_TYP == 1280) Probe &= ~(1 << REFS0); /* ATmega640/1280/2560 1.1V Reference with REFS0=0 */ #endif goto sample; /* re-run sampling */ } #endif samples++; /* one more done */ } #ifdef AUTOSCALE_ADC /* * convert ADC reading to voltage * - single sample: U = ADC reading * U_ref / 1024 */ /* get voltage of reference used */ if (Probe & (1 << REFS1)) U = ADCconfig.U_Bandgap; /* bandgap reference */ else U = ADCconfig.U_AVCC; /* Vcc reference */ #else U = ADCconfig.U_AVCC; /* Vcc reference */ #endif /* convert to voltage; */ Value *= U; /* ADC readings * U_ref */ Value /= 1023; /* / 1024 for 10bit ADC */ /* de-sample to get average voltage */ Value /= ADCconfig.Samples; U = (unsigned int) Value; return U; //return ((unsigned int)(Value / (1023 * (unsigned long)ADCconfig.Samples))); }