From 97c59aa96cf3c0bd530de299534b9326e9afb5d1 Mon Sep 17 00:00:00 2001 From: lucordes Date: Mon, 23 Jun 2025 19:21:54 +0200 Subject: [PATCH] some changes --- Core/Inc/main.h | 10 +++ Core/Src/ili9341.h | 6 +- Core/Src/ili9341_touch.h | 4 +- Core/Src/main.c | 162 +++++++++++++++++++++++++++++++-------- touchscreengames.ioc | 55 +++++++++---- 5 files changed, 187 insertions(+), 50 deletions(-) diff --git a/Core/Inc/main.h b/Core/Inc/main.h index be9a3f3..e814364 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -57,6 +57,16 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ +#define DISPLAY_DC_Pin GPIO_PIN_2 +#define DISPLAY_DC_GPIO_Port GPIOA +#define DISPLAY_RES_Pin GPIO_PIN_3 +#define DISPLAY_RES_GPIO_Port GPIOA +#define DISPLAY_CS_Pin GPIO_PIN_4 +#define DISPLAY_CS_GPIO_Port GPIOA +#define TOUCH_IRQ_Pin GPIO_PIN_5 +#define TOUCH_IRQ_GPIO_Port GPIOB +#define TOUCH_CS_Pin GPIO_PIN_6 +#define TOUCH_CS_GPIO_Port GPIOB /* USER CODE BEGIN Private defines */ diff --git a/Core/Src/ili9341.h b/Core/Src/ili9341.h index ecf8bf0..5f2a095 100644 --- a/Core/Src/ili9341.h +++ b/Core/Src/ili9341.h @@ -18,11 +18,11 @@ #define ILI9341_SPI_PORT hspi1 extern SPI_HandleTypeDef ILI9341_SPI_PORT; -#define ILI9341_RES_Pin GPIO_PIN_3 +#define ILI9341_RES_Pin GPIO_PIN_3 //output #define ILI9341_RES_GPIO_Port GPIOA -#define ILI9341_CS_Pin GPIO_PIN_4 +#define ILI9341_CS_Pin GPIO_PIN_4 //output #define ILI9341_CS_GPIO_Port GPIOA -#define ILI9341_DC_Pin GPIO_PIN_2 +#define ILI9341_DC_Pin GPIO_PIN_2 //output #define ILI9341_DC_GPIO_Port GPIOA // default orientation /* diff --git a/Core/Src/ili9341_touch.h b/Core/Src/ili9341_touch.h index 309da59..9589ec0 100644 --- a/Core/Src/ili9341_touch.h +++ b/Core/Src/ili9341_touch.h @@ -11,9 +11,9 @@ #define ILI9341_TOUCH_SPI_PORT hspi2 extern SPI_HandleTypeDef ILI9341_TOUCH_SPI_PORT; -#define ILI9341_TOUCH_IRQ_Pin GPIO_PIN_5 // Arduino D5 +#define ILI9341_TOUCH_IRQ_Pin GPIO_PIN_5 #define ILI9341_TOUCH_IRQ_GPIO_Port GPIOB -#define ILI9341_TOUCH_CS_Pin GPIO_PIN_6 // Arduino D2 +#define ILI9341_TOUCH_CS_Pin GPIO_PIN_6 #define ILI9341_TOUCH_CS_GPIO_Port GPIOB // change depending on screen orientation diff --git a/Core/Src/main.c b/Core/Src/main.c index 4d0467f..83afa10 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -57,6 +57,10 @@ const osThreadAttr_t draw_attributes = { .name = "draw", .stack_size = 128 * 4, osThreadId_t reactiongameHandle; const osThreadAttr_t reactiongame_attributes = { .name = "reactiongame", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityLow, }; +/* Definitions for gamepicker */ +osThreadId_t gamepickerHandle; +const osThreadAttr_t gamepicker_attributes = { .name = "gamepicker", + .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityLow, }; /* Definitions for presses */ osMessageQueueId_t pressesHandle; const osMessageQueueAttr_t presses_attributes = { .name = "presses" }; @@ -73,8 +77,9 @@ static void MX_GPIO_Init(void); static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); void StartTouchHist(void *argument); -void startdraw(void *argument); +void snakegame(void *argument); void startreactiongame(void *argument); +void gamepicker_entry(void *argument); /* USER CODE BEGIN PFP */ @@ -82,6 +87,7 @@ void startreactiongame(void *argument); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ + #define touchbuffersize 50 struct { int x[touchbuffersize]; @@ -166,6 +172,10 @@ void GameInit() { snake.fruitCordY = rand() % snake.gamesizeheight; snake.playerScore = 0; snake.TailLen = 0; + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_FillScreen(ILI9341_WHITE); + osMutexRelease(displayHandle); + } } // Function for updating the game state void UpdateGame() { @@ -220,7 +230,7 @@ void UpdateGame() { break; } - // Checks for snake's collision with the wall (|) + // Checks for snake's collision with the wall if (snake.x >= snake.gamesizewidth || snake.x < 0 || snake.y >= snake.gamesizeheight || snake.y < 0) snake.isGameOver = true; @@ -241,7 +251,7 @@ void UpdateGame() { if (snake.isGameOver) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - if (Flash_Read_HighScore() < snake.playerScore) { + if (Flash_Read_HighScore() > snake.playerScore) { char str[50]; sprintf(str, "Highscore Remains: %lu", Flash_Read_HighScore()); ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, @@ -259,6 +269,7 @@ void UpdateGame() { } } // Function to handle user UserInput +int prevpressed; void UserInput() { // Checks if a key is pressed or not @@ -285,10 +296,24 @@ void UserInput() { } // Send the direction to the queue - - osStatus_t status = osMessageQueuePut(pressesHandle, &dir, 0, 0); - if (status != osOK) { - // Optional: Handle error + if (!prevpressed && ILI9341_TouchPressed()) { + osStatus_t status = osMessageQueuePut(pressesHandle, &dir, 0, 0); + if (status != osOK) { + // Optional: Handle error + } + } + prevpressed = 1; + } else { + prevpressed = 0; + //give illegal coords + //if it is already we can skip it + if (touchcoord.x[0] != ILI9341_WIDTH) { //is the last buffer coord illegal? + for (int i = 0; i < touchbuffersize - 1; i++) { + touchcoord.x[i] = touchcoord.x[i + 1]; + touchcoord.y[i] = touchcoord.y[i + 1]; + } + touchcoord.x[touchbuffersize - 1] = ILI9341_WIDTH; + touchcoord.y[touchbuffersize - 1] = ILI9341_HEIGHT; } } @@ -306,8 +331,9 @@ void GameRender() { if (x == snake.x && y == snake.y) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_FillRectangle((x * ILI9341_WIDTH) / ILI9341_WIDTH, - (y * ILI9341_WIDTH) / ILI9341_WIDTH, + ILI9341_FillRectangle( + (x * ILI9341_WIDTH) / snake.gamesizewidth, + (y * ILI9341_HEIGHT) / snake.gamesizeheight, ILI9341_WIDTH / snake.gamesizewidth, ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_BLACK); @@ -317,10 +343,11 @@ void GameRender() { //cout << "O"; // Creating the sanke's food with '#' - else if (x == snake.fruitCordY && y == snake.fruitCordX) { + else if (x == snake.fruitCordX && y == snake.fruitCordY) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_FillRectangle((x * ILI9341_WIDTH) / ILI9341_WIDTH, - (y * ILI9341_WIDTH) / ILI9341_WIDTH, + ILI9341_FillRectangle( + (x * ILI9341_WIDTH) / snake.gamesizewidth, + (y * ILI9341_HEIGHT) / snake.gamesizeheight, ILI9341_WIDTH / snake.gamesizewidth, ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_RED); osMutexRelease(displayHandle); @@ -331,8 +358,9 @@ void GameRender() { // Creating snake's head with 'O' else if (snake.TailX[0] == x && snake.TailY[0] == y) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_FillRectangle((x * ILI9341_WIDTH) / ILI9341_WIDTH, - (y * ILI9341_WIDTH) / ILI9341_WIDTH, + ILI9341_FillRectangle( + (x * ILI9341_WIDTH) / snake.gamesizewidth, + (y * ILI9341_HEIGHT) / snake.gamesizeheight, ILI9341_WIDTH / snake.gamesizewidth, ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_GREEN); @@ -342,8 +370,9 @@ void GameRender() { } else if (snake.TailPendingDeletionX == x && snake.TailPendingDeletionY == y) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_FillRectangle((x * ILI9341_WIDTH) / ILI9341_WIDTH, - (y * ILI9341_WIDTH) / ILI9341_WIDTH, + ILI9341_FillRectangle( + (x * ILI9341_WIDTH) / snake.gamesizewidth, + (y * ILI9341_HEIGHT) / snake.gamesizeheight, ILI9341_WIDTH / snake.gamesizewidth, ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_WHITE); @@ -374,7 +403,7 @@ int main(void) { HAL_Init(); /* USER CODE BEGIN Init */ - + ILI9341_Init(); /* USER CODE END Init */ /* Configure the system clock */ @@ -423,6 +452,17 @@ int main(void) { touchhistoryHandle = osThreadNew(StartTouchHist, NULL, &touchhistory_attributes); + /* creation of draw */ + drawHandle = osThreadNew(snakegame, NULL, &draw_attributes); + + /* creation of reactiongame */ + reactiongameHandle = osThreadNew(startreactiongame, NULL, + &reactiongame_attributes); + + /* creation of gamepicker */ + gamepickerHandle = osThreadNew(gamepicker_entry, NULL, + &gamepicker_attributes); + /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ titlescreen(); @@ -431,7 +471,7 @@ int main(void) { osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, osWaitForever); // blocking if (dir == 'L') - drawHandle = osThreadNew(startdraw, NULL, &draw_attributes); + drawHandle = osThreadNew(snakegame, NULL, &draw_attributes); if (dir == 'R') reactiongameHandle = osThreadNew(startreactiongame, NULL, &reactiongame_attributes); @@ -448,9 +488,7 @@ int main(void) { /* Infinite loop */ /* USER CODE BEGIN WHILE */ - uint16_t a, b; - ILI9341_TouchGetCoordinates(&a, &b); - GameInit(); + while (1) { /* USER CODE END WHILE */ @@ -576,6 +614,7 @@ static void MX_SPI2_Init(void) { * @retval None */ static void MX_GPIO_Init(void) { + GPIO_InitTypeDef GPIO_InitStruct = { 0 }; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ @@ -584,6 +623,33 @@ static void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOA, DISPLAY_DC_Pin | DISPLAY_RES_Pin | DISPLAY_CS_Pin, + GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pins : DISPLAY_DC_Pin DISPLAY_RES_Pin DISPLAY_CS_Pin */ + GPIO_InitStruct.Pin = DISPLAY_DC_Pin | DISPLAY_RES_Pin | DISPLAY_CS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : TOUCH_IRQ_Pin */ + GPIO_InitStruct.Pin = TOUCH_IRQ_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(TOUCH_IRQ_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : TOUCH_CS_Pin */ + GPIO_InitStruct.Pin = TOUCH_CS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(TOUCH_CS_GPIO_Port, &GPIO_InitStruct); + /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ @@ -613,27 +679,29 @@ void StartTouchHist(void *argument) { osMutexRelease(displayHandle); } - osDelay(10); + osDelay(1); } /* USER CODE END 5 */ } -/* USER CODE BEGIN Header_startdraw */ +/* USER CODE BEGIN Header_snakegame */ /** * @brief Function implementing the draw thread. * @param argument: Not used * @retval None */ -/* USER CODE END Header_startdraw */ -void startdraw(void *argument) { - /* USER CODE BEGIN startdraw */ +/* USER CODE END Header_snakegame */ +void snakegame(void *argument) { + /* USER CODE BEGIN snakegame */ /* Infinite loop */ + GameInit(); for (;;) { - osDelay(100); + osDelay(200); UpdateGame(); GameRender(); } - /* USER CODE END startdraw */ + + /* USER CODE END snakegame */ } /* USER CODE BEGIN Header_startreactiongame */ @@ -654,7 +722,7 @@ void startreactiongame(void *argument) { char str[50]; // add the check for clicking too early. add the message clicked too early - if (osMessageQueueGet(pressesHandle, &dir, NULL, 0)!=osOK) { // Check if someone pressed during the delay → early press + if (osMessageQueueGet(pressesHandle, &dir, NULL, 0) != osOK) { // Check if someone pressed during the delay → early press if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { ILI9341_FillScreen(ILI9341_GREEN); @@ -692,7 +760,6 @@ void startreactiongame(void *argument) { osMutexRelease(displayHandle); } - } osDelay(1000); if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { @@ -708,6 +775,41 @@ void startreactiongame(void *argument) { /* USER CODE END startreactiongame */ } +/* USER CODE BEGIN Header_gamepicker_entry */ +/** + * @brief Function implementing the gamepicker thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_gamepicker_entry */ +void gamepicker_entry(void *argument) { + /* USER CODE BEGIN gamepicker_entry */ + /* Infinite loop */ + for (;;) { + osDelay(1); + titlescreen(); // Render title screen + + char dir; + // Wait for input (blocking) + osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, + osWaitForever); + + if (status == osOK) { + if (dir == 'L') { + drawHandle = osThreadNew(snakegame, NULL, &draw_attributes); + osThreadExit(); // Game Manager exits or waits for signal to restart + } else if (dir == 'R') { + reactiongameHandle = osThreadNew(startreactiongame, NULL, + &reactiongame_attributes); + osThreadExit(); + } else { + // not implemeted + } + } + } + /* USER CODE END gamepicker_entry */ +} + /** * @brief Period elapsed callback in non blocking mode * @note This function is called when TIM2 interrupt took place, inside diff --git a/touchscreengames.ioc b/touchscreengames.ioc index 2be6386..4e71b06 100644 --- a/touchscreengames.ioc +++ b/touchscreengames.ioc @@ -6,7 +6,7 @@ FREERTOS.FootprintOK=true FREERTOS.IPParameters=Tasks01,FootprintOK,configUSE_NEWLIB_REENTRANT,Queues01,Mutexes01 FREERTOS.Mutexes01=display,Dynamic,NULL,Available FREERTOS.Queues01=presses,16,char,0,Dynamic,NULL,NULL -FREERTOS.Tasks01=touchhistory,24,128,StartTouchHist,Default,NULL,Dynamic,NULL,NULL;draw,8,128,startdraw,Default,NULL,Dynamic,NULL,NULL;reactiongame,8,128,startreactiongame,Default,NULL,Dynamic,NULL,NULL +FREERTOS.Tasks01=touchhistory,24,128,StartTouchHist,Default,NULL,Dynamic,NULL,NULL;draw,8,128,snakegame,Default,NULL,Dynamic,NULL,NULL;reactiongame,8,128,startreactiongame,Default,NULL,Dynamic,NULL,NULL;gamepicker,8,128,gamepicker_entry,Default,NULL,Dynamic,NULL,NULL FREERTOS.configUSE_NEWLIB_REENTRANT=1 File.Version=6 GPIO.groupedBy=Group By Peripherals @@ -22,20 +22,25 @@ Mcu.IP5=SYS Mcu.IPNb=6 Mcu.Name=STM32F401C(B-C)Ux Mcu.Package=UFQFPN48 -Mcu.Pin0=PA5 -Mcu.Pin1=PA6 -Mcu.Pin10=PB4 -Mcu.Pin11=VP_FREERTOS_VS_CMSIS_V2 -Mcu.Pin12=VP_SYS_VS_tim2 -Mcu.Pin2=PA7 -Mcu.Pin3=PB10 -Mcu.Pin4=PB14 -Mcu.Pin5=PB15 -Mcu.Pin6=PA13 -Mcu.Pin7=PA14 -Mcu.Pin8=PA15 -Mcu.Pin9=PB3 -Mcu.PinsNb=13 +Mcu.Pin0=PA2 +Mcu.Pin1=PA3 +Mcu.Pin10=PA14 +Mcu.Pin11=PA15 +Mcu.Pin12=PB3 +Mcu.Pin13=PB4 +Mcu.Pin14=PB5 +Mcu.Pin15=PB6 +Mcu.Pin16=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin17=VP_SYS_VS_tim2 +Mcu.Pin2=PA4 +Mcu.Pin3=PA5 +Mcu.Pin4=PA6 +Mcu.Pin5=PA7 +Mcu.Pin6=PB10 +Mcu.Pin7=PB14 +Mcu.Pin8=PB15 +Mcu.Pin9=PA13 +Mcu.PinsNb=18 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F401CCUx @@ -67,6 +72,18 @@ PA14.Signal=SYS_JTCK-SWCLK PA15.Locked=true PA15.Mode=JTAG_5_pins PA15.Signal=SYS_JTDI +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=DISPLAY_DC +PA2.Locked=true +PA2.Signal=GPIO_Output +PA3.GPIOParameters=GPIO_Label +PA3.GPIO_Label=DISPLAY_RES +PA3.Locked=true +PA3.Signal=GPIO_Output +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=DISPLAY_CS +PA4.Locked=true +PA4.Signal=GPIO_Output PA5.Mode=Full_Duplex_Master PA5.Signal=SPI1_SCK PA6.Mode=Full_Duplex_Master @@ -85,6 +102,14 @@ PB3.Signal=SYS_JTDO-SWO PB4.Locked=true PB4.Mode=JTAG_5_pins PB4.Signal=SYS_JTRST +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=TOUCH_IRQ +PB5.Locked=true +PB5.Signal=GPIO_Input +PB6.GPIOParameters=GPIO_Label +PB6.GPIO_Label=TOUCH_CS +PB6.Locked=true +PB6.Signal=GPIO_Output PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false