//********************************************************************************************* // verifySequence_tick() // verify sequence state machine //********************************************************************************************* void verifySequence_tick() { switch(verify_state) { //verify_init //Resets all error cases and sets all timers to zero //Gets the current sequence length //enables the button handler case verify_init: verify_isTimeOutError = V_DISABLED; verify_isUserInputError = V_DISABLED; verify_completed = V_DISABLED; timer_waiting = INIT_ZERO; verifyValue = INIT_ZERO; verify_current_sequence_length = globals_getSequenceIterationLength(); if(verify_enable) { simonbuttonHandler_enable(); verify_state = verify_waiting; } break; //verify_waiting //provides the user with time to touch the screen //if the user does not touch before TIMER_EXPIRED_VALUE, verify_isTimeOutError occurs //disables the button handler after waiting is over case verify_waiting: timer_waiting++; if(timer_waiting == TIMER_EXPIRED_VALUE) { verify_isTimeOutError = V_ENABLED; simonbuttonHandler_disable(); verify_state = verify_complete; } if(display_isTouched()) { if(!simonbuttonHandler_releaseDetected() && timer_waiting < TIMER_EXPIRED_VALUE) { verify_state = verify_wait_release; } } break; //verify_wait_release //waits for the user to release the touch screen and disables the button handler case verify_wait_release: if(simonbuttonHandler_releaseDetected()) { simonRegion = simonbuttonHandler_getRegionNumber(); timer_waiting = INIT_ZERO; simonbuttonHandler_disable(); verify_state = verify_validate; } break; //verify_validate //compares the verifyValue to the sequence value to see if the sequence is over //if they are not the same, user input error has occurred case verify_validate: if(simonRegion == globals_getSequenceValue(verifyValue)) { verifyValue++; if(verifyValue == verify_current_sequence_length) { verifyValue = INIT_ZERO; verify_state = verify_complete; } else { timer_waiting = INIT_ZERO; verify_state = verify_waiting; simonbuttonHandler_enable(); } } else { verify_isUserInputError = V_ENABLED; verify_state = verify_complete; } break; //verify_complete //signifies the state machine has completed //restarts if and only if the state machine is enabled case verify_complete: verify_completed = V_ENABLED; timer_waiting = INIT_ZERO; if(verify_enable) { verify_state = verify_init; } break; default: verify_state = verify_init; break; } }
void simonControl_tick() { SC_debugStatePrint(); /// //ACTIONS*********************************************************************** switch(SC_State) { case SC_init_st: //do nothing break; case SC_instructions_st: display_setTextColor(DISPLAY_WHITE); display_setCursor(SC_INSTRUCTION_CURSORX,SC_INSTRUCTION_CURSORY); display_setTextSize(SC_INSTRUCTION_TEXTSIZE); display_println(SC_INSTRUCTIONS); break; case SC_wait_first_touch_st: // do nothing break; case SC_get_sequence_st: SC_currentScore = 0; //reset SC_setSequence(); break; case SC_flash_sequence_st: //do nothing break; case SC_verify_sequence_st: //do nothing break; case SC_error_st: errorTimer++; if (verifySequence_isTimeOutError()) // user didn't press { display_setTextSize(SC_TEXTSIZE); display_println(ERROR_MESSAGE_TIMEOUT); } else if (verifySequence_isUserInputError()) //pressed wrong input { display_setTextSize(SC_TEXTSIZE); display_println(ERROR_MESSAGE_INPUT); } verifySequence_disable(); //set this here so we can read these flags. disable resets the error flags break; case SC_print_score_st: sprintf(maxScoreString, SC_HIGHSCORE_MESSAGE, SC_maxScore); display_setTextSize(SC_TEXTSIZE); //decrease text size display_println(maxScoreString); //reset scores, index, and sequence SC_currentIndex = 1; //reset to 1. since this is sequence length, when we setSequence, don't put to zero SC_maxScore = 0; //reset errorTimer = 0; //reset timer lvlMessageTimer = 0; break; case SC_level_complete_st: lvlMessageTimer++; if(printFlag) //set a flag so it doesn't keep being printed { display_println(SC_LVL_MESSAGE); printFlag = false; //switch flag } break; default: printf(SC_ERROR_MESSAGE); //invalid state break; } //TRANSITIONS*********************************************************************** switch(SC_State) { case SC_init_st: SC_State = SC_instructions_st; //just go to instructions break; case SC_instructions_st: SC_State = SC_wait_first_touch_st; //go wait after drawing. break; case SC_wait_first_touch_st: if (display_isTouched()) //if touched, move ahead { SC_State = SC_get_sequence_st; display_fillScreen(DISPLAY_BLACK); //clear screen of instructions } break; case SC_get_sequence_st: SC_State = SC_flash_sequence_st; flashSequence_enable(); break; case SC_flash_sequence_st: if (flashSequence_completed()) { SC_State = SC_verify_sequence_st; //go to verify flashSequence_disable(); //disable flash machine simonDisplay_drawAllButtons(); //draw the buttons upon exit verifySequence_enable(); } break; case SC_verify_sequence_st: if (verifySequence_isComplete()) //done verifying { //if there a time out error or wrong input error if (verifySequence_isTimeOutError() || verifySequence_isUserInputError()) //no errors { SC_State = SC_error_st; display_fillScreen(DISPLAY_BLACK); //clear buttons off screen } //level complete else if (globals_getSequenceIterationLength() == SC_sequence_length) { SC_sequence_length++; SC_State = SC_level_complete_st; verifySequence_disable(); display_fillScreen(DISPLAY_BLACK); //clear buttons off screen SC_currentIndex = 1; //reset SC_maxScore = SC_currentScore; } else { SC_State = SC_flash_sequence_st; flashSequence_enable(); SC_currentIndex++; //how many to flash? globals_setSequenceIterationLength(SC_currentIndex); //udate how many to falsh verifySequence_disable(); display_fillScreen(DISPLAY_BLACK); //clear buttons off screen SC_currentScore++; if (SC_currentScore > SC_maxScore) //before first level is complete, maxScore doesn't get set { SC_maxScore = SC_currentScore; //this mostly before first level is complete } } } break; case SC_error_st: if (errorTimer >= SC_ERROR_EXPIRE) { SC_State = SC_print_score_st; //print highest score display_fillScreen(DISPLAY_BLACK); } break; case SC_print_score_st: SC_State = SC_instructions_st; SC_maxScore = 0; //reset the maxScore! sequenceSeed++; //change the seed break; case SC_level_complete_st: if (lvlMessageTimer > SC_LVL_MESSAGE_EXPIRE) //timed out { SC_State = SC_print_score_st; } else if (display_isTouched()) { SC_State = SC_instructions_st; display_fillScreen(DISPLAY_BLACK); // clear screen sequenceSeed++; //change the seed printFlag = true; //rest print flag } break; default: printf(SC_ERROR_MESSAGE); break; } }
void verifySequence_tick() { static uint16_t index = 0; static uint16_t timeOutTimer = 0; // counter to track whether a timeout occurs ///////////////////////////////// // Perform state action first. // ///////////////////////////////// switch (verifySequence_state) { case init_st: isTimeOutError = false; isUserInputError = false; index = 0; timeOutTimer = 0; break; case wait_for_timeout_st: timeOutTimer++; buttonHandler_enable(); break; case wait_for_release_st: break; case verification_st: break; case complete_st: break; default: printf("Default case hit in verifySequence tick.\n"); break; } //////////////////////////////// // Perform state update next. // //////////////////////////////// switch (verifySequence_state) { case init_st: if (enabled) { buttonHandler_enable(); verifySequence_state = wait_for_timeout_st; } else { verifySequence_state = init_st; } break; case wait_for_timeout_st: if(display_isTouched()) { timeOutTimer = 0; verifySequence_state = wait_for_release_st; } // If the use waits too long before doing anything else if (timeOutTimer >= WAIT_TIMEOUT) { //printf("userTouchTimer: %d", userTouchTimer); isTimeOutError = true; timeOutTimer = 0; verifySequence_state = complete_st; } else { verifySequence_state = wait_for_timeout_st; } break; case wait_for_release_st: if (buttonHandler_releaseDetected()) { buttonHandler_disable(); verifySequence_state = verification_st; } else { verifySequence_state = wait_for_release_st; } break; case verification_st: uint8_t tempSequenceValue, tempRegionNumber; tempSequenceValue = globals_getSequenceValue(index); tempRegionNumber = buttonHandler_getRegionNumber(); if(tempSequenceValue == tempRegionNumber) { //user touched the correct square // If that was the last square if (globals_getSequenceIterationLength() == (index + 1)) { //because index starts at 0 and length at 1 verifySequence_state = complete_st; } else { index++; verifySequence_state = wait_for_timeout_st; } } else { isUserInputError = true; //printf("USER INPUT ERROR"); verifySequence_state = complete_st; } break; case complete_st: if (!enabled) { verifySequence_state = init_st; } else { verifySequence_state = complete_st; } break; default: printf("Default case hit in verifySequence tick.\n"); break; } }
// Standard tick function. void verifySequence_tick(){ // state actions switch (verifyState){ case init_st: break; case enable_button_st: // enabble the buttonHandler state machine buttonHandler_enable(); break; case wait_for_release_st: // Increment timout value while waiting for the display to be relased timeOut++; break; case verify_region_st: // disable the buttonhandler state machine buttonHandler_disable(); // if the user tapped the wrong sequence, raise the errorFlag if (globals_getSequenceValue(index) != buttonHandler_getRegionNumber()){ userErrorFlag = 1; } break; case increment_st: break; case done_st: break; } // state transitions switch (verifyState){ case init_st: // wait for the state machine to be enabled if (verifyEnableFlag) { // reset all flags and counters index = 0; completeFlag = 0; timeOutFlag = 0; userErrorFlag = 0; timeOut = 0; verifyState = enable_button_st; } break; case enable_button_st: verifyState = wait_for_release_st; break; case wait_for_release_st: // if the timout value is reached if (timeOut == TIME_OUT_VALUE){ // raise the timeOutFlag timeOutFlag = 1; // raise the completeFlag completeFlag = 1; // erase all the buttons simonDisplay_eraseAllButtons(); // and go to done verifyState = done_st; } // if the display is currently touched, reset the counter. // I didn't want it to timeout if the user is holding the buton. else if (display_isTouched()){ timeOut = 0; } // otherwise if the display was released else if (buttonHandler_releaseDetected()){ // go check the region pressed against the reion in the sequence verifyState = verify_region_st; } break; case verify_region_st: verifyState = increment_st; break; case increment_st: // if we're at the end of the sequence if (index == (globals_getSequenceIterationLength())){ // raise completeFlag to indicate it's over completeFlag = 1; // erase all the buttons simonDisplay_eraseAllButtons(); // go to done verifyState = done_st; } // if the user made an error else if (userErrorFlag){ // raise completeFlag completeFlag = 1; // erase the buttons simonDisplay_eraseAllButtons(); // go to done verifyState = done_st; } else { // otherwise increase the index and verify the next button // in the sequence index++; verifyState = enable_button_st; } break; case done_st: // if the enable flag goes low if (!verifyEnableFlag) { // go to init verifyState = init_st; } break; } }