Search code examples
cswitch-statementembeddedavr

Switch statement won't restart after termination


I am struggling with exiting from the following switch statement. Any help is greatly appreciated.

I have several case statements and my problem is if the break flag goes up high from an external interrupt, any operation should be stopped and go back to its initial state waiting for start flag to go up high.

Currently all described functions are working except for going back to its initial state after break flag is high. For example, operation gets terminated when I press cancel. However, the system won't start again after cancellation.

Thanks in advance.

while(1)
{   

    switch(state)
    {
        case STOPPED:   // Master control
            if(start_flag == true)
            {
                state = WAITING_FOR_SYNC;
                start_flag = false;
            }
            break;

        case WAITING_FOR_SYNC:
            if(sync_flag == true)   // waiting for input to be synchronised
            {
                state = SAMPLED_AND_PROCESSING;
                sync_flag = false;
                sampleCounter = 0;
                samplingComplete = false;
            }
            break;

        case SAMPLED_AND_PROCESSING:    
            if(samplingComplete == true) // samples to be loaded in a buffer
            {   
                gpio_set_pin_low(AVR32_PIN_PA07);
                windowing();
                rms(x);
                fft_run(window);
                peak_search(fft_mag);
                envelope_output(envelope);
                state = LOOP;
            }
            break;

        case LOOP:
            gpio_set_pin_high(AVR32_PIN_PA07);
            delay_ms(5);
            loop++;
            if(loop == 23)
            {
                state = RS485_OUT;
                loop=0;
            }
            else
            {
                state = SAMPLED_AND_PROCESSING;
                sampleCounter = 0;
                samplingComplete = false;
            }
            break;

        case RS485_OUT:
            //SendTx();
            state = STOPPED;
            break;
       }
    } // switch statement close bracket
    if(break_flag == true)
      state = STOPPED;
}// while close bracket

Solution

  • The problem is probably that break_flag remains true and stops the operation from restarting properly. When you process start_flag, you set it to false after setting the state to WAITING_FOR_SYNC:

    if(start_flag == true)
    {
         state = WAITING_FOR_SYNC;
         start_flag = false;
    }
    

    so apply the same logic to break_flag:

    if(break_flag == true)
    {
        state = STOPPED;
        break_flag = false;
    }
    

    This way break_flag will only be applied once and you won't have to clear it before restarting.