//*************************************************************************** // // Author(s)...: Pashgan http://ChipEnable.Ru // Target(s)...: любой микроконтроллер mega // Compiler....: IAR 5.11A // Description.: Заготовка для событийной системы на таблицах // Data........: 30.09.12 // //*************************************************************************** #include "event-system.h" //функция-заглушка static void EmptyFunc(void); //кольцевой буфер static volatile es_event_t cycleBuf[SIZE_BUF]; static volatile uint8_t tailBuf = 0; static volatile uint8_t headBuf = 0; static volatile uint8_t countBuf = 0; static volatile es_state_t _State; typedef struct { es_state_t startState; es_state_t endState; es_event_t startEvent; es_event_t endEvent; es_state_t nextstate; void (*pStateFunc1)(void); void (*pStateFunc2)(void); } table_state_t; /** таблица состояний */ const table_state_t table[] = { /* STATE from STATE to EVENT from EVENT to NEXT STATE STATE_FUNC1 STATE_FUNC2 */ /* обязательная пустая строка таблицы */ {stNoChange, stNoChange, eventNull, eventNull, stNoChange, EmptyFunc, EmptyFunc} }; /** * @brief Take event. * @param None * @retval Event */ es_event_t ES_GetEvent(void) { es_event_t event; if (countBuf > 0){ event = cycleBuf[headBuf]; countBuf--; headBuf = (headBuf + 1) & (SIZE_BUF - 1); return event; } return eventNull; } /** * @brief Place event. * @param Event * @retval None */ void ES_PlaceEvent(es_event_t event) { if (countBuf < SIZE_BUF){ cycleBuf[tailBuf] = event; tailBuf = (tailBuf + 1) & (SIZE_BUF - 1); countBuf++; /* сигнализация переполнения буфера событий */ } else { while(1); } } /** * @brief Initialize event system. * @param Start Event * @retval None */ void ES_Init(es_state_t init_state) { tailBuf = 0; headBuf = 0; countBuf = 0; _State = init_state; } /** * @brief Fake function. * @param None * @retval None */ static void EmptyFunc(void) { } /** * @brief Dispatcher of event system. * @param Event * @retval None */ void ES_Dispatch(es_event_t event) { void (*pStateFunc1)(void); void (*pStateFunc2)(void); uint8_t i; pStateFunc1 = NULL; pStateFunc2 = NULL; //определяем следующее состояние for (i=0; table[i].startEvent || table[i].endEvent; i++) { //если текущее состояние попадает в диапазон if ((_State >= table[i].startState)&&(_State <= table[i].endState)){ //если поступившее событие попадает в диапазон if((event >= table[i].startEvent) && (event <= table[i].endEvent)){ //меняем состояние если требуется if (table[i].nextstate != stNoChange) _State = table[i].nextstate; pStateFunc1 = table[i].pStateFunc1; pStateFunc2 = table[i].pStateFunc2; break; } } } if (pStateFunc1) pStateFunc1(); if (pStateFunc2) pStateFunc2(); } /** * @brief Return current state code. * @param None * @retval Event */ es_state_t ES_GetState(void) { return _State; } /** * @brief Set current state to given code . * @param Event * @retval None */ void ES_SetState(es_state_t new_state) { _State = new_state; }