1 /* 2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef HSM_H_ 16 #define HSM_H_ 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 typedef enum 23 { 24 USM_RET_NO_ERROR = 0, 25 USM_RET_TIMEOUT, 26 USM_RET_FAILED, 27 } USB_RET_CODE_E; 28 29 typedef int Event; 30 typedef struct { 31 Event evt; 32 unsigned char srcStmIdx; 33 unsigned char dstStmIdx; 34 unsigned int param0; 35 unsigned int param1; 36 unsigned int param2; 37 } Msg; 38 39 typedef struct Hsm Hsm; 40 typedef Msg const *(*EvtHndlr)(Hsm*, Msg const*); 41 42 typedef struct State State; 43 struct State { 44 State *super; /* pointer to superstate */ 45 EvtHndlr hndlr; /* state's handler function */ 46 char const *name; 47 }; 48 49 void AddState(State *me, char const *name, State *super, EvtHndlr hndlr); 50 #define StateOnEvent(me_, ctx_, msg_) \ 51 (*(me_)->hndlr)((ctx_), (msg_)) 52 53 struct Hsm { /* Hierarchical State Machine base class */ 54 char const *name; /* pointer to static name */ 55 State *curr; /* current state */ 56 State *next; /* next state (non 0 if transition taken) */ 57 State *source; /* source state during last transition */ 58 State top; /* top-most state object */ 59 }; 60 61 void HsmCtor(Hsm *me, char const *name, EvtHndlr topHndlr); 62 void HsmOnStart(Hsm *me); /* enter and start the top state */ 63 void HsmOnEvent(Hsm *me, Msg const *msg); /* "HSM engine" */ 64 65 /* protected: */ 66 unsigned char HsmToLCA_(Hsm *me, State *target); 67 void HsmExit_(Hsm *me, unsigned char toLca); 68 /* get current state */ 69 #define STATE_CURR(me_) (((Hsm *)me_)->curr) 70 71 /* take start transition (no states need to be exited) */ 72 #define STATE_START(me_, target_) (((Hsm *)me_)->next = (target_)) 73 74 /* take a state transition (exit states up to the LCA) */ 75 #define STATE_TRAN(me_, target_) if (1) { \ 76 static unsigned char toLca_ = 0xFF; \ 77 ASSERT(((Hsm *)me_)->next == 0,"%p",((Hsm *)me_)->next); \ 78 if (toLca_ == 0xFF) \ 79 toLca_ = HsmToLCA_((Hsm *)(me_), (target_)); \ 80 HsmExit_((Hsm *)(me_), toLca_); \ 81 ((Hsm *)(me_))->next = (target_); \ 82 TRACE(1, "target=%s",((Hsm *)(me_))->next->name);\ 83 } else ((void)0) 84 85 #define START_EVT ((Event)(-1)) 86 #define ENTRY_EVT ((Event)(-2)) 87 #define EXIT_EVT ((Event)(-3)) 88 89 #ifdef __cplusplus 90 } 91 #endif 92 93 #endif /* hsm_h */ 94