diff --git a/libs/mavlink-skyward-lib b/libs/mavlink-skyward-lib index 4874d08b4a6340d6a9da8da9a33f96b8f01d789b..1374b7d63113a5bcf178e7ea4ac87c1524f81609 160000 --- a/libs/mavlink-skyward-lib +++ b/libs/mavlink-skyward-lib @@ -1 +1 @@ -Subproject commit 4874d08b4a6340d6a9da8da9a33f96b8f01d789b +Subproject commit 1374b7d63113a5bcf178e7ea4ac87c1524f81609 diff --git a/src/shared/utils/PinObserver/PinObserver.cpp b/src/shared/utils/PinObserver/PinObserver.cpp index 14430cda3df132bbfdcbf58565715f3b88067834..820158a145510ad54b17a727a255ed543429f9bc 100644 --- a/src/shared/utils/PinObserver/PinObserver.cpp +++ b/src/shared/utils/PinObserver/PinObserver.cpp @@ -22,17 +22,19 @@ #include "PinObserver.h" +#include <drivers/timer/TimestampTimer.h> + #include <functional> namespace Boardcore { bool PinObserver::registerPinCallback(miosix::GpioPin pin, PinCallback callback, - unsigned int detectionThreshold) + uint32_t detectionThreshold) { // Try to insert the callback - auto result = - callbacks.insert({pin, {callback, detectionThreshold, pin.value(), 0}}); + auto result = callbacks.insert( + {pin, {callback, detectionThreshold, 0, 0, pin.value() == 1, 0}}); // Check if the insertion took place if (result.second) @@ -54,6 +56,13 @@ bool PinObserver::start() { return scheduler.start(); } void PinObserver::stop() { scheduler.stop(); } +PinData PinObserver::getPinData(miosix::GpioPin pin) { return callbacks[pin]; } + +void PinObserver::resetPinChangesCount(miosix::GpioPin pin) +{ + callbacks[pin].changesCount = 0; +} + PinObserver::PinObserver() { scheduler.start(); } void PinObserver::periodicPinValueCheck(miosix::GpioPin pin) @@ -62,36 +71,37 @@ void PinObserver::periodicPinValueCheck(miosix::GpioPin pin) if (callbacks.find(pin) == callbacks.end()) return; + auto &pinData = callbacks[pin]; + // Retrieve the pin information - const PinCallback &callback = std::get<0>(callbacks[pin]); - const unsigned int detectionThreshold = std::get<1>(callbacks[pin]); - bool &previousState = std::get<2>(callbacks[pin]); - unsigned int &detectedCount = std::get<3>(callbacks[pin]); + uint32_t &count = pinData.periodCount; // Read the current pin status const bool newState = pin.value(); // Are we in a transition? - if (previousState != newState) + if (pinData.lastState != newState) { - detectedCount = 0; // Yes, reset the counter + count = 0; // Yes, reset the counter + pinData.changesCount++; // And register the change } else { - detectedCount++; // No, continue to increment + count++; // No, continue to increment // If the count reaches the threshold, then trigger the event - if (detectedCount > detectionThreshold) + if (count > pinData.threshold) { if (newState) - callback(PinTransition::RISING_EDGE); + pinData.callback(PinTransition::RISING_EDGE); else - callback(PinTransition::FALLING_EDGE); + pinData.callback(PinTransition::FALLING_EDGE); } } // Save the current pin status - previousState = newState; + pinData.lastStateTimestamp = TimestampTimer::getTimestamp(); + pinData.lastState = newState; } } // namespace Boardcore diff --git a/src/shared/utils/PinObserver/PinObserver.h b/src/shared/utils/PinObserver/PinObserver.h index 07090622a702af94f2dcbc04fdd1e3fe05065f62..692d514d40f2176c3f32af747599aade0279ba00 100644 --- a/src/shared/utils/PinObserver/PinObserver.h +++ b/src/shared/utils/PinObserver/PinObserver.h @@ -40,6 +40,19 @@ enum class PinTransition RISING_EDGE ///< The pin goes from low to high. }; +/** + * @brief Pin informations. + */ +struct PinData +{ + std::function<void(PinTransition)> callback; ///< The callback function. + uint32_t threshold; ///< Number of periods to trigger an event. + uint32_t periodCount; ///< Number of periods the value was the same. + uint64_t lastStateTimestamp; ///< Timestamp of the last measurement. + bool lastState; ///< The last measured pin state. + uint32_t changesCount; ///< Incremental count of the pin changes. +}; + /** * Class used to call a callback after a pin performs a specific transition * (RISING or FALLING edge) and stays in the new state for a specific amount of @@ -71,7 +84,7 @@ public: * @return False if another callback was already registered for the pin. */ bool registerPinCallback(miosix::GpioPin pin, PinCallback callback, - unsigned int detectionThreshold = 1); + uint32_t detectionThreshold = 1); /** * @brief Unregisters the callback associated with the specified pin, if @@ -97,6 +110,16 @@ public: */ void stop(); + /** + * @brief Returns the information for the specified pin. + */ + PinData getPinData(miosix::GpioPin pin); + + /** + * @brief Resets the changes counter for the specified pin. + */ + void resetPinChangesCount(miosix::GpioPin pin); + private: /** * @brief Construct a new PinObserver object. @@ -115,19 +138,8 @@ private: TaskScheduler scheduler; - /** - * @brief Map of all the callbacks registered in the PinObserver. - - * The type stored is a tuple containing: - * - The button callback function; - * - Detection threshold: number of periods to trigger an event - * - The last pin status; - * - Number of periods the pin values stayed the same; - */ - std::map<miosix::GpioPin, - std::tuple<PinCallback, unsigned int, bool, unsigned int>, - GpioPinCompare> - callbacks; + /// Map of all the callbacks registered in the PinObserver. + std::map<miosix::GpioPin, PinData, GpioPinCompare> callbacks; }; } // namespace Boardcore