How to restart the main void loop from an interrupt routine...

I have written a sketch to create periodic signals (a frequency generator).

Activities in the setup:

  • in the beginning, the user can select the shape (sine, square, chainsaw up, etc.) and set the frequency (using a button and a potentiometer).
  • then 256 values (for example a sine wave over a full period) are being calculated and stored in an arrray.
  • then the parameters to control the timing (dealy before loading the next value to Port D) are being calculated.

Activities in the main void loop,

  • the program selects/calls the appropriate endless loop that generates the desired signal with the desired frequency at Port D (followed by a DAC). - As mentioned this is endless (four endless loops at the bottom)...

Everything works well and the program can generate signal shapes along with accurate timing.


Now, I want to extend that sketch: When the generator is running (in the endless loop), I would like to change the frequency. By using an interrupt timer, I can enter new parameters (frequeuncy and wave shape). This is done in the interrupt loop: So far so well.

Here is the challenge: Is there a way to stop the endless loop that is embedded at the end of the main void loop from the interrupt loop (that is located outside the main loop)...?

Right now the generator works well and I can even enter new parameters via the interrupt loop (in parallel the endless loop generates the signal), but I have not found a way to somehow stop the endless loop in the main void loop.
I know, that the interrupt loop after execution simply jumps back into the endless loop that is embedded at the end of the main void loop (this is normal). - Is there a way that the jump back to the main program can be redirected to the BEGINNING of the main void loop, rather than jumping back into the endless loop where it came from?

Here's an extent of the sketch for illustration:

interrupt loop () {
// read new frequency and signal shape...

// When the new parameters are set, the signal shape and timing are (re-)calculated...

==> Now the main void loop should be restarted (DO NOT jump back to the endless loop at the end)!!!!

==> Is there a command that jumps from end of interrupt loop directly to the main loop (NOT back to the endless loop at the bottom of the main loop)? - Somehow the jump back address of the program pointer should be overwritten...

}

void setup () {
// read frequency and signal shape...
// calculate signal shape and timing...

}

void loop() {

// call the appropriate endless loop to generate the signal...

noInterrupts();
DDRD |= Port_D_Pinrange_Operate; // Pins 7,6,5,4,3,2,1 set to OUTPUT, and D0 is ready for Rx-function to PC

switch (Generator_Type) {
case 17: Loop_512_17 (); break; // endless loop to generate signal...
case 18: Loop_512_18 (); break; // endless loop to generate signal...
case 19: Loop_512_19 (); break; // endless loop to generate signal...
case 20: Loop_512_20_3n (); break; // endless loop to generate signal...
}

// four endless loops...

void Loop_512_20_3n ()
{
byte NOPs_3x = NOPs_byte;
byte Cycle, Index;
while (true) {
PORTD = PD_B [Index]; Cycle = NOPs_3x; while (--Cycle < 255) NOOP(0); ++Index; if (L_D_B[Index]) NOOP(3); else NOOP(1);
PORTD = PD_A [Index]; Cycle = NOPs_3x; while (--Cycle < 255) NOOP(0); if (L_D_A[Index]) NOOP(3); else NOOP(1);
}
}

void Loop_512_19 ()
{
byte Index;
while (true) {
++Index; PORTD = PD_A [Index]; if (L_D_A[Index]) NOOP(3); else NOOP(1);
NOOP(5); PORTD = PD_B [Index]; if (L_D_B[Index]) NOOP(3); else NOOP(1);
}
}

void Loop_512_18 ()
{
byte Index;
while (true) {
PORTD = PD_B [Index]; if (L_D_B[Index]) NOOP(3); else NOOP(1); NOOP(1); ++Index;
PORTD = PD_A [Index]; if (L_D_A[Index]) NOOP(3); else NOOP(1);
}
}

void Loop_512_17 ()
{
byte Index;
while (true) {
PORTD = PD_B [Index]; ++Index; if (L_D_B[Index]) NOOP(3); else NOOP(1);
PORTD = PD_A [Index]; if (L_D_A[Index]) NOOP(3); else NOOP(1);
}
}

}

Is there a way that the jump back to the main program can be redirected to the BEGINNING of the main void loop,

loop() is just a function like any other, it just happens to be called from a hidden main() function. If you return from loop() it will go back to main() and get called again.

Here is the challenge: Is there a way to stop the endless loop that is embedded at the end of the main void loop from the interrupt loop (that is located outside the main loop)...?

Make your endless loops not endless (pseudo code but it should show the concept):

volatile bool restart_loop;

void loop() {
  restart_loop = false;
...
  // previous endless loop
  while (!restart_loop) {
  }
...
}

ISR {
  restart_loop = true;
}

pylon:
Make your endless loops not endless (pseudo code but it should show the concept):

Very nice idea - simple.

...R