/*..........................................................................*/ QState Bomb4_timing(Bomb4 *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->code = 0; /* clear the defuse code */ return Q_HANDLED(); } case UP_SIG: { me->code <<= 1; me->code |= 1; return Q_HANDLED(); } case DOWN_SIG: { me->code <<= 1; return Q_HANDLED(); } case ARM_SIG: { if (me->code == me->defuse) { return Q_TRAN(&Bomb4_setting); } return Q_HANDLED(); } case TICK_SIG: { if (((TickEvt const *)e)->fine_time == 0) { --me->timeout; BSP_display(me->timeout); if (me->timeout == 0) { BSP_boom(); /* destroy the bomb */ } } return Q_HANDLED(); } } return Q_IGNORED(); }
/*..........................................................................*/ QState Bomb_timing(Bomb *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_arm((QActive *)me, BSP_TICKS_PER_SEC/4); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { QActive_arm((QActive *)me, BSP_TICKS_PER_SEC/4); if (me->ctr > (uint8_t)0) { if ((me->ctr & 0x01) != 0) { LED_on(); } else { LED_off(); } --me->ctr; } else { /* timeout expired */ return Q_TRAN(&Bomb_blast); } return Q_HANDLED(); } } return Q_IGNORED(); }
/*..........................................................................*/ QState Alarm_on(Alarm *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** Alarm ON %02ld:%02ld\n", me->alarm_time/60, me->alarm_time%60); fflush(stdout); return Q_HANDLED(); } case ALARM_SET_SIG: { printf("*** Cannot set Alarm when it is ON\n"); fflush(stdout); return Q_HANDLED(); } case ALARM_OFF_SIG: { return Q_TRAN(&Alarm_off); } case TIME_SIG: { if (Q_PAR(me) == me->alarm_time) { printf("ALARM!!!\n"); /* asynchronously post the event to the container AO */ QActive_post((QActive *)&AO_AlarmClock, ALARM_SIG, 0); } return Q_HANDLED(); } } return Q_IGNORED(); }
/*..........................................................................*/ QState Bomb_blast(Bomb *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_arm((QActive *)me, 2 * BSP_TICKS_PER_SEC); LED_on(); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { return Q_TRAN(&Bomb_off); } } return Q_IGNORED(); }
/*..........................................................................*/ QState Bomb_off(Bomb *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { LED_off(); return Q_HANDLED(); } case ARM_SIG: { me->ctr = Q_PAR(me) * 4; /* arm the downcounter */ return Q_TRAN(&Bomb_timing); } } return Q_IGNORED(); }
/*..........................................................................*/ QState Philo_hungry(Philo *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_post((QActive *)&AO_Table, HUNGRY_SIG, me->super.prio); return Q_HANDLED(); } case EAT_SIG: { BSP_busyDelay(); return Q_TRAN(&Philo_eating); } // case DONE_SIG: { // Q_ERROR(); /* thes event should never arrive in this state */ // return Q_HANDLED(); // } } return Q_IGNORED(); }
/*..........................................................................*/ QState Philo_thinking(Philo *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_arm((QActive *)me, THINK_TIME); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { BSP_busyDelay(); return Q_TRAN(&Philo_hungry); } // case EAT_SIG: // case DONE_SIG: { // Q_ERROR(); /* these events should never arrive in this state */ // return Q_HANDLED(); // } } return Q_IGNORED(); }
/*..........................................................................*/ QState Oper_run(Oper *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_arm((QActive *)me, me->interval); return Q_HANDLED(); } case Q_EXIT_SIG: { uint8_t timeout = me->bomb_prev + 1; if (timeout > me->bomb_max) { timeout = me->bomb_min; } me->bomb_prev = timeout; QActive_post((QActive *)&AO_Bomb, ARM_SIG, timeout); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { return Q_TRAN(&Oper_run); /* transition to self */ } } return Q_IGNORED(); }
void QFsm_dispatch(QFsm *me) { #else void QFsm_dispatch(QFsm *me) Q_REENTRANT { #endif QStateHandler s = me->state; if ((*s)(me) == Q_RET_TRAN) { /* transition taken? */ Q_SIG(me) = (QSignal)Q_EXIT_SIG; (void)(*s)(me); /* exit the source */ Q_SIG(me) = (QSignal)Q_ENTRY_SIG; (void)(*me->state)(me); /* enter the target */ } } #endif /* Q_NFSM */ #ifndef Q_NHSM /*..........................................................................*/ QState QHsm_top(QHsm *me) { (void)me; /* supress the "unused argument" compiler warning */ return Q_IGNORED(); /* the top state ignores all events */ }
/*..........................................................................*/ QState Philo_eating(Philo *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QActive_arm((QActive *)me, EAT_TIME); return Q_HANDLED(); } case Q_EXIT_SIG: { BSP_busyDelay(); QActive_post((QActive *)&AO_Table, DONE_SIG, me->super.prio); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { return Q_TRAN(&Philo_thinking); } // case EAT_SIG: // case DONE_SIG: { // Q_ERROR(); /* these events should never arrive in this state */ // return Q_HANDLED(); // } } return Q_IGNORED(); }
/*..........................................................................*/ QState Bomb4_setting(Bomb4 *me, QEvent const *e) { switch (e->sig) { case UP_SIG: { if (me->timeout < 60) { ++me->timeout; BSP_display(me->timeout); } return Q_HANDLED(); } case DOWN_SIG: { if (me->timeout > 1) { --me->timeout; BSP_display(me->timeout); } return Q_HANDLED(); } case ARM_SIG: { return Q_TRAN(&Bomb4_timing); /* transition to "timing" */ } } return Q_IGNORED(); }
/*..........................................................................*/ QState Alarm_off(Alarm *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { /* while in the off state, the alarm is kept in decimal format */ me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; printf("*** Alarm OFF %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); fflush(stdout); return Q_HANDLED(); } case Q_EXIT_SIG: { /* upon exit, the alarm is converted to binary format */ me->alarm_time = (me->alarm_time/100)*60 + me->alarm_time%100; return Q_HANDLED(); } case ALARM_ON_SIG: { /* alarm in range? */ if ((me->alarm_time / 100 < 24) && (me->alarm_time % 100 < 60)) { return Q_TRAN(&Alarm_on); } else { /* alarm out of range -- clear and don't transition */ me->alarm_time = 0; printf("*** Alarm reset %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); return Q_HANDLED(); } } case ALARM_SET_SIG: { /* while setting, the alarm is kept in decimal format */ me->alarm_time = (10 * me->alarm_time + Q_PAR(me)) % 10000; printf("*** Alarm SET %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); fflush(stdout); return Q_HANDLED(); } } return Q_IGNORED(); }
/*..........................................................................*/ QState QHsm_top(void const * const me, QEvt const * const e) { (void)me; /* suppress the "unused argument" compiler warning */ (void)e; /* suppress the "unused argument" compiler warning */ return Q_IGNORED(); /* the top state ignores all events */ }