void DBNC_Process(DBNC_FSMData *data) { DBNC_KeySet keys; for(;;) { /* for loop, will return */ switch(data->state) { case DBNC_KEY_IDLE: /* idle, and now getting a key */ data->scanValue = data->getKeys(); data->longKeyCnt = 1; /* zero is a special value */ data->state = DBNC_KEY_PRESSED; /* advance to next state */ (void)TRG_SetTrigger(data->trigger, data->debounceTicks, (TRG_Callback)DBNC_Process, (void*)data); return; case DBNC_KEY_PRESSED: keys = data->getKeys(); if (keys==data->scanValue) { /* still pressing the same keys */ /*! \todo See how it checks long or short press */ if (data->longKeyCnt>=data->longKeyTicks) { /* yes, long key press detected */ data->longKeyCnt=0; /* zero is a special value to prevent counting */ data->onDebounceEvent(DBNC_EVENT_LONG_PRESSED, data->scanValue); } else if (data->longKeyCnt>0) { /* zero is a special value to prevent counting */ data->longKeyCnt += data->debounceTicks; /* increment loop counter */ } (void)TRG_SetTrigger(data->trigger, data->debounceTicks, (TRG_Callback)DBNC_Process, (void*)data); /* continue waiting */ return; } else if (keys==0) { /* all keys are released */ if (data->longKeyCnt!=0) { /* zero means we already issued the long button press message */ data->onDebounceEvent(DBNC_EVENT_PRESSED, data->scanValue); /* we have a key press: call event handler */ } data->state = DBNC_KEY_RELEASE; /* advance to next state */ (void)TRG_SetTrigger(data->trigger, data->debounceTicks, (TRG_Callback)DBNC_Process, (void*)data); return; } else { /* we got another key set pressed */ /*! \todo Here it goes to the next state */ data->state = DBNC_KEY_RELEASE; } break; case DBNC_KEY_RELEASE: /* wait until keys are released */ keys = data->getKeys(); if (keys==0) { /* all keys released, go back to idle state. */ data->onDebounceEvent(DBNC_EVENT_RELEASED, data->scanValue); data->state = DBNC_KEY_IDLE; /* go back to idle */ data->onDebounceEvent(DBNC_EVENT_END, data->scanValue); /* callback at the end of debouncing. */ return; } else { /* continue waiting */ /* create events for the delta */ data->onDebounceEvent(DBNC_EVENT_RELEASED, (uint8_t)(data->scanValue&(~keys))); data->scanValue = keys; data->longKeyCnt = 1; /* zero is a special value */ data->state = DBNC_KEY_PRESSED; } break; } /* switch */ } /* for */ }
uint8_t BUZ_PlayTune(BUZ_Tunes tune) { if (tune>=BUZ_TUNE_NOF_TUNES) { return ERR_OVERFLOW; } BUZ_Melodies[tune].idx = 0; /* reset index */ return TRG_SetTrigger(TRG_BUZ_TUNE, 0, BUZ_Play, (void*)&BUZ_Melodies[tune]); }
static void BUZ_Play(void *dataPtr) { int idx = (int)dataPtr; BUZ_Beep(Melody[idx].freq, Melody[idx].ms); idx++; if (idx<(sizeof(Melody)/sizeof(Melody[0]))) { TRG_SetTrigger(TRG_BUZ_TUNE, Melody[idx-1].ms/TRG_TICKS_MS, BUZ_Play, (void*)idx); } }
static void BUZ_Play(void *dataPtr) { MelodyDesc *melody = (MelodyDesc*)dataPtr; BUZ_Beep(melody->melody[melody->idx].freq, melody->melody[melody->idx].ms); melody->idx++; if (melody->idx<melody->maxIdx) { TRG_SetTrigger(TRG_BUZ_TUNE, melody->melody[melody->idx-1].ms/TRG_TICKS_MS, BUZ_Play, (void*)melody); } }
uint8_t BUZ_Beep(uint16_t freq, uint16_t durationMs) {/*freq max 500Hz*/ if (trgInfo.buzIterationCntr==0) { /* only if buzzer is not running right now */ BUZ1_SetVal(); /* turn buzzer on */ trgInfo.buzPeriodTicks = (500*TRG_TICKS_MS)/freq; //500 because 1000/2 trgInfo.buzIterationCntr = durationMs/TRG_TICKS_MS/trgInfo.buzPeriodTicks; return TRG_SetTrigger(TRG_BUZ_BEEP, trgInfo.buzPeriodTicks, &BUZ_Toggle, (void*)&trgInfo); } else { return ERR_BUSY; } }
uint8_t BUZ_Beep(uint16_t freq, uint16_t durationMs) { if (trgInfo.buzIterationCntr==0) { /* only if buzzer is not running right now */ BUZ1_SetVal(); /* turn buzzer on */ trgInfo.buzPeriodTicks = (1000/(TRG_TICKS_MS*freq)); trgInfo.buzIterationCntr = durationMs/TRG_TICKS_MS/trgInfo.buzPeriodTicks; return TRG_SetTrigger(TRG_BUZ_BEEP, trgInfo.buzPeriodTicks, BUZ_Toggle, (void*)&trgInfo); } else { return ERR_BUSY; } }
static void BUZ_Toggle(void *dataPtr) { BUZ_TrgInfo *trgInfo = (BUZ_TrgInfo *)dataPtr; if (trgInfo->buzIterationCntr==0) { BUZ1_ClrVal(); /* turn buzzer off */ } else { trgInfo->buzIterationCntr--; BUZ1_NegVal(); (void)TRG_SetTrigger(TRG_BUZ_BEEP, trgInfo->buzPeriodTicks, &BUZ_Toggle, trgInfo); } }
void heartBeat(TRG_CallBackDataPtr data) { TRG_SetTrigger(TRG_HEARTBEAT, 500, &heartBeat, NULL); Led_Toggle(led1); Led_Toggle(led2); }
uint8_t BUZ_PlayTune(void) { return TRG_SetTrigger(TRG_BUZ_TUNE, 1, BUZ_Play, (void*)0); }
void BUTTON_BLUE_OnInterrupt(void) { Events_fireEvent(BUTTON_BLUE_PRESSED); TRG_SetTrigger(TRG_BLUE_BUTTON_PRESSED, 100, blueButtonCallback, 0); }