6 #ifndef __STATE_MACHINE_H__
7 #define __STATE_MACHINE_H__
13 template <
class PeerList>
16 class ChangedAlarm :
public Alarm {
20 virtual ~ChangedAlarm () {}
26 virtual void trigger (__attribute__((unused))
AlarmClock& clock) {
32 enum { DELAY_NO=0x00, DELAY_INFINITE=0xffffffff };
39 StateMachine () :
Alarm(0), state(AS_CM_JT_NONE), change(
false), calarm(*
this), actlst(0) {}
42 virtual void trigger (__attribute__((unused))
AlarmClock& clock) {
43 uint8_t next = getNextState(state);
44 uint32_t dly = getDelayForState(next,actlst);
45 setState(next,dly,actlst);
48 bool changed ()
const {
return change; }
49 void changed (
bool c) { change=c; }
51 void setState (uint8_t next,uint32_t delay,
const PeerList& lst=PeerList(0)) {
54 if( next != AS_CM_JT_NONE ) {
56 sysclock.cancel(*
this);
58 while (state != next) {
59 switchState(state, next, delay);
62 if (delay == DELAY_NO) {
64 next = getNextState(state);
65 delay = getDelayForState(next,lst);
68 if (delay != DELAY_INFINITE) {
75 virtual void switchState(__attribute__((unused)) uint8_t oldstate,__attribute__((unused)) uint8_t newstate, __attribute__((unused)) uint32_t) {}
77 void jumpToTarget(
const PeerList& lst) {
78 uint8_t next = getJumpTarget(state,lst);
79 if( next != AS_CM_JT_NONE ) {
81 uint32_t dly = getDelayForState(next,lst);
83 if( next == state && (next == AS_CM_JT_ON || next == AS_CM_JT_OFF) && dly < DELAY_INFINITE) {
84 bool minimal = next == AS_CM_JT_ON ? lst.onTimeMode() : lst.offTimeMode();
86 if( minimal ==
true ) {
88 uint32_t curdly = sysclock.get(*
this);
89 if( curdly == 0 || curdly > dly ) {
96 setState(next,dly,lst);
100 virtual uint8_t getNextState (uint8_t stat) {
102 case AS_CM_JT_ONDELAY:
return AS_CM_JT_REFON;
103 case AS_CM_JT_REFON:
return AS_CM_JT_RAMPON;
104 case AS_CM_JT_RAMPON:
return AS_CM_JT_ON;
105 case AS_CM_JT_ON:
return AS_CM_JT_OFFDELAY;
106 case AS_CM_JT_OFFDELAY:
return AS_CM_JT_REFOFF;
107 case AS_CM_JT_REFOFF:
return AS_CM_JT_RAMPOFF;
108 case AS_CM_JT_RAMPOFF:
return AS_CM_JT_OFF;
109 case AS_CM_JT_OFF:
return AS_CM_JT_ONDELAY;
111 return AS_CM_JT_NONE;
114 virtual uint32_t getDelayForState(uint8_t stat,
const PeerList& lst) {
115 uint32_t delay = getDefaultDelay(stat);
116 if( lst.valid() ==
true ) {
119 case AS_CM_JT_ONDELAY: value = lst.onDly();
break;
120 case AS_CM_JT_ON: value = lst.onTime();
break;
121 case AS_CM_JT_OFFDELAY: value = lst.offDly();
break;
122 case AS_CM_JT_OFF: value = lst.offTime();
break;
123 default:
return delay;
break;
125 delay = AskSinBase::byteTimeCvt(value);
130 virtual uint32_t getDefaultDelay(uint8_t stat)
const {
134 return DELAY_INFINITE;
139 bool delayActive ()
const {
return sysclock.get(*
this) > 0; }
141 void triggerChanged (uint32_t delay) {
142 calarm.set(delay,sysclock);
145 uint8_t getJumpTarget(uint8_t stat,
const PeerList& lst)
const {
147 case AS_CM_JT_ONDELAY:
return lst.jtDlyOn();
148 case AS_CM_JT_REFON:
return lst.jtRefOn();
149 case AS_CM_JT_RAMPON:
return lst.jtRampOn();
150 case AS_CM_JT_ON:
return lst.jtOn();
151 case AS_CM_JT_OFFDELAY:
return lst.jtDlyOff();
152 case AS_CM_JT_REFOFF:
return lst.jtRefOff();
153 case AS_CM_JT_RAMPOFF:
return lst.jtRampOff();
154 case AS_CM_JT_OFF:
return lst.jtOff();
156 return AS_CM_JT_NONE;
159 uint8_t getConditionForState(uint8_t stat,
const PeerList& lst)
const {
161 case AS_CM_JT_ONDELAY:
return lst.ctDlyOn();
162 case AS_CM_JT_REFON:
return lst.ctRepOn();
163 case AS_CM_JT_RAMPON:
return lst.ctRampOn();
164 case AS_CM_JT_ON:
return lst.ctOn();
165 case AS_CM_JT_OFFDELAY:
return lst.ctDlyOff();
166 case AS_CM_JT_REFOFF:
return lst.ctRepOff();
167 case AS_CM_JT_RAMPOFF:
return lst.ctRampOff();
168 case AS_CM_JT_OFF:
return lst.ctOff();
170 return AS_CM_CT_X_GE_COND_VALUE_LO;
173 bool checkCondition (uint8_t stat,
const PeerList& lst,uint8_t value) {
174 uint8_t cond = getConditionForState(stat,lst);
177 case AS_CM_CT_X_GE_COND_VALUE_LO:
178 doit = (value >= lst.ctValLo());
180 case AS_CM_CT_X_GE_COND_VALUE_HI:
181 doit = (value >= lst.ctValHi());
183 case AS_CM_CT_X_LT_COND_VALUE_LO:
184 doit = (value < lst.ctValLo());
186 case AS_CM_CT_X_LT_COND_VALUE_HI:
187 doit = (value < lst.ctValHi());
189 case AS_CM_CT_COND_VALUE_LO_LE_X_LT_COND_VALUE_HI:
190 doit = ((lst.ctValLo() <= value) && (value < lst.ctValHi()));
192 case AS_CM_CT_X_LT_COND_VALUE_LO_OR_X_GE_COND_VALUE_HI:
193 doit = ((value < lst.ctValLo()) || (value >= lst.ctValHi()));