diff --git a/CMakeLists.txt b/CMakeLists.txt index f83632ac4302a9d6d131c2ecbac8e211d2711a37..15113e630fb8bae96a18bf3896489d5989593da8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,13 +79,6 @@ add_executable(con_rig-entry src/entrypoints/ConRIG/con_rig-entry.cpp ${CON_RIG_ target_include_directories(con_rig-entry PRIVATE ${OBSW_INCLUDE_DIRS}) sbs_target(con_rig-entry stm32f429zi_con_rig) -add_executable(base-groundstation-entry - src/entrypoints/Groundstation/base-groundstation-entry.cpp - ${GROUNDSTATION_COMMON} ${GROUNDSTATION_BASE} -) -target_include_directories(base-groundstation-entry PRIVATE ${OBSW_INCLUDE_DIRS}) -sbs_target(base-groundstation-entry stm32f767zi_gemini_gs) - add_executable(nokia-groundstation-entry src/entrypoints/Groundstation/nokia-groundstation-entry.cpp ${GROUNDSTATION_COMMON} ${GROUNDSTATION_NOKIA} @@ -97,3 +90,10 @@ sbs_target(nokia-groundstation-entry stm32f429zi_nokia) add_executable(gs-entry src/entrypoints/Gs/gs-entry.cpp ${GS_COMPUTER}) target_include_directories(gs-entry PRIVATE ${OBSW_INCLUDE_DIRS}) sbs_target(gs-entry stm32f767zi_gemini_gs) + +add_executable(base-groundstation-entry + src/entrypoints/Groundstation/base-groundstation-entry.cpp + ${GROUNDSTATION_COMMON} ${GROUNDSTATION_BASE} +) +target_include_directories(base-groundstation-entry PRIVATE ${OBSW_INCLUDE_DIRS}) +sbs_target(base-groundstation-entry stm32f767zi_gemini_gs) \ No newline at end of file diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 1e77239ce7e8cf8273640307e8f2b78a99e37daa..2bc679a566b467a3d245be3657414d17a934bb12 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -42,6 +42,19 @@ set(MAIN_COMPUTER src/boards/Main/StatsRecorder/StatsRecorder.cpp ) +set(GROUNDSTATION_COMMON + src/boards/Groundstation/Base/Radio/Radio.cpp + src/boards/Groundstation/Base/Radio/RadioStatus.cpp + src/boards/Groundstation/Base/Hub.cpp +) + +set(GS_COMPUTER + src/boards/Gs/Ports/Serial.cpp + src/boards/Gs/Radio/Radio.cpp + src/boards/Gs/Radio/RadioStatus.cpp + src/boards/Gs/Hub.cpp +) + set(MOTOR_SOURCES src/boards/Motor/PersistentVars/PersistentVars.cpp src/boards/Motor/HIL/HIL.cpp @@ -111,16 +124,15 @@ set(GROUNDSTATION_NOKIA src/boards/Groundstation/Nokia/Hub.cpp ) -set(GROUNDSTATION_COMMON - src/boards/Groundstation/Common/Ports/Serial.cpp - src/boards/Groundstation/Common/Ports/EthernetBase.cpp - src/boards/Groundstation/Common/Radio/RadioBase.cpp - src/boards/Groundstation/Common/HubBase.cpp -) - set(GS_COMPUTER src/boards/Gs/Ports/Serial.cpp src/boards/Gs/Radio/Radio.cpp src/boards/Gs/Radio/RadioStatus.cpp src/boards/Gs/Hub.cpp +) + +set(GROUNDSTATION_BASE + src/boards/Groundstation/Common/Ports/Serial.cpp + src/boards/Groundstation/Common/Radio/RadioBase.cpp + src/boards/Groundstation/Common/HubBase.cpp ) \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Buses.h b/src/boards/Groundstation/Base/Buses.h index e776148116ef7d9d5a8dd6da54ff568eb840ee23..c6203753989b09e1f2b9b749508bf02a3fdad010 100644 --- a/src/boards/Groundstation/Base/Buses.h +++ b/src/boards/Groundstation/Base/Buses.h @@ -28,7 +28,7 @@ #include "interfaces-impl/hwmapping.h" -namespace GroundstationBase +namespace Groundstation { class Buses : public Boardcore::Module @@ -45,4 +45,4 @@ public: } }; -} // namespace GroundstationBase \ No newline at end of file +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Hub.cpp b/src/boards/Groundstation/Base/Hub.cpp index af0b0608d7006b26b6cb3622a1faa34a85f9c81d..abea1b3d18ec813f01da72d0991a93492bbebc09 100644 --- a/src/boards/Groundstation/Base/Hub.cpp +++ b/src/boards/Groundstation/Base/Hub.cpp @@ -22,54 +22,45 @@ #include "Hub.h" -#include <Groundstation/Base/BoardStatus.h> -#include <Groundstation/Base/Ports/Ethernet.h> -#include <Groundstation/Base/Radio/Radio.h> #include <Groundstation/Common/Config/GeneralConfig.h> #include <Groundstation/Common/Ports/Serial.h> +#include <Groundstation/Base/Radio/Radio.h> +#include <Groundstation/Base/Radio/RadioStatus.h> using namespace Groundstation; -using namespace GroundstationBase; using namespace Boardcore; void Hub::dispatchOutgoingMsg(const mavlink_message_t& msg) { - BoardStatus* status = ModuleManager::getInstance().get<BoardStatus>(); + RadioStatus* status = ModuleManager::getInstance().get<RadioStatus>(); + + // TODO: Dispatch to correct radio using mavlink ids bool send_ok = false; - if (status->isMainRadioPresent() && msg.sysid == MAV_SYSID_MAIN) + if (status->isMainRadioPresent()) { RadioMain* radio = ModuleManager::getInstance().get<RadioMain>(); send_ok |= radio->sendMsg(msg); } - if (status->isPayloadRadioPresent() && msg.sysid == MAV_SYSID_PAYLOAD) + if (status->isPayloadRadioPresent()) { RadioPayload* radio = ModuleManager::getInstance().get<RadioPayload>(); send_ok |= radio->sendMsg(msg); } - (void)send_ok; - // If both of the sends went wrong, just send a nack - // This doesn't work well with multiple GS on the same ethernet network - // if (!send_ok) - // { - // sendNack(msg); - // } + if (!send_ok) + { + sendNack(msg); + } } void Hub::dispatchIncomingMsg(const mavlink_message_t& msg) { - BoardStatus* status = ModuleManager::getInstance().get<BoardStatus>(); - Serial* serial = ModuleManager::getInstance().get<Serial>(); serial->sendMsg(msg); - if (status->isEthernetPresent()) - { - Ethernet* ethernet = ModuleManager::getInstance().get<Ethernet>(); - ethernet->sendMsg(msg); - } + // TODO: Add UDP dispatch } \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Hub.h b/src/boards/Groundstation/Base/Hub.h index c22a7339f62554cc8fc91ae8707fd58f5cb3da05..b17667b1139a6081b78fe0b4f55e02dabde91b11 100644 --- a/src/boards/Groundstation/Base/Hub.h +++ b/src/boards/Groundstation/Base/Hub.h @@ -22,18 +22,18 @@ #pragma once -#include <Groundstation/Common/HubBase.h> #include <common/Mavlink.h> #include <utils/ModuleManager/ModuleManager.hpp> +#include <Groundstation/Common/HubBase.h> -namespace GroundstationBase +namespace Groundstation { /** * @brief Central hub connecting all outgoing and ingoing modules. */ -class Hub : public Groundstation::HubBase +class Hub : public HubBase { public: Hub() {} @@ -51,4 +51,4 @@ public: void dispatchIncomingMsg(const mavlink_message_t& msg) override; }; -} // namespace GroundstationBase \ No newline at end of file +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Radio/Radio.cpp b/src/boards/Groundstation/Base/Radio/Radio.cpp index a8bf2456f544496a8c5c9608fb131fe850fbd0bd..ace3e5a3e0077e645e83540652e3173fdb614f36 100644 --- a/src/boards/Groundstation/Base/Radio/Radio.cpp +++ b/src/boards/Groundstation/Base/Radio/Radio.cpp @@ -22,14 +22,13 @@ #include "Radio.h" -#include <Groundstation/Base/BoardStatus.h> #include <Groundstation/Base/Buses.h> #include <Groundstation/Base/Hub.h> +#include <Groundstation/Base/Radio/RadioStatus.h> #include <Groundstation/Common/Ports/Serial.h> #include <radio/SX1278/SX1278Frontends.h> using namespace Groundstation; -using namespace GroundstationBase; using namespace Boardcore; using namespace miosix; @@ -76,7 +75,7 @@ bool RadioMain::start() std::unique_ptr<Boardcore::SX1278Fsk> sx1278 = std::make_unique<Boardcore::SX1278Fsk>( - ModuleManager::getInstance().get<Buses>()->radio1_bus, + ModuleManager::getInstance().get<Groundstation::Buses>()->radio1_bus, radio1::cs::getPin(), radio1::dio0::getPin(), radio1::dio1::getPin(), radio1::dio3::getPin(), SPI::ClockDivider::DIV_64, std::move(frontend)); @@ -84,7 +83,7 @@ bool RadioMain::start() // First check if the device is even connected bool present = sx1278->checkVersion(); - ModuleManager::getInstance().get<BoardStatus>()->setMainRadioPresent( + ModuleManager::getInstance().get<RadioStatus>()->setMainRadioPresent( present); if (present) @@ -108,7 +107,7 @@ bool RadioMain::start() bool RadioPayload::start() { -#ifdef SKYWARD_GS_PAYLOAD_USE_BACKUP_RF +#ifdef SKYWARD_GS_MAIN_USE_BACKUP_RF std::unique_ptr<SX1278::ISX1278Frontend> frontend = std::make_unique<EbyteFrontend>(radio2::txen::getPin(), radio2::rxen::getPin()); @@ -119,7 +118,7 @@ bool RadioPayload::start() std::unique_ptr<Boardcore::SX1278Fsk> sx1278 = std::make_unique<Boardcore::SX1278Fsk>( - ModuleManager::getInstance().get<Buses>()->radio2_bus, + ModuleManager::getInstance().get<Groundstation::Buses>()->radio2_bus, radio2::cs::getPin(), radio2::dio0::getPin(), radio2::dio1::getPin(), radio2::dio3::getPin(), SPI::ClockDivider::DIV_64, std::move(frontend)); @@ -127,7 +126,7 @@ bool RadioPayload::start() // First check if the device is even connected bool present = sx1278->checkVersion(); - ModuleManager::getInstance().get<BoardStatus>()->setPayloadRadioPresent( + ModuleManager::getInstance().get<RadioStatus>()->setPayloadRadioPresent( present); if (present) diff --git a/src/boards/Groundstation/Base/Radio/Radio.h b/src/boards/Groundstation/Base/Radio/Radio.h index e09d207c9166a97403167b204dc25681b059cc8e..805b1c673d4614190bf2bf1afb440bd7cc29ac59 100644 --- a/src/boards/Groundstation/Base/Radio/Radio.h +++ b/src/boards/Groundstation/Base/Radio/Radio.h @@ -24,19 +24,18 @@ #include <Groundstation/Common/Radio/RadioBase.h> -namespace GroundstationBase -{ +namespace Groundstation { -class RadioMain : public Groundstation::RadioBase, public Boardcore::Module +class RadioMain : public RadioBase, public Boardcore::Module { public: [[nodiscard]] bool start(); }; -class RadioPayload : public Groundstation::RadioBase, public Boardcore::Module +class RadioPayload : public RadioBase, public Boardcore::Module { public: [[nodiscard]] bool start(); }; -} // namespace GroundstationBase \ No newline at end of file +} \ No newline at end of file diff --git a/src/boards/Gs/Radio/RadioStatus.cpp b/src/boards/Groundstation/Base/Radio/RadioStatus.cpp similarity index 93% rename from src/boards/Gs/Radio/RadioStatus.cpp rename to src/boards/Groundstation/Base/Radio/RadioStatus.cpp index fc7dfd7abe4f2e3a4f13d61b89343dd88e38db84..60e5cb68a1601a5ab96dfc415a8cb8ae7ff12ab5 100644 --- a/src/boards/Gs/Radio/RadioStatus.cpp +++ b/src/boards/Groundstation/Base/Radio/RadioStatus.cpp @@ -22,13 +22,14 @@ #include "RadioStatus.h" -#include <Gs/Config/GeneralConfig.h> -#include <Gs/Hub.h> +#include <Groundstation/Base/Radio/Radio.h> +#include <Groundstation/Common/Config/GeneralConfig.h> +#include <Groundstation/Common/HubBase.h> #include <common/Mavlink.h> #include <drivers/timer/TimestampTimer.h> using namespace Boardcore; -using namespace Gs; +using namespace Groundstation; bool RadioStatus::isMainRadioPresent() { return main_radio_present; } bool RadioStatus::isPayloadRadioPresent() { return payload_radio_present; } @@ -102,6 +103,6 @@ void RadioStatus::run() mavlink_msg_receiver_tm_encode(GS_SYSTEM_ID, GS_COMPONENT_ID, &msg, &tm); - ModuleManager::getInstance().get<Hub>()->dispatchIncomingMsg(msg); + ModuleManager::getInstance().get<HubBase>()->dispatchIncomingMsg(msg); } } \ No newline at end of file diff --git a/src/boards/Gs/Radio/RadioStatus.h b/src/boards/Groundstation/Base/Radio/RadioStatus.h similarity index 95% rename from src/boards/Gs/Radio/RadioStatus.h rename to src/boards/Groundstation/Base/Radio/RadioStatus.h index 62eb543094e4d63b20a7a909ff93f1d09c87d166..f9086384f38a6aa3d005205785645fdaf2ae6a3c 100644 --- a/src/boards/Gs/Radio/RadioStatus.h +++ b/src/boards/Groundstation/Base/Radio/RadioStatus.h @@ -23,13 +23,13 @@ #pragma once #include <ActiveObject.h> -#include <Gs/Config/RadioConfig.h> -#include <Gs/Radio/Radio.h> +#include <Groundstation/Common/Config/RadioConfig.h> +#include <Groundstation/Common/Radio/RadioBase.h> #include <utils/collections/CircularBuffer.h> #include <utils/ModuleManager/ModuleManager.hpp> -namespace Gs +namespace Groundstation { /** @@ -109,4 +109,4 @@ private: bool payload_radio_present = false; }; -} // namespace Gs \ No newline at end of file +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Config/RadioConfig.h b/src/boards/Groundstation/Common/Config/RadioConfig.h index c32abe0d514e7145a4f19e319d123f450ba7b25d..cd63868510d0ed0a048c6844ccbd8e5198068ef6 100644 --- a/src/boards/Groundstation/Common/Config/RadioConfig.h +++ b/src/boards/Groundstation/Common/Config/RadioConfig.h @@ -35,7 +35,7 @@ namespace Groundstation constexpr size_t MAV_OUT_QUEUE_SIZE = 10; constexpr size_t MAV_PENDING_OUT_QUEUE_SIZE = 10; -constexpr uint16_t MAV_SLEEP_AFTER_SEND = 5; +constexpr uint16_t MAV_SLEEP_AFTER_SEND = 0; constexpr size_t MAV_OUT_BUFFER_MAX_AGE = 10; /// @brief Every how many ms force the flush of the send queue. diff --git a/src/boards/Groundstation/Common/Ports/Serial.cpp b/src/boards/Groundstation/Common/Ports/Serial.cpp index 45f4b7712016451e394c9ce4284e5bcb8c6fb4ce..017a6783c912653b6ea902f59d82b0c3fccbf873 100644 --- a/src/boards/Groundstation/Common/Ports/Serial.cpp +++ b/src/boards/Groundstation/Common/Ports/Serial.cpp @@ -23,7 +23,6 @@ #include "Serial.h" #include <Groundstation/Common/HubBase.h> -#include <filesystem/console/console_device.h> using namespace miosix; using namespace Groundstation; @@ -31,12 +30,7 @@ using namespace Boardcore; bool Serial::start() { - auto mav_handler = [this](SerialMavDriver* channel, - const mavlink_message_t& msg) { handleMsg(msg); }; - - mav_driver = std::make_unique<SerialMavDriver>(this, mav_handler, 0, 10); - - if (!mav_driver->start()) + if (!ActiveObject::start()) { return false; } @@ -44,28 +38,40 @@ bool Serial::start() return true; } -void Serial::sendMsg(const mavlink_message_t& msg) -{ - if (mav_driver && mav_driver->isStarted()) - { - mav_driver->enqueueMsg(msg); - } -} - -void Serial::handleMsg(const mavlink_message_t& msg) +void Serial::sendMsg(const mavlink_message_t &msg) { - // Dispatch the message through the hub. - ModuleManager::getInstance().get<HubBase>()->dispatchOutgoingMsg(msg); -} + Lock<FastMutex> l(mutex); + uint8_t msg_buf[MAVLINK_NUM_NON_PAYLOAD_BYTES + + MAVLINK_MAX_DIALECT_PAYLOAD_SIZE]; + int msg_len = mavlink_msg_to_send_buffer(msg_buf, &msg); -ssize_t Serial::receive(uint8_t* pkt, size_t max_len) -{ auto serial = miosix::DefaultConsole::instance().get(); - return serial->readBlock(pkt, max_len, 0); + serial->writeBlock(msg_buf, msg_len, 0); } -bool Serial::send(uint8_t* pkt, size_t len) +void Serial::run() { - auto serial = miosix::DefaultConsole::instance().get(); - return serial->writeBlock(pkt, len, 0) != static_cast<ssize_t>(len); + mavlink_message_t msg; + mavlink_status_t status; + uint8_t msg_buf[256]; + + while (!shouldStop()) + { + auto serial = miosix::DefaultConsole::instance().get(); + int rcv_len = serial->readBlock(msg_buf, sizeof(msg_buf), 0); + + for (int i = 0; i < rcv_len; i++) + { + uint8_t parse_result = + mavlink_parse_char(MAVLINK_COMM_0, msg_buf[i], &msg, &status); + + if (parse_result == 1) + { + // Dispatch the message through the hub. + ModuleManager::getInstance() + .get<HubBase>() + ->dispatchOutgoingMsg(msg); + } + } + } } \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Ports/Serial.h b/src/boards/Groundstation/Common/Ports/Serial.h index ea39b639428dd17b623c6e0899ac2cd6c5e7e630..46845b0cdff9778ebb60766376ee5dd37a06833e 100644 --- a/src/boards/Groundstation/Common/Ports/Serial.h +++ b/src/boards/Groundstation/Common/Ports/Serial.h @@ -24,28 +24,21 @@ #include <ActiveObject.h> #include <common/Mavlink.h> -#include <radio/MavlinkDriver/MavlinkDriver.h> +#include <drivers/usart/USART.h> -#include <memory> #include <utils/ModuleManager/ModuleManager.hpp> namespace Groundstation { -using SerialMavDriver = - Boardcore::MavlinkDriver<1024, 10, MAVLINK_MAX_DIALECT_PAYLOAD_SIZE>; - /** * @brief Class responsible for UART communication. */ -class Serial : public Boardcore::Module, public Boardcore::Transceiver +class Serial : public Boardcore::Module, private Boardcore::ActiveObject { public: Serial() {} - /** - * @brief Initialize the serial module. - */ [[nodiscard]] bool start(); /** @@ -53,18 +46,14 @@ public: */ void sendMsg(const mavlink_message_t& msg); -private: +protected: /** - * @brief Called internally when a message is received. + * @brief Internal run method */ - void handleMsg(const mavlink_message_t& msg); - - ssize_t receive(uint8_t* pkt, size_t max_len) override; - - bool send(uint8_t* pkt, size_t len) override; + void run() override; +private: miosix::FastMutex mutex; - std::unique_ptr<SerialMavDriver> mav_driver; }; } // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Radio/RadioBase.cpp b/src/boards/Groundstation/Common/Radio/RadioBase.cpp index 2ff68656c97562e9c05ded77bc908384c89aca03..6a2899a21abedbe8c1b75a956e15b5c4eca8e2bd 100644 --- a/src/boards/Groundstation/Common/Radio/RadioBase.cpp +++ b/src/boards/Groundstation/Common/Radio/RadioBase.cpp @@ -79,12 +79,12 @@ bool RadioBase::start(std::unique_ptr<SX1278Fsk> sx1278) { this->sx1278 = std::move(sx1278); - auto mav_handler = [this](RadioMavDriver* channel, - const mavlink_message_t& msg) { handleMsg(msg); }; + auto mav_handler = [this](MavDriver* channel, const mavlink_message_t& msg) + { handleMsg(msg); }; - mav_driver = std::make_unique<RadioMavDriver>( - this, mav_handler, Groundstation::MAV_SLEEP_AFTER_SEND, - Groundstation::MAV_OUT_BUFFER_MAX_AGE); + mav_driver = + std::make_unique<MavDriver>(this, mav_handler, Groundstation::MAV_SLEEP_AFTER_SEND, + Groundstation::MAV_OUT_BUFFER_MAX_AGE); if (!mav_driver->start()) { @@ -108,7 +108,7 @@ void RadioBase::run() miosix::Thread::sleep(AUTOMATIC_FLUSH_PERIOD); // If enough time has passed, automatically flush. - if (Kernel::getOldTick() > last_eot_packet_ts + AUTOMATIC_FLUSH_DELAY) + if (miosix::getTick() > last_eot_packet_ts + AUTOMATIC_FLUSH_DELAY) { flush(); } @@ -144,7 +144,7 @@ void RadioBase::handleMsg(const mavlink_message_t& msg) if (isEndOfTransmissionPacket(msg)) { - last_eot_packet_ts = Kernel::getOldTick(); + last_eot_packet_ts = miosix::getTick(); flush(); } } diff --git a/src/boards/Groundstation/Common/Radio/RadioBase.h b/src/boards/Groundstation/Common/Radio/RadioBase.h index 3067912106fb345926e74fc8c63039ae43592115..6ffdf6ce4be1f310786f5d32afed86098d5f7ace 100644 --- a/src/boards/Groundstation/Common/Radio/RadioBase.h +++ b/src/boards/Groundstation/Common/Radio/RadioBase.h @@ -35,9 +35,8 @@ namespace Groundstation { -using RadioMavDriver = - Boardcore::MavlinkDriver<Boardcore::SX1278Fsk::MTU, - Groundstation::MAV_OUT_QUEUE_SIZE, +using MavDriver = + Boardcore::MavlinkDriver<Boardcore::SX1278Fsk::MTU, Groundstation::MAV_OUT_QUEUE_SIZE, MAVLINK_MAX_DIALECT_PAYLOAD_SIZE>; /** @@ -122,7 +121,7 @@ private: // Objects are always destructed in reverse order, so keep them in this // order std::unique_ptr<Boardcore::SX1278Fsk> sx1278; - std::unique_ptr<RadioMavDriver> mav_driver; + std::unique_ptr<MavDriver> mav_driver; }; } // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Gs/Buses.h b/src/boards/Gs/Buses.h deleted file mode 100644 index d6cbc9d895c77554ff37e677b68d5f83a643f494..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Buses.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2023 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 <drivers/spi/SPIBus.h> - -#include <utils/ModuleManager/ModuleManager.hpp> - -#include "interfaces-impl/hwmapping.h" - -namespace Gs -{ - -class Buses : public Boardcore::Module -{ -public: - Boardcore::SPIBus radio1_bus; - Boardcore::SPIBus radio2_bus; - Boardcore::SPIBus ethernet_bus; - - Buses() - : radio1_bus(MIOSIX_RADIO1_SPI), radio2_bus(MIOSIX_RADIO2_SPI), - ethernet_bus(MIOSIX_ETHERNET_SPI) - { - } -}; - -} // namespace Gs \ No newline at end of file diff --git a/src/boards/Gs/Config/GeneralConfig.h b/src/boards/Gs/Config/GeneralConfig.h deleted file mode 100644 index f10454b845ac425161887c3d9a1720fc7eef7e17..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Config/GeneralConfig.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2023 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 <cstdint> - -namespace Gs -{ - -constexpr uint8_t GS_COMPONENT_ID = 1; -constexpr uint8_t GS_SYSTEM_ID = 1; - -} // namespace Gs \ No newline at end of file diff --git a/src/boards/Gs/Config/RadioConfig.h b/src/boards/Gs/Config/RadioConfig.h deleted file mode 100644 index 58f19acdaea818c8621c0f15a9c3e167f2f4e503..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Config/RadioConfig.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2023 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 <cstddef> -#include <cstdint> - -// Uncomment the following line to enable backup RF for main -// #define SKYWARD_GS_MAIN_USE_BACKUP_RF -// Uncomment the following line to enable backup RF for payload -// #define SKYWARD_GS_PAYLOAD_USE_BACKUP_RF - -namespace Gs -{ - -constexpr size_t MAV_OUT_QUEUE_SIZE = 10; -constexpr size_t MAV_PENDING_OUT_QUEUE_SIZE = 10; -constexpr uint16_t MAV_SLEEP_AFTER_SEND = 0; -constexpr size_t MAV_OUT_BUFFER_MAX_AGE = 10; - -/// @brief Every how many ms force the flush of the send queue. -constexpr unsigned int AUTOMATIC_FLUSH_PERIOD = 250; -/// @brief After how many ms stop waiting for the other side to send commands. -constexpr long long AUTOMATIC_FLUSH_DELAY = 2000; - -/// @brief Period of the radio status telemetry. -constexpr unsigned int RADIO_STATUS_PERIOD = 250; -/// @brief Size in ms of the radio moving bitrate window size. -constexpr size_t RADIO_BITRATE_WINDOW_SIZE = 1000; - -} // namespace Gs diff --git a/src/boards/Gs/Config/SerialConfig.h b/src/boards/Gs/Config/SerialConfig.h deleted file mode 100644 index 5f8ea370d0b11667e02b351ec6ea73178967573e..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Config/SerialConfig.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2023 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 - -namespace Gs -{ - -constexpr int SERIAL_BAUD_RATE = 115200; - -} // namespace Gs \ No newline at end of file diff --git a/src/boards/Gs/Hub.cpp b/src/boards/Gs/Hub.cpp deleted file mode 100644 index cb2649f46f6e3b7d49254684c7ca0c7dab47031b..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Hub.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2023 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. - */ - -#include "Hub.h" - -#include <Gs/Config/GeneralConfig.h> -#include <Gs/Ports/Serial.h> -#include <Gs/Radio/Radio.h> -#include <Gs/Radio/RadioStatus.h> - -using namespace Gs; -using namespace Boardcore; - -void Hub::dispatchOutgoingMsg(const mavlink_message_t& msg) -{ - RadioStatus* status = ModuleManager::getInstance().get<RadioStatus>(); - - // TODO: Dispatch to correct radio using mavlink ids - - bool send_ok = false; - - if (status->isMainRadioPresent()) - { - RadioMain* radio = ModuleManager::getInstance().get<RadioMain>(); - send_ok |= radio->sendMsg(msg); - } - - if (status->isPayloadRadioPresent()) - { - RadioPayload* radio = ModuleManager::getInstance().get<RadioPayload>(); - send_ok |= radio->sendMsg(msg); - } - - // If both of the sends went wrong, just send a nack - if (!send_ok) - { - sendNack(msg); - } -} - -void Hub::dispatchIncomingMsg(const mavlink_message_t& msg) -{ - Serial* serial = ModuleManager::getInstance().get<Serial>(); - serial->sendMsg(msg); - - // TODO: Add UDP dispatch -} - -void Hub::sendNack(const mavlink_message_t& msg) -{ - mavlink_message_t nack_msg; - mavlink_msg_nack_tm_pack(GS_SYSTEM_ID, GS_COMPONENT_ID, &nack_msg, - msg.msgid, msg.seq); - - dispatchIncomingMsg(nack_msg); -} \ No newline at end of file diff --git a/src/boards/Gs/Hub.h b/src/boards/Gs/Hub.h deleted file mode 100644 index fdb950cd56d44c63884f4a16ecc986ed9681213f..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Hub.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2023 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 <common/Mavlink.h> - -#include <utils/ModuleManager/ModuleManager.hpp> - -namespace Gs -{ - -/** - * @brief Central hub connecting all outgoing and ingoing modules. - */ -class Hub : public Boardcore::Module -{ -public: - Hub() {} - - /** - * @brief Dispatch to the correct interface and outgoing packet (gs -> - * rocket). - */ - void dispatchOutgoingMsg(const mavlink_message_t& msg); - - /** - * @brief Dispatch to the correct interface and incoming packet (rocket -> - * gs). - */ - void dispatchIncomingMsg(const mavlink_message_t& msg); - -private: - /** - * @brief Used internally to signal to the gs computer that something went - * wrong, and the packet could not be delivered. - */ - void sendNack(const mavlink_message_t& msg); -}; - -} // namespace Gs \ No newline at end of file diff --git a/src/boards/Gs/Ports/Serial.cpp b/src/boards/Gs/Ports/Serial.cpp deleted file mode 100644 index 96e7e0fb891b954637dcc941b5197001c5fb1d22..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Ports/Serial.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2023 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. - */ - -#include "Serial.h" - -#include <Gs/Hub.h> -#include <Gs/Radio/Radio.h> -#include <Gs/Radio/RadioStatus.h> - -using namespace miosix; -using namespace Gs; -using namespace Boardcore; - -bool Serial::start() -{ - if (!ActiveObject::start()) - { - return false; - } - - return true; -} - -void Serial::sendMsg(const mavlink_message_t &msg) -{ - Lock<FastMutex> l(mutex); - uint8_t msg_buf[MAVLINK_NUM_NON_PAYLOAD_BYTES + - MAVLINK_MAX_DIALECT_PAYLOAD_SIZE]; - int msg_len = mavlink_msg_to_send_buffer(msg_buf, &msg); - - auto serial = miosix::DefaultConsole::instance().get(); - serial->writeBlock(msg_buf, msg_len, 0); -} - -void Serial::run() -{ - mavlink_message_t msg; - mavlink_status_t status; - uint8_t msg_buf[256]; - - while (!shouldStop()) - { - auto serial = miosix::DefaultConsole::instance().get(); - int rcv_len = serial->readBlock(msg_buf, sizeof(msg_buf), 0); - - for (int i = 0; i < rcv_len; i++) - { - uint8_t parse_result = - mavlink_parse_char(MAVLINK_COMM_0, msg_buf[i], &msg, &status); - - if (parse_result == 1) - { - // Dispatch the message through the hub. - ModuleManager::getInstance().get<Hub>()->dispatchOutgoingMsg( - msg); - } - } - } -} \ No newline at end of file diff --git a/src/boards/Gs/Ports/Serial.h b/src/boards/Gs/Ports/Serial.h deleted file mode 100644 index 8d5832666db5a95e04ed0dbb90670ec4299352e3..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Ports/Serial.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2023 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 <ActiveObject.h> -#include <Gs/Config/SerialConfig.h> -#include <common/Mavlink.h> -#include <drivers/usart/USART.h> - -#include <utils/ModuleManager/ModuleManager.hpp> - -namespace Gs -{ - -/** - * @brief Class responsible for UART communication. - */ -class Serial : public Boardcore::Module, private Boardcore::ActiveObject -{ -public: - Serial() {} - - [[nodiscard]] bool start(); - - /** - * @brief Send a mavlink message through this port. - */ - void sendMsg(const mavlink_message_t& msg); - -protected: - /** - * @brief Internal run method - */ - void run() override; - -private: - miosix::FastMutex mutex; -}; - -} // namespace Gs \ No newline at end of file diff --git a/src/boards/Gs/Radio/Radio.cpp b/src/boards/Gs/Radio/Radio.cpp deleted file mode 100644 index 943d71ef5ab69f6cf3080d155ba99838b8c63210..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Radio/Radio.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (c) 2023 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. - */ - -#include "Radio.h" - -#include <Gs/Buses.h> -#include <Gs/Hub.h> -#include <Gs/Ports/Serial.h> -#include <Gs/Radio/RadioStatus.h> -#include <radio/SX1278/SX1278Frontends.h> - -using namespace miosix; -using namespace Gs; -using namespace Boardcore; - -void __attribute__((used)) MIOSIX_RADIO1_DIO0_IRQ() -{ - ModuleManager::getInstance().get<RadioMain>()->handleDioIRQ(); -} - -void __attribute__((used)) MIOSIX_RADIO1_DIO1_IRQ() -{ - ModuleManager::getInstance().get<RadioMain>()->handleDioIRQ(); -} - -void __attribute__((used)) MIOSIX_RADIO1_DIO3_IRQ() -{ - ModuleManager::getInstance().get<RadioMain>()->handleDioIRQ(); -} - -void __attribute__((used)) MIOSIX_RADIO2_DIO0_IRQ() -{ - ModuleManager::getInstance().get<RadioPayload>()->handleDioIRQ(); -} - -void __attribute__((used)) MIOSIX_RADIO2_DIO1_IRQ() -{ - ModuleManager::getInstance().get<RadioPayload>()->handleDioIRQ(); -} - -void __attribute__((used)) MIOSIX_RADIO2_DIO3_IRQ() -{ - ModuleManager::getInstance().get<RadioPayload>()->handleDioIRQ(); -} - -bool RadioBase::sendMsg(const mavlink_message_t& msg) -{ - Lock<FastMutex> l(pending_msgs_mutex); - if (pending_msgs_count >= MAV_PENDING_OUT_QUEUE_SIZE) - { - return false; - } - else - { - pending_msgs[pending_msgs_count] = msg; - pending_msgs_count += 1; - - return true; - } -} - -void RadioBase::handleDioIRQ() -{ - if (started) - { - sx1278->handleDioIRQ(); - } -} - -RadioStats RadioBase::getStats() -{ - if (started) - { - auto mav_stats = mav_driver->getStatus(); - - return {.send_errors = mav_stats.nSendErrors, - .packet_rx_success_count = - mav_stats.mavStats.packet_rx_success_count, - .packet_rx_drop_count = mav_stats.mavStats.packet_rx_drop_count, - .bits_rx_count = bits_rx_count, - .bits_tx_count = bits_tx_count, - .rx_rssi = sx1278->getLastRxRssi(), - .rx_fei = sx1278->getLastRxFei()}; - } - else - { - return {0}; - } -} - -bool RadioBase::start(std::unique_ptr<SX1278Fsk> sx1278, - const SX1278Fsk::Config& config) -{ - this->sx1278 = std::move(sx1278); - - // Configure the radio - if (this->sx1278->configure(config) != SX1278Fsk::Error::NONE) - { - return false; - } - - auto mav_handler = [this](MavDriver* channel, const mavlink_message_t& msg) - { handleMsg(msg); }; - - mav_driver = - std::make_unique<MavDriver>(this, mav_handler, Gs::MAV_SLEEP_AFTER_SEND, - Gs::MAV_OUT_BUFFER_MAX_AGE); - - if (!mav_driver->start()) - { - return false; - } - - if (!ActiveObject::start()) - { - return false; - } - - started = true; - return true; -} - -bool RadioMain::start() -{ -#ifdef SKYWARD_GS_MAIN_USE_BACKUP_RF - std::unique_ptr<SX1278::ISX1278Frontend> frontend = - std::make_unique<EbyteFrontend>(radio1::txen::getPin(), - radio1::rxen::getPin()); -#else - std::unique_ptr<SX1278::ISX1278Frontend> frontend = - std::make_unique<Skyward433Frontend>(); -#endif - - std::unique_ptr<Boardcore::SX1278Fsk> sx1278 = - std::make_unique<Boardcore::SX1278Fsk>( - ModuleManager::getInstance().get<Gs::Buses>()->radio1_bus, - radio1::cs::getPin(), radio1::dio0::getPin(), - radio1::dio1::getPin(), radio1::dio3::getPin(), - SPI::ClockDivider::DIV_64, std::move(frontend)); - - // First check if the device is even connected - RadioStatus* status = ModuleManager::getInstance().get<RadioStatus>(); - // Set if the device is present - status->setMainRadioPresent(sx1278->checkVersion()); - - if (status->isMainRadioPresent()) - { - // Initialize if only if present - if (!RadioBase::start(std::move(sx1278), Common::MAIN_RADIO_CONFIG)) - { - return false; - } - } - - return true; -} - -bool RadioPayload::start() -{ -#ifdef SKYWARD_GS_MAIN_USE_BACKUP_RF - std::unique_ptr<SX1278::ISX1278Frontend> frontend = - std::make_unique<EbyteFrontend>(radio2::txen::getPin(), - radio2::rxen::getPin()); -#else - std::unique_ptr<SX1278::ISX1278Frontend> frontend = - std::make_unique<Skyward433Frontend>(); -#endif - - std::unique_ptr<Boardcore::SX1278Fsk> sx1278 = - std::make_unique<Boardcore::SX1278Fsk>( - ModuleManager::getInstance().get<Gs::Buses>()->radio2_bus, - radio2::cs::getPin(), radio2::dio0::getPin(), - radio2::dio1::getPin(), radio2::dio3::getPin(), - SPI::ClockDivider::DIV_64, std::move(frontend)); - - // First check if the device is even connected - RadioStatus* status = ModuleManager::getInstance().get<RadioStatus>(); - // Set if the device is present - status->setPayloadRadioPresent(sx1278->checkVersion()); - - if (status->isPayloadRadioPresent()) - { - // Initialize if only if present - if (!RadioBase::start(std::move(sx1278), Common::PAYLOAD_RADIO_CONFIG)) - { - return false; - } - } - - return true; -} - -void RadioBase::run() -{ - - while (!shouldStop()) - { - miosix::Thread::sleep(AUTOMATIC_FLUSH_PERIOD); - - // If enough time has passed, automatically flush. - if (miosix::getTick() > last_eot_packet_ts + AUTOMATIC_FLUSH_DELAY) - { - flush(); - } - } -} - -ssize_t RadioBase::receive(uint8_t* pkt, size_t max_len) -{ - ssize_t ret = sx1278->receive(pkt, max_len); - if (ret > 0) - { - bits_rx_count += ret * 8; - } - - return ret; -} - -bool RadioBase::send(uint8_t* pkt, size_t len) -{ - bool ret = sx1278->send(pkt, len); - if (ret) - { - bits_tx_count += len * 8; - } - - return ret; -} - -void RadioBase::handleMsg(const mavlink_message_t& msg) -{ - // Dispatch the message through the hub. - ModuleManager::getInstance().get<Hub>()->dispatchIncomingMsg(msg); - - if (isEndOfTransmissionPacket(msg)) - { - last_eot_packet_ts = miosix::getTick(); - flush(); - } -} - -void RadioBase::flush() -{ - Lock<FastMutex> l(pending_msgs_mutex); - for (size_t i = 0; i < pending_msgs_count; i++) - { - mav_driver->enqueueMsg(pending_msgs[i]); - } - - pending_msgs_count = 0; -} - -bool RadioBase::isEndOfTransmissionPacket(const mavlink_message_t& msg) -{ - return msg.msgid == MAVLINK_MSG_ID_ROCKET_FLIGHT_TM || - msg.msgid == MAVLINK_MSG_ID_PAYLOAD_FLIGHT_TM; -} \ No newline at end of file diff --git a/src/boards/Gs/Radio/Radio.h b/src/boards/Gs/Radio/Radio.h deleted file mode 100644 index 617dfd01887bdb119a26c860e44b1ba58f8e169e..0000000000000000000000000000000000000000 --- a/src/boards/Gs/Radio/Radio.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Copyright (c) 2023 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 <ActiveObject.h> -#include <Gs/Config/RadioConfig.h> -#include <common/Mavlink.h> -#include <common/Radio.h> -#include <radio/MavlinkDriver/MavlinkDriver.h> -#include <radio/SX1278/SX1278Fsk.h> - -#include <memory> -#include <utils/ModuleManager/ModuleManager.hpp> - -namespace Gs -{ - -using MavDriver = - Boardcore::MavlinkDriver<Boardcore::SX1278Fsk::MTU, Gs::MAV_OUT_QUEUE_SIZE, - MAVLINK_MAX_DIALECT_PAYLOAD_SIZE>; - -/** - * @brief Statistics of the radio. - */ -struct RadioStats -{ - uint16_t send_errors; //< Number of failed sends. - uint16_t packet_rx_success_count; //< Number of received packets. - uint16_t packet_rx_drop_count; //< Number of packet drops. - uint32_t bits_rx_count; //< Number of bits received. - uint32_t bits_tx_count; //< Number of bits sent. - float rx_rssi; //< RSSI in dBm of last received packet. - float rx_fei; //< Frequency error index in Hz of last received packet. -}; - -/** - * @brief Base radio class, used to implement functionality independent of - * main/payload radios. - */ -class RadioBase : private Boardcore::ActiveObject, public Boardcore::Transceiver -{ -public: - RadioBase() {} - - /** - * @brief Send a mavlink message through this radio. - * - * @returns false when the queue is full. - */ - bool sendMsg(const mavlink_message_t& msg); - - /** - * @brief Handle generic DIO irq. - */ - void handleDioIRQ(); - - /** - * @brief Retrieve current statistics metrics. - */ - RadioStats getStats(); - -protected: - /** - * @brief Initialize this radio module. - * - * Used in RadioMain/RadioPayload to initialize the correct device with the - * correct config. - */ - bool start(std::unique_ptr<Boardcore::SX1278Fsk> sx1278, - const Boardcore::SX1278Fsk::Config& config); - -private: - void run() override; - - ssize_t receive(uint8_t* pkt, size_t max_len) override; - - bool send(uint8_t* pkt, size_t len) override; - - /** - * @brief Called internally when a message is received. - */ - void handleMsg(const mavlink_message_t& msg); - - /** - * @brief Flush all pending messages. - */ - void flush(); - - /** - * @brief Check if a message signals an end of trasmissiont - */ - bool isEndOfTransmissionPacket(const mavlink_message_t& msg); - - bool started = false; - - miosix::FastMutex pending_msgs_mutex; - mavlink_message_t pending_msgs[Gs::MAV_PENDING_OUT_QUEUE_SIZE]; - size_t pending_msgs_count = 0; - - long long last_eot_packet_ts = 0; - - uint32_t bits_rx_count = 0; - uint32_t bits_tx_count = 0; - - // Objects are always destructed in reverse order, so keep them in this - // order - std::unique_ptr<Boardcore::SX1278Fsk> sx1278; - std::unique_ptr<MavDriver> mav_driver; -}; - -class RadioMain : public RadioBase, public Boardcore::Module -{ -public: - [[nodiscard]] bool start(); -}; - -class RadioPayload : public RadioBase, public Boardcore::Module -{ -public: - [[nodiscard]] bool start(); -}; - -} // namespace Gs \ No newline at end of file diff --git a/src/entrypoints/Groundstation/base-groundstation-entry.cpp b/src/entrypoints/Groundstation/base-groundstation-entry.cpp index 99b7374fcdf25f5f52de7378682f9f132abf8f4e..48d92498d742f90724c6f38871faf1630ebfcd48 100644 --- a/src/entrypoints/Groundstation/base-groundstation-entry.cpp +++ b/src/entrypoints/Groundstation/base-groundstation-entry.cpp @@ -20,24 +20,22 @@ * THE SOFTWARE. */ -#include <Groundstation/Base/BoardStatus.h> #include <Groundstation/Base/Buses.h> #include <Groundstation/Base/Hub.h> -#include <Groundstation/Base/Ports/Ethernet.h> #include <Groundstation/Base/Radio/Radio.h> +#include <Groundstation/Base/Radio/RadioStatus.h> #include <Groundstation/Common/Ports/Serial.h> #include <miosix.h> using namespace Groundstation; -using namespace GroundstationBase; using namespace Boardcore; using namespace miosix; -void idleLoop() +void spinLoop() { while (1) { - Thread::wait(); + Thread::sleep(1000); } } @@ -59,10 +57,9 @@ int main() Hub *hub = new Hub(); Buses *buses = new Buses(); Serial *serial = new Serial(); - Ethernet *ethernet = new Ethernet(); RadioMain *radio_main = new RadioMain(); RadioPayload *radio_payload = new RadioPayload(); - BoardStatus *board_status = new BoardStatus(); + RadioStatus *radio_status = new RadioStatus(); ModuleManager &modules = ModuleManager::getInstance(); @@ -71,10 +68,9 @@ int main() ok &= modules.insert<HubBase>(hub); ok &= modules.insert(buses); ok &= modules.insert(serial); - ok &= modules.insert(ethernet); ok &= modules.insert(radio_main); ok &= modules.insert(radio_payload); - ok &= modules.insert(board_status); + ok &= modules.insert(radio_status); // If insertion failed, stop right here if (!ok) @@ -91,12 +87,6 @@ int main() printf("[error] Failed to start serial!\n"); } - ok &= ethernet->start(); - if (!ok) - { - printf("[error] Failed to start ethernet!\n"); - } - ok &= radio_main->start(); if (!ok) { @@ -109,35 +99,28 @@ int main() printf("[error] Failed to start payload radio!\n"); } - ok &= board_status->start(); + ok &= radio_status->start(); if (!ok) { - printf("[error] Failed to start board status!\n"); + printf("[error] Failed to start radio status!\n"); } - if (board_status->isMainRadioPresent()) + if (radio_status->isMainRadioPresent()) { - printf("Main radio detected!\n"); led2On(); } - if (board_status->isPayloadRadioPresent()) + if (radio_status->isPayloadRadioPresent()) { - printf("Payload radio detected!\n"); led3On(); } - if (board_status->isEthernetPresent()) - { - printf("Ethernet detected!\n"); - } - if (!ok) { errorLoop(); } led1On(); - idleLoop(); + spinLoop(); return 0; } \ No newline at end of file diff --git a/src/entrypoints/Gs/gs-entry.cpp b/src/entrypoints/Gs/gs-entry.cpp deleted file mode 100644 index c9cee870872d2241a880db20e24ef13aa683f4d2..0000000000000000000000000000000000000000 --- a/src/entrypoints/Gs/gs-entry.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright (c) 2023 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. - */ - -#include <Gs/Buses.h> -#include <Gs/Ports/Serial.h> -#include <Gs/Radio/Radio.h> -#include <Gs/Radio/RadioStatus.h> -#include <miosix.h> - -using namespace Gs; -using namespace Boardcore; - -// FIXME: Temporary hack waiting for IRQ fix. -// #define DISABLE_MAIN_RADIO -#define DISABLE_PAYLOAD_RADIO - -void spinLoop() -{ - while (1) - { - miosix::Thread::sleep(1000); - } -} - -void errorLoop() -{ - while (1) - { - miosix::led1On(); - miosix::Thread::sleep(100); - miosix::led1Off(); - miosix::Thread::sleep(100); - } -} - -int main() -{ - miosix::ledOff(); - - Buses *buses = new Buses(); - Serial *serial = new Serial(); -#ifndef DISABLE_MAIN_RADIO - RadioMain *radio_main = new RadioMain(); -#endif -#ifndef DISABLE_PAYLOAD_RADIO - RadioPayload *radio_payload = new RadioPayload(); -#endif - RadioStatus *radio_status = new RadioStatus(); - - ModuleManager &modules = ModuleManager::getInstance(); - - bool ok = true; - - ok &= modules.insert(buses); - ok &= modules.insert(serial); -#ifndef DISABLE_MAIN_RADIO - ok &= modules.insert(radio_main); -#endif -#ifndef DISABLE_PAYLOAD_RADIO - ok &= modules.insert(radio_payload); -#endif - ok &= modules.insert(radio_status); - - // If insertion failed, stop right here - if (!ok) - { - printf("[error] Failed to insert all modules!\n"); - errorLoop(); - } - - // Ok now start them - - ok &= serial->start(); - if (!ok) - { - printf("[error] Failed to start serial!\n"); - } - -#ifndef DISABLE_MAIN_RADIO - ok &= radio_main->start(); - if (!ok) - { - printf("[error] Failed to start main radio!\n"); - } -#endif - -#ifndef DISABLE_PAYLOAD_RADIO - ok &= radio_payload->start(); - if (!ok) - { - printf("[error] Failed to start payload radio!\n"); - } -#endif - - ok &= radio_status->start(); - if (!ok) - { - printf("[error] Failed to start radio status!\n"); - } - - if (radio_status->isMainRadioPresent()) - { - miosix::led2On(); - } - - if (radio_status->isPayloadRadioPresent()) - { - miosix::led3On(); - } - - if (!ok) - { - errorLoop(); - } - - miosix::led1On(); - spinLoop(); - return 0; -} \ No newline at end of file