4

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

KharoBangdo
  • 321
  • 5
  • 14
  • "*pulse*" in which sense? What kind of "*pulse*". What do want to pulse? – alk Jul 22 '17 at 10:30
  • You could switch high in one loop then switch low in next, e.g. by using a state 4 "pulsing". – Yunnosch Jul 22 '17 at 10:30
  • Single Pulse as in a signal which is default low but when some condition occurs goes high & low with high time = say 1ms – KharoBangdo Jul 22 '17 at 10:37
  • @Yunnosch I tried something like "if(signal=0) signal =1; else signal = 0" but that will generate multiple pulses as long as that state is stable – KharoBangdo Jul 22 '17 at 10:41
  • You need to provide more context. With the code you have shown, something like "entry action" is not possible. Please try to give something closer to a [mcve]. A step towards a suitable powerful state machine would be to maintain a "statebefore" variable. – Yunnosch Jul 22 '17 at 10:44
  • Would it be a problem if the state machine is "blind" for events while waiting the desired 1ms? – Yunnosch Jul 22 '17 at 10:47
  • @Yunnosch AFAIK usleep blocks so, the next loop & state machine is executed after 1 ms only – KharoBangdo Jul 22 '17 at 10:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149881/discussion-between-yunnosch-and-kharobangdo). – Yunnosch Jul 22 '17 at 10:57

3 Answers3

3

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;
    }
}
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
1

You just need to implement little logic for state changing and action for each state, like this:

int state = 0;
while(1) {
  switch(state) {
    case 0: // generate single pulse
       start_pulse();
       usleep(1000);
       stop_pulse();
       break;
    case 1: // dont generate , wait 1ms?
       usleep(1000);
       break;
    case 2: // dont generate, wait 1ms?
       usleep(1000);
       break;
    case 3: // generate single pulse
       start_pulse();
       usleep(1000);
       stop_pulse();
       break;
  }
  state = (state+1)%3; // next state: 0, 1, 2, 3, 0, 1, 2,...
} 
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
0

To simplify the switch examples

switch( state ) {
case 1:
case 2:
  usleep(1000);
  break;
case 0:
case 3:
  /* pulse high */
  usleep(1000);
  /* pulse low */
}

More is possible but probably not worth is, let the compiler figure it out.

dcy665
  • 35
  • 4