The fastest-repeated measurements are needed for PWM LEDs. OTOH,
things like buttons, battery voltage, ambient lights, etc. can be
read less frequently, and should be read in a deterministic time frame.
So we will measure PWMLED current in the free-running mode (as fast
as possible), and the other "slow" ADC inputs with each PATTERN_DIV-th
timer tick.
{ 0, 1, 0 }, // buttons
};
{ 0, 1, 0 }, // buttons
};
-volatile static unsigned char current_adc;
+volatile static unsigned char current_adc, current_slow_adc;
static uint16_t adc_sum, zero_count, drop_count, read_count, n_reads_log;
#define ADC1_GAIN20_OFFSET_SHIFT 6
static uint16_t adc1_gain20_offset;
static uint16_t adc_sum, zero_count, drop_count, read_count, n_reads_log;
#define ADC1_GAIN20_OFFSET_SHIFT 6
static uint16_t adc1_gain20_offset;
static void start_next_adc()
{
static void start_next_adc()
{
- if (current_adc > 0) {
- current_adc--;
+ if (current_adc == 0) {
+ if (current_slow_adc > N_PWMLEDS) {
+ // read one of the non-PWMLED ADCs
+ current_adc = --current_slow_adc;
+ } else {
+ // no more non-PWMLEDs to do, start with PWMLEDs
+ current_adc = N_PWMLEDS-1;
+ }
+ } else if (current_adc >= N_PWMLEDS) {
+ // one of the non-PWMLED ADCs just finished, skip to PWMLEDs.
+ current_adc = N_PWMLEDS-1;
- // TODO: kick the watchdog here.
- current_adc = NUM_ADCS;
- return;
+ // next PWMLED
+ current_adc--;
+#if 0
+ log_byte(0x90 + current_adc); // debug ADC switching
+#endif
+
adc_sum = 0;
// we use the last iteration of zero_count to set up the MUX
// to its final destination, hence the "1 +" below:
adc_sum = 0;
// we use the last iteration of zero_count to set up the MUX
// to its final destination, hence the "1 +" below:
+void timer_start_slow_adcs()
- if (current_adc == NUM_ADCS) // Don't start if in progress
- start_next_adc();
- else
- log_byte(0x99); // overrun
+ if (current_slow_adc > N_PWMLEDS) { // Don't start if in progress
+ log_byte(0x80 + current_slow_adc);
+ } else {
+ current_slow_adc = NUM_ADCS;
+ // TODO: kick the watchdog here
+ }
void init_adc()
{
unsigned char i;
void init_adc()
{
unsigned char i;
- current_adc = NUM_ADCS;
+ current_slow_adc = NUM_ADCS;
+ current_adc = 0;
ADCSRA = _BV(ADEN) // enable
| _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
ADCSRA = _BV(ADEN) // enable
| _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
#define PWMLED_ADC_SHIFT 3 /* 1<<3 measurements per single callback */
void init_adc();
void susp_adc();
#define PWMLED_ADC_SHIFT 3 /* 1<<3 measurements per single callback */
void init_adc();
void susp_adc();
-void timer_start_adcs();
+void timer_start_slow_adcs();
if (--pattern_div == 0) {
timer_check_buttons();
patterns_next_tick();
if (--pattern_div == 0) {
timer_check_buttons();
patterns_next_tick();
+ timer_start_slow_adcs();
pattern_div = PATTERN_DIV;
}
pattern_div = PATTERN_DIV;
}