/** * 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); /* ring buffer */ 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 state; es_event_t event; es_state_t nextState; void (*pStateFunc1)(void); void (*pStateFunc2)(void); } table_state_t; /** * Sate Table - heart of state machine */ const table_state_t stateTable[] = { /* STATE EVENT NEXT STATE STATE_FUNC1 STATE_FUNC2 */ /* show date, time, ... */ // 'Select' Button pressed {stShowTime, evBTN1Pressed, stShowWDay, showWD, NULL}, {stShowWDay, evBTN1Pressed, stShowDM, showDayMon, NULL}, {stShowDM, evBTN1Pressed, stShowYear, showYear, NULL}, {stShowYear, evBTN1Pressed, stShowDNhours, showDNhour, NULL}, {stShowDNhours, evBTN1Pressed, stShowDNbright, showDNbright, NULL}, {stShowDNbright, evBTN1Pressed, stShowDNmode, showDNmode, NULL}, {stShowDNmode, evBTN1Pressed, stShowDNcolour, showDNcolour, NULL}, {stShowDNcolour, evBTN1Pressed, stShowTime, showTime, NULL}, // '+' Button pressed {stShowTime, evBTN2Pressed, stShowMMSS, showMMSS, NULL}, {stShowMMSS, evBTN2Pressed, stShowTime, showTime, NULL}, // Top Buton pressed {stShowTime, evBTN4Pressed, stShowTemperature, showTemperature, NULL}, {stShowTemperature, evBTN4Pressed, stShowHumidity, showHumidity, NULL}, {stShowHumidity, evBTN4Pressed, stShowPressure, showPressure, NULL}, {stShowPressure, evBTN4Pressed, stShowTime, showTime, NULL}, /* display wdt events */ {stShowWDay, evDisplayWDT, stShowTime, showTime, NULL}, {stShowDM, evDisplayWDT, stShowTime, showTime, NULL}, {stShowYear, evDisplayWDT, stShowTime, showTime, NULL}, {stShowHumidity, evDisplayWDT, stShowTime, showTime, NULL}, {stShowTemperature, evDisplayWDT, stShowTime, showTime, NULL}, {stShowPressure, evDisplayWDT, stShowTime, showTime, NULL}, {stShowDNhours, evDisplayWDT, stShowTime, showTime, NULL}, {stShowDNbright, evDisplayWDT, stShowTime, showTime, NULL}, {stShowDNmode, evDisplayWDT, stShowTime, showTime, NULL}, {stShowDNcolour, evDisplayWDT, stShowTime, showTime, NULL}, /* refresh output */ {stShowTime, evNewSecond, stNoChange, showTime, NULL}, {stShowMMSS, evNewSecond, stNoChange, showMMSS, NULL}, /* set time */ {stShowTime, evBTN1Holded, stSetHH, setTimeBegin, setHHBegin}, {stSetHH, evBTN1Holded, stShowTime, setTimeEnd, showTime}, {stSetMM, evBTN1Holded, stShowTime, setTimeEnd, showTime}, {stSetHH, evBTN1Pressed, stSetMM, setMMBegin, NULL}, {stSetMM, evBTN1Pressed, stSetHH, setHHBegin, NULL}, {stSetHH, evBTN2Pressed, stNoChange, setHHInc, setTimeShow}, {stSetHH, evBTN3Pressed, stNoChange, setHHDec, setTimeShow}, {stSetMM, evBTN2Pressed, stNoChange, setMMInc, setTimeShow}, {stSetMM, evBTN3Pressed, stNoChange, setMMDec, setTimeShow}, {stSetHH, evDisplayWDT, stShowTime, showTime, NULL}, {stSetMM, evDisplayWDT, stShowTime, showTime, NULL}, /* set calendar */ // begin {stShowWDay, evBTN1Holded, stSetWD, setDateBegin, setWDBegin}, {stShowDM, evBTN1Holded, stSetMD, setDateBegin, setMDBegin}, {stShowYear, evBTN1Holded, stSetYear, setDateBegin, setYearBegin}, // end {stSetWD, evBTN1Holded, stShowWDay, setDateEnd, showWD}, {stSetMD, evBTN1Holded, stShowDM, setDateEnd, showDayMon}, {stSetMon, evBTN1Holded, stShowDM, setDateEnd, showDayMon}, {stSetYear, evBTN1Holded, stShowYear, setDateEnd, showYear}, // next {stSetWD, evBTN1Pressed, stSetMD, setMDBegin, NULL}, {stSetMD, evBTN1Pressed, stSetMon, setMonthBegin, NULL}, {stSetMon, evBTN1Pressed, stSetYear, setYearBegin, NULL}, {stSetYear, evBTN1Pressed, stSetWD, setWDBegin, NULL}, // change {stSetWD, evBTN2Pressed, stNoChange, setIncWDay, setWDShow}, {stSetWD, evBTN3Pressed, stNoChange, setDecWDay, setWDShow}, {stSetMD, evBTN2Pressed, stNoChange, setIncMDay, setDMShow}, {stSetMD, evBTN3Pressed, stNoChange, setDecMDay, setDMShow}, {stSetMon, evBTN2Pressed, stNoChange, setIncMonth, setDMShow}, {stSetMon, evBTN3Pressed, stNoChange, setDecMonth, setDMShow}, {stSetYear, evBTN2Pressed, stNoChange, setIncYear, setYearShow}, {stSetYear, evBTN3Pressed, stNoChange, setDecYear, setYearShow}, // WDT {stSetWD, evDisplayWDT, stShowTime, showTime, NULL}, {stSetMD, evDisplayWDT, stShowTime, showTime, NULL}, {stSetMon, evDisplayWDT, stShowTime, showTime, NULL}, {stSetYear, evDisplayWDT, stShowTime, showTime, NULL}, /* set lighting */ // begin {stShowDNhours, evBTN1Holded, stSetDayHour, setDNbegin, setDayHourBegin}, {stShowDNbright, evBTN1Holded, stSetDayBright, setDNbegin, setDayBrightBegin}, {stShowDNmode, evBTN1Holded, stSetDayMode, setDNbegin, setDayModeBegin}, {stShowDNcolour, evBTN1Holded, stSetDayColour, setDNbegin, setDayColourBegin}, // end {stSetDayHour, evBTN1Holded, stShowDNhours, setDNend, showDNhour}, {stSetNightHour, evBTN1Holded, stShowDNhours, setDNend, showDNhour}, {stSetDayBright, evBTN1Holded, stShowDNbright, setDNend, showDNbright}, {stSetNightBright, evBTN1Holded, stShowDNbright, setDNend, showDNbright}, {stSetDayMode, evBTN1Holded, stShowDNmode, setDNend, showDNmode}, {stSetNightMode, evBTN1Holded, stShowDNmode, setDNend, showDNmode}, {stSetDayColour, evBTN1Holded, stShowDNcolour, setDNend, showDNcolour}, {stSetNightColour, evBTN1Holded, stShowDNcolour, setDNend, showDNcolour}, // next {stSetDayHour, evBTN1Pressed, stSetNightHour, setNightHourBegin, NULL}, {stSetNightHour, evBTN1Pressed, stSetDayBright, setDayBrightBegin, NULL}, {stSetDayBright, evBTN1Pressed, stSetNightBright, setNightBrightBegin, NULL}, {stSetNightBright, evBTN1Pressed, stSetDayMode, setDayModeBegin, NULL}, {stSetDayMode, evBTN1Pressed, stSetNightMode, setNightModeBegin, NULL}, {stSetNightMode, evBTN1Pressed, stSetDayColour, setDayColourBegin, NULL}, {stSetDayColour, evBTN1Pressed, stSetNightColour, setNightColourBegin, NULL}, {stSetNightColour, evBTN1Pressed, stSetDayHour, setDayHourBegin, NULL}, // change {stSetDayHour, evBTN2Pressed, stNoChange, setIncDayHour, showDNhour}, {stSetDayHour, evBTN3Pressed, stNoChange, setDecDayHour, showDNhour}, {stSetNightHour, evBTN2Pressed, stNoChange, setIncNightHour, showDNhour}, {stSetNightHour, evBTN3Pressed, stNoChange, setDecNightHour, showDNhour}, {stSetDayBright, evBTN2Pressed, stNoChange, setIncDayBright, showDNbright}, {stSetDayBright, evBTN3Pressed, stNoChange, setDecDayBright, showDNbright}, {stSetNightBright, evBTN2Pressed, stNoChange, setIncNightBright, showDNbright}, {stSetNightBright, evBTN3Pressed, stNoChange, setDecNightBright, showDNbright}, {stSetDayMode, evBTN2Pressed, stNoChange, setIncDayMode, showDNmode}, {stSetDayMode, evBTN3Pressed, stNoChange, setDecDayMode, showDNmode}, {stSetNightMode, evBTN2Pressed, stNoChange, setIncNightMode, showDNmode}, {stSetNightMode, evBTN3Pressed, stNoChange, setDecNightMode, showDNmode}, {stSetDayColour, evBTN2Pressed, stNoChange, setIncDayColour, showDNcolour}, {stSetDayColour, evBTN3Pressed, stNoChange, setDecDayColour, showDNcolour}, {stSetNightColour, evBTN2Pressed, stNoChange, setIncNightColour, showDNcolour}, {stSetNightColour, evBTN3Pressed, stNoChange, setDecNightColour, showDNcolour}, // WDT {stSetDayHour, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetNightHour, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetDayBright, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetNightBright, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetDayMode, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetNightMode, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetDayColour, evDisplayWDT, stShowTime, setDNbreak, showTime}, {stSetNightColour, evDisplayWDT, stShowTime, setDNbreak, showTime}, /* mandatory empty table row */ {stNoChange, eventNull, stNoChange, EmptyFunc, EmptyFunc} }; /** * @brief Take event. * @param None * @retval Event code */ 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 { // tube power off TIM1->CCER &= ~(TIM_CCER_CC1E); TIM3->CCER &= ~(TIM_CCER_CC4E); TIM3->CCER &= ~(TIM_CCER_CC3E); TIM3->CCER &= ~(TIM_CCER_CC2E); TIM3->CCER &= ~(TIM_CCER_CC1E); GPIOA->BSRR = 0x10; // color - pink TIM1->CCR2 = 0xff; TIM1->CCR3 = 0x14; TIM1->CCR4 = 0x93; 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) { uint8_t i; void (*pStateFunc1)(void); void (*pStateFunc2)(void); pStateFunc1 = NULL; pStateFunc2 = NULL; /* get next state */ for (i=0; stateTable[i].state; i++) { /* if the current state and the received event match */ if (stateTable[i].state == _State && stateTable[i].event == event) { /* change current state if needed */ if (stateTable[i].nextState != stNoChange) { _State = stateTable[i].nextState; } /* get functions */ pStateFunc1 = stateTable[i].pStateFunc1; pStateFunc2 = stateTable[i].pStateFunc2; break; } } if (pStateFunc1) { pStateFunc1(); } if (pStateFunc2) { pStateFunc2(); } } /** * @brief Return current state code. * @param None * @retval State code */ es_state_t ES_GetState(void) { return _State; } /** * @brief Set current state to given code . * @param State * @retval None */ void ES_SetState(es_state_t new_state) { _State = new_state; }