From 1c6028d6c31f69dc8cf3c016af7d0247843e768c Mon Sep 17 00:00:00 2001
From: Davide <davide.mor@skywarder.eu>
Date: Tue, 2 Apr 2024 18:13:52 +0200
Subject: [PATCH] [Main] Disabled debug logs, added a way to safely disable
 sensors, added BoardScheduler

---
 CMakeLists.txt                            |  1 +
 src/boards/Main/BoardScheduler.h          | 67 ++++++++++++++++++++++
 src/boards/Main/Configs/SchedulerConfig.h | 47 ++++++++++++++++
 src/boards/Main/Configs/SensorsConfig.h   | 10 +++-
 src/boards/Main/Radio/Radio.cpp           |  4 +-
 src/boards/Main/Sensors/Sensors.cpp       | 31 ++++++-----
 src/entrypoints/Main/main-entry.cpp       | 68 ++++++++++++-----------
 7 files changed, 179 insertions(+), 49 deletions(-)
 create mode 100644 src/boards/Main/BoardScheduler.h
 create mode 100644 src/boards/Main/Configs/SchedulerConfig.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 423224651..336891fa2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,7 @@ project(OnBoardSoftware)
 
 add_executable(main-entry src/entrypoints/Main/main-entry.cpp ${MAIN_COMPUTER})
 target_include_directories(main-entry PRIVATE ${OBSW_INCLUDE_DIRS})
+target_compile_definitions(main-entry PRIVATE DEFAULT_STDOUT_LOG_LEVEL=20)
 sbs_target(main-entry stm32f767zi_bikeshed)
 
 add_executable(payload-entry-roccaraso src/entrypoints/Payload/payload-entry.cpp ${PAYLOAD_COMPUTER})
diff --git a/src/boards/Main/BoardScheduler.h b/src/boards/Main/BoardScheduler.h
new file mode 100644
index 000000000..ac99d6a68
--- /dev/null
+++ b/src/boards/Main/BoardScheduler.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2024 Skyward Experimental Rocketry
+ * Author: Davide Mor
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <Main/Configs/SchedulerConfig.h>
+#include <scheduler/TaskScheduler.h>
+
+#include <utils/ModuleManager/ModuleManager.hpp>
+
+namespace Main
+{
+
+class BoardScheduler : public Boardcore::Module
+{
+public:
+    BoardScheduler()
+        : nas(Main::Config::NAS_PRIORITY), ada(Main::Config::ADA_PRIORITY),
+          sensors(Main::Config::SENSORS_PRIORITY),
+          others(Main::Config::OTHERS_PRIORITY)
+    {
+    }
+
+    [[nodiscard]] bool start()
+    {
+        return nas.start() && ada.start() && sensors.start() && others.start();
+    }
+
+    Boardcore::TaskScheduler &getNasScheduler() { return nas; }
+
+    Boardcore::TaskScheduler &getAdaScheduler() { return ada; }
+
+    Boardcore::TaskScheduler &getSensorsScheduler() { return sensors; }
+
+    Boardcore::TaskScheduler &getRadioScheduler() { return others; }
+
+    Boardcore::TaskScheduler &getCanBusScheduler() { return others; }
+
+    Boardcore::TaskScheduler &getActuatorsScheduler() { return others; }
+
+private:
+    Boardcore::TaskScheduler nas;
+    Boardcore::TaskScheduler ada;
+    Boardcore::TaskScheduler sensors;
+    Boardcore::TaskScheduler others;
+};
+
+}  // namespace Main
\ No newline at end of file
diff --git a/src/boards/Main/Configs/SchedulerConfig.h b/src/boards/Main/Configs/SchedulerConfig.h
new file mode 100644
index 000000000..88e542925
--- /dev/null
+++ b/src/boards/Main/Configs/SchedulerConfig.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2024 Skyward Experimental Rocketry
+ * Author: Davide Mor
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <miosix.h>
+
+namespace Main
+{
+
+namespace Config
+{
+
+// Used for NAS related activities (state machines/scheduler)
+static const miosix::Priority NAS_PRIORITY = miosix::PRIORITY_MAX - 1;
+// Used for ADA related activities (state machines/scheduler)
+static const miosix::Priority ADA_PRIORITY = miosix::PRIORITY_MAX - 1;
+// Used for Sensors TaskScheduler
+static const miosix::Priority SENSORS_PRIORITY = miosix::PRIORITY_MAX - 2;
+// Used for everything else:
+// - Radio periodic telemetry
+// - CanBus periodic heartbeat
+// - Actuators buzzer
+static const miosix::Priority OTHERS_PRIORITY = miosix::PRIORITY_MAX - 3;
+
+}  // namespace Config
+
+}  // namespace Main
\ No newline at end of file
diff --git a/src/boards/Main/Configs/SensorsConfig.h b/src/boards/Main/Configs/SensorsConfig.h
index e2de8a3e9..f3592922c 100644
--- a/src/boards/Main/Configs/SensorsConfig.h
+++ b/src/boards/Main/Configs/SensorsConfig.h
@@ -43,6 +43,7 @@ namespace LPS22DF
 static constexpr Boardcore::LPS22DF::AVG AVG = Boardcore::LPS22DF::AVG_4;
 static constexpr Boardcore::LPS22DF::ODR ODR = Boardcore::LPS22DF::ODR_100;
 static constexpr uint32_t PERIOD             = 20;  // [ms] 50Hz
+static constexpr bool ENABLED                = true;
 }  // namespace LPS22DF
 
 namespace LPS28DFW
@@ -52,6 +53,7 @@ static constexpr Boardcore::LPS28DFW::FullScaleRange FS =
 static constexpr Boardcore::LPS28DFW::AVG AVG = Boardcore::LPS28DFW::AVG_4;
 static constexpr Boardcore::LPS28DFW::ODR ODR = Boardcore::LPS28DFW::ODR_100;
 static constexpr uint32_t PERIOD              = 20;  // [ms] 50Hz
+static constexpr bool ENABLED                 = true;
 }  // namespace LPS28DFW
 
 namespace H3LIS331DL
@@ -61,6 +63,7 @@ static constexpr Boardcore::H3LIS331DLDefs::OutputDataRate ODR =
 static constexpr Boardcore::H3LIS331DLDefs::FullScaleRange FS =
     Boardcore::H3LIS331DLDefs::FullScaleRange::FS_100;
 static constexpr uint32_t PERIOD = 10;  // [ms] 100Hz
+static constexpr bool ENABLED    = true;
 }  // namespace H3LIS331DL
 
 namespace LIS2MDL
@@ -68,12 +71,14 @@ namespace LIS2MDL
 static constexpr Boardcore::LIS2MDL::ODR ODR = Boardcore::LIS2MDL::ODR_100_HZ;
 static constexpr unsigned int TEMP_DIVIDER   = 5;
 static constexpr uint32_t PERIOD             = 10;  // [ms] 100Hz
+static constexpr bool ENABLED                = true;
 }  // namespace LIS2MDL
 
 namespace UBXGPS
 {
 static constexpr uint32_t PERIOD = 200;  // [ms] 5Hz
-}
+static constexpr bool ENABLED    = true;
+}  // namespace UBXGPS
 
 namespace LSM6DSRX
 {
@@ -92,6 +97,7 @@ static constexpr Boardcore::LSM6DSRXConfig::OPERATING_MODE GYR_OP_MODE =
     Boardcore::LSM6DSRXConfig::OPERATING_MODE::HIGH_PERFORMANCE;
 
 static constexpr uint32_t PERIOD = 20;  // [ms] 50Hz
+static constexpr bool ENABLED    = true;
 }  // namespace LSM6DSRX
 
 namespace ADS131M08
@@ -100,11 +106,13 @@ static constexpr Boardcore::ADS131M08Defs::OversamplingRatio OSR =
     Boardcore::ADS131M08Defs::OversamplingRatio::OSR_8192;
 static constexpr bool GLOBAL_CHOP_MODE_EN = true;
 static constexpr uint32_t PERIOD          = 10;  // [ms] 100Hz
+static constexpr bool ENABLED             = true;
 }  // namespace ADS131M08
 
 namespace InternalADC
 {
 static constexpr uint32_t PERIOD = 100;  // [ms] 10Hz
+static constexpr bool ENABLED    = true;
 
 static constexpr Boardcore::InternalADC::Channel VBAT_CH =
     Boardcore::InternalADC::Channel::CH8;
diff --git a/src/boards/Main/Radio/Radio.cpp b/src/boards/Main/Radio/Radio.cpp
index db3d9453f..b61faa564 100644
--- a/src/boards/Main/Radio/Radio.cpp
+++ b/src/boards/Main/Radio/Radio.cpp
@@ -95,14 +95,14 @@ bool Radio::start()
     }
 
     if (scheduler.addTask([this]() { sendHighRateTelemetry(); },
-                          Config::Radio::TELEMETRY_PERIOD))
+                          Config::Radio::TELEMETRY_PERIOD) == 0)
     {
         LOG_ERR(logger, "Failed to add periodic telemetry task");
         return false;
     }
 
     if (scheduler.addTask([this]() { sendLowRateTelemetry(); },
-                          Config::Radio::TELEMETRY_PERIOD * 2))
+                          Config::Radio::TELEMETRY_PERIOD * 2) == 0)
     {
         LOG_ERR(logger, "Failed to add periodic telemetry task");
         return false;
diff --git a/src/boards/Main/Sensors/Sensors.cpp b/src/boards/Main/Sensors/Sensors.cpp
index 80fe5df09..5c10a1e8a 100644
--- a/src/boards/Main/Sensors/Sensors.cpp
+++ b/src/boards/Main/Sensors/Sensors.cpp
@@ -148,7 +148,8 @@ void Sensors::lps22dfInit(SensorManager::SensorMap_t &map)
                                         spiConfig, config);
 
     SensorInfo info{"LPS22DF", Config::Sensors::LPS22DF::PERIOD,
-                    [this]() { lps22dfCallback(); }};
+                    [this]() { lps22dfCallback(); },
+                    Config::Sensors::LPS22DF::ENABLED};
     map.emplace(lps22df.get(), info);
 }
 
@@ -169,7 +170,8 @@ void Sensors::lps28dfwInit(SensorManager::SensorMap_t &map)
         std::make_unique<LPS28DFW>(modules.get<Buses>()->getLPS28DFW(), config);
 
     SensorInfo info{"LPS28DFW", Config::Sensors::LPS28DFW::PERIOD,
-                    [this]() { lps28dfwCallback(); }};
+                    [this]() { lps28dfwCallback(); },
+                    Config::Sensors::LPS28DFW::ENABLED};
     map.emplace(lps28dfw.get(), info);
 }
 
@@ -190,7 +192,8 @@ void Sensors::h3lis331dlInit(SensorManager::SensorMap_t &map)
         Config::Sensors::H3LIS331DL::FS);
 
     SensorInfo info{"H3LIS331DL", Config::Sensors::H3LIS331DL::PERIOD,
-                    [this]() { h3lis331dlCallback(); }};
+                    [this]() { h3lis331dlCallback(); },
+                    Config::Sensors::H3LIS331DL::ENABLED};
     map.emplace(h3lis331dl.get(), info);
 }
 
@@ -213,7 +216,8 @@ void Sensors::lis2mdlInit(SensorManager::SensorMap_t &map)
                                         spiConfig, config);
 
     SensorInfo info{"LIS2MDL", Config::Sensors::LIS2MDL::PERIOD,
-                    [this]() { lis2mdlCallback(); }};
+                    [this]() { lis2mdlCallback(); },
+                    Config::Sensors::LIS2MDL::ENABLED};
     map.emplace(lis2mdl.get(), info);
 }
 
@@ -231,7 +235,8 @@ void Sensors::ubxgpsInit(SensorManager::SensorMap_t &map)
                                          spiConfig, 5);
 
     SensorInfo info{"UBXGPS", Config::Sensors::UBXGPS::PERIOD,
-                    [this]() { ubxgpsCallback(); }};
+                    [this]() { ubxgpsCallback(); },
+                    Config::Sensors::UBXGPS::ENABLED};
     map.emplace(ubxgps.get(), info);
 }
 
@@ -266,7 +271,8 @@ void Sensors::lsm6dsrxInit(SensorManager::SensorMap_t &map)
                                           spiConfig, config);
 
     SensorInfo info{"LSM6DSRX", Config::Sensors::LSM6DSRX::PERIOD,
-                    [this]() { lsm6dsrxCallback(); }};
+                    [this]() { lsm6dsrxCallback(); },
+                    Config::Sensors::LSM6DSRX::ENABLED};
     map.emplace(lsm6dsrx.get(), info);
 }
 
@@ -303,16 +309,12 @@ void Sensors::ads131m08Init(SensorManager::SensorMap_t &map)
         modules.get<Buses>()->getADS131M08(), sensors::ADS131M08::cs::getPin(),
         spiConfig, config);
 
-    SensorInfo info{"ADS131M08", 2000, [this]() { ads131m08Callback(); }};
+    SensorInfo info{"ADS131M08", 2000, [this]() { ads131m08Callback(); },
+                    Config::Sensors::ADS131M08::ENABLED};
     map.emplace(ads131m08.get(), info);
 }
 
-void Sensors::ads131m08Callback()
-{
-    auto sample = ads131m08->getLastSample();
-    LOG_ERR(logger, "\n{} {} {}", sample.voltage[0], sample.voltage[1],
-            sample.voltage[2]);
-}
+void Sensors::ads131m08Callback() {}
 
 void Sensors::internalAdcInit(Boardcore::SensorManager::SensorMap_t &map)
 {
@@ -326,7 +328,8 @@ void Sensors::internalAdcInit(Boardcore::SensorManager::SensorMap_t &map)
     internalAdc->enableVbat();
 
     SensorInfo info{"InternalADC", Config::Sensors::InternalADC::PERIOD,
-                    [this]() { internalAdcCallback(); }};
+                    [this]() { internalAdcCallback(); },
+                    Config::Sensors::InternalADC::ENABLED};
     map.emplace(internalAdc.get(), info);
 }
 
diff --git a/src/entrypoints/Main/main-entry.cpp b/src/entrypoints/Main/main-entry.cpp
index 75853b32b..2b7106278 100644
--- a/src/entrypoints/Main/main-entry.cpp
+++ b/src/entrypoints/Main/main-entry.cpp
@@ -20,6 +20,7 @@
  * THE SOFTWARE.
  */
 
+#include <Main/BoardScheduler.h>
 #include <Main/Buses.h>
 #include <Main/CanHandler/CanHandler.h>
 #include <Main/Radio/Radio.h>
@@ -36,72 +37,75 @@ using namespace Main;
 
 int main()
 {
+    ledOff();
+
     ModuleManager &modules = ModuleManager::getInstance();
     PrintLogger logger     = Logging::getLogger("main");
 
-    // TODO: Move this to a dedicated board scheduler
-    TaskScheduler *scheduler1 = new TaskScheduler(2);
-    TaskScheduler *scheduler2 = new TaskScheduler(3);
+    Buses *buses              = new Buses();
+    BoardScheduler *scheduler = new BoardScheduler();
 
-    Buses *buses           = new Buses();
-    Sensors *sensors       = new Sensors(*scheduler2);
-    Radio *radio           = new Radio(*scheduler1);
+    Sensors *sensors       = new Sensors(scheduler->getSensorsScheduler());
+    Radio *radio           = new Radio(scheduler->getRadioScheduler());
     CanHandler *canHandler = new CanHandler();
 
-    bool initResult = true;
-
     // Insert modules
-    if (!modules.insert<Buses>(buses))
-    {
-        initResult = false;
-    }
-
-    if (!modules.insert<Sensors>(sensors))
+    bool initResult = modules.insert<Buses>(buses) &&
+                      modules.insert<BoardScheduler>(scheduler) &&
+                      modules.insert<Sensors>(sensors) &&
+                      modules.insert<Radio>(radio) &&
+                      modules.insert<CanHandler>(canHandler);
+
+    // Status led indicators
+    // led1: Sensors ok
+    // led2: Radio ok
+    // led3: CanBus ok
+    // led4: Everything ok
+
+    if (!sensors->start())
     {
         initResult = false;
+        LOG_ERR(logger, "Error failed to start Sensors module");
     }
-
-    if (!modules.insert<Radio>(radio))
-    {
-        initResult = false;
-    }
-
-    if (!modules.insert<CanHandler>(canHandler))
+    else
     {
-        initResult = false;
+        led1On();
     }
 
-    // if (!sensors->start())
-    // {
-    //     initResult = false;
-    //     LOG_ERR(logger, "Error failed to start Sensors module");
-    // }
-
     if (!radio->start())
     {
         initResult = false;
         LOG_ERR(logger, "Error failed to start Radio module");
     }
+    else
+    {
+        led2On();
+    }
 
     if (!canHandler->start())
     {
         initResult = false;
         LOG_ERR(logger, "Error failed to start CanHandler module");
     }
+    else
+    {
+        led3On();
+    }
 
-    if (!scheduler1->start() || !scheduler2->start())
+    if (!scheduler->start())
     {
         initResult = false;
         LOG_ERR(logger, "Error failed to start scheduler");
     }
 
-    if (initResult)
+    if (!initResult)
     {
-        LOG_INFO(logger, "All good!");
+        LOG_ERR(logger, "Init failure!");
     }
     else
     {
-        LOG_ERR(logger, "Init failure!");
+        LOG_INFO(logger, "All good!");
+        led4On();
     }
 
     for (auto info : sensors->getSensorInfo())
-- 
GitLab