diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4767f4..4869f27 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,12 @@ repos: + - repo: https://github.com/pre-commit/mirrors-clang-format rev: 7d85583be209cb547946c82fbe51f4bc5dd1d017 hooks: - - id: clang-format - args: - [ - "--style={BasedOnStyle: Google, SortIncludes: false, ColumnLimit: 120}", - ] - files: \.(cpp|hpp)$ - stages: [commit] + - id: clang-format + args: [--style=Google] + files: \.(cpp|hpp)$ + stages: [commit] - repo: https://github.com/pre-commit/mirrors-prettier rev: v2.5.1 @@ -20,8 +18,8 @@ repos: rev: v0.4.1 hooks: - id: ruff - types_or: [python, pyi] - args: [--fix] + types_or: [ python, pyi ] + args: [ --fix ] stages: [commit] - id: ruff-format stages: [commit] diff --git a/Components/DataBroker/Inc/DataBroker.hpp b/Components/DataBroker/Inc/DataBroker.hpp deleted file mode 100644 index 0605787..0000000 --- a/Components/DataBroker/Inc/DataBroker.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/** - ******************************************************************************** - * @file DataBroker.hpp - * @author Shivam Desai - * @date Nov 23, 2024 - * @brief - ******************************************************************************** - */ - -#ifndef DATA_BROKER_HPP_ -#define DATA_BROKER_HPP_ - -/************************************ - * INCLUDES - ************************************/ -#include "Publisher.hpp" -#include "SensorDataTypes.hpp" -#include "Command.hpp" -#include "DataBrokerMessageTypes.hpp" -#include "SystemDefines.hpp" -#include "Mutex.hpp" -#include -#include -#include -#include - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ - -/************************************ - * CLASS DEFINITIONS - ************************************/ -class DataBroker { - public: - /** - * @brief Publish data of a certain type - * NOTE: You must ensure that there is a publisher for that type - */ - template - static void Publish(T* dataToPublish) { - if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { - Publisher* publisher = getPublisher(); - if (publisher != nullptr) { - publisher->Publish(dataToPublish); - } else { - SOAR_ASSERT("Data Publisher not found \n"); - } - subscriberListLock.Unlock(); - return; - } else { - SOAR_PRINT("Could Not Subscribe to Data Broker Publisher \n"); - } - return; - } - - /** - * @brief Subscribe to a certain type of data in the system - * @param taskToSubscribe Task Handle of the task that will receive - * and handle the data. (i.e. -> Subscribe(this)) - */ - template - static void Subscribe(Task* taskToSubscribe) { - if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { - Publisher* publisher = getPublisher(); - if (publisher != nullptr) { - publisher->Subscribe(taskToSubscribe); - } else { - SOAR_ASSERT("Data Publisher not found \n"); - } - subscriberListLock.Unlock(); - return; - } else { - SOAR_PRINT("Could Not Subscribe to Data Broker Publisher \n"); - } - return; - } - - /** - * @brief Unsubscribe to a certain type of data in the system - * @param taskToUnsubscribe Task Handle of the task that will stop - * receiving the data. (i.e. -> Unsubscribe(this)) - */ - template - static void Unsubscribe(Task* taskToUnsubscribe) { - if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { - Publisher* publisher = getPublisher(); - if (publisher != nullptr) { - publisher->Unsubscribe(taskToUnsubscribe); - } else { - SOAR_ASSERT("Data Publisher not found \n"); - } - subscriberListLock.Unlock(); - return; - } else { - SOAR_PRINT("Could Not Unsubscribe to Data Broker Publisher \n"); - } - return; - } - - /** - * @brief This API can be used to offload the data from the databroker message - * into a new object in the receiving task - * @param cm the Command object that contains the databroker message - */ - template - static constexpr T ExtractData(const Command& cm) { - if (cm.GetCommand() != DATA_BROKER_COMMAND) { - SOAR_ASSERT("Not a Data Broker Command!\n"); - } - - Publisher* publisher = getPublisher(); - DataBrokerMessageTypes messageType = DataBroker::getMessageType(cm); - - if (messageType != publisher->GetPublisherMessageType()) { - const std::string errorMessage = "Trying to unpack the wrong type of message. You are trying to use " + - DataBrokerMessageType::ToString(publisher->GetPublisherMessageType()) + - " instead of " + DataBrokerMessageType::ToString(messageType) + "\n\n"; - - const char* messageCStr = errorMessage.c_str(); - SOAR_PRINT(messageCStr); - SOAR_ASSERT(false, ""); - } - - // The data allocated by this command ptr will be freed when cm.Reset()] - // is called. So we do not have to free this memory here - T* dataPtr = reinterpret_cast(cm.GetDataPointer()); - - T data{}; - - std::memcpy(&data, dataPtr, sizeof(T)); - - return data; - } - - /** - * @brief This API can be use to get the type of data broker message contained - * in the message. - * All the message types can be found in DataBrokerMessageTypes.hpp - * @param cm the Command object that contains the databroker message - */ - static DataBrokerMessageTypes getMessageType(const Command& cm) { - return static_cast(cm.GetTaskCommand()); - } - - private: - // Deleting the default constructor as this class is not - // instanceable - DataBroker() = delete; - - // Deleting the copy constructor to prevent copies - DataBroker(const DataBroker& obj) = delete; - - // Deleting assignment operator to prevent assignment operations - DataBroker& operator=(DataBroker const&) = delete; - - // Mutex to access the Subscriber List - inline static Mutex subscriberListLock{}; - // Mutex lock wait time - static constexpr uint16_t SUBSCRIBER_LIST_MUTEX_TIMEOUT = 1000; - - /** - * @brief Checks if the 2 template types are the same - */ - template - static constexpr bool matchType() { - return std::is_same_v; - } - - /** - * @brief Returns the correct Publisher object for a template type - */ - template - static constexpr auto getPublisher(void) { - if constexpr (matchType()) { - return &IMU_Data_publisher; - } else { - SOAR_ASSERT(false, "This publisher type does not exist, you must create it"); - return (Publisher*)nullptr; - } - } - - // List of Publishers - inline static Publisher IMU_Data_publisher{DataBrokerMessageTypes::IMU_DATA}; - -}; -/************************************ - * FUNCTION DECLARATIONS - ************************************/ - -#endif /* DATA_BROKER_HPP_ */ diff --git a/Components/DataBroker/Inc/Publisher.hpp b/Components/DataBroker/Inc/Publisher.hpp deleted file mode 100644 index c664c44..0000000 --- a/Components/DataBroker/Inc/Publisher.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/** - ******************************************************************************** - * @file Publisher.hpp - * @author Shivam Desai - * @date Nov 23, 2024 - * @brief - ******************************************************************************** - */ - -#ifndef PUBLISHER_HPP_ -#define PUBLISHER_HPP_ - -/************************************ - * INCLUDES - ************************************/ -#include -#include -#include -#include "Task.hpp" -#include "Subscriber.hpp" -#include "SystemDefines.hpp" - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ - -/************************************ - * CLASS DEFINITIONS - ************************************/ -template -class Publisher { - public: - // Constructor - Publisher(DataBrokerMessageTypes messageType) { publisherMessageType = messageType; } - - // subscribe - bool Subscribe(Task* taskToSubscribe) { - // Check if subscriber already exists - for (Subscriber& subscriber : subscribersList) { - if (subscriber.getSubscriberTaskHandle() == taskToSubscribe) { - return true; - } - } - - // Add the subscriber - for (Subscriber& subscriber : subscribersList) { - if (subscriber.getSubscriberTaskHandle() == nullptr) { - subscriber.Init(taskToSubscribe); - return true; - } - } - - SOAR_ASSERT(true, "Failed to add subscriber\n"); - return false; - } - - // unsubscribe - bool Unsubscribe(Task* taskToUnsubscribe) { - for (Subscriber& subscriber : subscribersList) { - if (subscriber.getSubscriberTaskHandle() == taskToUnsubscribe) { - subscriber.Delete(); - return true; - } - } - - SOAR_ASSERT(true, "Subscriber not Deleted\n"); - return false; - } - - // publish - void Publish(T* dataToPublish) { - for (const Subscriber& subscriber : subscribersList) { - if (subscriber.getSubscriberTaskHandle() != nullptr) { - // create command - uint16_t messageType = static_cast(publisherMessageType); - - Command brokerData(DATA_BROKER_COMMAND, messageType); - - uint8_t* messsageData = reinterpret_cast(dataToPublish); - - // copy data to command - brokerData.CopyDataToCommand(messsageData, sizeof(T)); - - subscriber.getSubscriberQueueHandle()->Send(brokerData); - } - } - } - - DataBrokerMessageTypes GetPublisherMessageType() { return publisherMessageType; } - - private: - // list of subscribers - Subscriber subscribersList[MaxSubscribers] = {}; - - // message type for system routing - DataBrokerMessageTypes publisherMessageType = DataBrokerMessageTypes::INVALID; -}; - -/************************************ - * FUNCTION DECLARATIONS - ************************************/ - -#endif /* PUBLISHER_HPP_ */ diff --git a/Components/DataBroker/Inc/Subscriber.hpp b/Components/DataBroker/Inc/Subscriber.hpp deleted file mode 100644 index 3352b80..0000000 --- a/Components/DataBroker/Inc/Subscriber.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - ******************************************************************************** - * @file Subscriber.hpp - * @author Shivam Desai - * @date Nov 23, 2024 - * @brief - ******************************************************************************** - */ - -#ifndef SUBSCRIBER_HPP_ -#define SUBSCRIBER_HPP_ - -/************************************ - * INCLUDES - ************************************/ -#include "Task.hpp" -#include "SystemDefines.hpp" - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ - -/************************************ - * CLASS DEFINITIONS - ************************************/ -class Subscriber { - public: - void Init(Task* subscriberTaskHandle) { - if (taskHandle != nullptr || taskQueue != nullptr) { - SOAR_ASSERT(false, "You cannot overwrite a subscriber"); - return; - } - taskHandle = subscriberTaskHandle; - taskQueue = taskHandle->GetEventQueue(); - } - - void Delete() { - taskHandle = nullptr; - taskQueue = nullptr; - } - - inline const Task* getSubscriberTaskHandle() const { return taskHandle; } - - inline Queue* getSubscriberQueueHandle() const { return taskQueue; } - - private: - Task* taskHandle = nullptr; - Queue* taskQueue = nullptr; -}; - -/************************************ - * FUNCTION DECLARATIONS - ************************************/ - -#endif /* SUBSCRIBER_HPP_ */ diff --git a/Components/SystemTypes/DataBrokerMessageTypes.hpp b/Components/SystemTypes/DataBrokerMessageTypes.hpp deleted file mode 100644 index 23f4965..0000000 --- a/Components/SystemTypes/DataBrokerMessageTypes.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - ******************************************************************************** - * @file DataBrokerMessageTypes.hpp - * @author Shivam Desai - * @date Nov 23, 2024 - * @brief - ******************************************************************************** - */ - -#ifndef DATA_BROKER_MESSAGE_TYPES_HPP_ -#define DATA_BROKER_MESSAGE_TYPES_HPP_ - -/************************************ - * INCLUDES - ************************************/ -#include -#include - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ -enum class DataBrokerMessageTypes : uint8_t { - INVALID = 0, - IMU_DATA, - GPS_DATA, - BARO_DATA, - FILTER_DATA, - MAG_DATA, -}; - -namespace DataBrokerMessageType { -/************************************ - * CLASS DEFINITIONS - ************************************/ - -/************************************ - * FUNCTION DECLARATIONS - ************************************/ -std::string ToString(DataBrokerMessageTypes messageType); - -inline std::string ToString(DataBrokerMessageTypes messageType) { - switch (messageType) { - case DataBrokerMessageTypes::IMU_DATA: { - std::string type{"IMU_DATA"}; - return type; - } - case DataBrokerMessageTypes::GPS_DATA: { - std::string type{"GPS_DATA"}; - return type; - } - case DataBrokerMessageTypes::BARO_DATA: { - std::string type{"BARO_DATA"}; - return type; - } - case DataBrokerMessageTypes::FILTER_DATA: { - std::string type{"FILTER_DATA"}; - return type; - } - case DataBrokerMessageTypes::MAG_DATA: { - std::string type{"MAG_DATA"}; - return type; - } - case DataBrokerMessageTypes::INVALID: - [[fallthrough]]; - default: { - std::string type{"INVALID"}; - return type; - } - } -} - -} // namespace DataBrokerMessageType - -#endif /* DATA_BROKER_MESSAGE_TYPES_HPP_ */ diff --git a/Components/SystemTypes/SensorDataTypes.hpp b/Components/SystemTypes/SensorDataTypes.hpp deleted file mode 100644 index 21cc20a..0000000 --- a/Components/SystemTypes/SensorDataTypes.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - ******************************************************************************** - * @file SensorDataTypes.hpp - * @author Shivam Desai - * @date Nov 3, 2024 - * @brief General sensor data structure to pass around in the system or - *log it to flash memory - ******************************************************************************** - */ - -#ifndef SENSORDATATYPES_HPP_ -#define SENSORDATATYPES_HPP_ - -#include - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ - -/** - * @param accelX The acceleration in the X axis relative to the sensor - * @param accelY The acceleration in the Y axis relative to the sensor - * @param accelZ The acceleration in the Z axis relative to the sensor - */ -struct IMUData { - uint32_t accelX; - uint32_t accelY; - uint32_t accelZ; -}; - -/** - * @param Temperature. Can be any where from -2147483648 to 2147483647 - */ -struct ThermocoupleData { - int32_t temperature; -}; - -struct GPSData{ - uint32_t gps; -}; - -struct BaroData{ - uint32_t baro; -}; - -struct FilterData{ - uint32_t filter; -}; - -struct MagData{ - uint32_t mag; -}; - -#endif /* SENSORDATATYPES_HPP_ */ diff --git a/Components/SystemTypes/SystemCommunicationTypes.hpp b/Components/SystemTypes/SystemCommunicationTypes.hpp deleted file mode 100644 index e3d046b..0000000 --- a/Components/SystemTypes/SystemCommunicationTypes.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/** - ******************************************************************************** - * @file SystemCommunicationTypes.hpp - * @author Shivam Desai - * @date Nov 3, 2024 - * @brief Data structures to pass around other system information such as - * commands, events or state information - ******************************************************************************** - */ - -#ifndef SYSTEMCOMMUNICATIONTYPES_HPP_ -#define SYSTEMCOMMUNICATIONTYPES_HPP_ - -/************************************ - * MACROS AND DEFINES - ************************************/ - -/************************************ - * TYPEDEFS - ************************************/ - -#endif /* SYSTEMCOMMUNICATIONTYPES_HPP_ */ diff --git a/Components/SystemTypes/SystemConfigTypes.hpp b/Components/SystemTypes/SystemConfigTypes.hpp deleted file mode 100644 index 578f097..0000000 --- a/Components/SystemTypes/SystemConfigTypes.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/** - ******************************************************************************** - * @file SystemConfigTypes.hpp - * @author Shivam Desai - * @date Nov 3, 2024 - * @brief Defines that allow the system to build with different - *functionality by changing the value of the define in this file - ******************************************************************************** - */ - -#ifndef SYSTEMCONFIGTYPES_HPP_ -#define SYSTEMCONFIGTYPES_HPP_ - -/************************************ - * MACROS AND DEFINES - ************************************/ - -#endif /* SYSTEMCONFIGTYPES_HPP_ */ diff --git a/Core/Command.cpp b/Core/Command.cpp index 9b8f8ab..035a080 100644 --- a/Core/Command.cpp +++ b/Core/Command.cpp @@ -100,7 +100,7 @@ uint8_t* Command::AllocateData(uint16_t dataSize) statAllocationCounter += 1; //TODO: May want to print out whenever we have an imbalance in statAllocationCounter by more than ~5 or so. - SOAR_ASSERT(statAllocationCounter < MAX_NUMBER_OF_COMMAND_ALLOCATIONS); + CUBE_ASSERT(statAllocationCounter < MAX_NUMBER_OF_COMMAND_ALLOCATIONS); return this->data; } return nullptr; diff --git a/Core/CubeUtils.cpp b/Core/CubeUtils.cpp index f7a929b..33b7d67 100644 --- a/Core/CubeUtils.cpp +++ b/Core/CubeUtils.cpp @@ -170,14 +170,14 @@ int32_t Utils::ExtractIntParameter(const char* msg, uint16_t identifierLen) { // Handle a command with an int parameter at the end if (static_cast(strlen(msg)) < identifierLen+1) { - SOAR_PRINT("Int parameter insufficient length\r\n"); + CUBE_PRINT("Int parameter insufficient length\r\n"); return ERRVAL; } // Extract the value and attempt conversion to integer const int32_t val = Utils::StringToLong(&msg[identifierLen]); if (val == ERRVAL) { - SOAR_PRINT("Int parameter invalid value\r\n"); + CUBE_PRINT("Int parameter invalid value\r\n"); } return val; diff --git a/Core/Inc/PQueue.hpp b/Core/Inc/PQueue.hpp index b44687e..c751b1a 100644 --- a/Core/Inc/PQueue.hpp +++ b/Core/Inc/PQueue.hpp @@ -107,7 +107,7 @@ class PQueue { bool operator<(const PriorityQueueItem& other) const { if(priority_ == other.priority_) { #ifdef PQUEUE_ENABLE_SEQN_CIRCULAR_CHECK - SOAR_ASSERT(pSeqN_ != nullptr, "PQueue null seqn pointer"); + CUBE_ASSERT(pSeqN_ != nullptr, "PQueue null seqn pointer"); seq_t seqN = *pSeqN_; if((order_ < seqN && other.order_ < seqN) || (order_ >= seqN && other.order_ >= seqN)) { @@ -267,10 +267,10 @@ bool PQueue::ReceiveWait(T& item) { template void PQueue::HandleConsistencyError() { // Print an error - SOAR_PRINT("ERROR: PQueue Data Consistency\r\n"); + CUBE_PRINT("ERROR: PQueue Data Consistency\r\n"); // Count the error, if it exceeds the max, we must reset the system - SOAR_ASSERT(++errCount_ > PQUEUE_ERROR_COUNT_MAX, + CUBE_ASSERT(++errCount_ > PQUEUE_ERROR_COUNT_MAX, "PQueue data consistency faults exceeded limits"); // Pop/Add items to the RT queue until it matches that of the priority queue diff --git a/Core/Mutex.cpp b/Core/Mutex.cpp index b2ff5e9..b016faf 100644 --- a/Core/Mutex.cpp +++ b/Core/Mutex.cpp @@ -18,7 +18,7 @@ Mutex::Mutex() { rtSemaphoreHandle = xSemaphoreCreateMutex(); - SOAR_ASSERT(rtSemaphoreHandle != NULL, "Semaphore creation failed."); + CUBE_ASSERT(rtSemaphoreHandle != NULL, "Semaphore creation failed."); } diff --git a/Core/Queue.cpp b/Core/Queue.cpp index c216b07..33c3d94 100644 --- a/Core/Queue.cpp +++ b/Core/Queue.cpp @@ -59,7 +59,7 @@ bool Queue::SendToFront(Command& command) if (xQueueSendToFront(rtQueueHandle, &command, DEFAULT_QUEUE_SEND_WAIT_TICKS) == pdPASS) return true; - SOAR_PRINT("Could not send data to front of queue!\n"); + CUBE_PRINT("Could not send data to front of queue!\n"); command.Reset(); return false; @@ -79,7 +79,7 @@ bool Queue::Send(Command& command, bool reportFull) if (xQueueSend(rtQueueHandle, &command, DEFAULT_QUEUE_SEND_WAIT_TICKS) == pdPASS) return true; - if (reportFull) SOAR_PRINT("Could not send data to queue!\n"); + if (reportFull) CUBE_PRINT("Could not send data to queue!\n"); command.Reset(); diff --git a/Core/Timer.cpp b/Core/Timer.cpp index 0a3df33..25c1cb3 100644 --- a/Core/Timer.cpp +++ b/Core/Timer.cpp @@ -22,7 +22,7 @@ Timer::Timer() // 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", timerPeriod, pdFALSE, (void *)this, DefaultCallback); - SOAR_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); + CUBE_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); timerState = UNINITIALIZED; } @@ -36,7 +36,7 @@ Timer::Timer() Timer::Timer(void (*TimerDefaultCallback_t)( TimerHandle_t xTimer )) { rtTimerHandle = xTimerCreate("Timer", timerPeriod, pdFALSE, (void *)this, TimerDefaultCallback_t); - SOAR_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); + CUBE_ASSERT(rtTimerHandle, "Error Occurred, Timer not created"); timerState = UNINITIALIZED; } @@ -47,10 +47,10 @@ Timer::Timer(void (*TimerDefaultCallback_t)( TimerHandle_t xTimer )) Timer::~Timer() { if (xTimerDelete(rtTimerHandle, DEFAULT_TIMER_COMMAND_WAIT_PERIOD*2) == pdPASS) { - SOAR_PRINT("Timer has been deleted \n\n"); + CUBE_PRINT("Timer has been deleted \n\n"); } else { - SOAR_PRINT("WARNING, FAILED TO DELETE TIMER! \n\n"); + CUBE_PRINT("WARNING, FAILED TO DELETE TIMER! \n\n"); } } @@ -142,7 +142,7 @@ bool Timer::Stop() bool Timer::ResetTimer() { if (timerState == UNINITIALIZED) { - SOAR_PRINT("Cannot Restart as timer has not yet started!"); + CUBE_PRINT("Cannot Restart as timer has not yet started!"); return false; } if (ChangePeriodMs(timerPeriod) == true) { @@ -158,7 +158,7 @@ bool Timer::ResetTimer() bool Timer::ResetTimerAndStart() { if (timerState == UNINITIALIZED) { - SOAR_PRINT("Cannot Restart as timer has not yet started!"); + CUBE_PRINT("Cannot Restart as timer has not yet started!"); return false; } if (ChangePeriodMsAndStart(timerPeriod) == true) { @@ -223,12 +223,12 @@ void Timer::SetAutoReload(bool setReloadOn) if (setReloadOn == true){ vTimerSetReloadMode(rtTimerHandle, pdTRUE); //Testing purposes - SOAR_PRINT("Set to Auto Reload\n\n"); + CUBE_PRINT("Set to Auto Reload\n\n"); } if (setReloadOn == false){ vTimerSetReloadMode(rtTimerHandle, pdFALSE); //Testing purposes - SOAR_PRINT("Set to One Shot\n\n"); + CUBE_PRINT("Set to One Shot\n\n"); } } diff --git a/CubeDefines.cpp b/CubeDefines.cpp index 43cdb65..362dfee 100644 --- a/CubeDefines.cpp +++ b/CubeDefines.cpp @@ -53,7 +53,7 @@ void cube_print(const char* str, ...) else { // Print out that we could not acquire the VA list mutex - SOAR_ASSERT(false, "Could not acquire VA_LIST mutex"); + CUBE_ASSERT(false, "Could not acquire VA_LIST mutex"); } #endif } diff --git a/CubeDefines.hpp b/CubeDefines.hpp index 80b53a4..e075e76 100644 --- a/CubeDefines.hpp +++ b/CubeDefines.hpp @@ -51,11 +51,11 @@ constexpr uint16_t ASSERT_TAKE_MAX_TIME_MS = 500; // Max time in ms to ta // Assert macro, use this for checking all possible program errors eg. malloc success etc. supports a custom message in printf format // This is our version of the stm32f4xx_hal_conf.h 'assert_param' macro with support for optional messages -// Example Usage: SOAR_ASSERT(ptr != 0, "Pointer on loop index %d is null!", index); -#define SOAR_ASSERT(expr, ...) ((expr) ? (void)0U : cube_assert_debug(false, (const char *)__FILE__, __LINE__, ##__VA_ARGS__)) +// Example Usage: CUBE_ASSERT(ptr != 0, "Pointer on loop index %d is null!", index); +#define CUBE_ASSERT(expr, ...) ((expr) ? (void)0U : cube_assert_debug(false, (const char *)__FILE__, __LINE__, ##__VA_ARGS__)) -// SOAR_PRINT macro, acts as an interface to the print function which sends a packet to the UART Task to print data -#define SOAR_PRINT(str, ...) (cube_print(str, ##__VA_ARGS__)) +// CUBE_PRINT macro, acts as an interface to the print function which sends a packet to the UART Task to print data +#define CUBE_PRINT(str, ...) (cube_print(str, ##__VA_ARGS__)) /** * @brief Malloc inline function, wraps malloc for multi-platform support, asserts successful allocation @@ -68,7 +68,7 @@ inline uint8_t* cube_malloc(uint32_t size) { #else uint8_t* ret = (uint8_t*)pvPortMalloc(size); #endif - SOAR_ASSERT(ret, "cube_malloc failed"); + CUBE_ASSERT(ret, "cube_malloc failed"); return ret; } diff --git a/CubeTask.cpp b/CubeTask.cpp index 894c093..d7590f3 100644 --- a/CubeTask.cpp +++ b/CubeTask.cpp @@ -14,7 +14,7 @@ void CubeTask::InitTask() { // Make sure the task is not already initialized - SOAR_ASSERT(rtTaskHandle == nullptr, "Cannot initialize UART task twice"); + CUBE_ASSERT(rtTaskHandle == nullptr, "Cannot initialize UART task twice"); // Start the task BaseType_t rtValue = @@ -26,7 +26,7 @@ void CubeTask::InitTask() (TaskHandle_t*)&rtTaskHandle); //Ensure creation succeded - SOAR_ASSERT(rtValue == pdPASS, "CUBETask::InitTask() - xTaskCreate() failed"); + CUBE_ASSERT(rtValue == pdPASS, "CUBETask::InitTask() - xTaskCreate() failed"); } /** @@ -65,13 +65,13 @@ void CubeTask::HandleCommand(Command& cm) #endif break; default: - SOAR_PRINT("CUBETask - Received Unsupported DATA_COMMAND {%d}\n", cm.GetTaskCommand()); + CUBE_PRINT("CUBETask - Received Unsupported DATA_COMMAND {%d}\n", cm.GetTaskCommand()); break; } break; } default: - SOAR_PRINT("CUBETask - Received Unsupported Command {%d}\n", cm.GetCommand()); + CUBE_PRINT("CUBETask - Received Unsupported Command {%d}\n", cm.GetCommand()); break; } diff --git a/Drivers/DMATransfer_README.md b/Drivers/DMATransfer_README.md index c105f38..278506f 100644 --- a/Drivers/DMATransfer_README.md +++ b/Drivers/DMATransfer_README.md @@ -12,7 +12,7 @@ This driver also manages **Cache Coherence** for Cortex-M7 (STM32H7) and Cortex- ## Features -* **Unified Interface:** Uses C++ `if constexpr` templates to detect the handle type (`SPI_HandleTypeDef`, `I2C_HandleTypeDef`, `UART_HandleTypeDef`) and call the matching HAL function. +* **Unified Interface:** Uses C++ `if constexpr` templates to detect the handle type (`SPI_HandleTypeDef`, `I2C_HandleTypeDef`, `UART_HandleTypeDef`, `QSPI_HandleTypeDef`) and call the matching HAL function. * **Cache Management:** Automatically calls `SCB_CleanDCache_by_Addr` and `SCB_InvalidateDCache_by_Addr` if the architecture requires it (H7/G4). * **Zero-Overhead:** Being header-only template library, the compiler optimizes unused branches, resulting in no runtime performance penalty compared to raw HAL calls. @@ -59,8 +59,14 @@ DMAControl::Transfer(&hi2c1, (0x68 << 1), nullptr, rxBuffer, 10); uint8_t txBuf[] = {0xCA, 0xFE}; uint8_t rxBuf[2]; -// Full Duplex Transfer +// Full Duplex Transfer (Simultaneous Tx/Rx) DMAControl::Transfer(&hspi1, 0, txBuf, rxBuf, 2); + +// Simplex Transfer (Transmit Only) +DMAControl::Transfer(&hspi1, 0, txBuf, nullptr, 2); + +// Simplex Transfer (Receive Only) +DMAControl::Transfer(&hspi1, 0, nullptr, rxBuf, 2); ``` ### UART @@ -75,7 +81,16 @@ uint8_t inputBuf[64]; DMAControl::Transfer(&huart1, 0, nullptr, inputBuf, 64); ``` -### NOTES +### QSPI + +*Note: For QSPI, the Command/Address phase must be sent first (usually via blocking `HAL_QSPI_Command`), followed by this DMA Data Transfer.* -* This Driver Requires HAL handles. It is not directly compatible with LL pointers without a wrapper. -* DMA channels should be enabled and linked to peripherals in main.c / msp.c before calling this function. +```cpp +// Transmit Data to Flash (Write) +// Arguments: Handle, 0 (Address ignored), TxBuffer, nullptr, Size +DMAControl::Transfer(&hqspi, 0, txBuffer, nullptr, 256); + +// Receive Data from Flash (Read) +// Arguments: Handle, 0 (Address ignored), nullptr, RxBuffer, Size +DMAControl::Transfer(&hqspi, 0, nullptr, rxBuffer, 256); +``` diff --git a/Drivers/Inc/DMATransfer.hpp b/Drivers/Inc/DMATransfer.hpp index 1b36111..1b5bdc1 100644 --- a/Drivers/Inc/DMATransfer.hpp +++ b/Drivers/Inc/DMATransfer.hpp @@ -36,8 +36,19 @@ class DMAControl { // === SPI Logic === if constexpr (std::is_same_v) { - // SPI Transfer (Full-Duplex) - return HAL_SPI_TransmitReceive_DMA(handle, txData, rxData, size); + + // Transmit Only (Simplex) + if (txData != nullptr && rxData == nullptr){ + return HAL_SPI_Transmit_DMA(handle, txData, size); + } + // Receive Only (Simplex) + if (txData == nullptr && rxData != nullptr){ + return HAL_SPI_Receive_DMA(handle, rxData, size); + } + // Full Duplex + if (txData != nullptr && rxData != nullptr){ + return HAL_SPI_TransmitReceive_DMA(handle, txData, rxData, size); + } } // === I2C Logic === @@ -64,6 +75,28 @@ class DMAControl { return HAL_UART_Receive_DMA(handle, rxData, size); } } + + + // === QSPI Logic === + + if constexpr (std::is_same_v) { + // Transmit (To Flash) + if (txData != nullptr && rxData == nullptr) { + return HAL_QSPI_Transmit_DMA(handle, txData); + } + // Receive (From Flash) + else if (rxData != nullptr && txData == nullptr) { + return HAL_QSPI_Receive_DMA(handle, rxData); + } + } + + // Handle type not supported + #ifdef SOAR_DEBUG { + SOAR_PRINT("DMAControl::Transfer - Unsupported handle type\n"); + } + #endif + + return HAL_ERROR; } }; diff --git a/Drivers/Inc/UARTDriver.hpp b/Drivers/Inc/UARTDriver.hpp index 29174f9..e278339 100644 --- a/Drivers/Inc/UARTDriver.hpp +++ b/Drivers/Inc/UARTDriver.hpp @@ -13,6 +13,28 @@ #include "SystemDefines.hpp" #include "cmsis_os.h" +// Example code on how to declare UART Driver Instances in the HPP +#if EXAMPLE_CODE +/* UART Driver Instances ------------------------------------------------------------------*/ +class UARTDriver; + +namespace Driver { + extern UARTDriver uart1; + extern UARTDriver uart2; + extern UARTDriver uart3; + extern UARTDriver uart5; +} + +/* UART Driver Aliases ------------------------------------------------------------------*/ +namespace UART { + constexpr UARTDriver* Umbilical_RCU = &Driver::uart1; + constexpr UARTDriver* Radio = &Driver::uart2; + constexpr UARTDriver* Conduit_PBB = &Driver::uart3; + // UART 4 (GPS) uses HAL + constexpr UARTDriver* Debug = &Driver::uart5; +} +#endif + /* UART Receiver Base Class ------------------------------------------------------------------*/ /** * @brief Any classes that are expected to receive using a UART driver diff --git a/Drivers/UARTDriver_README.md b/Drivers/UARTDriver_README.md index 2c48dfd..121091f 100644 --- a/Drivers/UARTDriver_README.md +++ b/Drivers/UARTDriver_README.md @@ -50,7 +50,7 @@ something like cpp_USART5_IRQHandler(), for example: * RunInterface.cpp */ -#include "main_avionics.hpp" +#include "main_system.hpp" #include "UARTDriver.hpp" extern "C" { diff --git a/README.md b/README.md index 39460e4..a374cc3 100644 --- a/README.md +++ b/README.md @@ -90,13 +90,13 @@ Please ensure the following folders are not in the exclude from build option: - (none for this version) ### Codebase Setup -An example project utilizing Cube++ with basic SOAR_PRINT support, in addition to a Debug receive task for parsing input data on the debug line can be found at https://github.com/cjchanx/cubeplusplus-examples/tree/main/Basic_Debug +An example project utilizing Cube++ with basic CUBE_PRINT support, in addition to a Debug receive task for parsing input data on the debug line can be found at https://github.com/cjchanx/cubeplusplus-examples/tree/main/Basic_Debug - It is recommended to setup a new folder called `Components` or `Modules` in the root where all the code goes. - There are a few files that you should have in `Components`/`Modules`: - SystemDefines.hpp : An example can be found [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/SystemDefines.hpp) - - main_avionics.cpp : This can be named anything you want, but should contain the run_main() function that is the entry point for your codebase, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/main_avionics.cpp) - - main_avionics.hpp : Header file for main_avionics.cpp, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/main_avionics.hpp) + - main_system.cpp : This can be named anything you want, but should contain the run_main() function that is the entry point for your codebase, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/main_system.cpp) + - main_system.hpp : Header file for main_system.cpp, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/main_system.hpp) - SysCore/Inc/RunInterface.hpp : Header file for the run interface which allows C code to call into the C++ codebase without errors, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/Core/Inc/RunInterface.hpp) - SysCore/RunInterface.cpp : Code file for the run interface, example [here](https://github.com/cjchanx/cubeplusplus-examples/blob/main/Basic_Debug/Components/Core/RunInterface.cpp) - Setup Debug UART