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
+