From dfbfc96e38de8f7a0006a7a50f6c5962fc1890af Mon Sep 17 00:00:00 2001 From: lucordes Date: Sat, 12 Jul 2025 17:22:17 +0200 Subject: [PATCH] some changes. and cleanup --- Core/Inc/main.h | 4 - Core/Inc/stm32f4xx_it.h | 1 + Core/Src/main.c | 638 +++++------------------------------ Core/Src/snake.c | 285 ++++++++++++++++ Core/Src/snake.h | 54 +++ Core/Src/stm32f4xx_hal_msp.c | 48 +-- Core/Src/stm32f4xx_it.c | 50 ++- touchscreengames.ioc | 81 ++--- 8 files changed, 488 insertions(+), 673 deletions(-) create mode 100644 Core/Src/snake.c create mode 100644 Core/Src/snake.h diff --git a/Core/Inc/main.h b/Core/Inc/main.h index f190af3..3ff6b4c 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -63,14 +63,10 @@ void Error_Handler(void); #define LED_BLUE_GPIO_Port GPIOC #define DISPLAY_CS_Pin GPIO_PIN_4 #define DISPLAY_CS_GPIO_Port GPIOA -#define TOUCH_CS_Pin GPIO_PIN_1 -#define TOUCH_CS_GPIO_Port GPIOB #define DISPLAY_DC_Pin GPIO_PIN_2 #define DISPLAY_DC_GPIO_Port GPIOB #define DISPLAY_RES_Pin GPIO_PIN_10 #define DISPLAY_RES_GPIO_Port GPIOA -#define TOUCH_IRQ_Pin GPIO_PIN_5 -#define TOUCH_IRQ_GPIO_Port GPIOB /* USER CODE BEGIN Private defines */ diff --git a/Core/Inc/stm32f4xx_it.h b/Core/Inc/stm32f4xx_it.h index 40646ed..a214e17 100644 --- a/Core/Inc/stm32f4xx_it.h +++ b/Core/Inc/stm32f4xx_it.h @@ -56,6 +56,7 @@ void TIM2_IRQHandler(void); void SPI1_IRQHandler(void); void DMA2_Stream0_IRQHandler(void); void DMA2_Stream3_IRQHandler(void); +void USART6_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Core/Src/main.c b/Core/Src/main.c index f90a6a3..e419fa1 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -23,11 +23,10 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ //#include "ili9341.h" -//#include "ili9341_touch.h" + #include "ILI9341_STM32_Driver.h" #include "ILI9341_GFX.h" -#include "ili9341_touch.h" -//#include "xpt2046.h" +#include "snake.h" /* USER CODE END Includes */ @@ -50,7 +49,6 @@ I2C_HandleTypeDef hi2c1; SPI_HandleTypeDef hspi1; -SPI_HandleTypeDef hspi2; DMA_HandleTypeDef hdma_spi1_rx; DMA_HandleTypeDef hdma_spi1_tx; @@ -74,18 +72,11 @@ const osThreadAttr_t draw_attributes = { .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityLow, }; -/* Definitions for reactiongame */ -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, +/* Definitions for menu */ +osThreadId_t menuHandle; +const osThreadAttr_t menu_attributes = { + .name = "menu", + .stack_size = 256 * 4, .priority = (osPriority_t) osPriorityLow, }; /* Definitions for presses */ @@ -107,16 +98,14 @@ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_SPI1_Init(void); -static void MX_SPI2_Init(void); static void MX_TIM1_Init(void); static void MX_TIM4_Init(void); static void MX_TIM5_Init(void); static void MX_USART6_UART_Init(void); static void MX_I2C1_Init(void); -void StartTouchHist(void *argument); + void snakegame(void *argument); -void startreactiongame(void *argument); -void gamepicker_entry(void *argument); +void handle_menu(void *argument); /* USER CODE BEGIN PFP */ @@ -125,11 +114,7 @@ void gamepicker_entry(void *argument); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ -#define touchbuffersize 50 -struct { - int x[touchbuffersize]; - int y[touchbuffersize]; -} touchcoord; + void titlescreen() { ILI9341_FillScreen(WHITE); @@ -142,367 +127,65 @@ void titlescreen() { //ILI9341_WriteString(320 / 2 + 100, 240 / 2, str, Font_11x18, //ILI9341_MAGENTA, ILI9341_WHITE); } -#define FLASH_USER_ADDR ((uint32_t)0x0803F000) // Last 4 KB -void Flash_Write_HighScore(uint32_t highscore) { - HAL_FLASH_Unlock(); - // Erase the sector first - FLASH_EraseInitTypeDef EraseInitStruct; - uint32_t PageError = 0; - EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; - EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; - EraseInitStruct.Sector = FLASH_SECTOR_5; - EraseInitStruct.NbSectors = 1; +#define RX_BUFFER_SIZE 1 +#define LINE_BUFFER_SIZE 128 - if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { - // Handle error - return; - } - - // Program the word - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_USER_ADDR, highscore) - != HAL_OK) { - // Handle error - } - - HAL_FLASH_Lock(); -} -uint32_t Flash_Read_HighScore(void) { - return *(uint32_t*) FLASH_USER_ADDR; -} - -struct Snake { - // Snake head coordinates (x-axis, y-axis) - int x, y; - // Food coordinates - int fruitCordX, fruitCordY; - // Player's score - int playerScore; - // Tail coordinates - int TailX[100], TailY[100]; - // Tail length - int TailLen; - // Movement direction - enum Direction { - STOP = 0, LEFT, RIGHT, UP, DOWN - } Dir; - - int gamesizewidth; //number of " pixels " in the horizontal - int gamesizeheight; - - int TailPendingDeletionX; - int TailPendingDeletionY; - - int TailGrowPending; // Delay tail growth by one frame - // Game over flag - int isGameOver; -} snake; -// Function to initialize game variables -void GameInit() { - - snake.gamesizeheight = 6; - snake.gamesizewidth = 8; - snake.isGameOver = 0; - snake.Dir = RIGHT; - snake.x = 1; //snake.gamesizewidth / 2; - snake.y = 1; //snake.gamesizeheight / 2; - snake.fruitCordX = 2; //rand() % snake.gamesizewidth; - snake.fruitCordY = 1; //rand() % snake.gamesizeheight; - snake.playerScore = 0; - snake.TailLen = 0; - snake.TailGrowPending = 0; - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_FillScreen(WHITE); - osMutexRelease(displayHandle); - } -} -// Function for updating the game state -void UpdateGame() { - - char dir; -// check the queue non blocking - osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, 0); // 0 = no wait - - if (status == osOK) { - switch (dir) { - case 'L': - snake.Dir = LEFT; - break; - case 'R': - snake.Dir = RIGHT; - break; - case 'U': - snake.Dir = UP; - break; - case 'D': - snake.Dir = DOWN; - break; - } - } - if (!snake.TailGrowPending) { - if (snake.TailLen > 0) { - snake.TailPendingDeletionX = snake.TailX[snake.TailLen - 1]; - snake.TailPendingDeletionY = snake.TailY[snake.TailLen - 1]; - } else { - snake.TailPendingDeletionX = snake.x; - snake.TailPendingDeletionY = snake.y; - } - } - snake.TailGrowPending = 0; - // tail movement - if (snake.TailLen > 0) { - for (int i = snake.TailLen - 1; i > 0; i--) { - snake.TailX[i] = snake.TailX[i - 1]; - snake.TailY[i] = snake.TailY[i - 1]; - } - snake.TailX[0] = snake.x; - snake.TailY[0] = snake.y; - } - - switch (snake.Dir) { - case LEFT: - snake.x--; - break; - case RIGHT: - snake.x++; - break; - case UP: - snake.y--; - break; - case DOWN: - snake.y++; - break; - } - -// 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 = 1; - -// Checks for collision with the tail (o) - for (int i = 0; i < snake.TailLen; i++) { - if (snake.TailX[i] == snake.x && snake.TailY[i] == snake.y) - snake.isGameOver = 1; - } - -// Checks for snake's collision with the food (#) - if (snake.x == snake.fruitCordX && snake.y == snake.fruitCordY) { - snake.playerScore += 10; - snake.fruitCordX = 0; //rand() % snake.gamesizewidth; - snake.fruitCordY = 0; //rand() % snake.gamesizeheight; - snake.TailLen++; - snake.TailX[snake.TailLen - 1] = snake.x; - snake.TailY[snake.TailLen - 1] = snake.y; - snake.TailGrowPending = 1; - //snake.TailPendingDeletionX = -1; - } - if (snake.isGameOver) { - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - - if (Flash_Read_HighScore() > snake.playerScore) { - char str[50]; - sprintf(str, "Highscore Remains: %lu", Flash_Read_HighScore()); - ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, - WHITE); - // ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, - //ILI9341_MAGENTA, ILI9341_WHITE); - } else { - char str[50]; - sprintf(str, "New Highscore: %lu", snake.playerScore); - //ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, - //ILI9341_MAGENTA, ILI9341_WHITE); - ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, - WHITE); - Flash_Write_HighScore(snake.playerScore); - } - osMutexRelease(displayHandle); - } - - } -} -// Function to handle user UserInput -int prevpressed; -void UserInput() { -// Checks if a key is pressed or not - -//case 'a': -// snake.Dir = LEFT; - uint16_t x, y; - - x = getX(); - y = getY(); - if (x != 0 || y != 0) { - int a = x; - } - int ia = HAL_GPIO_ReadPin(ILI9341_TOUCH_IRQ_GPIO_Port, - ILI9341_TOUCH_IRQ_Pin) == GPIO_PIN_RESET; - - if (ILI9341_TouchGetCoordinates(&x, &y)) { // Only act if touch detected - if ((x == 123 || x == 124 || x == 125 || x == 126) && y == 0) { - - } else { - - 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] = x; - touchcoord.y[touchbuffersize - 1] = y; - } - char dir; - if (x < 107) { - dir = 'L'; // Left - } else if (x > 213) { - dir = 'R'; // Right - } else if (y > 120) { - dir = 'U'; // Up - } else { - dir = 'D'; // Down - } - - dir = 'R'; - -// Send the direction to the queue -//if (!prevpressed && ILI9341_TouchPressed()) { +uint8_t rx_buffer[RX_BUFFER_SIZE]; +char line_buffer[LINE_BUFFER_SIZE]; +uint16_t line_pos = 0; +void process_line(const char *line) { + if (strncmp(line, "ABS:", 4) == 0) { + char axis[32]; + int value; + if (sscanf(line, "ABS:%31[^:]:%d:", axis, &value) == 2) { + // Handle axis input + if (strcmp(axis, "ABS_X") == 0) { + // Do something with X axis + } else if (strcmp(axis, "ABS_Y") == 0) { + // Do something with Y axis + } + } + } else if (strncmp(line, "KEY:", 4) == 0) { + char key[32]; + int state; + if (sscanf(line, "KEY:%31[^:]:%d:", key, &state) == 2) { + // Handle button press/release + char dir; + dir=key[0]; 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_SCREEN_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_SCREEN_WIDTH; - touchcoord.y[touchbuffersize - 1] = ILI9341_SCREEN_WIDTH; - } - } + if (key[0]=='D' && state == 1) { + // Button pressed + } else if (key[0]=='D' && state == 0) { + // Button released + } + } + } } -// Function for creating the game board & rendering -void GameRender() { +void UART_CALLBACK() { + char ch = rx_buffer[0]; -// Creating top walls -// Creating side walls -//ILI9341_FillRectangle(j, i, ILI9341_WIDTH/snake.gamesizewidth, ILI9341_HEIGHT/snake.gamesizeheight, ILI9341_YELLOW); -//ILI9341_FillScreen(MAGENTA); - for (int x = 0; x < snake.gamesizewidth; x++) { - for (int y = 0; y <= snake.gamesizeheight; y++) { - - if (x == snake.x && y == snake.y) { - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_DrawFilledRectangleCoord( - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth - + ILI9341_SCREEN_WIDTH - / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight - + ILI9341_SCREEN_HEIGHT - / snake.gamesizeheight, - BLACK); -// ILI9341_FillRectangle( -// (x * ILI9341_WIDTH) / snake.gamesizewidth, -// (y * ILI9341_HEIGHT) / snake.gamesizeheight, -// ILI9341_WIDTH / snake.gamesizewidth, -// ILI9341_HEIGHT / snake.gamesizeheight, -// ILI9341_BLACK); - osMutexRelease(displayHandle); - } - } - - //cout << "O"; - // Creating the sanke's food with '#' - else if (x == snake.fruitCordX && y == snake.fruitCordY) { - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_DrawFilledRectangleCoord( - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth - + ILI9341_SCREEN_WIDTH - / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight - + ILI9341_SCREEN_HEIGHT - / snake.gamesizeheight, - RED); -// ILI9341_FillRectangle( -// (x * ILI9341_WIDTH) / snake.gamesizewidth, -// (y * ILI9341_HEIGHT) / snake.gamesizeheight, -// ILI9341_WIDTH / snake.gamesizewidth, -// ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_RED); - osMutexRelease(displayHandle); - } - } - - //cout << "#"; - - else if (snake.TailLen >= 0) { - for (int i = 0; i < snake.TailLen; i++) { - - if (snake.TailX[0] == x && snake.TailY[0] == y) { - if (osMutexAcquire(displayHandle, osWaitForever) - == osOK) { - ILI9341_DrawFilledRectangleCoord( - (x * ILI9341_SCREEN_WIDTH) - / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) - / snake.gamesizeheight, - (x * ILI9341_SCREEN_WIDTH) - / snake.gamesizewidth - + ILI9341_SCREEN_WIDTH - / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) - / snake.gamesizeheight - + ILI9341_SCREEN_HEIGHT - / snake.gamesizeheight, - GREEN); -// ILI9341_FillRectangle( -// (x * ILI9341_WIDTH) / snake.gamesizewidth, -// (y * ILI9341_HEIGHT) / snake.gamesizeheight, -// ILI9341_WIDTH / snake.gamesizewidth, -// ILI9341_HEIGHT / snake.gamesizeheight, -// ILI9341_GREEN); - osMutexRelease(displayHandle); - } - } - } - - } - if (snake.TailPendingDeletionX == x - && snake.TailPendingDeletionY == y) { - - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - ILI9341_DrawFilledRectangleCoord( - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, - (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth - + ILI9341_SCREEN_WIDTH - / snake.gamesizewidth, - (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight - + ILI9341_SCREEN_HEIGHT - / snake.gamesizeheight, - WHITE); -// ILI9341_FillRectangle( -// (x * ILI9341_WIDTH) / snake.gamesizewidth, -// (y * ILI9341_HEIGHT) / snake.gamesizeheight, -// ILI9341_WIDTH / snake.gamesizewidth, -// ILI9341_HEIGHT / snake.gamesizeheight, -// ILI9341_WHITE); - osMutexRelease(displayHandle); - } - } + if (ch == '\r') { + // ignore + } else if (ch == '\n') { + //line_buffer[line_pos] = '\0'; + if(line_buffer[1]=='K'||line_buffer[1]=='A'){ + process_line(&line_buffer[1]); + }else{ + process_line(line_buffer); } + line_pos = 0; + } else if (line_pos < LINE_BUFFER_SIZE - 1) { + line_buffer[line_pos++] = ch; } + HAL_UART_Receive_IT(&huart6, rx_buffer, RX_BUFFER_SIZE); } /* USER CODE END 0 */ @@ -538,7 +221,6 @@ int main(void) MX_GPIO_Init(); MX_DMA_Init(); MX_SPI1_Init(); - MX_SPI2_Init(); MX_TIM1_Init(); MX_TIM4_Init(); MX_TIM5_Init(); @@ -549,7 +231,7 @@ int main(void) ILI9341_SetRotation(SCREEN_HORIZONTAL_1); ILI9341_FillScreen(MAGENTA); //void XPT2046_Init(); - + //Flash_Write_HighScore(100); /* USER CODE END 2 */ /* Init scheduler */ @@ -580,16 +262,13 @@ int main(void) /* Create the thread(s) */ /* creation of touchhistory */ - touchhistoryHandle = osThreadNew(StartTouchHist, NULL, &touchhistory_attributes); + //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); + /* creation of menu */ + menuHandle = osThreadNew(handle_menu, NULL, &menu_attributes); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ @@ -772,44 +451,6 @@ static void MX_SPI1_Init(void) } -/** - * @brief SPI2 Initialization Function - * @param None - * @retval None - */ -static void MX_SPI2_Init(void) -{ - - /* USER CODE BEGIN SPI2_Init 0 */ - - /* USER CODE END SPI2_Init 0 */ - - /* USER CODE BEGIN SPI2_Init 1 */ - - /* USER CODE END SPI2_Init 1 */ - /* SPI2 parameter configuration*/ - hspi2.Instance = SPI2; - hspi2.Init.Mode = SPI_MODE_MASTER; - hspi2.Init.Direction = SPI_DIRECTION_2LINES; - hspi2.Init.DataSize = SPI_DATASIZE_8BIT; - hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi2.Init.NSS = SPI_NSS_SOFT; - hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; - hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi2.Init.TIMode = SPI_TIMODE_DISABLE; - hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi2.Init.CRCPolynomial = 10; - if (HAL_SPI_Init(&hspi2) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN SPI2_Init 2 */ - - /* USER CODE END SPI2_Init 2 */ - -} - /** * @brief TIM1 Initialization Function * @param None @@ -1008,6 +649,8 @@ static void MX_USART6_UART_Init(void) Error_Handler(); } /* USER CODE BEGIN USART6_Init 2 */ + uint8_t rx_byte; + HAL_UART_Receive_IT(&huart6, &rx_byte, 1); /* USER CODE END USART6_Init 2 */ @@ -1056,7 +699,7 @@ static void MX_GPIO_Init(void) HAL_GPIO_WritePin(GPIOA, DISPLAY_CS_Pin|DISPLAY_RES_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOB, TOUCH_CS_Pin|DISPLAY_DC_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(DISPLAY_DC_GPIO_Port, DISPLAY_DC_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : LED_BLUE_Pin */ GPIO_InitStruct.Pin = LED_BLUE_Pin; @@ -1072,18 +715,12 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - /*Configure GPIO pins : TOUCH_CS_Pin DISPLAY_DC_Pin */ - GPIO_InitStruct.Pin = TOUCH_CS_Pin|DISPLAY_DC_Pin; + /*Configure GPIO pin : DISPLAY_DC_Pin */ + GPIO_InitStruct.Pin = DISPLAY_DC_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(GPIOB, &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); + HAL_GPIO_Init(DISPLAY_DC_GPIO_Port, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ @@ -1101,29 +738,7 @@ static void MX_GPIO_Init(void) * @retval None */ /* USER CODE END Header_StartTouchHist */ -void StartTouchHist(void *argument) -{ - /* USER CODE BEGIN 5 */ - /* Infinite loop */ - for (;;) { - UserInput(); - - if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { - // Mutex successfully locked - ILI9341_DrawPixel(touchcoord.x[touchbuffersize - 1], - touchcoord.y[touchbuffersize - 1], MAGENTA); - ILI9341_DrawPixel(touchcoord.x[0], touchcoord.y[0], MAGENTA); - //ILI9341_DrawPixel(touchcoord.x[touchbuffersize - 1], -// touchcoord.y[touchbuffersize - 1], ILI9341_MAGENTA); -// ILI9341_DrawPixel(touchcoord.x[0], touchcoord.y[0], ILI9341_WHITE); - osMutexRelease(displayHandle); - } - - osDelay(100); - } - /* USER CODE END 5 */ -} /* USER CODE BEGIN Header_snakegame */ /** @@ -1149,7 +764,10 @@ void snakegame(void *argument) vTaskDelay(1000); - //ILI9341_FillScreen(timer%0xFFFF); + if(isGameOver()){ + vTaskDelay(2000); + GameInit(); + } UpdateGame(); } @@ -1157,112 +775,22 @@ void snakegame(void *argument) /* USER CODE END snakegame */ } -/* USER CODE BEGIN Header_startreactiongame */ +/* USER CODE BEGIN Header_handle_menu */ /** - * @brief Function implementing the reactiongame thread. - * @param argument: Not used - * @retval None - */ -/* USER CODE END Header_startreactiongame */ -void startreactiongame(void *argument) +* @brief Function implementing the menu thread. +* @param argument: Not used +* @retval None +*/ +/* USER CODE END Header_handle_menu */ +void handle_menu(void *argument) { - /* USER CODE BEGIN startreactiongame */ - /* Infinite loop */ - uint32_t lasttimestamp = osKernelGetTickCount(); - for (;;) { - int a = rand() % 4000; - osDelay(1000 + a); - char dir; - 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 (osMutexAcquire(displayHandle, osWaitForever) == osOK) { -// ILI9341_FillScreen(ILI9341_GREEN); -// osMutexRelease(displayHandle); -// } -// lasttimestamp = osKernelGetTickCount(); -// // check the queue blocking -// osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, -// osWaitForever); -// -// int timediff = osKernelGetTickCount() - lasttimestamp; -// sprintf(str, "Time %d", timediff); -// if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { -// if (dir == 'L') { -// ILI9341_WriteString(320 / 2 - 100, 240 / 2, str, Font_11x18, -// ILI9341_MAGENTA, ILI9341_WHITE); -// } -// if (dir == 'R') { -// ILI9341_WriteString(320 / 2 + 100, 240 / 2, str, Font_11x18, -// ILI9341_MAGENTA, ILI9341_WHITE); -// } -// osMutexRelease(displayHandle); -// } -// } else { -// sprintf(str, "Pressed too early"); -// if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { -// if (dir == 'L') { -// ILI9341_WriteString(320 / 2 - 100, 240 / 2, str, Font_11x18, -// ILI9341_MAGENTA, ILI9341_WHITE); -// } -// if (dir == 'R') { -// ILI9341_WriteString(320 / 2 + 100, 240 / 2, str, Font_11x18, -// ILI9341_MAGENTA, ILI9341_WHITE); -// } -// osMutexRelease(displayHandle); -// } -// -// } -// osDelay(1000); -// if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { -// ILI9341_FillScreen(ILI9341_WHITE); -// osMutexRelease(displayHandle); -// } -// //clear the queue -// while (osMessageQueueGet(pressesHandle, &dir, NULL, 0) == osOK) { -// // Discarding messages one by one -// } - - } - /* 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 */ + /* USER CODE BEGIN handle_menu */ + /* Infinite loop */ + for(;;) + { + osDelay(1); + } + /* USER CODE END handle_menu */ } /** diff --git a/Core/Src/snake.c b/Core/Src/snake.c new file mode 100644 index 0000000..40aca6b --- /dev/null +++ b/Core/Src/snake.c @@ -0,0 +1,285 @@ +#include "main.h" // HAL, ILI9341, CMSIS-RTOS handles +#include "cmsis_os.h" // RTOS types like osMutexAcquire, osMessageQueueGet +#include "stdlib.h" // For rand() +#include "stdio.h" // For sprintf() +#include "snake.h" // Your own header for declarations +#include "ILI9341_STM32_Driver.h" +#include "fonts.h" + +struct Snake snake; // define the global variable here +#define FLASH_USER_ADDR ((uint32_t)0x0803F000) // Last 4 KB +void Flash_Write_HighScore(uint32_t highscore) { + HAL_FLASH_Unlock(); + + // Erase the sector first + FLASH_EraseInitTypeDef EraseInitStruct; + uint32_t PageError = 0; + + EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; + EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; + EraseInitStruct.Sector = FLASH_SECTOR_5; + EraseInitStruct.NbSectors = 1; + + if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { + // Handle error + return; + } + + // Program the word + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_USER_ADDR, highscore) + != HAL_OK) { + // Handle error + } + + HAL_FLASH_Lock(); +} +uint32_t Flash_Read_HighScore(void) { + return *(uint32_t*) FLASH_USER_ADDR; +} + + +// Function to initialize game variables +void GameInit() { + + snake.gamesizeheight = 6; + snake.gamesizewidth = 8; + snake.isGameOver = 0; + snake.Dir = RIGHT; + snake.x = 1; //snake.gamesizewidth / 2; + snake.y = 1; //snake.gamesizeheight / 2; + snake.fruitCordX = rand() % snake.gamesizewidth; + snake.fruitCordY = rand() % snake.gamesizeheight; + snake.playerScore = 0; + snake.TailLen = 0; + snake.TailGrowPending = 0; + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_FillScreen(WHITE); + osMutexRelease(displayHandle); + } +} +// Function for updating the game state +void UpdateGame() { + + char dir; +// check the queue non blocking + osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, 0); // 0 = no wait + + if (status == osOK) { + switch (dir) { + case 'L': + snake.Dir = LEFT; + break; + case 'R': + snake.Dir = RIGHT; + break; + case 'U': + snake.Dir = UP; + break; + case 'D': + snake.Dir = DOWN; + break; + } + } + if (!snake.TailGrowPending) { + if (snake.TailLen > 0) { + snake.TailPendingDeletionX = snake.TailX[snake.TailLen - 1]; + snake.TailPendingDeletionY = snake.TailY[snake.TailLen - 1]; + } else { + snake.TailPendingDeletionX = snake.x; + snake.TailPendingDeletionY = snake.y; + } + } + snake.TailGrowPending = 0; + // tail movement + if (snake.TailLen > 0) { + for (int i = snake.TailLen - 1; i > 0; i--) { + snake.TailX[i] = snake.TailX[i - 1]; + snake.TailY[i] = snake.TailY[i - 1]; + } + snake.TailX[0] = snake.x; + snake.TailY[0] = snake.y; + } + + switch (snake.Dir) { + case LEFT: + snake.x--; + break; + case RIGHT: + snake.x++; + break; + case UP: + snake.y--; + break; + case DOWN: + snake.y++; + break; + } + +// 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 = 1; + +// Checks for collision with the tail (o) + for (int i = 0; i < snake.TailLen; i++) { + if (snake.TailX[i] == snake.x && snake.TailY[i] == snake.y) + snake.isGameOver = 1; + } + +// Checks for snake's collision with the food (#) + if (snake.x == snake.fruitCordX && snake.y == snake.fruitCordY) { + snake.playerScore += 10; + snake.fruitCordX = rand() % snake.gamesizewidth; + snake.fruitCordY = rand() % snake.gamesizeheight; + snake.TailLen++; + snake.TailX[snake.TailLen - 1] = snake.x; + snake.TailY[snake.TailLen - 1] = snake.y; + snake.TailGrowPending = 1; + //snake.TailPendingDeletionX = -1; + } + if (snake.isGameOver) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + + if (Flash_Read_HighScore() > snake.playerScore) { + char str[50]; + sprintf(str, "Highscore Remains: %lu", Flash_Read_HighScore()); + ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, + WHITE); + // ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, + //ILI9341_MAGENTA, ILI9341_WHITE); + } else { + char str[50]; + sprintf(str, "New Highscore: %lu", snake.playerScore); + //ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, + //ILI9341_MAGENTA, ILI9341_WHITE); + ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, + WHITE); + Flash_Write_HighScore(snake.playerScore); + } + osMutexRelease(displayHandle); + + } + + } +} + +// Function for creating the game board & rendering +void GameRender() { + +// Creating top walls +// Creating side walls +//ILI9341_FillRectangle(j, i, ILI9341_WIDTH/snake.gamesizewidth, ILI9341_HEIGHT/snake.gamesizeheight, ILI9341_YELLOW); +//ILI9341_FillScreen(MAGENTA); + for (int x = 0; x < snake.gamesizewidth; x++) { + for (int y = 0; y <= snake.gamesizeheight; y++) { + + if (x == snake.x && y == snake.y) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + BLACK); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_BLACK); + osMutexRelease(displayHandle); + } + } + + //cout << "O"; + // Creating the sanke's food with '#' + else if (x == snake.fruitCordX && y == snake.fruitCordY) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + RED); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_RED); + osMutexRelease(displayHandle); + } + } + + //cout << "#"; + + else if (snake.TailLen >= 0) { + for (int i = 0; i < snake.TailLen; i++) { + + if (snake.TailX[0] == x && snake.TailY[0] == y) { + if (osMutexAcquire(displayHandle, osWaitForever) + == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) + / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) + / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) + / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + GREEN); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_GREEN); + osMutexRelease(displayHandle); + } + } + } + + } + if (snake.TailPendingDeletionX == x + && snake.TailPendingDeletionY == y) { + + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + WHITE); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_WHITE); + osMutexRelease(displayHandle); + } + } + } + + } + +} +int isGameOver(){ + return snake.isGameOver; +} diff --git a/Core/Src/snake.h b/Core/Src/snake.h new file mode 100644 index 0000000..69ffe54 --- /dev/null +++ b/Core/Src/snake.h @@ -0,0 +1,54 @@ +/* + * snake.h + * + * Created on: Jul 10, 2025 + * Author: user + */ + +#ifndef SRC_SNAKE_H_ +#define SRC_SNAKE_H_ + + +#include "main.h" +extern osMutexId_t displayHandle; +extern osMessageQueueId_t pressesHandle; +// Flash storage address for highscore +#define FLASH_USER_ADDR ((uint32_t)0x0803F000) // Adjusted to your sector layout + +// Highscore flash functions +void Flash_Write_HighScore(uint32_t highscore); +uint32_t Flash_Read_HighScore(void); + +// Snake movement direction enum +enum Direction { + STOP = 0, LEFT, RIGHT, UP, DOWN +}; + +// Snake structure definition +struct Snake { + int x, y; + int fruitCordX, fruitCordY; + int playerScore; + int TailX[100], TailY[100]; + int TailLen; + enum Direction Dir; + int gamesizewidth; + int gamesizeheight; + int TailPendingDeletionX; + int TailPendingDeletionY; + int TailGrowPending; + int isGameOver; +}; + +// External instance of the snake object +extern struct Snake snake; + + +// Game functions +void GameInit(void); +void UpdateGame(void); +void GameRender(void); +int isGameOver(); + + +#endif /* SRC_SNAKE_H_ */ diff --git a/Core/Src/stm32f4xx_hal_msp.c b/Core/Src/stm32f4xx_hal_msp.c index c18d2a0..5b1703f 100644 --- a/Core/Src/stm32f4xx_hal_msp.c +++ b/Core/Src/stm32f4xx_hal_msp.c @@ -225,31 +225,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ - } - else if(hspi->Instance==SPI2) - { - /* USER CODE BEGIN SPI2_MspInit 0 */ - /* USER CODE END SPI2_MspInit 0 */ - /* Peripheral clock enable */ - __HAL_RCC_SPI2_CLK_ENABLE(); - - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**SPI2 GPIO Configuration - PB10 ------> SPI2_SCK - PB14 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - */ - GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI2_MspInit 1 */ - - /* USER CODE END SPI2_MspInit 1 */ } } @@ -287,25 +263,6 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) /* USER CODE END SPI1_MspDeInit 1 */ } - else if(hspi->Instance==SPI2) - { - /* USER CODE BEGIN SPI2_MspDeInit 0 */ - - /* USER CODE END SPI2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI2_CLK_DISABLE(); - - /**SPI2 GPIO Configuration - PB10 ------> SPI2_SCK - PB14 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - */ - HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15); - - /* USER CODE BEGIN SPI2_MspDeInit 1 */ - - /* USER CODE END SPI2_MspDeInit 1 */ - } } @@ -519,6 +476,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) GPIO_InitStruct.Alternate = GPIO_AF8_USART6; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + /* USART6 interrupt Init */ + HAL_NVIC_SetPriority(USART6_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(USART6_IRQn); /* USER CODE BEGIN USART6_MspInit 1 */ /* USER CODE END USART6_MspInit 1 */ @@ -549,6 +509,8 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + /* USART6 interrupt DeInit */ + HAL_NVIC_DisableIRQ(USART6_IRQn); /* USER CODE BEGIN USART6_MspDeInit 1 */ /* USER CODE END USART6_MspDeInit 1 */ diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 963796b..3cb617b 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -1,20 +1,20 @@ /* USER CODE BEGIN Header */ /** - ****************************************************************************** - * @file stm32f4xx_it.c - * @brief Interrupt Service Routines. - ****************************************************************************** - * @attention - * - * Copyright (c) 2025 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32f4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ @@ -58,6 +58,7 @@ extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_tx; extern SPI_HandleTypeDef hspi1; +extern UART_HandleTypeDef huart6; extern TIM_HandleTypeDef htim2; /* USER CODE BEGIN EV */ @@ -76,9 +77,8 @@ void NMI_Handler(void) /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ - while (1) - { - } + while (1) { + } /* USER CODE END NonMaskableInt_IRQn 1 */ } @@ -218,6 +218,20 @@ void DMA2_Stream3_IRQHandler(void) /* USER CODE END DMA2_Stream3_IRQn 1 */ } +/** + * @brief This function handles USART6 global interrupt. + */ +void USART6_IRQHandler(void) +{ + /* USER CODE BEGIN USART6_IRQn 0 */ + + /* USER CODE END USART6_IRQn 0 */ + HAL_UART_IRQHandler(&huart6); + /* USER CODE BEGIN USART6_IRQn 1 */ + UART_CALLBACK(); + /* USER CODE END USART6_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/touchscreengames.ioc b/touchscreengames.ioc index 210253b..e34f85c 100644 --- a/touchscreengames.ioc +++ b/touchscreengames.ioc @@ -29,7 +29,7 @@ FREERTOS.FootprintOK=true FREERTOS.IPParameters=Tasks01,FootprintOK,configUSE_NEWLIB_REENTRANT,Queues01,Mutexes01,configGENERATE_RUN_TIME_STATS,configUSE_STATS_FORMATTING_FUNCTIONS 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,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.Tasks01=touchhistory,24,128,StartTouchHist,Default,NULL,Dynamic,NULL,NULL;draw,8,512,snakegame,Default,NULL,Dynamic,NULL,NULL;menu,8,256,handle_menu,Default,NULL,Dynamic,NULL,NULL FREERTOS.configGENERATE_RUN_TIME_STATS=1 FREERTOS.configUSE_NEWLIB_REENTRANT=1 FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1 @@ -40,52 +40,46 @@ Mcu.CPN=STM32F401CCU6 Mcu.Family=STM32F4 Mcu.IP0=DMA Mcu.IP1=FREERTOS -Mcu.IP10=TIM5 -Mcu.IP11=USART6 +Mcu.IP10=USART6 Mcu.IP2=I2C1 Mcu.IP3=NVIC Mcu.IP4=RCC Mcu.IP5=SPI1 -Mcu.IP6=SPI2 -Mcu.IP7=SYS -Mcu.IP8=TIM1 -Mcu.IP9=TIM4 -Mcu.IPNb=12 +Mcu.IP6=SYS +Mcu.IP7=TIM1 +Mcu.IP8=TIM4 +Mcu.IP9=TIM5 +Mcu.IPNb=11 Mcu.Name=STM32F401C(B-C)Ux Mcu.Package=UFQFPN48 Mcu.Pin0=PC13-ANTI_TAMP Mcu.Pin1=PA0-WKUP -Mcu.Pin10=PB2 -Mcu.Pin11=PB10 -Mcu.Pin12=PB14 -Mcu.Pin13=PB15 -Mcu.Pin14=PA8 -Mcu.Pin15=PA9 -Mcu.Pin16=PA10 -Mcu.Pin17=PA11 -Mcu.Pin18=PA12 -Mcu.Pin19=PA13 +Mcu.Pin10=PA8 +Mcu.Pin11=PA9 +Mcu.Pin12=PA10 +Mcu.Pin13=PA11 +Mcu.Pin14=PA12 +Mcu.Pin15=PA13 +Mcu.Pin16=PA14 +Mcu.Pin17=PA15 +Mcu.Pin18=PB3 +Mcu.Pin19=PB4 Mcu.Pin2=PA1 -Mcu.Pin20=PA14 -Mcu.Pin21=PA15 -Mcu.Pin22=PB3 -Mcu.Pin23=PB4 -Mcu.Pin24=PB5 -Mcu.Pin25=PB6 -Mcu.Pin26=PB7 -Mcu.Pin27=PB8 -Mcu.Pin28=PB9 -Mcu.Pin29=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin20=PB6 +Mcu.Pin21=PB7 +Mcu.Pin22=PB8 +Mcu.Pin23=PB9 +Mcu.Pin24=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin25=VP_SYS_VS_tim2 +Mcu.Pin26=VP_TIM5_VS_ClockSourceINT Mcu.Pin3=PA2 -Mcu.Pin30=VP_SYS_VS_tim2 -Mcu.Pin31=VP_TIM5_VS_ClockSourceINT Mcu.Pin4=PA3 Mcu.Pin5=PA4 Mcu.Pin6=PA5 Mcu.Pin7=PA6 Mcu.Pin8=PA7 -Mcu.Pin9=PB1 -Mcu.PinsNb=32 +Mcu.Pin9=PB2 +Mcu.PinsNb=27 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F401CCUx @@ -110,6 +104,7 @@ NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false NVIC.TIM2_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true NVIC.TimeBase=TIM2_IRQn NVIC.TimeBaseIP=TIM2 +NVIC.USART6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false PA0-WKUP.Signal=S_TIM5_CH1 PA1.Signal=S_TIM5_CH2 @@ -144,16 +139,6 @@ PA7.Mode=Full_Duplex_Master PA7.Signal=SPI1_MOSI PA8.Signal=S_TIM1_CH1 PA9.Signal=S_TIM1_CH2 -PB1.GPIOParameters=GPIO_Label -PB1.GPIO_Label=TOUCH_CS -PB1.Locked=true -PB1.Signal=GPIO_Output -PB10.Mode=Full_Duplex_Master -PB10.Signal=SPI2_SCK -PB14.Mode=Full_Duplex_Master -PB14.Signal=SPI2_MISO -PB15.Mode=Full_Duplex_Master -PB15.Signal=SPI2_MOSI PB2.GPIOParameters=GPIO_Label PB2.GPIO_Label=DISPLAY_DC PB2.Locked=true @@ -164,10 +149,6 @@ 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.Signal=S_TIM4_CH1 PB7.Signal=S_TIM4_CH2 PB8.Mode=I2C @@ -210,7 +191,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM4_Init-TIM4-false-HAL-true,8-MX_TIM5_Init-TIM5-false-HAL-true,9-MX_USART6_UART_Init-USART6-false-HAL-true,10-MX_I2C1_Init-I2C1-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,5-MX_TIM1_Init-TIM1-false-HAL-true,6-MX_TIM4_Init-TIM4-false-HAL-true,7-MX_TIM5_Init-TIM5-false-HAL-true,8-MX_USART6_UART_Init-USART6-false-HAL-true,9-MX_I2C1_Init-I2C1-false-HAL-true RCC.AHBFreq_Value=16000000 RCC.APB1Freq_Value=16000000 RCC.APB2Freq_Value=16000000 @@ -252,12 +233,6 @@ SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler SPI1.Mode=SPI_MODE_MASTER SPI1.VirtualType=VM_MASTER -SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32 -SPI2.CalculateBaudRate=500.0 KBits/s -SPI2.Direction=SPI_DIRECTION_2LINES -SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler -SPI2.Mode=SPI_MODE_MASTER -SPI2.VirtualType=VM_MASTER TIM1.EncoderMode=TIM_ENCODERMODE_TI12 TIM1.IPParameters=EncoderMode TIM4.EncoderMode=TIM_ENCODERMODE_TI12