diff --git a/Core/Inc/FreeRTOSConfig.h b/Core/Inc/FreeRTOSConfig.h new file mode 100644 index 0000000..4f11b74 --- /dev/null +++ b/Core/Inc/FreeRTOSConfig.h @@ -0,0 +1,150 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + This file is part of the FreeRTOS distribution. + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_TICKLESS_IDLE 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ CLOCK +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES 5 +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_MUTEXES 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_COUNTING_SEMAPHORES 0 + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) +#define configAPPLICATION_ALLOCATED_HEAP 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 3 +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 0 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xTimerCreate 1 +#define INCLUDE_xTimerDelete 1 +#define INCLUDE_xTimerReset 1 + + +#define xPortSysTickHandler SysTick_Handler +#define xPortPendSVHandler PendSV_Handler +#define vPortSVCHandler SVC_Handler + + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ + + +/* This is the value being used as per the ST library which permits 16 +priority values, 0 to 15. This must correspond to the +configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest +NVIC value of 255. */ +#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 5d50b37..cd02400 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -24,9 +24,13 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include #include "lcd.h" #include "game.h" -#include +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" /* USER CODE END Includes */ @@ -426,7 +430,194 @@ static void MX_GPIO_Init(void) } /* USER CODE BEGIN 4 */ +void logic() +{ + led1.SetHigh(); + usart.Send(); + xTaskCreate(vTaskLed, "LED", configMINIMAL_STACK_SIZE, NULL, 1, NULL); +// xTaskCreate(vTaskStateMachine, "FSM", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(vTaskPlayerSetup, "Player", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + vTaskStartScheduler(); + + while(1) { + + }; +} + +void vTaskPlayerSetup(void *parameter) +{ + while (1) + { + if (plusButton.PressedDebounced()) + { + game.AddPlayer(); + } + if (minusButton.PressedDebounced()) + { + game.RemovePlayer(); + } + +#ifdef DEBUG + for (auto i = 0; i < game.maxPlayers; i++) + buffer[i] = game.playerScore[i]; + usart.Send(); +#endif // DEBUG + + + if (game.activePlayers > 1 && bigButton.PressedDebounced()) + break; + + vTaskDelay(5); + } + xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + vTaskDelete(NULL); +} +void vTaskTimerSetup(void *parameter) { + while (1) + { + if (plusButton.PressedDebounced()) + { + game.IncrementTurnTime(); + } + else if (minusButton.PressedDebounced()) + { + game.DecrementTurnTime(); + } + else vTaskDelay(10); + + if (bigButton.PressedDebounced()) { + break; + } + vTaskDelay(10); + +#ifdef DEBUG + auto [minutes, seconds] = game.GetTimerValue(); + buffer[0] = minutes; + buffer[1] = seconds; + usart.Send(); +#endif // DEBUG + + } + + secondsTimerHandle = xTimerCreate("SecondsTimer", + pdMS_TO_TICKS(1000), //counts 1 sec + pdTRUE, //auto-reload + NULL, //not assigning ID + vTimerCallback // function to call after timer expires + ); + + xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + vTaskDelete(NULL); +} + +void vTaskConfig(void *parameter) { + while (1) + { + if (plusButton.PressedDebounced()) + game.countScores = !game.countScores; + if (minusButton.PressedDebounced()) + // show round number or change the way it counts + game.countScores = !game.countScores; + if (bigButton.PressedDebounced()) { + break; + } + vTaskDelay(10); + } + xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + vTaskDelete(NULL); +} + +/* +void vTaskTurn(void *parameter) { + xTimerReset(secondsTimerHandle, 0); + + TickType_t xLastWakeTime; + xLastWakeTime = xTaskGetTickCount(); + + while (1) + { + if (plusButton.PressedDebounced()) { + xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + break; + } + else if (minusButton.PressedDebounced()) { + xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + break; + } + else if (bigButton.PressedDebounced()) { + 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); + led2.Toggle(); + +#ifdef DEBUG + auto[minutes, seconds] = game.GetTimerValue(); + buffer[0] = minutes; + buffer[1] = seconds; + buffer[2] = game.currentPlayer; + buffer[4] = game.playerScore[0]; + buffer[5] = game.playerScore[1]; + buffer[6] = game.playerScore[2]; + usart.Send(); +#endif // DEBUG + + } + xTimerStop(secondsTimerHandle, 0); + game.ResetTurnTimer(); + if (xMusicHandle) { + vTaskDelete(xMusicHandle); + mp.Stop(); + xMusicHandle = NULL; + } + vTaskDelete(NULL); +} + +void vTaskTurnEnd(void *parameter) { + if (game.countScores) { + int32_t delta = 0; + while (1) { + if (bigButton.PressedDebounced()) { + game.ChangeScore(delta); + break; + } + else if (plusButton.PressedDebounced()) + { + delta++; + } + else if (minusButton.PressedDebounced()) + { + delta--; + } + vTaskDelay(10); + } + } + game.NextPlayer(); + xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL); + vTaskDelete(NULL); +} + +void vTimerCallback(TimerHandle_t xTimer) { + if (game.timerValue > 0) + game.timerValue--; +} + +void vTaskOvertime(void *parameter) { + while (1) + { + led2.SetHigh(); + mp.Play(tracks[3]); + led2.SetLow(); + vTaskDelay(1000); + } +} + */ /* USER CODE END 4 */ /** diff --git a/Makefile b/Makefile index 1cc147d..8fc81e9 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,10 @@ BUILD_DIR = build ###################################### # C sources C_SOURCES = \ +Middlewares/FreeRTOS/Src/tasks.c \ +Middlewares/FreeRTOS/Src/croutine.c \ +Middlewares/FreeRTOS/Src/queue.c \ +Middlewares/FreeRTOS/Src/timers.c \ Core/Src/main.c \ Core/Src/lcd.c \ Core/Src/game.c \ @@ -130,6 +134,7 @@ C_INCLUDES = \ -ICore/Inc \ -IDrivers/STM32F1xx_HAL_Driver/Inc \ -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ +-IMiddlewares/FreeRTOS/Inc \ -IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc \ -IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ -IDrivers/CMSIS/Device/ST/STM32F1xx/Include \