From 32819c11089d7c9447fd66f4c308ce744686c32a Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 2 Dec 2022 16:24:45 +0100 Subject: [PATCH] Add pending RX api --- include/sta/can/controller.hpp | 25 +++++++++ include/sta/can/iter.hpp | 63 ++++++++++++++++++++++ src/can/iter.cpp | 95 ++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 include/sta/can/iter.hpp create mode 100644 src/can/iter.cpp diff --git a/include/sta/can/controller.hpp b/include/sta/can/controller.hpp index 9abca01..73aee6d 100644 --- a/include/sta/can/controller.hpp +++ b/include/sta/can/controller.hpp @@ -19,6 +19,7 @@ #include #include +#include namespace sta @@ -60,6 +61,11 @@ namespace sta */ virtual uint32_t getRxFifoFlags() = 0; + /** + * @brief Get list of RX FIFO indices with pending messages. + */ + virtual CanPendingRxFifos getPendingRxFifos() = 0; + // RX filter // @@ -88,6 +94,25 @@ namespace sta * @brief Disable and clear all filters. */ virtual void clearFilters() = 0; + + + // Info + // + + /** + * @brief Get number of available filters. + */ + virtual uint8_t maxFilterCount() const = 0; + + /** + * @brief Get number of available FIFOs. + */ + virtual uint8_t maxFifoCount() const = 0; + + /** + * @brief Get maximum supported payload size. + */ + virtual uint8_t maxPayloadSize() const = 0; }; } // namespace sta diff --git a/include/sta/can/iter.hpp b/include/sta/can/iter.hpp new file mode 100644 index 0000000..fbd7722 --- /dev/null +++ b/include/sta/can/iter.hpp @@ -0,0 +1,63 @@ +#ifndef STA_CAN_ITER_HPP +#define STA_CAN_ITER_HPP + +#include + + +namespace sta +{ + class CanPendingRxFifos + { + public: + using value_type = uint8_t; + using reference = value_type &; + using const_reference = const value_type &; + using size_type = uint8_t; + + class const_iterator + { + public: + using value_type = CanPendingRxFifos::value_type; + using reference = const_reference; + using pointer = const value_type *; + + public: + const_iterator(const const_iterator & iter); + + const_iterator & operator=(const const_iterator & iter); + + bool operator==(const const_iterator & iter) const; + bool operator!=(const const_iterator & iter) const; + + const_iterator & operator++(); + const_iterator operator++(int); + + reference operator*() const; + + private: + const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx); + + bool isRxPending() const; + + friend class CanPendingRxFifos; + + private: + uint32_t rxFlags_; + uint8_t idx_; + uint8_t endIdx_; + }; + + public: + CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos); + + const_iterator begin() const; + const_iterator end() const; + + private: + uint32_t rxFlags_; + uint8_t numFifos_; + }; +} // namespace sta + + +#endif // STA_CAN_ITER_HPP diff --git a/src/can/iter.cpp b/src/can/iter.cpp new file mode 100644 index 0000000..82472cb --- /dev/null +++ b/src/can/iter.cpp @@ -0,0 +1,95 @@ +#include + +#include + + +namespace sta +{ + CanPendingRxFifos::const_iterator::const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx) + : rxFlags_{rxFlags}, idx_{idx}, endIdx_{endIdx} + {} + + CanPendingRxFifos::const_iterator::const_iterator(const const_iterator & iter) + : rxFlags_{iter.rxFlags_}, idx_{iter.idx_}, endIdx_{iter.endIdx_} + {} + + + CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator=(const const_iterator & iter) + { + rxFlags_ = iter.rxFlags_; + idx_ = iter.idx_; + endIdx_ = iter.endIdx_; + + return *this; + } + + + bool CanPendingRxFifos::const_iterator::operator==(const const_iterator & iter) const + { + return (rxFlags_ == iter.rxFlags_) && (idx_ == iter.idx_) && (endIdx_ == iter.endIdx_); + } + + bool CanPendingRxFifos::const_iterator::operator!=(const const_iterator & iter) const + { + return !(*this == iter); + } + + + CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator++() + { + while (idx_ < endIdx_) + { + ++idx_; + if (isRxPending()) + { + break; + } + } + + return *this; + } + + CanPendingRxFifos::const_iterator CanPendingRxFifos::const_iterator::operator++(int) + { + uint8_t oldIdx = idx_; + + while (idx_ < endIdx_) + { + ++idx_; + if (isRxPending()) + { + break; + } + } + + return const_iterator(rxFlags_, oldIdx, endIdx_); + } + + CanPendingRxFifos::const_iterator::reference CanPendingRxFifos::const_iterator::operator*() const + { + STA_ASSERT_MSG(idx_ != endIdx_, "Dereferencing out-of-bounds iterator"); + + return idx_; + } + + bool CanPendingRxFifos::const_iterator::isRxPending() const + { + return ( (rxFlags_ >> idx_) & 0x1 ); + } + + + + CanPendingRxFifos::CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos) + : rxFlags_{rxFlags}, numFifos_{numFifos} + {} + + CanPendingRxFifos::const_iterator CanPendingRxFifos::begin() const + { + return const_iterator(rxFlags_, 0, numFifos_); + } + + CanPendingRxFifos::const_iterator CanPendingRxFifos::end() const + { + return const_iterator(rxFlags_, numFifos_, numFifos_); + } +} // namespace sta