I have an ISR( ADC_vect ) interrupt defined that fills a volatile ring buffer from an ADC channel, switches channel and fills another. Once both are filled, a volatile flag is set.
The main loop checks the flag and calls a function to copy the ring buffers and process an FHT on each. I want to pause the interrupt while this function is called, but for some reason my setup function is called. I thought the setup function was only ever called once.
I've tried using cli(); before the function call, followed by a sei(); after the function call.
I've tried clearing and setting the ADATE bit in the ADCSRA register before and after the function call.
I've tried clearing and setting the ADEN and ADSC bits in the ADCSRA register before and after the function call.
The setup function keeps getting called and the function I want to run doesn't appear to be called at all.
My setup defines register settings and the flags:
void setup( void )
{
// ADCSRA.
ADCSRA = B00101101;
// ADEN - 0 // Disable ADC.
// ADSC - 0 // Disable conversions.
// ADATE - 1 // Enable ADC auto trigger.
// ADIF - 0 // Set by hardware
// ADIE - 1 // Enable interrupt.
// ADPS2 - 1 // }
// ADPS1 - 0 // }- ADC prescaler = 32.
// ADPS0 - 1 // }
// ADCSRB.
ADCSRB = B00000000;
// N/A //
// ACME - 0 // Disable Analogue Comparator Mux.
// N/A //
// N/A //
// N/A //
// ADTS2 - 0 // }
// ADTS1 - 0 // }- Free Running Mode.
// ADTS0 - 0 // }
// ADMUX.
ADMUX = B01100000;
// REFS1 - 0 // }- Use Vcc as reference.
// REFS0 - 1 // }
// ADLAR - 1 // Left adjust ADC results (8-bit mode).
// N/A //
// MUX3 - 0 // }
// MUX2 - 0 // }- ADC input 0.
// MUX1 - 0 // }
// MUX0 - 0 // }
// DIDR0.
DIDR0 = B00111111;
// N/A // }- Pins ADC7D & ADC6D do not have input buffers.
// N/A // }
// ADC5D - 1 // Disable digital input ADC5.
// ADC4D - 1 // Disable digital input ADC4.
// ADC3D - 1 // Disable digital input ADC3.
// ADC2D - 1 // Disable digital input ADC2.
// ADC1D - 1 // Disable digital input ADC1.
// ADC0D - 1 // Disable digital input ADC0.
// DIDR1.
DIDR1 = B00000011;
// Clear buffers.
memset( (void *) ADCBuffer, 0, sizeof( ADCBuffer ));
// Set up counters and flags.
ADCCounter = 0;
ChannelIndex = 0;
FHTStart = false;
if ( DEBUG ) Serial.begin( 115200 );
if ( DEBUG ) Serial.println( "Initialisation complete" );
delay( 1000 );
startADC();
}
The ISR is pretty simple:
ISR( ADC_vect )
{
// Fill next available buffer slot with ADC value.
ADCBuffer[ChannelIndex][ADCCounter] = ADCH; // Read ADC value.
// If the ADC buffer for the channel is full, switch channel.
if ( ++ADCCounter >= FHT_N )
{
ADCCounter = 0;
if ( ++ChannelIndex >= CHANNELS )
{
ChannelIndex = 0;
FHTStart = true; // Set flag to enable start of FHT.
}
// Switch to next channel.
ADMUX &= 0xE0;
ADMUX |= admux[ChannelIndex];
}
}
And the main code is:
void loop( void )
{
if ( FHTStart )
{
// cli();
// bitclr( ADCSRA, ADATE );
stopADC();
if ( DEBUG )
{
Serial.println( "Calling FHT routine" );
delay( 1000 );
}
getFHTOutput();
FHTStart = false;
// sei();
// bitset( ADCSRA, ADATE );
startADC();
}
}
At the moment the getFHTOutput function just prints some debug into to serial, except it never shows!
I see the main loop debug output but I get the setup() function debug output in each loop.
Why is the setup function being called when I try and restart the interrupt?
Is there a better way?