diff --git a/src/Parafoil/BoardScheduler.h b/src/Parafoil/BoardScheduler.h index 2843c6cc61052baba21be2d54e5d9b68efad96d8..cd331b343cb1718e8df0ba101324af21c60e2f67 100644 --- a/src/Parafoil/BoardScheduler.h +++ b/src/Parafoil/BoardScheduler.h @@ -54,6 +54,7 @@ public: Boardcore::TaskScheduler& nasController() { return critical; } Boardcore::TaskScheduler& sensors() { return high; } + Boardcore::TaskScheduler& pinHandler() { return high; } static Priority::PriorityLevel flightModeManagerPriority() { diff --git a/src/Parafoil/Configs/PinHandlerConfig.h b/src/Parafoil/Configs/PinHandlerConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..237fb032ee65c42906a5aea6007d2151217d986c --- /dev/null +++ b/src/Parafoil/Configs/PinHandlerConfig.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Author: Davide Basso + * + * 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 <utils/PinObserver/PinObserver.h> + +#include <chrono> + +namespace Parafoil +{ +namespace Config +{ +namespace PinHandler +{ + +/* linter-off */ using namespace std::chrono_literals; + +namespace PinObserver +{ +constexpr auto PERIOD = 20ms; +} + +namespace Expulsion +{ +constexpr auto DETECTION_THRESHOLD = 20; +constexpr auto TRIGGERING_TRANSITION = Boardcore::PinTransition::FALLING_EDGE; +} // namespace Expulsion + +} // namespace PinHandler +} // namespace Config +} // namespace Parafoil diff --git a/src/Parafoil/PinHandler/PinData.h b/src/Parafoil/PinHandler/PinData.h new file mode 100644 index 0000000000000000000000000000000000000000..2a2acf0aaa7af7503b7056ae6dc7c8f23d4b6bfd --- /dev/null +++ b/src/Parafoil/PinHandler/PinData.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Author: Davide Basso + * + * 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> +#include <iostream> + +namespace Parafoil +{ + +struct PinChangeData +{ + uint64_t timestamp = 0; + uint8_t pinId = 0; + bool lastState = false; + uint32_t changesCount = 0; + + static std::string header() + { + return "timestamp,pinId,lastState,changesCount\n"; + } + + void print(std::ostream& os) const + { + os << timestamp << "," << static_cast<int>(pinId) << "," + << static_cast<int>(lastState) << "," << changesCount << "\n"; + } +}; + +} // namespace Parafoil diff --git a/src/Parafoil/PinHandler/PinHandler.cpp b/src/Parafoil/PinHandler/PinHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f7721678388882326e458eed21d95672a54874d5 --- /dev/null +++ b/src/Parafoil/PinHandler/PinHandler.cpp @@ -0,0 +1,107 @@ + +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Author: Davide Basso + * + * 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 "PinHandler.h" + +#include <Parafoil/BoardScheduler.h> +#include <Parafoil/Configs/PinHandlerConfig.h> +#include <common/Events.h> +#include <drivers/timer/TimestampTimer.h> +#include <events/EventBroker.h> +#include <interfaces-impl/hwmapping.h> + +#include "PinData.h" + +using namespace Boardcore; +using namespace Common; +namespace config = Parafoil::Config::PinHandler; +namespace hwmap = miosix::inputs; + +namespace Parafoil +{ + +const decltype(PinHandler::PIN_LIST) PinHandler::PIN_LIST = { + PinList::NOSECONE_PIN, +}; + +bool PinHandler::start() +{ + using namespace std::chrono; + + auto& scheduler = getModule<BoardScheduler>()->pinHandler(); + + pinObserver = std::make_unique<PinObserver>( + scheduler, milliseconds{config::PinObserver::PERIOD}.count()); + + bool expulsionPinDetachResult = pinObserver->registerPinCallback( + hwmap::expulsion::getPin(), + [this](auto t) { onExpulsionPinTransition(t); }, + config::Expulsion::DETECTION_THRESHOLD); + + if (!expulsionPinDetachResult) + { + LOG_ERR(logger, + "Failed to register pin callback for the detach ramp pin"); + return false; + } + + started = true; + return true; +} + +bool PinHandler::isStarted() { return started; } + +PinData PinHandler::getPinData(PinList pin) +{ + switch (pin) + { + case PinList::NOSECONE_PIN: + return pinObserver->getPinData(hwmap::expulsion::getPin()); + default: + return PinData{}; + } +} + +void PinHandler::logPin(PinList pin) +{ + auto pinData = getPinData(pin); + auto pinChangeData = PinChangeData{ + .timestamp = TimestampTimer::getTimestamp(), + .pinId = static_cast<uint8_t>(pin), + .lastState = pinData.lastState, + .changesCount = pinData.changesCount, + }; + Logger::getInstance().log(pinChangeData); +} + +void PinHandler::onExpulsionPinTransition(PinTransition transition) +{ + logPin(PinList::NOSECONE_PIN); + LOG_INFO(logger, "Expulsion Pin transition detected: {}", + static_cast<int>(transition)); + + if (transition == config::Expulsion::TRIGGERING_TRANSITION) + EventBroker::getInstance().post(FLIGHT_NC_DETACHED, TOPIC_FLIGHT); +} + +} // namespace Parafoil diff --git a/src/Parafoil/PinHandler/PinHandler.h b/src/Parafoil/PinHandler/PinHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..6f8be18ae3571948d2fb06f1baf5a8de39f9085a --- /dev/null +++ b/src/Parafoil/PinHandler/PinHandler.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Author: Davide Basso + * + * 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/MavlinkOrion.h> +#include <diagnostic/PrintLogger.h> +#include <utils/DependencyManager/DependencyManager.h> +#include <utils/PinObserver/PinObserver.h> + +namespace Parafoil +{ +class BoardScheduler; + +enum class PinList : uint8_t +{ + NOSECONE_PIN = 0, +}; + +/** + * @brief This class contains the handlers for the detach pins on the payload. + * + * It uses Boardcore's PinObserver to bind these functions to the GPIO pins. + * The handlers post an event on the EventBroker. + */ +class PinHandler : public Boardcore::InjectableWithDeps<BoardScheduler> +{ +public: + static const std::array<PinList, 1> PIN_LIST; + + [[nodiscard]] bool start(); + + bool isStarted(); + + /** + * @brief Returns information about the specified pin. + */ + Boardcore::PinData getPinData(PinList pin); + +private: + void logPin(PinList pin); + + void onExpulsionPinTransition(Boardcore::PinTransition transition); + + std::unique_ptr<Boardcore::PinObserver> pinObserver; + + std::atomic<bool> started{false}; + + Boardcore::PrintLogger logger = Boardcore::Logging::getLogger("PinHandler"); +}; + +} // namespace Parafoil diff --git a/src/Parafoil/parafoil-entry.cpp b/src/Parafoil/parafoil-entry.cpp index d5c9d51b4c158da9a95be27a912f1d02c8eb9420..0b5451b3f21aa99ced8bdbfd34373ff5ecf9679b 100644 --- a/src/Parafoil/parafoil-entry.cpp +++ b/src/Parafoil/parafoil-entry.cpp @@ -22,6 +22,7 @@ #include <Parafoil/BoardScheduler.h> #include <Parafoil/Buses.h> +#include <Parafoil/PinHandler/PinHandler.h> #include <Parafoil/Sensors/Sensors.h> #include <Parafoil/StateMachines/FlightModeManager/FlightModeManager.h> #include <common/Events.h> @@ -78,8 +79,7 @@ using namespace Common; int main() { - std::cout << "Parafoil Entrypoint " - << "(" << BUILD_TYPE << ")" + std::cout << "Parafoil Entrypoint " << "(" << BUILD_TYPE << ")" << " by Skyward Experimental Rocketry" << std::endl; auto logger = Logging::getLogger("Parafoil"); @@ -101,7 +101,8 @@ int main() // Sensors auto sensors = new Sensors(); initResult &= depman.insert(sensors); - // TODO: PinHandler + auto pinHandler = new PinHandler(); + initResult &= depman.insert(pinHandler); // TODO: Radio @@ -159,4 +160,4 @@ int main() } return 0; -} \ No newline at end of file +}