diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 94d0850d8867b04e774e33ee911382d074d8f2fc..74b7c3142b06876e4ffd041b775273d43340eaf6 100755 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -763,6 +763,52 @@ "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery", "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery" ] + }, + { + "name": "stm32f767zi_gemini_gs", + "cStandard": "c11", + "cppStandard": "c++14", + "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", + "defines": [ + "{defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_gemini_gs", + "_BOARD_STM32F767ZI_GEMINI_GS", + "_ARCH_CORTEXM7_STM32F7", + "STM32F769xx", + "HSE_VALUE=25000000", + "SYSCLK_FREQ_216MHz=216000000", + "__ENABLE_XRAM", + "V_DDA_VOLTAGE=3.3f" + ], + "includePath": [ + "${defaultIncludePaths}", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f767zi_gemini_gs", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_gemini_gs" + ] + }, + { + "name": "stm32f429zi_skyward_groundstation_v2", + "cStandard": "c11", + "cppStandard": "c++14", + "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", + "defines": [ + "{defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_skyward_groundstation_v2", + "_BOARD_STM32F429ZI_SKYWARD_GS_V2", + "_ARCH_CORTEXM4_STM32F4", + "STM32F429xx", + "HSE_VALUE=8000000", + "SYSCLK_FREQ_168MHz=168000000", + "__ENABLE_XRAM", + "V_DDA_VOLTAGE=3.0f" + ], + "includePath": [ + "${defaultIncludePaths}", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2", + "${workspaceFolder}/skyward-boardcore/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2" + ] } ], "version": 4 diff --git a/.vscode/settings.json b/.vscode/settings.json index 6c2786aa3dce9c51c5660c36873f7ab01e2a8e4b..a51e6cc187fb81ae22cabe4c3fa1497faa877e3e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -118,13 +118,6 @@ "numbers": "cpp", "semaphore": "cpp" }, - "editor.formatOnSave": true, - "[c]": { - "editor.formatOnSave": false - }, - "[cmake]": { - "editor.formatOnSave": false - }, "cSpell.words": [ "Aeroutils", "AIRBRAKES", @@ -152,6 +145,7 @@ "Duca", "Eigen", "EXTI", + "Gpio", "GPIOF", "KALM", "kalman", @@ -161,6 +155,7 @@ "MPXH", "Nidasio", "pitot", + "RSSI", "SATS", "setb", "Setpoint", diff --git a/CMakeLists.txt b/CMakeLists.txt index 65a2c2f39dcc2afed86092df03fcbe3658d809c1..bb34a759c97938be60a951c975b88d18189764c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,3 +73,17 @@ sbs_target(rig-entry stm32f429zi_skyward_rig) add_executable(con_rig-entry src/entrypoints/con_RIG/con_rig-entry.cpp ${CON_RIG_COMPUTER}) target_include_directories(con_rig-entry PRIVATE ${OBSW_INCLUDE_DIRS}) sbs_target(con_rig-entry stm32f429zi_stm32f4discovery) + +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} +) +target_include_directories(nokia-groundstation-entry PRIVATE ${OBSW_INCLUDE_DIRS}) +sbs_target(nokia-groundstation-entry stm32f429zi_skyward_groundstation_v2) diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 65860823f9cd53c58948c5d92b194c6c28dc06c5..41e4ba50104153efdbed696ce42c47d2b654a726 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -95,3 +95,22 @@ set(PAYLOAD_COMPUTER src/boards/Payload/Sensors/RotatedIMU/RotatedIMU.cpp src/boards/Payload/WindEstimationScheme/WindEstimation.cpp ) + +set(GROUNDSTATION_BASE + src/boards/Groundstation/Base/Radio/Radio.cpp + src/boards/Groundstation/Base/Ports/Ethernet.cpp + src/boards/Groundstation/Base/BoardStatus.cpp + src/boards/Groundstation/Base/Hub.cpp +) + +set(GROUNDSTATION_NOKIA + src/boards/Groundstation/Nokia/Radio/Radio.cpp + 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 +) diff --git a/src/boards/Groundstation/Base/BoardStatus.cpp b/src/boards/Groundstation/Base/BoardStatus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8fb81e1e4cba8715d87f4039f07fa4f98ec5d15 --- /dev/null +++ b/src/boards/Groundstation/Base/BoardStatus.cpp @@ -0,0 +1,128 @@ +/* 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 "BoardStatus.h" + +#include <Groundstation/Base/Ports/Ethernet.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 Groundstation; +using namespace GroundstationBase; + +bool BoardStatus::isMainRadioPresent() { return main_radio_present; } +bool BoardStatus::isPayloadRadioPresent() { return payload_radio_present; } +bool BoardStatus::isEthernetPresent() { return ethernet_present; } + +bool BoardStatus::start() +{ + if (!ActiveObject::start()) + { + return false; + } + + return true; +} + +void BoardStatus::setMainRadioPresent(bool present) +{ + main_radio_present = present; +} + +void BoardStatus::setPayloadRadioPresent(bool present) +{ + payload_radio_present = present; +} + +void BoardStatus::setEthernetPresent(bool present) +{ + ethernet_present = present; +} + +void BoardStatus::run() +{ + while (!shouldStop()) + { + miosix::Thread::sleep(RADIO_STATUS_PERIOD); + + mavlink_receiver_tm_t tm = {0}; + tm.timestamp = TimestampTimer::getTimestamp(); + tm.battery_voltage = -420.0; + + if (main_radio_present) + { + tm.main_radio_present = 1; + + auto stats = + ModuleManager::getInstance().get<RadioMain>()->getStats(); + tm.main_packet_tx_error_count = stats.send_errors; + tm.main_tx_bitrate = main_tx_bitrate.update(stats.bits_tx_count); + tm.main_packet_rx_success_count = stats.packet_rx_success_count; + tm.main_packet_rx_drop_count = stats.packet_rx_drop_count; + tm.main_rx_bitrate = main_rx_bitrate.update(stats.bits_rx_count); + tm.main_rx_rssi = stats.rx_rssi; + tm.main_rx_fei = stats.rx_fei; + + last_main_stats = stats; + } + + if (payload_radio_present) + { + tm.payload_radio_present = 1; + + auto stats = + ModuleManager::getInstance().get<RadioPayload>()->getStats(); + tm.payload_packet_tx_error_count = stats.send_errors; + tm.payload_tx_bitrate = + payload_tx_bitrate.update(stats.bits_tx_count); + tm.payload_packet_rx_success_count = stats.packet_rx_success_count; + tm.payload_packet_rx_drop_count = stats.packet_rx_drop_count; + tm.payload_rx_bitrate = + payload_rx_bitrate.update(stats.bits_rx_count); + tm.payload_rx_rssi = stats.rx_rssi; + tm.payload_rx_fei = stats.rx_fei; + + last_payload_stats = stats; + } + + if (ethernet_present) + { + auto stats = + ModuleManager::getInstance().get<Ethernet>()->getState(); + + tm.ethernet_present = 1; + tm.ethernet_status = (stats.link_up ? 1 : 0) | + (stats.full_duplex ? 2 : 0) | + (stats.based_100mbps ? 4 : 0); + } + + mavlink_message_t msg; + mavlink_msg_receiver_tm_encode(GS_SYSTEM_ID, GS_COMPONENT_ID, &msg, + &tm); + + ModuleManager::getInstance().get<HubBase>()->dispatchIncomingMsg(msg); + } +} \ No newline at end of file diff --git a/src/boards/Groundstation/Base/BoardStatus.h b/src/boards/Groundstation/Base/BoardStatus.h new file mode 100644 index 0000000000000000000000000000000000000000..c684a33193256e2fdde4041c28ce41c27820fbe9 --- /dev/null +++ b/src/boards/Groundstation/Base/BoardStatus.h @@ -0,0 +1,123 @@ +/* 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 <Groundstation/Common/Config/RadioConfig.h> +#include <Groundstation/Common/Radio/RadioBase.h> +#include <utils/collections/CircularBuffer.h> + +#include <utils/ModuleManager/ModuleManager.hpp> + +namespace GroundstationBase +{ + +/** + * @brief Utility to calculate the bitrate + */ +template <unsigned int WINDOW_SIZE, unsigned int PERIOD> +class BitrateCalculator +{ +public: + BitrateCalculator() {} + + /** + * @brief Update the calculator, should be called every PERIOD ms + */ + uint16_t update(uint32_t sample) + { + if (window.isFull()) + { + uint32_t last = window.pop(); + window.put(sample); + + uint16_t delta = sample - last; + + // window size is in ms, we want the result in s + return delta * 1000 / WINDOW_SIZE; + } + else + { + window.put(sample); + return 0; + } + } + +private: + Boardcore::CircularBuffer<uint32_t, WINDOW_SIZE / PERIOD> window; +}; + +/** + * @brief Class responsible for keeping track of radio status and metrics. + */ +class BoardStatus : public Boardcore::Module, private Boardcore::ActiveObject +{ +public: + BoardStatus() {} + + bool start(); + + /** + * @brief Check wether the main radio was found during boot. + */ + bool isMainRadioPresent(); + + /** + * @brief Check wether the payload radio was found during boot. + */ + bool isPayloadRadioPresent(); + + /** + * @brief Check wether the ethernet was found during boot. + */ + bool isEthernetPresent(); + + void setMainRadioPresent(bool present); + void setPayloadRadioPresent(bool present); + void setEthernetPresent(bool present); + +private: + void run() override; + + Groundstation::RadioStats last_main_stats = {0}; + Groundstation::RadioStats last_payload_stats = {0}; + + BitrateCalculator<Groundstation::RADIO_BITRATE_WINDOW_SIZE, + Groundstation::RADIO_STATUS_PERIOD> + main_tx_bitrate; + BitrateCalculator<Groundstation::RADIO_BITRATE_WINDOW_SIZE, + Groundstation::RADIO_STATUS_PERIOD> + main_rx_bitrate; + BitrateCalculator<Groundstation::RADIO_BITRATE_WINDOW_SIZE, + Groundstation::RADIO_STATUS_PERIOD> + payload_tx_bitrate; + BitrateCalculator<Groundstation::RADIO_BITRATE_WINDOW_SIZE, + Groundstation::RADIO_STATUS_PERIOD> + payload_rx_bitrate; + + bool main_radio_present = false; + bool payload_radio_present = false; + bool ethernet_present = false; +}; + +} // namespace GroundstationBase \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Buses.h b/src/boards/Groundstation/Base/Buses.h new file mode 100644 index 0000000000000000000000000000000000000000..e776148116ef7d9d5a8dd6da54ff568eb840ee23 --- /dev/null +++ b/src/boards/Groundstation/Base/Buses.h @@ -0,0 +1,48 @@ +/* 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 GroundstationBase +{ + +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 GroundstationBase \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Hub.cpp b/src/boards/Groundstation/Base/Hub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af0b0608d7006b26b6cb3622a1faa34a85f9c81d --- /dev/null +++ b/src/boards/Groundstation/Base/Hub.cpp @@ -0,0 +1,75 @@ +/* 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 <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> + +using namespace Groundstation; +using namespace GroundstationBase; +using namespace Boardcore; + +void Hub::dispatchOutgoingMsg(const mavlink_message_t& msg) +{ + BoardStatus* status = ModuleManager::getInstance().get<BoardStatus>(); + + bool send_ok = false; + + if (status->isMainRadioPresent() && msg.sysid == MAV_SYSID_MAIN) + { + RadioMain* radio = ModuleManager::getInstance().get<RadioMain>(); + send_ok |= radio->sendMsg(msg); + } + + if (status->isPayloadRadioPresent() && msg.sysid == MAV_SYSID_PAYLOAD) + { + 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); + // } +} + +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); + } +} \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Hub.h b/src/boards/Groundstation/Base/Hub.h new file mode 100644 index 0000000000000000000000000000000000000000..c22a7339f62554cc8fc91ae8707fd58f5cb3da05 --- /dev/null +++ b/src/boards/Groundstation/Base/Hub.h @@ -0,0 +1,54 @@ +/* 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 <Groundstation/Common/HubBase.h> +#include <common/Mavlink.h> + +#include <utils/ModuleManager/ModuleManager.hpp> + +namespace GroundstationBase +{ + +/** + * @brief Central hub connecting all outgoing and ingoing modules. + */ +class Hub : public Groundstation::HubBase +{ +public: + Hub() {} + + /** + * @brief Dispatch to the correct interface and outgoing packet (gs -> + * rocket). + */ + void dispatchOutgoingMsg(const mavlink_message_t& msg) override; + + /** + * @brief Dispatch to the correct interface and incoming packet (rocket -> + * gs). + */ + void dispatchIncomingMsg(const mavlink_message_t& msg) override; +}; + +} // namespace GroundstationBase \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Ports/Ethernet.cpp b/src/boards/Groundstation/Base/Ports/Ethernet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..875c083cfee7d3869e1c0ede395c2ccda207b131 --- /dev/null +++ b/src/boards/Groundstation/Base/Ports/Ethernet.cpp @@ -0,0 +1,61 @@ +/* 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 "Ethernet.h" + +#include <Groundstation/Base/BoardStatus.h> +#include <Groundstation/Base/Buses.h> +#include <interfaces-impl/hwmapping.h> + +using namespace Groundstation; +using namespace GroundstationBase; +using namespace Boardcore; +using namespace miosix; + +void __attribute__((used)) MIOSIX_ETHERNET_IRQ() +{ + ModuleManager::getInstance().get<Ethernet>()->handleINTn(); +} + +bool Ethernet::start() +{ + std::unique_ptr<Wiz5500> wiz5500 = std::make_unique<Wiz5500>( + ModuleManager::getInstance().get<Buses>()->ethernet_bus, + ethernet::cs::getPin(), ethernet::intr::getPin(), + SPI::ClockDivider::DIV_64); + + // First check if the device is even connected + bool present = wiz5500->checkVersion(); + + ModuleManager::getInstance().get<BoardStatus>()->setEthernetPresent( + present); + + if (present) + { + if (!EthernetBase::start(std::move(wiz5500))) + { + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Ports/Ethernet.h b/src/boards/Groundstation/Base/Ports/Ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..4a8283b1915e0600dff19e94d191038b88d9274a --- /dev/null +++ b/src/boards/Groundstation/Base/Ports/Ethernet.h @@ -0,0 +1,38 @@ +/* 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 <Groundstation/Common/Ports/EthernetBase.h> + +#include <utils/ModuleManager/ModuleManager.hpp> + +namespace GroundstationBase +{ + +class Ethernet : public Groundstation::EthernetBase, public Boardcore::Module +{ +public: + [[nodiscard]] bool start(); +}; + +} // namespace GroundstationBase \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Radio/Radio.cpp b/src/boards/Groundstation/Base/Radio/Radio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8bf2456f544496a8c5c9608fb131fe850fbd0bd --- /dev/null +++ b/src/boards/Groundstation/Base/Radio/Radio.cpp @@ -0,0 +1,150 @@ +/* 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 <Groundstation/Base/BoardStatus.h> +#include <Groundstation/Base/Buses.h> +#include <Groundstation/Base/Hub.h> +#include <Groundstation/Common/Ports/Serial.h> +#include <radio/SX1278/SX1278Frontends.h> + +using namespace Groundstation; +using namespace GroundstationBase; +using namespace Boardcore; +using namespace miosix; + +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 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<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 + bool present = sx1278->checkVersion(); + + ModuleManager::getInstance().get<BoardStatus>()->setMainRadioPresent( + present); + + if (present) + { + // Configure the radio + if (sx1278->configure(Common::MAIN_RADIO_CONFIG) != + SX1278Fsk::Error::NONE) + { + return false; + } + + // Initialize if only if present + if (!RadioBase::start(std::move(sx1278))) + { + return false; + } + } + + return true; +} + +bool RadioPayload::start() +{ +#ifdef SKYWARD_GS_PAYLOAD_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<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 + bool present = sx1278->checkVersion(); + + ModuleManager::getInstance().get<BoardStatus>()->setPayloadRadioPresent( + present); + + if (present) + { + // Configure the radio + if (sx1278->configure(Common::PAYLOAD_RADIO_CONFIG) != + SX1278Fsk::Error::NONE) + { + return false; + } + + // Initialize if only if present + if (!RadioBase::start(std::move(sx1278))) + { + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/src/boards/Groundstation/Base/Radio/Radio.h b/src/boards/Groundstation/Base/Radio/Radio.h new file mode 100644 index 0000000000000000000000000000000000000000..e09d207c9166a97403167b204dc25681b059cc8e --- /dev/null +++ b/src/boards/Groundstation/Base/Radio/Radio.h @@ -0,0 +1,42 @@ +/* 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 <Groundstation/Common/Radio/RadioBase.h> + +namespace GroundstationBase +{ + +class RadioMain : public Groundstation::RadioBase, public Boardcore::Module +{ +public: + [[nodiscard]] bool start(); +}; + +class RadioPayload : public Groundstation::RadioBase, public Boardcore::Module +{ +public: + [[nodiscard]] bool start(); +}; + +} // namespace GroundstationBase \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Config/EthernetConfig.h b/src/boards/Groundstation/Common/Config/EthernetConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..ddb9872a061c453c240f1d61c6b77cb189b333ea --- /dev/null +++ b/src/boards/Groundstation/Common/Config/EthernetConfig.h @@ -0,0 +1,40 @@ +/* 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/WIZ5500/WIZ5500.h> + +#include <cstdint> + +namespace Groundstation +{ + +constexpr uint16_t RECV_PORT = 42070; +constexpr uint16_t SEND_PORT = 42069; + +constexpr Boardcore::WizMac MAC_BASE = {0x69, 0x69, 0x69, 0x69, 0, 0}; +constexpr Boardcore::WizIp IP_BASE = {192, 168, 1, 0}; +constexpr Boardcore::WizIp GATEWAY = {192, 168, 1, 1}; +constexpr Boardcore::WizIp SUBNET = {0, 0, 0, 0}; + +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Config/GeneralConfig.h b/src/boards/Groundstation/Common/Config/GeneralConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..b7c8b8d3fe845fc9ad13a9ec2a3226f201273bd6 --- /dev/null +++ b/src/boards/Groundstation/Common/Config/GeneralConfig.h @@ -0,0 +1,33 @@ +/* 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 Groundstation +{ + +constexpr uint8_t GS_COMPONENT_ID = 1; +constexpr uint8_t GS_SYSTEM_ID = 1; + +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..c32abe0d514e7145a4f19e319d123f450ba7b25d --- /dev/null +++ b/src/boards/Groundstation/Common/Config/RadioConfig.h @@ -0,0 +1,51 @@ +/* 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 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 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 Groundstation diff --git a/src/boards/Groundstation/Common/HubBase.cpp b/src/boards/Groundstation/Common/HubBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b767dae7335db14cf2cfbd5be481971b7fdd77d --- /dev/null +++ b/src/boards/Groundstation/Common/HubBase.cpp @@ -0,0 +1,36 @@ +/* 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 "HubBase.h" + +#include <Groundstation/Common/Config/GeneralConfig.h> + +using namespace Groundstation; + +void HubBase::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/Groundstation/Common/HubBase.h b/src/boards/Groundstation/Common/HubBase.h new file mode 100644 index 0000000000000000000000000000000000000000..d7caa7ed04d3f593a0b148e279b6a72f608e13f8 --- /dev/null +++ b/src/boards/Groundstation/Common/HubBase.h @@ -0,0 +1,58 @@ +/* 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 Groundstation +{ + +/** + * @brief Central hub connecting all outgoing and ingoing modules. + */ +class HubBase : public Boardcore::Module +{ +public: + /** + * @brief Dispatch to the correct interface and outgoing packet (gs -> + * rocket). + */ + virtual void dispatchOutgoingMsg(const mavlink_message_t& msg) = 0; + + /** + * @brief Dispatch to the correct interface and incoming packet (rocket -> + * gs). + */ + virtual void dispatchIncomingMsg(const mavlink_message_t& msg) = 0; + +protected: + /** + * @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 Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Ports/EthernetBase.cpp b/src/boards/Groundstation/Common/Ports/EthernetBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6c627b234ded251bbd0d6f44bc914e269c69063 --- /dev/null +++ b/src/boards/Groundstation/Common/Ports/EthernetBase.cpp @@ -0,0 +1,124 @@ +/* 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 "EthernetBase.h" + +#include <Groundstation/Common/Config/EthernetConfig.h> +#include <Groundstation/Common/HubBase.h> + +#include <random> + +using namespace Groundstation; +using namespace Boardcore; +using namespace miosix; + +WizIp Groundstation::genNewRandomIp() +{ + WizIp ip = IP_BASE; + ip.d = (rand() % 253) + 1; // Generate in range 1-254 + + return ip; +} + +WizMac Groundstation::genNewRandomMac() +{ + WizMac mac = MAC_BASE; + mac.e = (rand() % 253) + 1; // Generate in range 1-254 + mac.f = (rand() % 253) + 1; // Generate in range 1-254 + + return mac; +} + +void EthernetBase::handleINTn() +{ + if (wiz5500) + { + wiz5500->handleINTn(); + } +} + +void EthernetBase::sendMsg(const mavlink_message_t& msg) +{ + if (mav_driver && mav_driver->isStarted()) + { + mav_driver->enqueueMsg(msg); + } +} + +Boardcore::Wiz5500::PhyState EthernetBase::getState() +{ + return wiz5500->getPhyState(); +} + +bool EthernetBase::start(std::unique_ptr<Boardcore::Wiz5500> wiz5500) +{ + this->wiz5500 = std::move(wiz5500); + + // Reset the device + this->wiz5500->reset(); + + // Setup ip and other stuff + this->wiz5500->setSubnetMask(SUBNET); + this->wiz5500->setGatewayIp(GATEWAY); + this->wiz5500->setSourceIp(genNewRandomIp()); + this->wiz5500->setSourceMac(genNewRandomMac()); + + this->wiz5500->setOnIpConflict( + [this]() { this->wiz5500->setSourceIp(genNewRandomIp()); }); + + // Ok now open the UDP socket + if (!this->wiz5500->openUdp(0, RECV_PORT, {255, 255, 255, 255}, SEND_PORT, + 500)) + { + return false; + } + + auto mav_handler = [this](EthernetMavDriver* channel, + const mavlink_message_t& msg) { handleMsg(msg); }; + + mav_driver = std::make_unique<EthernetMavDriver>(this, mav_handler, 0, 10); + + if (!mav_driver->start()) + { + return false; + } + + return true; +} + +void EthernetBase::handleMsg(const mavlink_message_t& msg) +{ + // Dispatch the message through the hub. + ModuleManager::getInstance().get<HubBase>()->dispatchOutgoingMsg(msg); +} + +ssize_t EthernetBase::receive(uint8_t* pkt, size_t max_len) +{ + WizIp dst_ip; + uint16_t dst_port; + return wiz5500->recvfrom(0, pkt, max_len, dst_ip, dst_port); +} + +bool EthernetBase::send(uint8_t* pkt, size_t len) +{ + return wiz5500->send(0, pkt, len, 100); +} \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Ports/EthernetBase.h b/src/boards/Groundstation/Common/Ports/EthernetBase.h new file mode 100644 index 0000000000000000000000000000000000000000..cd377b5744d86893fbaf592e9bf652cf8440fd34 --- /dev/null +++ b/src/boards/Groundstation/Common/Ports/EthernetBase.h @@ -0,0 +1,70 @@ +/* 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 <common/Mavlink.h> +#include <drivers/WIZ5500/WIZ5500.h> +#include <radio/MavlinkDriver/MavlinkDriver.h> + +#include <memory> + +namespace Groundstation +{ + +Boardcore::WizIp genNewRandomIp(); +Boardcore::WizMac genNewRandomMac(); + +using EthernetMavDriver = + Boardcore::MavlinkDriver<1024, 10, MAVLINK_MAX_DIALECT_PAYLOAD_SIZE>; + +class EthernetBase : public Boardcore::Transceiver +{ +public: + EthernetBase() {} + + void handleINTn(); + + void sendMsg(const mavlink_message_t& msg); + + Boardcore::Wiz5500::PhyState getState(); + +protected: + bool start(std::unique_ptr<Boardcore::Wiz5500> wiz5500); + +private: + /** + * @brief Called internally when a message is received. + */ + 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; + + bool started = false; + std::unique_ptr<Boardcore::Wiz5500> wiz5500; + std::unique_ptr<EthernetMavDriver> mav_driver; +}; + +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Ports/Serial.cpp b/src/boards/Groundstation/Common/Ports/Serial.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45f4b7712016451e394c9ce4284e5bcb8c6fb4ce --- /dev/null +++ b/src/boards/Groundstation/Common/Ports/Serial.cpp @@ -0,0 +1,71 @@ +/* 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 <Groundstation/Common/HubBase.h> +#include <filesystem/console/console_device.h> + +using namespace miosix; +using namespace Groundstation; +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()) + { + return false; + } + + 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) +{ + // Dispatch the message through the hub. + ModuleManager::getInstance().get<HubBase>()->dispatchOutgoingMsg(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); +} + +bool Serial::send(uint8_t* pkt, size_t len) +{ + auto serial = miosix::DefaultConsole::instance().get(); + return serial->writeBlock(pkt, len, 0) != static_cast<ssize_t>(len); +} \ No newline at end of file diff --git a/src/boards/Groundstation/Common/Ports/Serial.h b/src/boards/Groundstation/Common/Ports/Serial.h new file mode 100644 index 0000000000000000000000000000000000000000..ea39b639428dd17b623c6e0899ac2cd6c5e7e630 --- /dev/null +++ b/src/boards/Groundstation/Common/Ports/Serial.h @@ -0,0 +1,70 @@ +/* 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 <common/Mavlink.h> +#include <radio/MavlinkDriver/MavlinkDriver.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 +{ +public: + Serial() {} + + /** + * @brief Initialize the serial module. + */ + [[nodiscard]] bool start(); + + /** + * @brief Send a mavlink message through this port. + */ + void sendMsg(const mavlink_message_t& msg); + +private: + /** + * @brief Called internally when a message is received. + */ + 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; + + 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 new file mode 100644 index 0000000000000000000000000000000000000000..22be5ff3b345e82f6ab3be4e18705317eec2b7c1 --- /dev/null +++ b/src/boards/Groundstation/Common/Radio/RadioBase.cpp @@ -0,0 +1,167 @@ +/* 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 "RadioBase.h" + +#include <Groundstation/Common/HubBase.h> + +#include <memory> + +using namespace miosix; +using namespace Groundstation; +using namespace Boardcore; + +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) +{ + this->sx1278 = std::move(sx1278); + + auto mav_handler = [this](RadioMavDriver* 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); + + if (!mav_driver->start()) + { + return false; + } + + if (!ActiveObject::start()) + { + return false; + } + + started = true; + 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<HubBase>()->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/Groundstation/Common/Radio/RadioBase.h b/src/boards/Groundstation/Common/Radio/RadioBase.h new file mode 100644 index 0000000000000000000000000000000000000000..3067912106fb345926e74fc8c63039ae43592115 --- /dev/null +++ b/src/boards/Groundstation/Common/Radio/RadioBase.h @@ -0,0 +1,128 @@ +/* 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 <Groundstation/Common/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 Groundstation +{ + +using RadioMavDriver = + Boardcore::MavlinkDriver<Boardcore::SX1278Fsk::MTU, + Groundstation::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. + */ + bool start(std::unique_ptr<Boardcore::SX1278Fsk> sx1278); + +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 transmission + */ + bool isEndOfTransmissionPacket(const mavlink_message_t& msg); + + bool started = false; + + miosix::FastMutex pending_msgs_mutex; + mavlink_message_t pending_msgs[Groundstation::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<RadioMavDriver> mav_driver; +}; + +} // namespace Groundstation \ No newline at end of file diff --git a/src/boards/Groundstation/Nokia/Buses.h b/src/boards/Groundstation/Nokia/Buses.h new file mode 100644 index 0000000000000000000000000000000000000000..8a3f17a1865b311d626f89ceb74b858fe26db83a --- /dev/null +++ b/src/boards/Groundstation/Nokia/Buses.h @@ -0,0 +1,42 @@ +/* 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 GroundstationNokia +{ + +class Buses : public Boardcore::Module +{ +public: + Boardcore::SPIBus radio_bus; + + Buses() : radio_bus(SPI4) {} +}; + +} // namespace GroundstationNokia \ No newline at end of file diff --git a/src/boards/Groundstation/Nokia/Hub.cpp b/src/boards/Groundstation/Nokia/Hub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab06368e13450c6af99606ff8291560584f188f1 --- /dev/null +++ b/src/boards/Groundstation/Nokia/Hub.cpp @@ -0,0 +1,47 @@ +/* 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 <Groundstation/Common/Config/GeneralConfig.h> +#include <Groundstation/Common/Ports/Serial.h> +#include <Groundstation/Nokia/Radio/Radio.h> + +using namespace Groundstation; +using namespace GroundstationNokia; +using namespace Boardcore; + +void Hub::dispatchOutgoingMsg(const mavlink_message_t& msg) +{ + Radio* radio = ModuleManager::getInstance().get<Radio>(); + + if (!radio->sendMsg(msg)) + { + sendNack(msg); + } +} + +void Hub::dispatchIncomingMsg(const mavlink_message_t& msg) +{ + Serial* serial = ModuleManager::getInstance().get<Serial>(); + serial->sendMsg(msg); +} \ No newline at end of file diff --git a/src/boards/Groundstation/Nokia/Hub.h b/src/boards/Groundstation/Nokia/Hub.h new file mode 100644 index 0000000000000000000000000000000000000000..0351d7ab839d6b4c5e25faa51bfb8eebf0751cbf --- /dev/null +++ b/src/boards/Groundstation/Nokia/Hub.h @@ -0,0 +1,54 @@ +/* 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 <Groundstation/Common/HubBase.h> +#include <common/Mavlink.h> + +#include <utils/ModuleManager/ModuleManager.hpp> + +namespace GroundstationNokia +{ + +/** + * @brief Central hub connecting all outgoing and ingoing modules. + */ +class Hub : public Groundstation::HubBase +{ +public: + Hub() {} + + /** + * @brief Dispatch to the correct interface and outgoing packet (gs -> + * rocket). + */ + void dispatchOutgoingMsg(const mavlink_message_t& msg) override; + + /** + * @brief Dispatch to the correct interface and incoming packet (rocket -> + * gs). + */ + void dispatchIncomingMsg(const mavlink_message_t& msg) override; +}; + +} // namespace GroundstationNokia \ No newline at end of file diff --git a/src/boards/Groundstation/Nokia/Radio/Radio.cpp b/src/boards/Groundstation/Nokia/Radio/Radio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e27dfac357304bfcc07248e2bc505819a19b03c --- /dev/null +++ b/src/boards/Groundstation/Nokia/Radio/Radio.cpp @@ -0,0 +1,94 @@ +/* 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 <Groundstation/Common/Ports/Serial.h> +#include <Groundstation/Nokia/Buses.h> +#include <radio/SX1278/SX1278Frontends.h> + +#include "interfaces-impl/hwmapping.h" + +using namespace Groundstation; +using namespace GroundstationNokia; +using namespace Boardcore; +using namespace miosix; + +#define SX1278_DIO0_IRQ EXTI6_IRQHandlerImpl +#define SX1278_DIO1_IRQ EXTI4_IRQHandlerImpl +#define SX1278_DIO3_IRQ EXTI11_IRQHandlerImpl + +void __attribute__((used)) SX1278_DIO0_IRQ() +{ + ModuleManager::getInstance().get<Radio>()->handleDioIRQ(); +} + +void __attribute__((used)) SX1278_DIO1_IRQ() +{ + ModuleManager::getInstance().get<Radio>()->handleDioIRQ(); +} + +void __attribute__((used)) SX1278_DIO3_IRQ() +{ + ModuleManager::getInstance().get<Radio>()->handleDioIRQ(); +} + +bool Radio::start() +{ +#ifdef SKYWARD_GS_MAIN_USE_BACKUP_RF +#error "Backup RF not supported on nokia" +#else + std::unique_ptr<SX1278::ISX1278Frontend> frontend = + std::make_unique<RA01Frontend>(); +#endif + + std::unique_ptr<Boardcore::SX1278Fsk> sx1278 = + std::make_unique<Boardcore::SX1278Fsk>( + ModuleManager::getInstance() + .get<GroundstationNokia::Buses>() + ->radio_bus, + peripherals::ra01::pc13::cs::getPin(), + peripherals::ra01::pc13::dio0::getPin(), + peripherals::ra01::pc13::dio1::getPin(), + peripherals::ra01::pc13::dio3::getPin(), SPI::ClockDivider::DIV_64, + std::move(frontend)); + + // First check if the device is even connected + if (!sx1278->checkVersion()) + { + return false; + } + + // Configure the radio + if (sx1278->configure(Common::MAIN_RADIO_CONFIG) != SX1278Fsk::Error::NONE) + { + return false; + } + + // Initialize if only if present + if (!RadioBase::start(std::move(sx1278))) + { + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/boards/Groundstation/Nokia/Radio/Radio.h b/src/boards/Groundstation/Nokia/Radio/Radio.h new file mode 100644 index 0000000000000000000000000000000000000000..950b8243a3ccbded6daa6e9e9d58bcc18ff6f2f7 --- /dev/null +++ b/src/boards/Groundstation/Nokia/Radio/Radio.h @@ -0,0 +1,36 @@ +/* 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 <Groundstation/Common/Radio/RadioBase.h> + +namespace GroundstationNokia +{ + +class Radio : public Groundstation::RadioBase, public Boardcore::Module +{ +public: + [[nodiscard]] bool start(); +}; + +} // namespace GroundstationNokia \ No newline at end of file diff --git a/src/boards/common/Radio.h b/src/boards/common/Radio.h new file mode 100644 index 0000000000000000000000000000000000000000..efdfa4b891240c09733cb2fd0fef96239c898d35 --- /dev/null +++ b/src/boards/common/Radio.h @@ -0,0 +1,54 @@ +/* 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 <radio/SX1278/SX1278Fsk.h> + +namespace Common +{ + +static const Boardcore::SX1278Fsk::Config MAIN_RADIO_CONFIG = { + .freq_rf = 419000000, + .freq_dev = 50000, + .bitrate = 48000, + .rx_bw = Boardcore::SX1278Fsk::Config::RxBw::HZ_125000, + .afc_bw = Boardcore::SX1278Fsk::Config::RxBw::HZ_125000, + .ocp = 120, + .power = 13, + .shaping = Boardcore::SX1278Fsk::Config::Shaping::GAUSSIAN_BT_1_0, + .dc_free = Boardcore::SX1278Fsk::Config::DcFree::WHITENING, + .enable_crc = false}; + +static const Boardcore::SX1278Fsk::Config PAYLOAD_RADIO_CONFIG = { + .freq_rf = 868000000, + .freq_dev = 50000, + .bitrate = 48000, + .rx_bw = Boardcore::SX1278Fsk::Config::RxBw::HZ_125000, + .afc_bw = Boardcore::SX1278Fsk::Config::RxBw::HZ_125000, + .ocp = 120, + .power = 13, + .shaping = Boardcore::SX1278Fsk::Config::Shaping::GAUSSIAN_BT_1_0, + .dc_free = Boardcore::SX1278Fsk::Config::DcFree::WHITENING, + .enable_crc = false}; + +} // namespace Common \ No newline at end of file diff --git a/src/entrypoints/Groundstation/base-groundstation-entry.cpp b/src/entrypoints/Groundstation/base-groundstation-entry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..99b7374fcdf25f5f52de7378682f9f132abf8f4e --- /dev/null +++ b/src/entrypoints/Groundstation/base-groundstation-entry.cpp @@ -0,0 +1,143 @@ +/* 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 <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/Common/Ports/Serial.h> +#include <miosix.h> + +using namespace Groundstation; +using namespace GroundstationBase; +using namespace Boardcore; +using namespace miosix; + +void idleLoop() +{ + while (1) + { + Thread::wait(); + } +} + +void errorLoop() +{ + while (1) + { + led1On(); + Thread::sleep(100); + led1Off(); + Thread::sleep(100); + } +} + +int main() +{ + ledOff(); + + 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(); + + ModuleManager &modules = ModuleManager::getInstance(); + + bool ok = true; + + 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); + + // 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"); + } + + ok &= ethernet->start(); + if (!ok) + { + printf("[error] Failed to start ethernet!\n"); + } + + ok &= radio_main->start(); + if (!ok) + { + printf("[error] Failed to start main radio!\n"); + } + + ok &= radio_payload->start(); + if (!ok) + { + printf("[error] Failed to start payload radio!\n"); + } + + ok &= board_status->start(); + if (!ok) + { + printf("[error] Failed to start board status!\n"); + } + + if (board_status->isMainRadioPresent()) + { + printf("Main radio detected!\n"); + led2On(); + } + + if (board_status->isPayloadRadioPresent()) + { + printf("Payload radio detected!\n"); + led3On(); + } + + if (board_status->isEthernetPresent()) + { + printf("Ethernet detected!\n"); + } + + if (!ok) + { + errorLoop(); + } + + led1On(); + idleLoop(); + return 0; +} \ No newline at end of file diff --git a/src/entrypoints/Groundstation/nokia-groundstation-entry.cpp b/src/entrypoints/Groundstation/nokia-groundstation-entry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da685704b93e00882cb953e9e0a398d95714abd6 --- /dev/null +++ b/src/entrypoints/Groundstation/nokia-groundstation-entry.cpp @@ -0,0 +1,88 @@ +/* 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 <Groundstation/Common/Ports/Serial.h> +#include <Groundstation/Nokia/Buses.h> +#include <Groundstation/Nokia/Hub.h> +#include <Groundstation/Nokia/Radio/Radio.h> +#include <miosix.h> + +using namespace Groundstation; +using namespace GroundstationNokia; +using namespace Boardcore; +using namespace miosix; + +void idleLoop() +{ + while (1) + { + Thread::wait(); + } +} + +int main() +{ + ledOff(); + + Hub *hub = new Hub(); + Buses *buses = new Buses(); + Radio *radio = new Radio(); + Serial *serial = new Serial(); + + ModuleManager &modules = ModuleManager::getInstance(); + + bool ok = true; + + ok &= modules.insert<HubBase>(hub); + ok &= modules.insert(buses); + ok &= modules.insert(serial); + ok &= modules.insert(radio); + + // If insertion failed, stop right here + if (!ok) + { + printf("[error] Failed to insert all modules!\n"); + idleLoop(); + } + + // Ok now start them + + ok &= serial->start(); + if (!ok) + { + printf("[error] Failed to start serial!\n"); + } + + ok &= radio->start(); + if (!ok) + { + printf("[error] Failed to start radio!\n"); + } + + if (ok) + { + printf("Init complete!\n"); + } + + idleLoop(); + return 0; +} \ No newline at end of file