diff --git a/Core/Inc/FreeRTOSConfig.h b/Core/Inc/FreeRTOSConfig.h index 6efff7d..8743294 100644 --- a/Core/Inc/FreeRTOSConfig.h +++ b/Core/Inc/FreeRTOSConfig.h @@ -73,7 +73,7 @@ #define configUSE_TICKLESS_IDLE 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 -#define configCPU_CLOCK_HZ 48000000 +#define configCPU_CLOCK_HZ 24000000 #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES 5 #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) diff --git a/Core/Inc/lcd.h b/Core/Inc/lcd.h index 9e849e3..236ad57 100644 --- a/Core/Inc/lcd.h +++ b/Core/Inc/lcd.h @@ -18,5 +18,6 @@ void LCD_SendData(LCD_HandleTypeDef *lcd, uint8_t data); void LCD_Init(LCD_HandleTypeDef *lcd); void LCD_SendChar(LCD_HandleTypeDef *lcd, char chr); void LCD_SendString(LCD_HandleTypeDef *lcd, char *str); +void LCD_MoveHome(LCD_HandleTypeDef *lcd); #endif \ No newline at end of file diff --git a/Core/Inc/main.h b/Core/Inc/main.h index e84d835..41daf63 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -71,6 +71,7 @@ void vTaskConfig(void *parameter); void vTaskTimerSetup(void *parameter); void vTaskTurn(void *parameter); void vTaskTurnEnd(void *parameter); +void vTaskTurnTimeUpdate(void *parameter); void vTimerCallback(TimerHandle_t xTimer); /* USER CODE END EFP */ diff --git a/Core/Src/game.c b/Core/Src/game.c index 280b377..2898af5 100644 --- a/Core/Src/game.c +++ b/Core/Src/game.c @@ -6,11 +6,12 @@ void InitGameEngine() { game.timerValue = game.turnTime; game.countScores = false; game.activePlayers = 0; - game.currentPlayer = 0; + game.currentPlayer = 1; game.turnTime = TIMER_MAX / 2; game.timerValue = game.turnTime; - for (int i=0; i 0) { - game.scores[game.activePlayers--] = -1; + if (game.activePlayers > 1) { + game.scores[--game.activePlayers] = -1; } } -uint32_t GetCurrentPlayer() { - return game.currentPlayer; -} - -uint32_t GetTimerValue() { - return game.timerValue; -} - void ChangeScore(int8_t delta) { game.scores[game.currentPlayer] += delta; } @@ -58,6 +51,6 @@ void ResetTurnTimer() { } void NextPlayer() { - game.currentPlayer = (game.currentPlayer + 1) % game.activePlayers; + game.currentPlayer = ((game.currentPlayer) % (game.activePlayers+1) + 1 ); ResetTurnTimer(); } \ No newline at end of file diff --git a/Core/Src/lcd.c b/Core/Src/lcd.c index 122f92c..6ff95f9 100644 --- a/Core/Src/lcd.c +++ b/Core/Src/lcd.c @@ -101,6 +101,7 @@ void LCD_MoveCursor(LCD_HandleTypeDef *lcd, uint8_t line, uint8_t column) { void LCD_MoveHome(LCD_HandleTypeDef *lcd) { LCD_SendCommand(lcd, LCD_RETURNHOME ); vTaskDelay(2); + LCD_SendCommand(lcd, LCD_CLEARDISPLAY); } void LCD_Init(LCD_HandleTypeDef *lcd) { diff --git a/Core/Src/main.c b/Core/Src/main.c index 144bbb5..de4dcad 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -99,6 +99,7 @@ Button *bigButton = &buttons[0]; TimerHandle_t secondsTimerHandle = NULL; TaskHandle_t xMusicHandle = NULL; +TaskHandle_t xLCDUpdaterHandle = NULL; asm( "tetris:\n\t" @@ -550,36 +551,72 @@ void vTaskConfig(void *parameter) { vTaskDelete(NULL); } -void vTaskTurn(void *parameter) { - xTimerReset(secondsTimerHandle, 0); - - LCD_MoveHome(&hlcd); - +void vTaskTurnTimeUpdate(void *parameter) { TickType_t xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); while (1) { - if (plusButton->pressed) { - xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); - break; - } - else if (minusButton->pressed) { - xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL); - break; - } - else if (bigButton->pressed) { - xTaskCreate(vTaskTurnEnd, "TaskTurnEnd", configMINIMAL_STACK_SIZE, NULL, 1, NULL); - break; - } - - else if(game.timerValue == 0 && xMusicHandle == NULL) - { - xTaskCreate(vTaskOvertime, "vTaskOvertime", configMINIMAL_STACK_SIZE, NULL, 1, &xMusicHandle); - } - vTaskDelayUntil(&xLastWakeTime,100); + LCD_MoveCursor(&hlcd, 0, 0); + sprintf(lcdBuffer, " %1ld:%02ld ",game.timerValue / 60, game.timerValue % 60); + LCD_SendString(&hlcd, lcdBuffer); + + vTaskDelayUntil(&xLastWakeTime,1000); + } +} + +void vTaskTurn(void *parameter) { + xTaskCreate(vTaskTurnTimeUpdate, "TimeUpdate", configMINIMAL_STACK_SIZE, NULL, 1, &xLCDUpdaterHandle); + vTaskDelay(1); + TickType_t xLastWakeTime; + xLastWakeTime = xTaskGetTickCount(); + + xTimerReset(secondsTimerHandle, 0); + LCD_MoveHome(&hlcd); - HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); + if (game.countScores) + { + memset(&lcdBuffer,'\0', sizeof(lcdBuffer)); + LCD_MoveCursor(&hlcd, 2, 1); + for (int i = 1; i <= game.activePlayers; i++) + { + char tmp[8]; + sprintf(tmp, "%1d:%3ld|", i, game.scores[i]); + strcat(lcdBuffer, tmp); + if (strlen(lcdBuffer) > (LCD_COLS-6)) + { + LCD_SendString(&hlcd, lcdBuffer); + memset(&lcdBuffer,'\0', sizeof(lcdBuffer)); + LCD_MoveCursor(&hlcd, 3, 1); + } + } + LCD_SendString(&hlcd, lcdBuffer); + memset(&lcdBuffer,'\0', sizeof(lcdBuffer)); + } + + LCD_MoveCursor(&hlcd, 1, 0); + sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]); + LCD_SendString(&hlcd, lcdBuffer); + + while (1) + { + if (xSemaphoreTake(buttonPressed, portMAX_DELAY) == pdPASS ) + { + if (plusButton->pressed) { + xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + break; + } + else if (minusButton->pressed) { + xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + break; + } + else if (bigButton->pressed) { + xTaskCreate(vTaskTurnEnd, "TaskTurnEnd", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + break; + } + } + vTaskDelayUntil(&xLastWakeTime,100); +// HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } xTimerStop(secondsTimerHandle, 0); ResetTurnTimer(); @@ -589,27 +626,39 @@ void vTaskTurn(void *parameter) { MusicStop(); xMusicHandle = NULL; } + vTaskDelete(xLCDUpdaterHandle); vTaskDelete(NULL); } void vTaskTurnEnd(void *parameter) { if (game.countScores) { int32_t delta = 0; + LCD_MoveHome(&hlcd); + LCD_MoveCursor(&hlcd, 1, 0); + sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]); + LCD_SendString(&hlcd, lcdBuffer); while (1) { - if (bigButton->pressed) { - ChangeScore(delta); - break; - } - else if (plusButton->pressed) - { - delta++; - } - else if (minusButton->pressed) - { - delta--; - } - vTaskDelay(10); - } + LCD_MoveCursor(&hlcd, 2, 0); + sprintf(lcdBuffer, "Result: %+4ld", delta); + LCD_SendString(&hlcd, lcdBuffer); + if (xSemaphoreTake(buttonPressed, portMAX_DELAY) == pdPASS ) { + if (bigButton->pressed) { + ChangeScore(delta); + break; + } + else if (plusButton->pressed) + { + plusButton->pressed = false; + delta++; + } + else if (minusButton->pressed) + { + minusButton->pressed = false; + delta--; + } + vTaskDelay(10); + } + } } NextPlayer(); xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL); @@ -633,6 +682,10 @@ void vTaskOvertime(void *parameter) { void vTimerCallback(TimerHandle_t xTimer) { if (game.timerValue > 0) game.timerValue--; + else if(game.timerValue == 0 && xMusicHandle == NULL) + { + xTaskCreate(vTaskOvertime, "vTaskOvertime", configMINIMAL_STACK_SIZE, NULL, 1, &xMusicHandle); + } } void vTaskButtonPoll(void *parameter) {