diff --git a/.cproject b/.cproject index 5dac8533..62eb3ca4 100644 --- a/.cproject +++ b/.cproject @@ -98,10 +98,14 @@ +<<<<<<< HEAD + +>>>>>>> ef0277edecfdc6058bab831e34734f3d064ecbe3 @@ -299,4 +303,4 @@ - \ No newline at end of file + diff --git a/AvionicsSoftware.ioc b/AvionicsSoftware.ioc index cc4a559a..ac44c8ca 100644 --- a/AvionicsSoftware.ioc +++ b/AvionicsSoftware.ioc @@ -53,11 +53,12 @@ Dma.UART5_TX.2.Priority=DMA_PRIORITY_LOW Dma.UART5_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.FootprintOK=true FREERTOS.INCLUDE_vTaskDelayUntil=1 -FREERTOS.IPParameters=Tasks01,INCLUDE_vTaskDelayUntil,FootprintOK,configMAX_TASK_NAME_LEN,configUSE_NEWLIB_REENTRANT,configTOTAL_HEAP_SIZE +FREERTOS.IPParameters=Tasks01,INCLUDE_vTaskDelayUntil,FootprintOK,configMAX_TASK_NAME_LEN,configUSE_NEWLIB_REENTRANT,configTOTAL_HEAP_SIZE,configUSE_TIMERS FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL FREERTOS.configMAX_TASK_NAME_LEN=64 FREERTOS.configTOTAL_HEAP_SIZE=24576 FREERTOS.configUSE_NEWLIB_REENTRANT=1 +FREERTOS.configUSE_TIMERS=1 File.Version=6 GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false diff --git a/Components/Core/Inc/DMAController.hpp b/Components/Core/Inc/DMAController.hpp index 452566b0..e3735b80 100644 --- a/Components/Core/Inc/DMAController.hpp +++ b/Components/Core/Inc/DMAController.hpp @@ -39,4 +39,4 @@ class DMAController }; -#endif /* AVIONICS_INCLUDE_SOAR_CORE_DMA_CONTROLLER_BASE_H */ \ No newline at end of file +#endif /* AVIONICS_INCLUDE_SOAR_CORE_DMA_CONTROLLER_BASE_H */ diff --git a/Components/Core/Inc/Queue.hpp b/Components/Core/Inc/Queue.hpp index bf7f3e70..185661ed 100644 --- a/Components/Core/Inc/Queue.hpp +++ b/Components/Core/Inc/Queue.hpp @@ -50,4 +50,4 @@ class Queue{ uint16_t queueDepth; // Max queue depth }; -#endif /* AVIONICS_INCLUDE_SOAR_CORE_QUEUE_H */ \ No newline at end of file +#endif /* AVIONICS_INCLUDE_SOAR_CORE_QUEUE_H */ diff --git a/Components/Core/Inc/Timer.hpp b/Components/Core/Inc/Timer.hpp index 3c7d5993..59a07e12 100644 --- a/Components/Core/Inc/Timer.hpp +++ b/Components/Core/Inc/Timer.hpp @@ -9,12 +9,22 @@ /* Includes ------------------------------------------------------------------*/ #include "cmsis_os.h" #include "Utils.hpp" +#include "FreeRTOS.h" /* Macros --------------------------------------------------------------------*/ constexpr uint32_t DEFAULT_TIMER_COMMAND_WAIT_PERIOD = MS_TO_TICKS(15); // Default time to block a task if a command cannot be issued to the timer #define DEFAULT_TIMER_PERIOD (MS_TO_TICKS(1000)) // 1s +// Enumeration representing the 4 timer states +enum TimerState { + UNINITIALIZED=0, + COUNTING, + PAUSED, + COMPLETE +}; + + /* Class -----------------------------------------------------------------*/ /** @@ -25,21 +35,32 @@ constexpr uint32_t DEFAULT_TIMER_COMMAND_WAIT_PERIOD = MS_TO_TICKS(15); // Defau class Timer { public: - Timer(); - - bool ChangePeriod(const uint32_t period); - - // WORK-IN-PROGRESS - // NOTES: - // - I can think of several timer types - // 1) Default Ctor Timer (1 second polling timer that requires polling to acquire state with no callback) - // 2) Callback Enabled Timer (user-provided callback) + Timer(); // Default Constructor (Polling Timer) + Timer(void (*TimerCallbackFunction_t)( TimerHandle_t xTimer )); // Constructor for Callback Enabled Timer + ~Timer(); + bool ChangePeriod(const uint32_t period_ms); + bool ChangePeriodAndStart(const uint32_t period_ms); + bool Start(); + bool Stop(); + bool ResetTimer(); + bool ResetTimerAndStart(); + void SetAutoReload(bool setReloadOn); + bool GetAutoReload(); + TimerState GetState(); + const uint32_t GetPeriod(); + const uint32_t GetRemainingTime(); + static void CallbackFunction( TimerHandle_t xTimer ); protected: TimerHandle_t rtTimerHandle; - + TimerState timerState; + uint32_t remainingTime; + uint32_t remainingTimeBetweenPauses; + uint32_t rtosTimeRemaning(); }; -#endif /* AVIONICS_INCLUDE_SOAR_CORE_COMMAND_H */ \ No newline at end of file + + +#endif /* AVIONICS_INCLUDE_SOAR_CORE_TIMER_H*/ diff --git a/Components/Core/Timer.cpp b/Components/Core/Timer.cpp index fdf1a555..f6f5716f 100644 --- a/Components/Core/Timer.cpp +++ b/Components/Core/Timer.cpp @@ -1,34 +1,226 @@ +#include "SystemDefines.hpp" +#include "Timer.hpp" + /** ****************************************************************************** * File Name : Timer.cpp * Description : FreeRTOS Timer Wrapper ****************************************************************************** */ -#include "SystemDefines.hpp" -#include "Timer.hpp" /** - * @brief Empty callback function, used internally for default polling timers -*/ -void empty_callback(TimerHandle_t rtTimerHandle) {}; - -/** - * @brief Default constructor makes a timer that can only be polled for state + * Default constructor makes a timer that can only be polled for state + * Default behaviour : ->Autoreload is set to false (One shot Timer) + * ->Timer Period is 1000ms + * ->The Callback function simply changes state to COMPLETE and has no other functionality */ Timer::Timer() { // We make a timer named "Timer" with a callback function that does nothing, Autoreload false, and the default period of 1s. // The timer ID is specified as (void *)this to provide a unique ID for each timer object - however this is not necessary for polling timers. // The timer is created in the dormant state. - rtTimerHandle = xTimerCreate("Timer", DEFAULT_TIMER_PERIOD, pdFALSE, (void *)this, empty_callback); + rtTimerHandle = xTimerCreate("Timer", DEFAULT_TIMER_PERIOD, pdFALSE, (void *)this, CallbackFunction); + SOAR_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); + timerState = UNINITIALIZED; +} + +/** + * Constructor for callback enabled timer + * ! User has to add "Timer::CallbackFunction(rtTimerHandle);" in the callback function for accurate functioning of Timer States + * Default behaviour : ->Autoreload is set to false (One shot Timer) + * ->Timer Period is 1000ms + * ->The Callback function will be provided by the user while making sure to follow instruction above +*/ +Timer::Timer(void (*TimerCallbackFunction_t)( TimerHandle_t xTimer )) +{ + rtTimerHandle = xTimerCreate("Timer", DEFAULT_TIMER_PERIOD, pdFALSE, (void *)this, TimerCallbackFunction_t); + SOAR_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); + timerState = UNINITIALIZED; +} + +/** + * @brief Default de-constructor makes a timer that can only be polled for state +*/ +Timer::~Timer() +{ + if (xTimerDelete(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD*2) == pdPASS) { + SOAR_PRINT("Timer has been deleted \n\n"); + } +} + +/** + * @brief Callback function for polling timers +*/ +void Timer::CallbackFunction(TimerHandle_t xTimer){ + Timer* ptrTimer = (Timer*)pvTimerGetTimerID(xTimer); + ptrTimer->timerState = COMPLETE; } /** - * @brief Changes this timer object's RTOS timer period, returns true on success, returns false on failure (timer command queue full) + * @brief Changes timer period, Sets timer state back to uninitialized and stops timer */ bool Timer::ChangePeriod(const uint32_t period_ms) { - if (xTimerChangePeriod(rtTimerHandle, MS_TO_TICKS(period_ms), DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdTRUE) + if (xTimerChangePeriod(rtTimerHandle, MS_TO_TICKS(period_ms), DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdTRUE) { + if (xTimerStop(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + timerState = UNINITIALIZED; + return true; + } + } + return false; +} + +/** + * @brief Changes timer period, Sets timer state back to counting and starts timer + */ +bool Timer::ChangePeriodAndStart(const uint32_t period_ms) +{ + if (xTimerChangePeriod(rtTimerHandle, MS_TO_TICKS(period_ms), DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdTRUE) { + timerState = COUNTING; + return true; + } + return false; +} + +/** + * @brief Starts the timer +*/ +bool Timer::Start() +{ + if ((timerState == COMPLETE) || (timerState == COUNTING)) { + return false; + } + else if (timerState == PAUSED) { + ChangePeriod(remainingTimeBetweenPauses); + } + if (xTimerStart(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + timerState = COUNTING; return true; + } return false; } + +/** + * @brief Stops the timer +*/ +bool Timer::Stop() +{ + // Checks if timer is in counting state because it cannot be stopped in any other state + if (timerState != COUNTING) { + return false; + } + // Calculates the time left on the timer before it is paused + remainingTimeBetweenPauses = rtosTimeRemaning(); + if (xTimerStop(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + timerState = PAUSED; + return true; + } + return false; +} + +/** + * @brief Restarts timer without starting to count +*/ +bool Timer::ResetTimer() +{ + if (timerState == UNINITIALIZED) { + return false; + } + if (xTimerReset(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + if (xTimerStop(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + timerState = UNINITIALIZED; + return true; + } + } + return false; +} + +/** + * @brief Restarts Timer and starts counting +*/ +bool Timer::ResetTimerAndStart() +{ + if (timerState == UNINITIALIZED) { + return false; + } + if (xTimerReset(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD) == pdPASS) { + timerState = COUNTING; + return true; + } + return false; +} + +/** + * @brief Sets timer to auto-reload if parameter is set to true, Sets timer to one shot if parameter is set to false +*/ +void Timer::SetAutoReload(bool setReloadOn) +{ + if (setReloadOn == true){ + vTimerSetReloadMode(rtTimerHandle, pdTRUE); + //Testing purposes + SOAR_PRINT("Set to Auto Reload\n\n"); + } + if (setReloadOn == false){ + vTimerSetReloadMode(rtTimerHandle, pdFALSE); + //Testing purposes + SOAR_PRINT("Set to One Shot\n\n"); + } +} + +/** + * @brief Returns true if the timer is set to autoreload and false if it is set to one-shot +*/ +bool Timer::GetAutoReload() +{ + if ((uxTimerGetReloadMode(rtTimerHandle)) == (( UBaseType_t ) pdTRUE)) { + return true; + } + if ((uxTimerGetReloadMode(rtTimerHandle)) == (( UBaseType_t ) pdFALSE)) { + return false; + } +} + +/** + * @brief Returns timer state enum +*/ +TimerState Timer::GetState() +{ + return timerState; +} + +/** + * @brief Returns the timers' period +*/ +const uint32_t Timer::GetPeriod() +{ + return (TICKS_TO_MS(xTimerGetPeriod(rtTimerHandle))); +} + +/** + * @brief Returns remaining time on timer based on current state +*/ +const uint32_t Timer::GetRemainingTime() +{ + if (timerState == UNINITIALIZED){ + return (GetPeriod()); + } + else if (timerState == COUNTING){ + return rtosTimeRemaning(); + } + else if (timerState == PAUSED){ + return remainingTimeBetweenPauses; + } + else { + return 0; + } +} + + +/** + * @brief Calculates remaining time on timer in counting state + */ +uint32_t Timer::rtosTimeRemaning() +{ + remainingTime = (TICKS_TO_MS(xTimerGetExpiryTime(rtTimerHandle) - xTaskGetTickCount())); + return remainingTime; +} diff --git a/Components/FlightControl/FlightTask.cpp b/Components/FlightControl/FlightTask.cpp index d7296656..ed019b1e 100644 --- a/Components/FlightControl/FlightTask.cpp +++ b/Components/FlightControl/FlightTask.cpp @@ -7,6 +7,288 @@ #include "FlightTask.hpp" #include "GPIO.hpp" #include "SystemDefines.hpp" +#include "Timer.hpp" + +void test_timer_state () { + Timer testTimer1; + SOAR_PRINT("Expected Output: 0 (UNINITIALIZED)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + + SOAR_PRINT("Starting Timer...\n"); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + testTimer1.Start(); + SOAR_PRINT("Expected Output: 1 (COUNTING)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + + testTimer1.Stop(); + SOAR_PRINT("Expected Output: 2 (PAUSED)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + + testTimer1.Start(); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + SOAR_PRINT("Expected Output: 1 (COUNTING)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + + SOAR_PRINT("Stopping Timer...\n"); + testTimer1.Stop(); + SOAR_PRINT("Time : %d \n", testTimer1.GetRemainingTime()); + SOAR_PRINT("Expected Output: 2 (PAUSED)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + testTimer1.Start(); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + osDelay(1100); + SOAR_PRINT("Time after finish: %d \n", testTimer1.GetRemainingTime()); + SOAR_PRINT("Expected Output: 3 (COMPLETE)\n"); + SOAR_PRINT("The current timer state is: %d\n\n", testTimer1.GetState()); + + SOAR_PRINT("'TIMER HAS BEEN DELETED' should be printed: \n"); +} + +void test_destructor() { + SOAR_PRINT("\n Testing destructor...\n"); + SOAR_PRINT("Expected Output: 'TIMER HAS BEEN DELETED'\n"); + { + Timer testTimer2; + } +} + +void test_period () { + SOAR_PRINT("\n Testing Period related functions \n\n"); + + Timer testTimer3; + + testTimer3.ChangePeriod(3000); + SOAR_PRINT("Expected Output : 3000 ms \n"); + SOAR_PRINT("Actual Output : %d ms \n", testTimer3.GetRemainingTime()); + + testTimer3.Start(); + osDelay(1000); + SOAR_PRINT("Expected Output : 2000 ms \n"); + SOAR_PRINT("Actual Output : %d ms \n", testTimer3.GetRemainingTime()); + + testTimer3.Start(); + SOAR_PRINT("\n Testing GetPeriod function...\n"); + SOAR_PRINT("Expected Output: 1000 ms\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer3.GetPeriod()); + + SOAR_PRINT("Changing Period to 5000ms...\n"); + testTimer3.ChangePeriod(5000); + osDelay(500); + SOAR_PRINT("Expected Result: 5000ms\n"); + SOAR_PRINT("Actual Result: %d\n\n", testTimer3.GetPeriod()); + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 2 (PAUSED)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer3.GetState()); + + SOAR_PRINT("Testing ChangePeriodAndStart function...\n"); + testTimer3.ChangePeriodAndStart(7000); + SOAR_PRINT("Expected Output: 7000 ms\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer3.GetPeriod()); + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 1 (COUNTING)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer3.GetState()); + + SOAR_PRINT("Making sure timer is couting... \n"); + osDelay(1000); + SOAR_PRINT("Expected Output: 6000 ms\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer3.GetRemainingTime()); + + SOAR_PRINT("'TIMER HAS BEEN DELETED' should be printed: \n"); +} + +void test_autoreload () { + Timer testTimer4; + + SOAR_PRINT("\n\n Testing GetAutoReload function...\n"); + SOAR_PRINT("Expected Output: ERROR OCCURRED!!\n"); + if (testTimer4.GetAutoReload() == true) { + SOAR_PRINT("Actual Output : 'Timer is set to autoreload'\n\n"); + } + else { + SOAR_PRINT("ERROR OCCURRED!!!\n\n"); + } + + SOAR_PRINT("Changing timer to one-shot...\n"); + testTimer4.SetAutoReload(false); + osDelay(10); + SOAR_PRINT("Expected Output: 'Timer is set to one-shot'\n"); + if (testTimer4.GetAutoReload() == false) { + SOAR_PRINT("Actual Output : 'Timer is set to one-shot'\n\n"); + } + else { + SOAR_PRINT("ERROR OCCURRED!!!\n\n"); + } + + SOAR_PRINT("'TIMER HAS BEEN DELETED' should be printed: \n"); +} + +void test_reset(){ + Timer testTimer5; + SOAR_PRINT("\n Trying to reset timer in UNINITIALIZED state\n"); + SOAR_PRINT("Expected Output: Timer did not reset\n"); + if (testTimer5.ResetTimer() == false) { + SOAR_PRINT("Actual Output: Timer did not reset\n\n"); + } + else { + SOAR_PRINT("ERROR OCCURRED!!!\n\n"); + } + + testTimer5.Start(); + osDelay(300); + SOAR_PRINT("Testing reset function...\n"); + osDelay(20); + SOAR_PRINT("Expected Result: Timer Reset Successfully\n"); + if (testTimer5.ResetTimer() == true) { + SOAR_PRINT("Actual Output: Timer Reset Successfully\n\n"); + } + else { + SOAR_PRINT("ERROR OCCURRED!!!\n\n"); + } + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 0 (UNINITIALIZED)\n"); // Ask chris is i should make rest to paused state + SOAR_PRINT("Actual Output: %d\n\n", testTimer5.GetState()); + + testTimer5.Start(); + osDelay(300); + SOAR_PRINT("Expected Output: 700 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer5.GetRemainingTime()); + + SOAR_PRINT("Testing ResetTimerAndStart function..\n"); + SOAR_PRINT("Expected Output: Timer Reset Successfully\n"); + if (testTimer5.ResetTimerAndStart() == true) { + SOAR_PRINT("Actual Output: Timer Reset Successfully\n\n"); + } + else { + SOAR_PRINT("ERROR OCCURRED!!!\n\n"); + } + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 1 (COUNTING)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer5.GetState()); + + osDelay(300); + SOAR_PRINT("Expected Output: 700 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer5.GetRemainingTime()); + + SOAR_PRINT("'TIMER HAS BEEN DELETED' should be printed: \n"); +} + +void test_get_time () { + Timer testTimer6; + + testTimer6.Start(); + SOAR_PRINT("\nTesting GetRemainingTime function ...\n"); + SOAR_PRINT("Expected Output: 1000 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer6.GetRemainingTime()); + + osDelay(300); + SOAR_PRINT("Expected Output: 700 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer6.GetRemainingTime()); + + osDelay(300); + testTimer6.Stop(); + SOAR_PRINT("Expected Output: 400 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer6.GetRemainingTime()); + SOAR_PRINT("Pausing Timer ... \n\n"); + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 2 (PAUSED)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer6.GetState()); + + osDelay(1000); + SOAR_PRINT("Expected Output: 400 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer6.GetRemainingTime()); + + SOAR_PRINT("Starting Timer ... \n"); + testTimer6.Start(); + osDelay(200); + SOAR_PRINT("Expected Output: 200 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testTimer6.GetRemainingTime()); + + SOAR_PRINT("'TIMER HAS BEEN DELETED' should be printed: \n"); +} + +void Test2 () { + Timer testtimer; + SOAR_PRINT("Expected Output: 1000 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testtimer.GetRemainingTime()); + testtimer.Start(); + + osDelay(1050); + + SOAR_PRINT("Expected Output: 0 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testtimer.GetRemainingTime()); + + testtimer.ResetTimerAndStart(); + osDelay(5); + SOAR_PRINT("Expected Output: 1000 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testtimer.GetRemainingTime()); + + osDelay(300); + SOAR_PRINT("Expected Output: 700 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testtimer.GetRemainingTime()); + + osDelay(1050); + + SOAR_PRINT("Expected Output: 0 ms\n"); + SOAR_PRINT("Actual Output: %d ms \n\n", testtimer.GetRemainingTime()); + + testtimer.ResetTimer(); + + +} + +void Callback (TimerHandle_t rtTimerHandle) +{ + // USER HAS TO HAVE CALLBACK FUNCTION HERE + Timer::CallbackFunction(rtTimerHandle); + SOAR_PRINT("\n\n The Timer is now Complete and callback function has been executed. Test Number 520 \n\n"); +} + +void testCallback () +{ + SOAR_PRINT("Testing CALLBACK ENABLED Timers \n\n"); + Timer testTimer(Callback); + Timer testTimer2; + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 0 (UNINITIALIZED)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer.GetState()); + + testTimer.ChangePeriod(3000); + osDelay(20); + SOAR_PRINT("Expected Output : 3000 ms \n"); + SOAR_PRINT("Actual Output : %d ms \n", testTimer.GetRemainingTime()); + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 0 (UNINITIALIZED)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer.GetState()); + + testTimer.Start(); + osDelay(1000); + + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 1 (COUNTING)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer.GetState()); + SOAR_PRINT("Expected Output : 2000 ms \n"); + SOAR_PRINT("Actual Output : %d ms \n", testTimer.GetRemainingTime()); + osDelay(5000); + SOAR_PRINT("Testing GetState function...\n"); + SOAR_PRINT("Expected Output: 3 (COMPLETE)\n"); + SOAR_PRINT("Actual Output: %d\n\n", testTimer.GetState()); + + testTimer.Start(); + osDelay(500); + testTimer.ChangePeriod(5000); + osDelay(1000); + SOAR_PRINT("Expected Output : 5000 ms \n"); + SOAR_PRINT("Actual Output : %d ms \n", testTimer.GetRemainingTime()); +} //TODO: Consider moving all InitTask functions to the bottom of the cpp file, since it shouldn't need to be changed that much void FlightTask::InitTask() @@ -34,6 +316,15 @@ void FlightTask::Run(void * pvParams) uint32_t tempSecondCounter = 0; // TODO: Temporary counter, would normally be in HeartBeat task or HID Task, unless FlightTask is the HeartBeat task GPIO::LED1::Off(); + test_timer_state(); + test_destructor(); + test_period (); + test_autoreload (); + test_reset(); + test_get_time (); + Test2(); + testCallback(); + while (1) { // There's effectively 3 types of tasks... 'Async' and 'Synchronous-Blocking' and 'Synchronous-Non-Blocking' // Asynchronous tasks don't require a fixed-delay and can simply delay using xQueueReceive, it will immedietly run the next task diff --git a/Components/GPIO.hpp b/Components/GPIO.hpp index 402ab128..703f970a 100644 --- a/Components/GPIO.hpp +++ b/Components/GPIO.hpp @@ -37,4 +37,4 @@ namespace GPIO } -#endif /* AVIONICS_INCLUDE_SOAR_CORE_GPIO_H */ \ No newline at end of file +#endif /* AVIONICS_INCLUDE_SOAR_CORE_GPIO_H */ diff --git a/Components/Utils.cpp b/Components/Utils.cpp index a125a696..49204f99 100644 --- a/Components/Utils.cpp +++ b/Components/Utils.cpp @@ -91,4 +91,4 @@ uint32_t Utils::getCRC32(uint8_t* data, uint32_t size) // Calculate the CRC32 return HAL_CRC_Calculate(SystemHandles::CRC_Handle, (uint32_t*)buffer, (size+pad)/4); -} \ No newline at end of file +} diff --git a/Components/Utils.hpp b/Components/Utils.hpp index f90a7e08..3ceeb71e 100644 --- a/Components/Utils.hpp +++ b/Components/Utils.hpp @@ -43,4 +43,4 @@ namespace Utils } -#endif // AVIONICS_INCLUDE_SOAR_UTILS_HPP_ \ No newline at end of file +#endif // AVIONICS_INCLUDE_SOAR_UTILS_HPP_ diff --git a/Components/main_avionics.cpp b/Components/main_avionics.cpp index 7348d9d7..f85be699 100644 --- a/Components/main_avionics.cpp +++ b/Components/main_avionics.cpp @@ -18,6 +18,7 @@ #include "UARTTask.hpp" #include "FlightTask.hpp" #include "DebugTask.hpp" +#include "Timer.hpp" /* Global Variables ------------------------------------------------------------------*/ diff --git a/Core/Inc/FreeRTOSConfig.h b/Core/Inc/FreeRTOSConfig.h index 7cc7fb64..02a7d6c4 100644 --- a/Core/Inc/FreeRTOSConfig.h +++ b/Core/Inc/FreeRTOSConfig.h @@ -80,6 +80,12 @@ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 2 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 256 + /* The following flag must be enabled only when using newlib */ #define configUSE_NEWLIB_REENTRANT 1 diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index d02275f9..d8716e97 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -55,6 +55,9 @@ /* GetIdleTaskMemory prototype (linked to static allocation support) */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); +/* GetTimerTaskMemory prototype (linked to static allocation support) */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xIdleTaskTCBBuffer; static StackType_t xIdleStack[configMINIMAL_STACK_SIZE]; @@ -68,6 +71,19 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackTy } /* USER CODE END GET_IDLE_TASK_MEMORY */ +/* USER CODE BEGIN GET_TIMER_TASK_MEMORY */ +static StaticTask_t xTimerTaskTCBBuffer; +static StackType_t xTimerStack[configTIMER_TASK_STACK_DEPTH]; + +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCBBuffer; + *ppxTimerTaskStackBuffer = &xTimerStack[0]; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + /* place for user code */ +} +/* USER CODE END GET_TIMER_TASK_MEMORY */ + /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ diff --git a/_IDE/VS2022/AvionicsSoftware.vcxproj b/_IDE/VS2022/AvionicsSoftware.vcxproj index e57ff892..a642c95e 100644 --- a/_IDE/VS2022/AvionicsSoftware.vcxproj +++ b/_IDE/VS2022/AvionicsSoftware.vcxproj @@ -632,4 +632,4 @@ - \ No newline at end of file + diff --git a/_IDE/VS2022/AvionicsSoftware.vcxproj.filters b/_IDE/VS2022/AvionicsSoftware.vcxproj.filters index 9c0db311..022077b6 100644 --- a/_IDE/VS2022/AvionicsSoftware.vcxproj.filters +++ b/_IDE/VS2022/AvionicsSoftware.vcxproj.filters @@ -1521,4 +1521,4 @@ Source Files\Libraries\embedded-template-library - \ No newline at end of file + diff --git a/_IDE/VS2022/AvionicsSoftware.vcxproj.user b/_IDE/VS2022/AvionicsSoftware.vcxproj.user index 9d15dd5a..d3817efb 100644 --- a/_IDE/VS2022/AvionicsSoftware.vcxproj.user +++ b/_IDE/VS2022/AvionicsSoftware.vcxproj.user @@ -5,4 +5,4 @@ $(LocalDebuggerEnvironment) WindowsLocalDebugger - \ No newline at end of file +