Search code examples
clogicpulse

How to gererate a single pulse depending on a state machne in C?


I want to write a c code to generate a pulse but cant seem to wrap my head around the logic to implement it. I come from a strong Verilog background & know how to do this in verilog(look for a change of state using xor & use that pulse, stretch it over time if needed by registering it multiple times)

How should I do this in C? I want to do something like

while(1)
{
   switch(state)
   case 0: // generate single pulse
   case 1: // dont generate 
   case 2: // dont gererate
   case 3: // generate single pulse
   usleep(1000) // I want a 1ms pulse
}  

state is modified by a code running on FPGA, so it changes depending on some logic.
Cant seem to thing of a way to do that. Some guidance will be appreciated


Solution

  • You need a slightly more powerful statemachine, which can do entry-actions.

    Assuming

    • it is Ok for the state machine to be blind while pulsing
    • variable state changes inside your loop (e.g. being volatile and updated from ISR perhaps)
    • or state is updated somehow inside the loop (pseudo code for that is present)

    You indicated in chat that you have some control over when the variable state changes. That is important. Either use the polling function updatestate(), which is called from a pseudo code line; or somehow make sure that the variable does not change between // enter protection ... and // leave protection ....
    However, the statemachine will still be blind for changes between, especially during the usleep(1000);. If that is a problem, you need noticably more complex mechanisms.

    Pseudo code proposal:

    // somewhere before
    volatile int state = 0; // somehow changing within the loop 
    
    int statecopy = 0;  
    int statebefore = state,
    
    while(1)
    {
        // updatestate(); // if that is necessary
    
        // Note that the state machine is blind for changes to state
        // between executions of these initial lines.
        // I.e. changes are noticed only when executing the update above
        // or the critical section below this comment. (depending on how
        // the variable state changes.
    
        // enter protection for critical section
        statebefore = statecopy;
        statecopy   = state;
        // leave protection for critical section
    
        switch(statecopy )
        {
            case 0: // generate single pulse
                if (statecopy != statebefore)
                {
                    // switch high
                    usleep(1000); // I want a 1ms pulse
                    // switch low
                }
                break;
            case 1: // dont generate 
                break;
            case 2: // dont gererate
                break;
            case 3: // generate single pulse
                if (statecopy != statebefore)
                {
                    // switch high
                    usleep(1000); // I want a 1ms pulse
                    // switch low
                }
                break;
            default:
                break;
        }
    }