Ok, so here's a followup - the code now looks like:
/
****************************************************************************** \ |
* ADC has finished a conversion, store it and trigger another \******************************************************************************/ ISR (ADC_vect) { static uint8_t channel = SAMPLE_LEFT;
switch (channel) { case SAMPLE_LEFT: __adc[SAMPLE_LEFT] = ADCH; PORTB = ADCH; channel = SAMPLE_TC1; ADMUX = _BV(ADLAR) | TIMECODE_CHANNEL; ADCSRA |= _BV(ADSC); break;
case SAMPLE_TC1: __adc[SAMPLE_TC1] = ADCH; channel = SAMPLE_RIGHT; ADMUX = _BV(ADLAR) | RIGHT_AUDIO_CHANNEL; ADCSRA |= _BV(ADSC); break;
case SAMPLE_RIGHT: __adc[SAMPLE_RIGHT] = ADCH; channel = SAMPLE_TC2; ADMUX = _BV(ADLAR) | TIMECODE_CHANNEL; ADCSRA |= _BV(ADSC); break;
default: case SAMPLE_TC2: __adc[SAMPLE_TC1] = ADCH; channel = SAMPLE_LEFT; ADMUX = _BV(ADLAR) | LEFT_AUDIO_CHANNEL; ADCSRA |= _BV(ADSC); break; } }
/
****************************************************************************** \ |
* Timer-0 overflow. Either change the ADC MUX or sample a value \******************************************************************************/ ISR (TIMER0_COMPA_vect) { static uint8_t state = SAMPLE_LEFT;
/
************************************************************************** \ |
* State machine for setting up samples, and sampling \**************************************************************************/ switch (state) { case SAMPLE_LEFT: state = SAMPLE_TC1; cbWrite(&_left, __adc[SAMPLE_LEFT]); break;
case SAMPLE_TC1: state = SAMPLE_RIGHT; cbWrite(&_tc, __adc[SAMPLE_TC1]); break;
case SAMPLE_RIGHT: state = SAMPLE_TC2; cbWrite(&_right, __adc[SAMPLE_RIGHT]); break;
case SAMPLE_TC2: state = SAMPLE_LEFT; cbWrite(&_tc, __adc[SAMPLE_TC1]); break; } TCNT0 = 0; }
Note that PORTB is being set to the value of ADCH within the ISR, and that there's no loops waiting for anything any more - the ADC_vect is self-triggering once the first conversion has been requested.
In this situation, the LEDs light up for port-B no matter which input (TIMECODE_CHANNEL, LEFT_AUDIO_CHANNEL, RIGHT_AUDIO_CHANNEL) is connected to the potentiometer. I tried changing the ADC sample-rate (setting the ADC prescaler to 128 from 16) and the interrupt-sample- rate (setting timer0's prescaler to CLK/64 from CLK). No difference.
At this point, it looks as though the AVR is simply ignoring my request to change the MUX. I'm seriously thinking of getting 3 AT- Tiny's and making them do one channel each rather than try to mux it on the mega-AVR...
Simon