Initial question
Update: interrupts and state charts
I will provide a specific situation. Let us assume we want to implement a state chart, which is composed by 4 blocks:
- Transitions/Effect.
- Exit conditions.
- Entry activity.
- Do activity.
This is what a professor taught us at university. Probably, not the best way of doing it is by following this scheme:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
Let us also assume that from, say STATE_A
, I want to be sensitive to a interrupt coming from a set of buttons (with debouce system, etc. etc.). When someone presses one of these buttons, an interrupt is generated and the flag related to the input port is copied into a variable buttonPressed
. If the debounce is set to 200 ms in some way (watchdog timer, timer, counter, ...) we are sure that buttonPressed
cannot be updated with a new value before 200 ms.
This is what I am asking you (and myself :) of course)
Do I need to enable interrupt in the DO activity of STATE_A
and disable before leaving?
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
In a way that I am sure that the next time I execxute block 1 (transition/effects) at the next iteration I am sure that the conditions checked along the transitions are not coming from a subsequent interrupt that has overwritten the previous value of buttonPressed
that I need (although it is impossible that this happens because 250 ms must elapse).