mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/sta-core.git
synced 2025-06-10 16:55:58 +00:00
Fix indentation. Update doxygen comments
This commit is contained in:
parent
fc4eed38d5
commit
59585b2ae5
12
include/sta/arduino/not_implemented.hpp
Normal file
12
include/sta/arduino/not_implemented.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef STA_CORE_ARDUINO_NOT_IMPLEMENTED_HPP
|
||||||
|
#define STA_CORE_ARDUINO_NOT_IMPLEMENTED_HPP
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_arduino Arduino
|
||||||
|
* @ingroup sta_core_platforms
|
||||||
|
* @brief Modules implemented for the Arduino platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STA_CORE_ARDUINO_NOT_IMPLEMENTED_HPP
|
@ -11,20 +11,14 @@
|
|||||||
#define STA_CORE_ASSERT_HPP
|
#define STA_CORE_ASSERT_HPP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup staCore Core
|
* @defgroup sta_core Core
|
||||||
* @brief STA Core library
|
* @brief STA Core library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup staCoreBuildConfig Build Config
|
* @defgroup sta_core_platforms Platforms
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
* @brief Build configuration options
|
* @brief Platform specific implementations.
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup staCoreAssert Assert
|
|
||||||
* @ingroup staCore
|
|
||||||
* @brief Assertion handling.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -49,8 +43,21 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_assert Assert
|
||||||
|
* @ingroup sta_core
|
||||||
|
* @brief Assertion handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @ingroup sta_core_assert
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle failed assertions.
|
* @brief Handle failed assertions.
|
||||||
*
|
*
|
||||||
@ -62,8 +69,6 @@ namespace sta
|
|||||||
* @param expr Asserted expression or message
|
* @param expr Asserted expression or message
|
||||||
* @param file File name
|
* @param file File name
|
||||||
* @param line Line number
|
* @param line Line number
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
void assert_failed(const char * expr, const char * file, uint32_t line);
|
void assert_failed(const char * expr, const char * file, uint32_t line);
|
||||||
|
|
||||||
@ -71,48 +76,38 @@ namespace sta
|
|||||||
* @brief Stop execution.
|
* @brief Stop execution.
|
||||||
*
|
*
|
||||||
* Weak implementation can be overridden.
|
* Weak implementation can be overridden.
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
void assert_halt();
|
void assert_halt();
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def STA_HALT
|
* @ingroup sta_core_assert
|
||||||
* @brief Set function called after failed asserts.
|
* @{
|
||||||
*
|
|
||||||
* @ingroup staCoreBuildConfig
|
|
||||||
*/
|
*/
|
||||||
# ifndef STA_HALT
|
|
||||||
# define STA_HALT() sta::assert_halt()
|
|
||||||
# endif // !STA_HALT
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assert expression.
|
* @brief Assert expression.
|
||||||
*
|
*
|
||||||
* @param expr Expression
|
* @param expr Expression
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
# define STA_ASSERT(expr) ( (void)( !(expr) && ( sta::assert_failed(#expr, __FILE__, __LINE__), 1 ) && ( STA_HALT(), 1 ) ) )
|
# define STA_ASSERT(expr) ( (void)( !(expr) && ( sta::assert_failed(#expr, __FILE__, __LINE__), 1 ) && ( sta::assert_halt(), 1 ) ) )
|
||||||
/**
|
/**
|
||||||
* @brief Assert expression.
|
* @brief Assert expression.
|
||||||
*
|
*
|
||||||
* @param expr Expression
|
* @param expr Expression
|
||||||
* @param msg Message shown on failure
|
* @param msg Message shown on failure
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
# define STA_ASSERT_MSG(expr, msg) ( (void)( !(expr) && ( sta::assert_failed(msg, __FILE__, __LINE__), 1 ) && ( STA_HALT(), 1 ) ) )
|
# define STA_ASSERT_MSG(expr, msg) ( (void)( !(expr) && ( sta::assert_failed(msg, __FILE__, __LINE__), 1 ) && ( sta::assert_halt(), 1 ) ) )
|
||||||
/**
|
/**
|
||||||
* @brief Assert expression if condition is true.
|
* @brief Assert expression if condition is true.
|
||||||
*
|
*
|
||||||
* @param cond Condition
|
* @param cond Condition
|
||||||
* @param expr Expression
|
* @param expr Expression
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
# define STA_ASSERT_COND(cond, expr) ( (void)( (cond) ? STA_ASSERT(expr) : 1 ) )
|
# define STA_ASSERT_COND(cond, expr) ( (void)( (cond) ? STA_ASSERT(expr) : 1 ) )
|
||||||
/**
|
/**
|
||||||
@ -121,13 +116,17 @@ namespace sta
|
|||||||
* @param cond Condition
|
* @param cond Condition
|
||||||
* @param expr Expression
|
* @param expr Expression
|
||||||
* @param msg Message shown on failure
|
* @param msg Message shown on failure
|
||||||
*
|
|
||||||
* @ingroup staCoreAssert
|
|
||||||
*/
|
*/
|
||||||
# define STA_ASSERT_COND_MSG(cond, expr, msg) ( (void)( (cond) ? STA_ASSERT_MSG(expr, msg) ) )
|
# define STA_ASSERT_COND_MSG(cond, expr, msg) ( (void)( (cond) ? STA_ASSERT_MSG(expr, msg) ) )
|
||||||
|
/**
|
||||||
|
* @brief Expression only evaluated when assertions are enabled.
|
||||||
|
*
|
||||||
|
* @param expr Expression
|
||||||
|
*/
|
||||||
|
# define STA_ASSERT_EXTRA(expr) expr
|
||||||
|
|
||||||
|
|
||||||
# define STA_ASSERT_EXTRA(expr) expr;
|
/** @} */
|
||||||
|
|
||||||
#else // !STA_ASSERT_ENABLED
|
#else // !STA_ASSERT_ENABLED
|
||||||
|
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
#ifndef STA_CORE_ATOMIC_MUTEX_HPP
|
#ifndef STA_CORE_ATOMIC_MUTEX_HPP
|
||||||
#define STA_CORE_ATOMIC_MUTEX_HPP
|
#define STA_CORE_ATOMIC_MUTEX_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
#ifdef STA_STDLIB_HAS_ATOMIC
|
#ifdef STA_STDLIB_HAS_ATOMIC
|
||||||
# define STA_ATOMIC_ENABLED
|
# define STA_ATOMIC_ENABLED
|
||||||
#endif // STA_STDLIB_HAS_ATOMIC
|
#endif // STA_STDLIB_HAS_ATOMIC
|
||||||
|
|
||||||
|
|
||||||
#if defined(STA_ATOMIC_ENABLED) || defined(DOXYGEN)
|
#if defined(STA_ATOMIC_ENABLED) || defined(DOXYGEN)
|
||||||
|
|
||||||
#include <sta/mutex.hpp>
|
#include <sta/mutex.hpp>
|
||||||
@ -22,20 +24,20 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of `Mutex` interface using `std::atomic_flag`.
|
* @brief Implementation of `Mutex` interface using `std::atomic_flag`.
|
||||||
*/
|
*/
|
||||||
class AtomicMutex : public Mutex
|
class AtomicMutex : public Mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AtomicMutex();
|
AtomicMutex();
|
||||||
|
|
||||||
void acquire() override;
|
void acquire() override;
|
||||||
void release() override;
|
void release() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic_flag lock_; /**< Atomic flag used as lock */
|
std::atomic_flag lock_; /**< Atomic flag used as lock */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
#ifndef STA_CORE_ATOMIC_SIGNAL_HPP
|
#ifndef STA_CORE_ATOMIC_SIGNAL_HPP
|
||||||
#define STA_CORE_ATOMIC_SIGNAL_HPP
|
#define STA_CORE_ATOMIC_SIGNAL_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
#ifdef STA_STDLIB_HAS_ATOMIC
|
#ifdef STA_STDLIB_HAS_ATOMIC
|
||||||
# define STA_ATOMIC_ENABLED
|
# define STA_ATOMIC_ENABLED
|
||||||
#endif // STA_STDLIB_HAS_ATOMIC
|
#endif // STA_STDLIB_HAS_ATOMIC
|
||||||
|
|
||||||
|
|
||||||
#if defined(STA_ATOMIC_ENABLED) || defined(DOXYGEN)
|
#if defined(STA_ATOMIC_ENABLED) || defined(DOXYGEN)
|
||||||
|
|
||||||
#include <sta/signal.hpp>
|
#include <sta/signal.hpp>
|
||||||
@ -22,22 +24,22 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of `Signal` interface using `std::atomic`.
|
* @brief Implementation of `Signal` interface using `std::atomic`.
|
||||||
*/
|
*/
|
||||||
class AtomicSignal : public Signal
|
class AtomicSignal : public Signal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AtomicSignal();
|
AtomicSignal();
|
||||||
|
|
||||||
void notify() override;
|
void notify() override;
|
||||||
bool peek() override;
|
bool peek() override;
|
||||||
bool test() override;
|
bool test() override;
|
||||||
void wait() override;
|
void wait() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<bool> signal_; /**< Atomic bool used as signal */
|
std::atomic<bool> signal_; /**< Atomic bool used as signal */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,16 +6,11 @@
|
|||||||
#define STA_CORE_CAN_CONTROLLER_HPP
|
#define STA_CORE_CAN_CONTROLLER_HPP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup can CAN
|
* @defgroup sta_core_can CAN
|
||||||
|
* @ingroup sta_core
|
||||||
* @brief CAN controller driver interface.
|
* @brief CAN controller driver interface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup canAPI API
|
|
||||||
* @ingroup can
|
|
||||||
* @brief Public interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <sta/can/filter.hpp>
|
#include <sta/can/filter.hpp>
|
||||||
#include <sta/can/headers.hpp>
|
#include <sta/can/headers.hpp>
|
||||||
@ -24,96 +19,96 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief CAN controller driver interface.
|
* @brief CAN controller driver interface.
|
||||||
*
|
*
|
||||||
* @ingroup canAPI
|
* @ingroup sta_core_can
|
||||||
*/
|
*/
|
||||||
class CanController
|
class CanController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// RX/TX
|
// RX/TX
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send frame to CAN controller for transmission.
|
* @brief Send frame to CAN controller for transmission.
|
||||||
*
|
*
|
||||||
* @param header CAN frame TX header
|
* @param header CAN frame TX header
|
||||||
* @param payload CAN frame payload
|
* @param payload CAN frame payload
|
||||||
* @return True on success
|
* @return True on success
|
||||||
*/
|
*/
|
||||||
virtual bool sendFrame(const CanTxHeader & header, const uint8_t * payload) = 0;
|
virtual bool sendFrame(const CanTxHeader & header, const uint8_t * payload) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get received frame from the CAN controller.
|
* @brief Get received frame from the CAN controller.
|
||||||
*
|
*
|
||||||
* @param[in] fifo FIFO storing frame
|
* @param[in] fifo FIFO storing frame
|
||||||
* @param[out] header CAN frame RX header destination
|
* @param[out] header CAN frame RX header destination
|
||||||
* @param[out] payload CAN frame payload destination
|
* @param[out] payload CAN frame payload destination
|
||||||
* @return True on success
|
* @return True on success
|
||||||
*/
|
*/
|
||||||
virtual bool receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload) = 0;
|
virtual bool receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get RX FIFO flags.
|
* @brief Get RX FIFO flags.
|
||||||
*
|
*
|
||||||
* @return FIFO flags
|
* @return FIFO flags
|
||||||
*/
|
*/
|
||||||
virtual uint32_t getRxFifoFlags() = 0;
|
virtual uint32_t getRxFifoFlags() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get list of RX FIFO indices with pending messages.
|
* @brief Get list of RX FIFO indices with pending messages.
|
||||||
*/
|
*/
|
||||||
virtual CanPendingRxFifos getPendingRxFifos() = 0;
|
virtual CanPendingRxFifos getPendingRxFifos() = 0;
|
||||||
|
|
||||||
|
|
||||||
// RX filter
|
// RX filter
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Change filter settings.
|
* @brief Change filter settings.
|
||||||
*
|
*
|
||||||
* @param idx Filter index
|
* @param idx Filter index
|
||||||
* @param filter Filter configuration
|
* @param filter Filter configuration
|
||||||
* @param active Enable filter after applying settings
|
* @param active Enable filter after applying settings
|
||||||
*/
|
*/
|
||||||
virtual void configureFilter(uint8_t idx, const CanFilter & filter, bool active = false) = 0;
|
virtual void configureFilter(uint8_t idx, const CanFilter & filter, bool active = false) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Enable filter.
|
* @brief Enable filter.
|
||||||
*
|
*
|
||||||
* @param idx Filter index
|
* @param idx Filter index
|
||||||
*/
|
*/
|
||||||
virtual void enableFilter(uint8_t idx) = 0;
|
virtual void enableFilter(uint8_t idx) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Disable filter.
|
* @brief Disable filter.
|
||||||
*
|
*
|
||||||
* @param idx Filter index
|
* @param idx Filter index
|
||||||
*/
|
*/
|
||||||
virtual void disableFilter(uint8_t idx) = 0;
|
virtual void disableFilter(uint8_t idx) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Disable and clear all filters.
|
* @brief Disable and clear all filters.
|
||||||
*/
|
*/
|
||||||
virtual void clearFilters() = 0;
|
virtual void clearFilters() = 0;
|
||||||
|
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get number of available filters.
|
* @brief Get number of available filters.
|
||||||
*/
|
*/
|
||||||
virtual uint8_t maxFilterCount() const = 0;
|
virtual uint8_t maxFilterCount() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get number of available FIFOs.
|
* @brief Get number of available FIFOs.
|
||||||
*/
|
*/
|
||||||
virtual uint8_t maxFifoCount() const = 0;
|
virtual uint8_t maxFifoCount() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get maximum supported payload size.
|
* @brief Get maximum supported payload size.
|
||||||
*/
|
*/
|
||||||
virtual uint8_t maxPayloadSize() const = 0;
|
virtual uint8_t maxPayloadSize() const = 0;
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,37 +12,37 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @defgroup canFilter Filters
|
* @defgroup sta_core_can_filters Filters
|
||||||
* @ingroup canAPI
|
* @ingroup sta_core_can
|
||||||
* @brief CAN message filter types.
|
* @brief CAN message filter types.
|
||||||
*/
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ID format matched by CAN filter.
|
* @brief ID format matched by CAN filter.
|
||||||
*
|
*/
|
||||||
* @ingroup canFilter
|
enum class CanFilterIdFormat
|
||||||
*/
|
{
|
||||||
enum class CanFilterIdFormat
|
ANY, /**< Match both ID formats */
|
||||||
{
|
STD, /**< Match standard format IDs */
|
||||||
ANY, /**< Match both ID formats */
|
EXT /**< Match extended format IDs */
|
||||||
STD, /**< Match standard format IDs */
|
};
|
||||||
EXT /**< Match extended format IDs */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN filter settings.
|
* @brief CAN filter settings.
|
||||||
*
|
*/
|
||||||
* @ingroup canFilter
|
struct CanFilter
|
||||||
*/
|
{
|
||||||
struct CanFilter
|
CanId obj; /**< ID object */
|
||||||
{
|
CanId mask; /**< ID mask */
|
||||||
CanId obj; /**< ID object */
|
CanFilterIdFormat type; /**< ID format to match */
|
||||||
CanId mask; /**< ID mask */
|
uint8_t fifo; /**< FIFO to store matches */
|
||||||
CanFilterIdFormat type; /**< ID format to match */
|
};
|
||||||
uint8_t fifo; /**< FIFO to store matches */
|
|
||||||
};
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,36 +12,36 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @defgroup canHeader Frame headers
|
* @defgroup sta_core_can_headers Frame headers
|
||||||
* @ingroup canAPI
|
* @ingroup sta_core_can
|
||||||
* @brief CAN header types for transmitted / received frames.
|
* @brief CAN header types for transmitted / received frames.
|
||||||
*/
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN TX frame header.
|
* @brief CAN TX frame header.
|
||||||
*
|
*/
|
||||||
* @ingroup canHeader
|
struct CanTxHeader
|
||||||
*/
|
{
|
||||||
struct CanTxHeader
|
CanFrameId id; /**< Frame ID */
|
||||||
{
|
uint8_t payloadLength; /**< Size of data to send */
|
||||||
CanFrameId id; /**< Frame ID */
|
};
|
||||||
uint8_t payloadLength; /**< Size of data to send */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN RX frame header.
|
* @brief CAN RX frame header.
|
||||||
*
|
*/
|
||||||
* @ingroup canHeader
|
struct CanRxHeader
|
||||||
*/
|
{
|
||||||
struct CanRxHeader
|
CanFrameId id; /**< Frame ID */
|
||||||
{
|
uint8_t payloadLength; /**< Size of received data */
|
||||||
CanFrameId id; /**< Frame ID */
|
uint32_t timestamp; /**< RX timestamp */
|
||||||
uint8_t payloadLength; /**< Size of received data */
|
uint8_t filter; /**< RX filter match */
|
||||||
uint32_t timestamp; /**< RX timestamp */
|
};
|
||||||
uint8_t filter; /**< RX filter match */
|
|
||||||
};
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,107 +10,99 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @defgroup canID Frame IDs
|
* @defgroup sta_core_can_ids Frame IDs
|
||||||
* @ingroup canAPI
|
* @ingroup sta_core_can
|
||||||
* @brief Types for working with CAN ID values and formats.
|
* @brief Types for working with CAN ID values and formats.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN frame ID format.
|
* @brief CAN frame ID format.
|
||||||
*
|
*
|
||||||
* @ingroup canID
|
* @ingroup sta_core_can_ids
|
||||||
*/
|
*/
|
||||||
enum class CanIdFormat : uint8_t
|
enum class CanIdFormat : uint8_t
|
||||||
{
|
{
|
||||||
STD, /**< Standard format */
|
STD, /**< Standard format */
|
||||||
EXT /**< Extended format */
|
EXT /**< Extended format */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN frame ID.
|
* @brief CAN frame ID.
|
||||||
*
|
*
|
||||||
* @ingroup canID
|
* @ingroup sta_core_can_ids
|
||||||
*/
|
*/
|
||||||
struct CanId
|
struct CanId
|
||||||
{
|
{
|
||||||
uint32_t sid; /**< Standard ID field (11 bits) */
|
uint32_t sid; /**< Standard ID field (11 bits) */
|
||||||
uint32_t eid; /**< Extended ID field (18 bits) */
|
uint32_t eid; /**< Extended ID field (18 bits) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN frame ID and format.
|
* @brief CAN frame ID and format.
|
||||||
*
|
*
|
||||||
* @ingroup canID
|
* @ingroup sta_core_can_ids
|
||||||
*/
|
*/
|
||||||
struct CanFrameId
|
struct CanFrameId
|
||||||
{
|
{
|
||||||
CanIdFormat format; /**< ID format */
|
CanIdFormat format; /**< ID format */
|
||||||
uint32_t sid; /**< Standard ID field (11 bits) */
|
uint32_t sid; /**< Standard ID field (11 bits) */
|
||||||
uint32_t eid; /**< Extended ID field (18 bits) */
|
uint32_t eid; /**< Extended ID field (18 bits) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Comparison operators
|
// Comparison operators
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equal to operator.
|
* @brief Equal to operator.
|
||||||
*
|
*
|
||||||
* @param lhs Left hand side CAN ID
|
* @param lhs Left hand side CAN ID
|
||||||
* @param rhs Right hand side CAN ID
|
* @param rhs Right hand side CAN ID
|
||||||
* @return True if CAN IDs are equal
|
* @return True if CAN IDs are equal
|
||||||
*
|
*/
|
||||||
* @ingroup canID
|
bool operator ==(const CanId & lhs, const CanId & rhs);
|
||||||
*/
|
/**
|
||||||
bool operator ==(const CanId & lhs, const CanId & rhs);
|
* @brief Not equal to operator.
|
||||||
/**
|
*
|
||||||
* @brief Not equal to operator.
|
* @param lhs Left hand side CAN ID
|
||||||
*
|
* @param rhs Right hand side CAN ID
|
||||||
* @param lhs Left hand side CAN ID
|
* @return True if CAN IDs are not equal
|
||||||
* @param rhs Right hand side CAN ID
|
*/
|
||||||
* @return True if CAN IDs are not equal
|
bool operator !=(const CanId & lhs, const CanId & rhs);
|
||||||
*
|
|
||||||
* @ingroup canID
|
|
||||||
*/
|
|
||||||
bool operator !=(const CanId & lhs, const CanId & rhs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equal to operator.
|
* @brief Equal to operator.
|
||||||
*
|
*
|
||||||
* @param lhs Left hand side CAN Frame ID
|
* @param lhs Left hand side CAN Frame ID
|
||||||
* @param rhs Right hand side CAN Frame ID
|
* @param rhs Right hand side CAN Frame ID
|
||||||
* @return True if CAN Frame IDs are equal
|
* @return True if CAN Frame IDs are equal
|
||||||
*
|
*/
|
||||||
* @ingroup canID
|
bool operator ==(const CanFrameId & lhs, const CanFrameId & rhs);
|
||||||
*/
|
/**
|
||||||
bool operator ==(const CanFrameId & lhs, const CanFrameId & rhs);
|
* @brief Not equal to operator.
|
||||||
/**
|
*
|
||||||
* @brief Not equal to operator.
|
* @param lhs Left hand side CAN Frame ID
|
||||||
*
|
* @param rhs Right hand side CAN Frame ID
|
||||||
* @param lhs Left hand side CAN Frame ID
|
* @return True if CAN Frame IDs are not equal
|
||||||
* @param rhs Right hand side CAN Frame ID
|
*/
|
||||||
* @return True if CAN Frame IDs are not equal
|
bool operator !=(const CanFrameId & lhs, const CanFrameId & rhs);
|
||||||
*
|
|
||||||
* @ingroup canID
|
|
||||||
*/
|
|
||||||
bool operator !=(const CanFrameId & lhs, const CanFrameId & rhs);
|
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum CAN standard ID value.
|
* @brief Maximum CAN standard ID value.
|
||||||
*
|
*
|
||||||
* @ingroup canID
|
* @ingroup sta_core_can_ids
|
||||||
*/
|
*/
|
||||||
#define CAN_SID_MAX UINT32_C(0x7FF)
|
#define CAN_SID_MAX UINT32_C(0x7FF)
|
||||||
/**
|
/**
|
||||||
* @brief Maximum CAN extended ID value.
|
* @brief Maximum CAN extended ID value.
|
||||||
*
|
*
|
||||||
* @ingroup canID
|
* @ingroup sta_core_can_ids
|
||||||
*/
|
*/
|
||||||
#define CAN_EID_MAX UINT32_C(0x3FFFF)
|
#define CAN_EID_MAX UINT32_C(0x3FFFF)
|
||||||
|
|
||||||
|
@ -10,57 +10,72 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
class CanPendingRxFifos
|
/**
|
||||||
{
|
* @brief Iterable container interface for CAN RX flags.
|
||||||
public:
|
*
|
||||||
using value_type = uint8_t;
|
* @ingroup sta_core_can_ids
|
||||||
using reference = value_type &;
|
*/
|
||||||
using const_reference = const value_type &;
|
class CanPendingRxFifos
|
||||||
using size_type = uint8_t;
|
{
|
||||||
|
public:
|
||||||
|
using value_type = uint8_t;
|
||||||
|
using reference = value_type &;
|
||||||
|
using const_reference = const value_type &;
|
||||||
|
using size_type = uint8_t;
|
||||||
|
|
||||||
class const_iterator
|
/**
|
||||||
{
|
* @brief Custom iterator for active RX queues.
|
||||||
public:
|
*/
|
||||||
using value_type = CanPendingRxFifos::value_type;
|
class const_iterator
|
||||||
using reference = const_reference;
|
{
|
||||||
using pointer = const value_type *;
|
public:
|
||||||
|
using value_type = CanPendingRxFifos::value_type;
|
||||||
|
using reference = const_reference;
|
||||||
|
using pointer = const value_type *;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const_iterator(const const_iterator & iter);
|
const_iterator(const const_iterator & iter);
|
||||||
|
|
||||||
const_iterator & operator=(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;
|
||||||
bool operator!=(const const_iterator & iter) const;
|
bool operator!=(const const_iterator & iter) const;
|
||||||
|
|
||||||
const_iterator & operator++();
|
const_iterator & operator++();
|
||||||
const_iterator operator++(int);
|
const_iterator operator++(int);
|
||||||
|
|
||||||
reference operator*() const;
|
reference operator*() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx);
|
const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx);
|
||||||
|
|
||||||
bool isRxPending() const;
|
/**
|
||||||
|
* @brief Check if current RX queue has pending data.
|
||||||
|
*/
|
||||||
|
bool isRxPending() const;
|
||||||
|
|
||||||
friend class CanPendingRxFifos;
|
friend class CanPendingRxFifos;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t rxFlags_;
|
uint32_t rxFlags_; /**< RX flag bits */
|
||||||
uint8_t idx_;
|
uint8_t idx_; /**< Current flag index */
|
||||||
uint8_t endIdx_;
|
uint8_t endIdx_; /**< Iterator end index */
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos);
|
/**
|
||||||
|
* @param rxFlags RX flag bits
|
||||||
|
* @param numFifos Number of RX FIFOs
|
||||||
|
*/
|
||||||
|
CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos);
|
||||||
|
|
||||||
const_iterator begin() const;
|
const_iterator begin() const;
|
||||||
const_iterator end() const;
|
const_iterator end() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t rxFlags_;
|
uint32_t rxFlags_; /**< RX flag bits */
|
||||||
uint8_t numFifos_;
|
uint8_t numFifos_; /**< Number of RX FIFOs */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,90 +11,88 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @defgroup canSub Subscription
|
* @defgroup sta_core_can_sub Subscription
|
||||||
* @ingroup canAPI
|
* @ingroup sta_core_can
|
||||||
* @brief Subscription interface for CAN controller drivers.
|
* @brief Subscription interface for CAN controller drivers.
|
||||||
*/
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback for handling received frames.
|
* @brief Callback for handling received frames.
|
||||||
*
|
*
|
||||||
* @param header Frame header
|
* @param header Frame header
|
||||||
* @param buffer Frame payload buffer
|
* @param buffer Frame payload buffer
|
||||||
*
|
*/
|
||||||
* @ingroup canSub
|
using CanRxCallback = void (*) (const CanRxHeader & header, const uint8_t * buffer);
|
||||||
*/
|
|
||||||
using CanRxCallback = void (*) (const CanRxHeader & header, const uint8_t * buffer);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Filter configuration and message handler.
|
* @brief Filter configuration and message handler.
|
||||||
*
|
*/
|
||||||
* @ingroup canSub
|
struct CanFilterConfig
|
||||||
*/
|
{
|
||||||
struct CanFilterConfig
|
CanFilter filter; /**< Filter handled by callback */
|
||||||
{
|
CanRxCallback callback; /**< Callback for message handling */
|
||||||
CanFilter filter; /**< Filter handled by callback */
|
};
|
||||||
CanRxCallback callback; /**< Callback for message handling */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN controller with subscriptions.
|
* @brief CAN controller with subscriptions.
|
||||||
*
|
*
|
||||||
* @tparam T Implementation of CanController interface
|
* @tparam T Implementation of CanController interface
|
||||||
*
|
*/
|
||||||
* @ingroup canSub
|
template <typename T>
|
||||||
*/
|
class SubscribableCanController : public T
|
||||||
template <typename T>
|
{
|
||||||
class SubscribableCanController : public T
|
public:
|
||||||
{
|
using T::T;
|
||||||
public:
|
|
||||||
using T::T;
|
|
||||||
|
|
||||||
// Subscriptions
|
// Subscriptions
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe to specific message types.
|
* @brief Subscribe to specific message types.
|
||||||
*
|
*
|
||||||
* @param subscriptions Array of message filters and handlers
|
* @param subscriptions Array of message filters and handlers
|
||||||
* @param num Number of array entries
|
* @param num Number of array entries
|
||||||
*/
|
*/
|
||||||
bool subscribe(const CanFilterConfig * subscriptions, uint8_t num);
|
bool subscribe(const CanFilterConfig * subscriptions, uint8_t num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe to all messages.
|
* @brief Subscribe to all messages.
|
||||||
*
|
*
|
||||||
* @param callback Called when message is received
|
* @param callback Called when message is received
|
||||||
* @param fifo FIFO used for received messages
|
* @param fifo FIFO used for received messages
|
||||||
*/
|
*/
|
||||||
void subscribeAll(CanRxCallback callback, uint8_t fifo);
|
void subscribeAll(CanRxCallback callback, uint8_t fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unsubscribe from all messages.
|
* @brief Unsubscribe from all messages.
|
||||||
*
|
*
|
||||||
* No more messages will be received.
|
* No more messages will be received.
|
||||||
*/
|
*/
|
||||||
void unsubscribeAll();
|
void unsubscribeAll();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read message from RX FIFO and notify subscriber.
|
* @brief Read message from RX FIFO and notify subscriber.
|
||||||
*/
|
*/
|
||||||
void receiveAndNotify(uint8_t fifo);
|
void receiveAndNotify(uint8_t fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Process pending frames from RX FIFOs.
|
* @brief Process pending frames from RX FIFOs.
|
||||||
*/
|
*/
|
||||||
void processMessages();
|
void processMessages();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CanRxCallback filterCallbacks_[T::MAX_FILTER_COUNT]; /**< Callbacks for RX filters */
|
CanRxCallback filterCallbacks_[T::MAX_FILTER_COUNT]; /**< Callbacks for RX filters */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,105 +15,105 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool SubscribableCanController<T>::subscribe(const CanFilterConfig * subscriptions, uint8_t num)
|
bool SubscribableCanController<T>::subscribe(const CanFilterConfig * subscriptions, uint8_t num)
|
||||||
{
|
{
|
||||||
// Check bounds
|
// Check bounds
|
||||||
if (num > T::MAX_FILTER_COUNT)
|
if (num > T::MAX_FILTER_COUNT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Clear previous subscriptions
|
// Clear previous subscriptions
|
||||||
unsubscribeAll();
|
unsubscribeAll();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < num; ++i)
|
for (uint8_t i = 0; i < num; ++i)
|
||||||
{
|
{
|
||||||
// Save handler callback
|
// Save handler callback
|
||||||
filterCallbacks_[i] = subscriptions[i].callback;
|
filterCallbacks_[i] = subscriptions[i].callback;
|
||||||
|
|
||||||
// Configure and enable filter
|
// Configure and enable filter
|
||||||
T::configureFilter(i, subscriptions[i].filter, true);
|
T::configureFilter(i, subscriptions[i].filter, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SubscribableCanController<T>::subscribeAll(CanRxCallback callback, uint8_t fifo)
|
void SubscribableCanController<T>::subscribeAll(CanRxCallback callback, uint8_t fifo)
|
||||||
{
|
{
|
||||||
uint8_t filterIdx = 0;
|
uint8_t filterIdx = 0;
|
||||||
|
|
||||||
// Clear previous subscriptions
|
// Clear previous subscriptions
|
||||||
unsubscribeAll();
|
unsubscribeAll();
|
||||||
|
|
||||||
// Setup default filter
|
// Setup default filter
|
||||||
CanFilter filter{};
|
CanFilter filter{};
|
||||||
filter.type = CanFilterIdFormat::ANY;
|
filter.type = CanFilterIdFormat::ANY;
|
||||||
filter.fifo = fifo;
|
filter.fifo = fifo;
|
||||||
|
|
||||||
// Store callback
|
// Store callback
|
||||||
filterCallbacks_[filterIdx] = callback;
|
filterCallbacks_[filterIdx] = callback;
|
||||||
|
|
||||||
// Configure and enable default filter
|
// Configure and enable default filter
|
||||||
T::configureFilter(filterIdx, filter, true);
|
T::configureFilter(filterIdx, filter, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SubscribableCanController<T>::unsubscribeAll()
|
void SubscribableCanController<T>::unsubscribeAll()
|
||||||
{
|
{
|
||||||
// Disable all filters
|
// Disable all filters
|
||||||
T::clearFilters();
|
T::clearFilters();
|
||||||
|
|
||||||
// Clear filter callbacks
|
// Clear filter callbacks
|
||||||
#ifndef STA_STDLIB_DISABLE
|
#ifndef STA_STDLIB_DISABLE
|
||||||
std::fill_n(filterCallbacks_, T::MAX_FILTER_COUNT, nullptr);
|
std::fill_n(filterCallbacks_, T::MAX_FILTER_COUNT, nullptr);
|
||||||
#else // STA_STDLIB_DISABLE
|
#else // STA_STDLIB_DISABLE
|
||||||
for (uint8_t i = 0; i < T::MAX_FILTER_COUNT; ++i)
|
for (uint8_t i = 0; i < T::MAX_FILTER_COUNT; ++i)
|
||||||
{
|
{
|
||||||
filterCallbacks_[i] = nullptr;
|
filterCallbacks_[i] = nullptr;
|
||||||
}
|
}
|
||||||
#endif // STA_STDLIB_DISABLE
|
#endif // STA_STDLIB_DISABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SubscribableCanController<T>::receiveAndNotify(uint8_t fifo)
|
void SubscribableCanController<T>::receiveAndNotify(uint8_t fifo)
|
||||||
{
|
{
|
||||||
CanRxHeader header;
|
CanRxHeader header;
|
||||||
uint8_t payload[T::MAX_PAYLOAD_SIZE];
|
uint8_t payload[T::MAX_PAYLOAD_SIZE];
|
||||||
|
|
||||||
if (T::receiveFrame(fifo, &header, payload))
|
if (T::receiveFrame(fifo, &header, payload))
|
||||||
{
|
{
|
||||||
//displayFrameUART(frame);
|
//displayFrameUART(frame);
|
||||||
|
|
||||||
// Forward frame to filter callback
|
// Forward frame to filter callback
|
||||||
if (fifo <= T::MAX_FILTER_COUNT && filterCallbacks_[header.filter])
|
if (fifo <= T::MAX_FILTER_COUNT && filterCallbacks_[header.filter])
|
||||||
{
|
{
|
||||||
filterCallbacks_[header.filter](header, payload);
|
filterCallbacks_[header.filter](header, payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SubscribableCanController<T>::processMessages()
|
void SubscribableCanController<T>::processMessages()
|
||||||
{
|
{
|
||||||
// Read RX interrupt flags
|
// Read RX interrupt flags
|
||||||
uint32_t RFIF = T::getRxFifoFlags();
|
uint32_t RFIF = T::getRxFifoFlags();
|
||||||
|
|
||||||
if (RFIF != 0)
|
if (RFIF != 0)
|
||||||
{
|
{
|
||||||
// Check all flags
|
// Check all flags
|
||||||
for (uint8_t fifo = 0; fifo < T::MAX_FIFO_COUNT; ++fifo)
|
for (uint8_t fifo = 0; fifo < T::MAX_FIFO_COUNT; ++fifo)
|
||||||
{
|
{
|
||||||
// Process messages if flag is set
|
// Process messages if flag is set
|
||||||
if (RFIF & 0x1)
|
if (RFIF & 0x1)
|
||||||
{
|
{
|
||||||
receiveAndNotify(fifo);
|
receiveAndNotify(fifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift next RX flag to LSB
|
// Shift next RX flag to LSB
|
||||||
RFIF >>= 1;
|
RFIF >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
#ifndef STA_CORE_DEBUG_SERIAL_HPP
|
#ifndef STA_CORE_DEBUG_SERIAL_HPP
|
||||||
#define STA_CORE_DEBUG_SERIAL_HPP
|
#define STA_CORE_DEBUG_SERIAL_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup staCoreDebug Debug Serial
|
|
||||||
* @ingroup staCore
|
|
||||||
* @brief Debug serial output.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
|
|
||||||
@ -35,19 +30,27 @@
|
|||||||
# endif // !STA_DEBUG_SERIAL_FORCE
|
# endif // !STA_DEBUG_SERIAL_FORCE
|
||||||
#endif // STA_DEBUG_SERIAL_UART
|
#endif // STA_DEBUG_SERIAL_UART
|
||||||
|
|
||||||
|
|
||||||
#if defined(STA_DEBUG_SERIAL_ENABLED) || defined(DOXYGEN)
|
#if defined(STA_DEBUG_SERIAL_ENABLED) || defined(DOXYGEN)
|
||||||
|
|
||||||
#include <sta/printable_uart.hpp>
|
#include <sta/printable_uart.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_debug Debug Serial
|
||||||
|
* @ingroup sta_core
|
||||||
|
* @brief Debug serial output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief %UART print object for debug serial output.
|
* @brief %UART print object for debug serial output.
|
||||||
*
|
*
|
||||||
* @ingroup staCoreDebug
|
* @ingroup sta_core_debug
|
||||||
*/
|
*/
|
||||||
extern PrintableUART DebugSerial;
|
extern PrintableUART DebugSerial;
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +59,7 @@ namespace sta
|
|||||||
*
|
*
|
||||||
* @param ... See @ref sta::PrintableUART::print
|
* @param ... See @ref sta::PrintableUART::print
|
||||||
*
|
*
|
||||||
* @ingroup staCoreDebug
|
* @ingroup sta_core_debug
|
||||||
*/
|
*/
|
||||||
# define STA_DEBUG_PRINT(...) sta::DebugSerial.print(__VA_ARGS__)
|
# define STA_DEBUG_PRINT(...) sta::DebugSerial.print(__VA_ARGS__)
|
||||||
/**
|
/**
|
||||||
@ -64,7 +67,7 @@ namespace sta
|
|||||||
*
|
*
|
||||||
* @param ... See @ref sta::PrintableUART::println
|
* @param ... See @ref sta::PrintableUART::println
|
||||||
*
|
*
|
||||||
* @ingroup staCoreDebug
|
* @ingroup sta_core_debug
|
||||||
*/
|
*/
|
||||||
# define STA_DEBUG_PRINTLN(...) sta::DebugSerial.println(__VA_ARGS__)
|
# define STA_DEBUG_PRINTLN(...) sta::DebugSerial.println(__VA_ARGS__)
|
||||||
#else // !STA_DEBUG_SERIAL_ENABLED
|
#else // !STA_DEBUG_SERIAL_ENABLED
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
#ifndef STA_CORE_ENDIAN_HPP
|
#ifndef STA_CORE_ENDIAN_HPP
|
||||||
#define STA_CORE_ENDIAN_HPP
|
#define STA_CORE_ENDIAN_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup staCoreEndian Endian
|
|
||||||
* @ingroup staCore
|
|
||||||
* @brief Endian handling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
|
|
||||||
@ -18,99 +13,95 @@
|
|||||||
#endif // !STA_MCU_BIG_ENDIAN && !STA_MCU_LITTLE_ENDIAN
|
#endif // !STA_MCU_BIG_ENDIAN && !STA_MCU_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_endian Endian
|
||||||
|
* @ingroup sta_core
|
||||||
|
* @brief Endian handling.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get 16-bit value with swapped byte order.
|
* @brief Get 16-bit value with swapped byte order.
|
||||||
*
|
*
|
||||||
* @param u16 16-bit input value
|
* @param u16 16-bit input value
|
||||||
* @return 16-bit value w/ swapped byte order
|
* @return 16-bit value w/ swapped byte order
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT16_SWAP_BYTE_ORDER(u16) \
|
#define STA_UINT16_SWAP_BYTE_ORDER(u16) \
|
||||||
( \
|
( \
|
||||||
((u16 & 0x00FF) << 8) \
|
((u16 & 0x00FF) << 8) \
|
||||||
| ((u16 & 0xFF00) >> 8) \
|
| ((u16 & 0xFF00) >> 8) \
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get 32-bit value with swapped byte order.
|
* @brief Get 32-bit value with swapped byte order.
|
||||||
*
|
*
|
||||||
* @param u32 32-bit input value
|
* @param u32 32-bit input value
|
||||||
* @return 32-bit value w/ swapped byte order
|
* @return 32-bit value w/ swapped byte order
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT32_SWAP_BYTE_ORDER(u32) \
|
#define STA_UINT32_SWAP_BYTE_ORDER(u32) \
|
||||||
( \
|
( \
|
||||||
((u32 & 0x000000FF) << 24) \
|
((u32 & 0x000000FF) << 24) \
|
||||||
| ((u32 & 0x0000FF00) << 8) \
|
| ((u32 & 0x0000FF00) << 8) \
|
||||||
| ((u32 & 0x00FF0000) >> 8) \
|
| ((u32 & 0x00FF0000) >> 8) \
|
||||||
| ((u32 & 0xFF000000) >> 24) \
|
| ((u32 & 0xFF000000) >> 24) \
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get initializer list for byte array with big-endian byte order from 16-bit value.
|
* @brief Get initializer list for byte array with big-endian byte order from 16-bit value.
|
||||||
*
|
*
|
||||||
* @param u16 16-bit input value
|
* @param u16 16-bit input value
|
||||||
* @return Initializer list for uint8_t[2]
|
* @return Initializer list for uint8_t[2]
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT16_TO_BYTES_BE(u16) \
|
#define STA_UINT16_TO_BYTES_BE(u16) \
|
||||||
{ \
|
{ \
|
||||||
static_cast<uint8_t>(u16 >> 8), \
|
static_cast<uint8_t>(u16 >> 8), \
|
||||||
static_cast<uint8_t>(u16) \
|
static_cast<uint8_t>(u16) \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get initializer list for byte array with little-endian byte order from 16-bit value.
|
* @brief Get initializer list for byte array with little-endian byte order from 16-bit value.
|
||||||
*
|
*
|
||||||
* @param u16 16-bit input value
|
* @param u16 16-bit input value
|
||||||
* @return Initializer list for uint8_t[2]
|
* @return Initializer list for uint8_t[2]
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT16_TO_BYTES_LE(u16) \
|
#define STA_UINT16_TO_BYTES_LE(u16) \
|
||||||
{ \
|
{ \
|
||||||
static_cast<uint8_t>(u16), \
|
static_cast<uint8_t>(u16), \
|
||||||
static_cast<uint8_t>(u16 >> 8) \
|
static_cast<uint8_t>(u16 >> 8) \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get initializer list for byte array with big-endian byte order from 32-bit value.
|
* @brief Get initializer list for byte array with big-endian byte order from 32-bit value.
|
||||||
*
|
*
|
||||||
* @param u32 32-bit input value
|
* @param u32 32-bit input value
|
||||||
* @return Initializer list for uint8_t[4]
|
* @return Initializer list for uint8_t[4]
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT32_TO_BYTES_BE(u32) \
|
#define STA_UINT32_TO_BYTES_BE(u32) \
|
||||||
{ \
|
{ \
|
||||||
static_cast<uint8_t>(u32 >> 24), \
|
static_cast<uint8_t>(u32 >> 24), \
|
||||||
static_cast<uint8_t>(u32 >> 16), \
|
static_cast<uint8_t>(u32 >> 16), \
|
||||||
static_cast<uint8_t>(u32 >> 8), \
|
static_cast<uint8_t>(u32 >> 8), \
|
||||||
static_cast<uint8_t>(u32) \
|
static_cast<uint8_t>(u32) \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get initializer list for byte array with little-endian byte order from 32-bit value.
|
* @brief Get initializer list for byte array with little-endian byte order from 32-bit value.
|
||||||
*
|
*
|
||||||
* @param u32 32-bit input value
|
* @param u32 32-bit input value
|
||||||
* @return Initializer list for uint8_t[4]
|
* @return Initializer list for uint8_t[4]
|
||||||
*
|
|
||||||
* @ingroup staCoreEndian
|
|
||||||
*/
|
*/
|
||||||
#define STA_UINT32_TO_BYTES_LE(u32) \
|
#define STA_UINT32_TO_BYTES_LE(u32) \
|
||||||
{ \
|
{ \
|
||||||
static_cast<uint8_t>(u32), \
|
static_cast<uint8_t>(u32), \
|
||||||
static_cast<uint8_t>(u32 >> 8), \
|
static_cast<uint8_t>(u32 >> 8), \
|
||||||
static_cast<uint8_t>(u32 >> 16), \
|
static_cast<uint8_t>(u32 >> 16), \
|
||||||
static_cast<uint8_t>(u32 >> 24) \
|
static_cast<uint8_t>(u32 >> 24) \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defe STA_UINT16_TO_BE(u16)
|
* @def STA_UINT16_TO_BE(u16)
|
||||||
* @brief Convert 16-bit value to big-endian byte order.
|
* @brief Convert 16-bit value to big-endian byte order.
|
||||||
*
|
*
|
||||||
* @param u16 16-bit input value
|
* @param u16 16-bit input value
|
||||||
@ -174,6 +165,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
#ifdef STA_MCU_LITTLE_ENDIAN
|
#ifdef STA_MCU_LITTLE_ENDIAN
|
||||||
|
|
||||||
# define STA_UINT16_TO_BE(u16) STA_UINT16_SWAP_BYTE_ORDER(u16)
|
# define STA_UINT16_TO_BE(u16) STA_UINT16_SWAP_BYTE_ORDER(u16)
|
||||||
@ -186,7 +180,7 @@
|
|||||||
# define STA_UINT32_TO_BYTES(u32) STA_UINT32_TO_BYTES_LE(u32)
|
# define STA_UINT32_TO_BYTES(u32) STA_UINT32_TO_BYTES_LE(u32)
|
||||||
# define STA_UINT32_TO_BYTES_SWAP(u32) STA_UINT32_TO_BYTES_BE(u32)
|
# define STA_UINT32_TO_BYTES_SWAP(u32) STA_UINT32_TO_BYTES_BE(u32)
|
||||||
|
|
||||||
#elif STA_MCU_BIG_ENDIAN
|
#else // STA_MCU_BIG_ENDIAN
|
||||||
|
|
||||||
# define STA_UINT16_TO_BE(u16) (u16)
|
# define STA_UINT16_TO_BE(u16) (u16)
|
||||||
# define STA_UINT16_TO_LE(u16) STA_UINT16_SWAP_BYTE_ORDER(u16)
|
# define STA_UINT16_TO_LE(u16) STA_UINT16_SWAP_BYTE_ORDER(u16)
|
||||||
|
@ -10,143 +10,143 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief 32-bit flag register with enum type representing single flag bits.
|
* @brief 32-bit flag register with enum type representing single flag bits.
|
||||||
*
|
*
|
||||||
* @tparam F Enum type used for flag bits
|
* @tparam F Enum type used for flag bits
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class EnumFlags
|
class EnumFlags
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using flag_type = F; /**< Enum type used for flag bits */
|
using flag_type = F; /**< Enum type used for flag bits */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor.
|
* @brief Default constructor.
|
||||||
*/
|
*/
|
||||||
EnumFlags();
|
EnumFlags();
|
||||||
/**
|
/**
|
||||||
* @brief Copy constructor.
|
* @brief Copy constructor.
|
||||||
*
|
*
|
||||||
* @param other Flags to copy
|
* @param other Flags to copy
|
||||||
*/
|
*/
|
||||||
EnumFlags(const EnumFlags & other);
|
EnumFlags(const EnumFlags & other);
|
||||||
/**
|
/**
|
||||||
* @brief Construct from single flag.
|
* @brief Construct from single flag.
|
||||||
*
|
*
|
||||||
* @param flag Single flag bit to set
|
* @param flag Single flag bit to set
|
||||||
*/
|
*/
|
||||||
EnumFlags(flag_type flag);
|
EnumFlags(flag_type flag);
|
||||||
|
|
||||||
|
|
||||||
// Modification
|
// Modification
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set bits from flags register.
|
* @brief Set bits from flags register.
|
||||||
*
|
*
|
||||||
* @param flags Flag bits to set
|
* @param flags Flag bits to set
|
||||||
*/
|
*/
|
||||||
void set(const EnumFlags & flags);
|
void set(const EnumFlags & flags);
|
||||||
/**
|
/**
|
||||||
* @brief Clear flag bits.
|
* @brief Clear flag bits.
|
||||||
*
|
*
|
||||||
* @param flags Flag bits to clear
|
* @param flags Flag bits to clear
|
||||||
*/
|
*/
|
||||||
void clear(const EnumFlags & flags);
|
void clear(const EnumFlags & flags);
|
||||||
/**
|
/**
|
||||||
* @brief Clear all flag bits.
|
* @brief Clear all flag bits.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
// Inspection
|
// Inspection
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Test if all flags are set.
|
* @brief Test if all flags are set.
|
||||||
*
|
*
|
||||||
* @param flags Flag bits to check
|
* @param flags Flag bits to check
|
||||||
* @return True if all checked flag bits are set
|
* @return True if all checked flag bits are set
|
||||||
*/
|
*/
|
||||||
bool isSet(const EnumFlags & flags) const;
|
bool isSet(const EnumFlags & flags) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Test if any flag is set.
|
* @brief Test if any flag is set.
|
||||||
*
|
*
|
||||||
* @param flags Flag bits to check
|
* @param flags Flag bits to check
|
||||||
* @return True if any checked flag bit is set
|
* @return True if any checked flag bit is set
|
||||||
*/
|
*/
|
||||||
bool isAnySet(const EnumFlags & flags) const;
|
bool isAnySet(const EnumFlags & flags) const;
|
||||||
|
|
||||||
|
|
||||||
// Operator overloads
|
// Operator overloads
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equal to operator.
|
* @brief Equal to operator.
|
||||||
*
|
*
|
||||||
* @param rhs Flags to compare
|
* @param rhs Flags to compare
|
||||||
* @return True if flags are equal
|
* @return True if flags are equal
|
||||||
*/
|
*/
|
||||||
bool operator ==(const EnumFlags & rhs) const;
|
bool operator ==(const EnumFlags & rhs) const;
|
||||||
/**
|
/**
|
||||||
* @brief Not equal to operator.
|
* @brief Not equal to operator.
|
||||||
*
|
*
|
||||||
* @param rhs Flags to compare
|
* @param rhs Flags to compare
|
||||||
* @return True if flags are not equal
|
* @return True if flags are not equal
|
||||||
*/
|
*/
|
||||||
bool operator !=(const EnumFlags & rhs) const;
|
bool operator !=(const EnumFlags & rhs) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bitwise AND operator.
|
* @brief Bitwise AND operator.
|
||||||
*
|
*
|
||||||
* @param rhs Other flags
|
* @param rhs Other flags
|
||||||
* @return Result of bitwise AND
|
* @return Result of bitwise AND
|
||||||
*/
|
*/
|
||||||
EnumFlags operator &(const EnumFlags & rhs) const;
|
EnumFlags operator &(const EnumFlags & rhs) const;
|
||||||
/**
|
/**
|
||||||
* @brief Bitwise OR operator.
|
* @brief Bitwise OR operator.
|
||||||
*
|
*
|
||||||
* @param rhs Other flags
|
* @param rhs Other flags
|
||||||
* @return Result of bitwise OR
|
* @return Result of bitwise OR
|
||||||
*/
|
*/
|
||||||
EnumFlags operator |(const EnumFlags & rhs) const;
|
EnumFlags operator |(const EnumFlags & rhs) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bitwise AND assignment operator.
|
* @brief Bitwise AND assignment operator.
|
||||||
*
|
*
|
||||||
* @param rhs Other flags
|
* @param rhs Other flags
|
||||||
* @return Reference to this
|
* @return Reference to this
|
||||||
*/
|
*/
|
||||||
EnumFlags & operator &=(const EnumFlags & rhs);
|
EnumFlags & operator &=(const EnumFlags & rhs);
|
||||||
/**
|
/**
|
||||||
* @brief Bitwise OR assignment operator.
|
* @brief Bitwise OR assignment operator.
|
||||||
*
|
*
|
||||||
* @param rhs Other flags
|
* @param rhs Other flags
|
||||||
* @return Reference to this
|
* @return Reference to this
|
||||||
*/
|
*/
|
||||||
EnumFlags & operator |=(const EnumFlags & rhs);
|
EnumFlags & operator |=(const EnumFlags & rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Explicitly convert flags to uint32_t.
|
* @brief Explicitly convert flags to uint32_t.
|
||||||
*/
|
*/
|
||||||
explicit operator uint32_t();
|
explicit operator uint32_t();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Construct from uint32_t flags.
|
* @brief Construct from uint32_t flags.
|
||||||
*
|
*
|
||||||
* @param flags Flags
|
* @param flags Flags
|
||||||
*/
|
*/
|
||||||
EnumFlags(uint32_t flags);
|
EnumFlags(uint32_t flags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t flags_; /**< Flags register */
|
uint32_t flags_; /**< Flags register */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
@ -155,23 +155,23 @@ namespace sta
|
|||||||
*
|
*
|
||||||
* @param enumType Enum type to overload
|
* @param enumType Enum type to overload
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
#define STA_ENUM_FLAGS_OVERLOAD(enumType) \
|
#define STA_ENUM_FLAGS_OVERLOAD(enumType) \
|
||||||
sta::EnumFlags<enumType> operator |(enumType lhs, enumType rhs) \
|
sta::EnumFlags<enumType> operator |(enumType lhs, enumType rhs) \
|
||||||
{ \
|
{ \
|
||||||
return sta::EnumFlags<enumType>{lhs} | rhs; \
|
return sta::EnumFlags<enumType>{lhs} | rhs; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Declare alias for sta::EnumFlags specialization.
|
* @brief Declare alias for sta::EnumFlags specialization.
|
||||||
*
|
*
|
||||||
* @param enumType Enum type for specialization
|
* @param enumType Enum type for specialization
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
#define STA_ENUM_FLAGS_ALIAS(enumType) \
|
#define STA_ENUM_FLAGS_ALIAS(enumType) \
|
||||||
using enumType ## Flags = sta::EnumFlags<enumType>
|
using enumType ## Flags = sta::EnumFlags<enumType>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Declare enum and create sta::EnumFlags alias and overloads.
|
* @brief Declare enum and create sta::EnumFlags alias and overloads.
|
||||||
@ -180,15 +180,15 @@ namespace sta
|
|||||||
* @param value1 First enum value
|
* @param value1 First enum value
|
||||||
* @param ... Enum values 2 - 32
|
* @param ... Enum values 2 - 32
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
#define STA_ENUM_FLAGS_DECL(enumType, value1, ...) \
|
#define STA_ENUM_FLAGS_DECL(enumType, value1, ...) \
|
||||||
enum class enumType \
|
enum class enumType \
|
||||||
{ \
|
{ \
|
||||||
value1, ##__VA_ARGS__ \
|
value1, ##__VA_ARGS__ \
|
||||||
}; \
|
}; \
|
||||||
STA_ENUM_FLAGS_ALIAS(enumType); \
|
STA_ENUM_FLAGS_ALIAS(enumType); \
|
||||||
STA_ENUM_FLAGS_OVERLOAD(enumType)
|
STA_ENUM_FLAGS_OVERLOAD(enumType)
|
||||||
|
|
||||||
|
|
||||||
// Include template implementation
|
// Include template implementation
|
||||||
|
@ -11,105 +11,105 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F>::EnumFlags()
|
EnumFlags<F>::EnumFlags()
|
||||||
: flags_{0}
|
: flags_{0}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F>::EnumFlags(const EnumFlags & other)
|
EnumFlags<F>::EnumFlags(const EnumFlags & other)
|
||||||
: flags_{other.flags_}
|
: flags_{other.flags_}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F>::EnumFlags(flag_type flag)
|
EnumFlags<F>::EnumFlags(flag_type flag)
|
||||||
: flags_{1U << static_cast<uint8_t>(flag)}
|
: flags_{1U << static_cast<uint8_t>(flag)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F>::EnumFlags(uint32_t flags)
|
EnumFlags<F>::EnumFlags(uint32_t flags)
|
||||||
: flags_{flags}
|
: flags_{flags}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void EnumFlags<F>::set(const EnumFlags & flags)
|
void EnumFlags<F>::set(const EnumFlags & flags)
|
||||||
{
|
{
|
||||||
flags_ |= flags.flags_;
|
flags_ |= flags.flags_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void EnumFlags<F>::clear(const EnumFlags & flags)
|
void EnumFlags<F>::clear(const EnumFlags & flags)
|
||||||
{
|
{
|
||||||
flags_ &= ~(flags.flags_);
|
flags_ &= ~(flags.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void EnumFlags<F>::clear()
|
void EnumFlags<F>::clear()
|
||||||
{
|
{
|
||||||
flags_ = 0;
|
flags_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool EnumFlags<F>::isSet(const EnumFlags & flags) const
|
bool EnumFlags<F>::isSet(const EnumFlags & flags) const
|
||||||
{
|
{
|
||||||
return (flags_ & flags.flags_) == flags.flags_;
|
return (flags_ & flags.flags_) == flags.flags_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool EnumFlags<F>::isAnySet(const EnumFlags & flags) const
|
bool EnumFlags<F>::isAnySet(const EnumFlags & flags) const
|
||||||
{
|
{
|
||||||
return (flags_ & flags.flags_) != 0;
|
return (flags_ & flags.flags_) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool EnumFlags<F>::operator ==(const EnumFlags<F> & rhs) const
|
bool EnumFlags<F>::operator ==(const EnumFlags<F> & rhs) const
|
||||||
{
|
{
|
||||||
return (flags_ == rhs.flags_);
|
return (flags_ == rhs.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool EnumFlags<F>::operator !=(const EnumFlags<F> & rhs) const
|
bool EnumFlags<F>::operator !=(const EnumFlags<F> & rhs) const
|
||||||
{
|
{
|
||||||
return (flags_ != rhs.flags_);
|
return (flags_ != rhs.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F> EnumFlags<F>::operator &(const EnumFlags<F> & rhs) const
|
EnumFlags<F> EnumFlags<F>::operator &(const EnumFlags<F> & rhs) const
|
||||||
{
|
{
|
||||||
return EnumFlags(flags_ & rhs.flags_);
|
return EnumFlags(flags_ & rhs.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F> EnumFlags<F>::operator |(const EnumFlags<F> & rhs) const
|
EnumFlags<F> EnumFlags<F>::operator |(const EnumFlags<F> & rhs) const
|
||||||
{
|
{
|
||||||
return EnumFlags(flags_ | rhs.flags_);
|
return EnumFlags(flags_ | rhs.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F> & EnumFlags<F>::operator &=(const EnumFlags<F> & rhs)
|
EnumFlags<F> & EnumFlags<F>::operator &=(const EnumFlags<F> & rhs)
|
||||||
{
|
{
|
||||||
flags_ &= rhs.flags_;
|
flags_ &= rhs.flags_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F> & EnumFlags<F>::operator |=(const EnumFlags<F> & rhs)
|
EnumFlags<F> & EnumFlags<F>::operator |=(const EnumFlags<F> & rhs)
|
||||||
{
|
{
|
||||||
flags_ |= rhs.flags_;
|
flags_ |= rhs.flags_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
EnumFlags<F>::operator uint32_t()
|
EnumFlags<F>::operator uint32_t()
|
||||||
{
|
{
|
||||||
return flags_;
|
return flags_;
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,107 +8,107 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief FIFO buffer.
|
* @brief FIFO buffer.
|
||||||
*
|
*
|
||||||
* @tparam Size Size type
|
* @tparam Size Size type
|
||||||
* @tparam N Buffer size
|
* @tparam N Buffer size
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
class FifoBuffer
|
class FifoBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief FIFO size type.
|
* @brief FIFO size type.
|
||||||
*/
|
*/
|
||||||
using size_type = Size;
|
using size_type = Size;
|
||||||
/**
|
/**
|
||||||
* @brief Max number of bytes in FIFO.
|
* @brief Max number of bytes in FIFO.
|
||||||
*/
|
*/
|
||||||
static constexpr size_type MAX_SIZE = N;
|
static constexpr size_type MAX_SIZE = N;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Construct empty FIFO buffer.
|
* @brief Construct empty FIFO buffer.
|
||||||
*/
|
*/
|
||||||
FifoBuffer();
|
FifoBuffer();
|
||||||
/**
|
/**
|
||||||
* @brief Construct FIFO buffer with initial data.
|
* @brief Construct FIFO buffer with initial data.
|
||||||
*
|
*
|
||||||
* @param buffer Source buffer
|
* @param buffer Source buffer
|
||||||
* @param size Buffer size
|
* @param size Buffer size
|
||||||
*/
|
*/
|
||||||
FifoBuffer(const uint8_t * buffer, Size size);
|
FifoBuffer(const uint8_t * buffer, Size size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clear buffer content.
|
* @brief Clear buffer content.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set data in buffer.
|
* @brief Set data in buffer.
|
||||||
*
|
*
|
||||||
* @param buffer Source buffer
|
* @param buffer Source buffer
|
||||||
* @param size Number of bytes to write
|
* @param size Number of bytes to write
|
||||||
*/
|
*/
|
||||||
void set(const uint8_t * buffer, size_type size);
|
void set(const uint8_t * buffer, size_type size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Append value to end of buffer.
|
* @brief Append value to end of buffer.
|
||||||
*
|
*
|
||||||
* @param value Value
|
* @param value Value
|
||||||
*/
|
*/
|
||||||
void pushBack(uint8_t value);
|
void pushBack(uint8_t value);
|
||||||
/**
|
/**
|
||||||
* @brief Append data to end of buffer.
|
* @brief Append data to end of buffer.
|
||||||
*
|
*
|
||||||
* @param buffer Source buffer
|
* @param buffer Source buffer
|
||||||
* @param size Number of bytes to write
|
* @param size Number of bytes to write
|
||||||
*/
|
*/
|
||||||
void pushBack(const uint8_t * buffer, size_type size);
|
void pushBack(const uint8_t * buffer, size_type size);
|
||||||
/**
|
/**
|
||||||
* @brief Append value repeatedly to end of buffer.
|
* @brief Append value repeatedly to end of buffer.
|
||||||
*
|
*
|
||||||
* @param value Fill value
|
* @param value Fill value
|
||||||
* @param count Repeat count
|
* @param count Repeat count
|
||||||
*/
|
*/
|
||||||
void pushBack(uint8_t value, size_type count);
|
void pushBack(uint8_t value, size_type count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Take data from start of buffer.
|
* @brief Take data from start of buffer.
|
||||||
*
|
*
|
||||||
* @param buffer Destination buffer
|
* @param buffer Destination buffer
|
||||||
* @param size Number of bytes to read
|
* @param size Number of bytes to read
|
||||||
*/
|
*/
|
||||||
void popFront(uint8_t * buffer, size_type size);
|
void popFront(uint8_t * buffer, size_type size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get size of data in buffer.
|
* @brief Get size of data in buffer.
|
||||||
*
|
*
|
||||||
* @return Data size
|
* @return Data size
|
||||||
*/
|
*/
|
||||||
size_type size() const;
|
size_type size() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if buffer is full.
|
* @brief Check if buffer is full.
|
||||||
*
|
*
|
||||||
* @return True if buffer is full
|
* @return True if buffer is full
|
||||||
*/
|
*/
|
||||||
bool isFull() const;
|
bool isFull() const;
|
||||||
/**
|
/**
|
||||||
* @brief Check if buffer is empty.
|
* @brief Check if buffer is empty.
|
||||||
*
|
*
|
||||||
* @return True if buffer is empty
|
* @return True if buffer is empty
|
||||||
*/
|
*/
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t * head_; /**< Read position */
|
uint8_t * head_; /**< Read position */
|
||||||
uint8_t * tail_; /**< Write position */
|
uint8_t * tail_; /**< Write position */
|
||||||
uint8_t buffer_[N]; /**< Buffer data */
|
uint8_t buffer_[N]; /**< Buffer data */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,93 +10,93 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
FifoBuffer<Size, N>::FifoBuffer()
|
FifoBuffer<Size, N>::FifoBuffer()
|
||||||
: head_{buffer_}, tail_{buffer_}
|
: head_{buffer_}, tail_{buffer_}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
FifoBuffer<Size, N>::FifoBuffer(const uint8_t * buffer, size_type size)
|
FifoBuffer<Size, N>::FifoBuffer(const uint8_t * buffer, size_type size)
|
||||||
{
|
{
|
||||||
set(buffer, size);
|
set(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::set(const uint8_t * buffer, size_type bsize)
|
void FifoBuffer<Size, N>::set(const uint8_t * buffer, size_type bsize)
|
||||||
{
|
{
|
||||||
STA_ASSERT(bsize <= sizeof(buffer_));
|
STA_ASSERT(bsize <= sizeof(buffer_));
|
||||||
STA_ASSERT(buffer != nullptr);
|
STA_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
head_ = buffer_;
|
head_ = buffer_;
|
||||||
tail_ = buffer_ + bsize;
|
tail_ = buffer_ + bsize;
|
||||||
memcpy(buffer_, buffer, bsize);
|
memcpy(buffer_, buffer, bsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::clear()
|
void FifoBuffer<Size, N>::clear()
|
||||||
{
|
{
|
||||||
head_ = tail_ = buffer_;
|
head_ = tail_ = buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::pushBack(uint8_t value)
|
void FifoBuffer<Size, N>::pushBack(uint8_t value)
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(tail_ < buffer_ + sizeof(buffer_), "Buffer overflow");
|
STA_ASSERT_MSG(tail_ < buffer_ + sizeof(buffer_), "Buffer overflow");
|
||||||
|
|
||||||
*tail_++ = value;
|
*tail_++ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::pushBack(const uint8_t * buffer, size_type bsize)
|
void FifoBuffer<Size, N>::pushBack(const uint8_t * buffer, size_type bsize)
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(size() + bsize <= sizeof(buffer_), "Buffer overflow");
|
STA_ASSERT_MSG(size() + bsize <= sizeof(buffer_), "Buffer overflow");
|
||||||
STA_ASSERT(buffer != nullptr);
|
STA_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
memcpy(tail_, buffer, bsize);
|
memcpy(tail_, buffer, bsize);
|
||||||
tail_ += bsize;
|
tail_ += bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::pushBack(uint8_t value, size_type count)
|
void FifoBuffer<Size, N>::pushBack(uint8_t value, size_type count)
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(size() + count <= sizeof(buffer_), "Buffer overflow");
|
STA_ASSERT_MSG(size() + count <= sizeof(buffer_), "Buffer overflow");
|
||||||
|
|
||||||
memset(tail_, value, count);
|
memset(tail_, value, count);
|
||||||
tail_ += count;
|
tail_ += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
void FifoBuffer<Size, N>::popFront(uint8_t * buffer, size_type bsize)
|
void FifoBuffer<Size, N>::popFront(uint8_t * buffer, size_type bsize)
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(size() >= bsize, "Not enough data");
|
STA_ASSERT_MSG(size() >= bsize, "Not enough data");
|
||||||
STA_ASSERT(buffer != nullptr);
|
STA_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
memcpy(buffer, head_, bsize);
|
memcpy(buffer, head_, bsize);
|
||||||
head_ += bsize;
|
head_ += bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
typename FifoBuffer<Size, N>::size_type FifoBuffer<Size, N>::size() const
|
typename FifoBuffer<Size, N>::size_type FifoBuffer<Size, N>::size() const
|
||||||
{
|
{
|
||||||
return (tail_ - head_);
|
return (tail_ - head_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
bool FifoBuffer<Size, N>::isFull() const
|
bool FifoBuffer<Size, N>::isFull() const
|
||||||
{
|
{
|
||||||
return (tail_ == buffer_ + sizeof(buffer_));
|
return (tail_ == buffer_ + sizeof(buffer_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Size, Size N>
|
template <typename Size, Size N>
|
||||||
bool FifoBuffer<Size, N>::isEmpty() const
|
bool FifoBuffer<Size, N>::isEmpty() const
|
||||||
{
|
{
|
||||||
return (head_ == tail_);
|
return (head_ == tail_);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,28 +8,39 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief GPIO pin state.
|
* @defgroup sta_core_gpio GPIO
|
||||||
*/
|
* @ingroup sta_core
|
||||||
enum class GpioPinState
|
* @brief GPIO pins.
|
||||||
{
|
* @{
|
||||||
LOW,
|
*/
|
||||||
HIGH
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Interface for GPIO pins.
|
/**
|
||||||
*/
|
* @brief GPIO pin state.
|
||||||
class GpioPin
|
*/
|
||||||
{
|
enum class GpioPinState
|
||||||
public:
|
{
|
||||||
/**
|
LOW,
|
||||||
* @brief Set pin output state.
|
HIGH
|
||||||
*
|
};
|
||||||
* @param state Output state
|
|
||||||
*/
|
/**
|
||||||
virtual void setState(GpioPinState state) = 0;
|
* @brief Interface for GPIO pins.
|
||||||
};
|
*/
|
||||||
|
class GpioPin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Set pin output state.
|
||||||
|
*
|
||||||
|
* @param state Output state
|
||||||
|
*/
|
||||||
|
virtual void setState(GpioPinState state) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
#ifndef STA_CORE_LANG_HPP
|
#ifndef STA_CORE_LANG_HPP
|
||||||
#define STA_CORE_LANG_HPP
|
#define STA_CORE_LANG_HPP
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup staCoreLang Lang
|
* @defgroup sta_core_lang Lang
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
* @brief Compiler instructions.
|
* @brief Compiler instructions.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -8,23 +8,25 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Interface for mutex objects.
|
* @brief Interface for mutex objects.
|
||||||
*/
|
*
|
||||||
class Mutex
|
* @ingroup sta_core
|
||||||
{
|
*/
|
||||||
public:
|
class Mutex
|
||||||
/**
|
{
|
||||||
* @brief Block until mutex has been acquired.
|
public:
|
||||||
*/
|
/**
|
||||||
virtual void acquire() = 0;
|
* @brief Block until mutex has been acquired.
|
||||||
/**
|
*/
|
||||||
* @brief Release mutex.
|
virtual void acquire() = 0;
|
||||||
*/
|
/**
|
||||||
virtual void release() = 0;
|
* @brief Release mutex.
|
||||||
|
*/
|
||||||
|
virtual void release() = 0;
|
||||||
|
|
||||||
static Mutex * ALWAYS_FREE; /**< Fake mutex that can always be acquired */
|
static Mutex * ALWAYS_FREE; /**< Fake mutex that can always be acquired */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,191 +13,191 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Integer representation.
|
* @brief Integer representation.
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
enum class IntegerBase
|
enum class IntegerBase
|
||||||
{
|
{
|
||||||
DEC, /**< Decimal */
|
DEC, /**< Decimal */
|
||||||
BIN, /**< Binary */
|
BIN, /**< Binary */
|
||||||
HEX /**< Hexadecimal */
|
HEX /**< Hexadecimal */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Printable interface for UART.
|
* @brief Printable interface for UART.
|
||||||
*
|
*
|
||||||
* @ingroup staCore
|
* @ingroup sta_core
|
||||||
*/
|
*/
|
||||||
class PrintableUART
|
class PrintableUART
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param intf UART instance
|
* @param intf UART instance
|
||||||
*/
|
*/
|
||||||
PrintableUART(UART * intf);
|
PrintableUART(UART * intf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print single character.
|
* @brief Print single character.
|
||||||
*
|
*
|
||||||
* @param c Character to print
|
* @param c Character to print
|
||||||
*/
|
*/
|
||||||
void print(char c);
|
void print(char c);
|
||||||
/**
|
/**
|
||||||
* @brief Print boolean value.
|
* @brief Print boolean value.
|
||||||
*
|
*
|
||||||
* @param b Boolean value
|
* @param b Boolean value
|
||||||
*/
|
*/
|
||||||
void print(bool b);
|
void print(bool b);
|
||||||
/**
|
/**
|
||||||
* @brief Print floating point value.
|
* @brief Print floating point value.
|
||||||
*
|
*
|
||||||
* @param d Floating point value
|
* @param d Floating point value
|
||||||
*/
|
*/
|
||||||
void print(double d);
|
void print(double d);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base.
|
* @brief Print integer in selected base.
|
||||||
*
|
*
|
||||||
* @param num 8-bit unsigned integer
|
* @param num 8-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void print(uint8_t num, IntegerBase base = IntegerBase::DEC);
|
void print(uint8_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base.
|
* @brief Print integer in selected base.
|
||||||
*
|
*
|
||||||
* @param num 16-bit unsigned integer
|
* @param num 16-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void print(uint16_t num, IntegerBase base = IntegerBase::DEC);
|
void print(uint16_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base.
|
* @brief Print integer in selected base.
|
||||||
*
|
*
|
||||||
* @param num 32-bit unsigned integer
|
* @param num 32-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void print(uint32_t num, IntegerBase base = IntegerBase::DEC);
|
void print(uint32_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base.
|
* @brief Print integer in selected base.
|
||||||
*
|
*
|
||||||
* @param num Integer
|
* @param num Integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void print(size_t num, IntegerBase base = IntegerBase::DEC);
|
void print(size_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print c-string.
|
* @brief Print c-string.
|
||||||
*
|
*
|
||||||
* @param str Null terminated string
|
* @param str Null terminated string
|
||||||
*/
|
*/
|
||||||
void print(const char * str);
|
void print(const char * str);
|
||||||
/**
|
/**
|
||||||
* @brief Print string.
|
* @brief Print string.
|
||||||
*
|
*
|
||||||
* @param str String buffer
|
* @param str String buffer
|
||||||
* @param length String length
|
* @param length String length
|
||||||
*/
|
*/
|
||||||
void print(const char * str, size_t length);
|
void print(const char * str, size_t length);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print new-line.
|
* @brief Print new-line.
|
||||||
*/
|
*/
|
||||||
void println();
|
void println();
|
||||||
/**
|
/**
|
||||||
* @brief Print single character followed by a new-line.
|
* @brief Print single character followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param c Character to print
|
* @param c Character to print
|
||||||
*/
|
*/
|
||||||
void println(char c);
|
void println(char c);
|
||||||
/**
|
/**
|
||||||
* @brief Print boolean value followed by a new-line.
|
* @brief Print boolean value followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param b Boolean value
|
* @param b Boolean value
|
||||||
*/
|
*/
|
||||||
void println(bool b);
|
void println(bool b);
|
||||||
/**
|
/**
|
||||||
* @brief Print floating point value followed by a new-line.
|
* @brief Print floating point value followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param d Floating point value
|
* @param d Floating point value
|
||||||
*/
|
*/
|
||||||
void println(double d);
|
void println(double d);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base followed by a new-line.
|
* @brief Print integer in selected base followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param num 8-bit unsigned integer
|
* @param num 8-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void println(uint8_t num, IntegerBase base = IntegerBase::DEC);
|
void println(uint8_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base followed by a new-line.
|
* @brief Print integer in selected base followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param num 16-bit unsigned integer
|
* @param num 16-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void println(uint16_t num, IntegerBase base = IntegerBase::DEC);
|
void println(uint16_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base followed by a new-line.
|
* @brief Print integer in selected base followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param num 32-bit unsigned integer
|
* @param num 32-bit unsigned integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void println(uint32_t num, IntegerBase base = IntegerBase::DEC);
|
void println(uint32_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print integer in selected base followed by a new-line.
|
* @brief Print integer in selected base followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param num Integer
|
* @param num Integer
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
*/
|
*/
|
||||||
void println(size_t num, IntegerBase base = IntegerBase::DEC);
|
void println(size_t num, IntegerBase base = IntegerBase::DEC);
|
||||||
/**
|
/**
|
||||||
* @brief Print c-string followed by a new-line.
|
* @brief Print c-string followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param str Null terminated string
|
* @param str Null terminated string
|
||||||
*/
|
*/
|
||||||
void println(const char * str);
|
void println(const char * str);
|
||||||
/**
|
/**
|
||||||
* @brief Print string followed by a new-line.
|
* @brief Print string followed by a new-line.
|
||||||
*
|
*
|
||||||
* @param str String buffer
|
* @param str String buffer
|
||||||
* @param length String length
|
* @param length String length
|
||||||
*/
|
*/
|
||||||
void println(const char * str, size_t length);
|
void println(const char * str, size_t length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Print unsigned integer in selected base.
|
* @brief Print unsigned integer in selected base.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
* @param base Integer base
|
* @param base Integer base
|
||||||
* @param fmt printf format string for base 10
|
* @param fmt printf format string for base 10
|
||||||
* @param size Size of value in bytes
|
* @param size Size of value in bytes
|
||||||
*/
|
*/
|
||||||
void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size);
|
void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size);
|
||||||
/**
|
/**
|
||||||
* @brief Print unsigned integer in base 10.
|
* @brief Print unsigned integer in base 10.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
* @param fmt printf format string
|
* @param fmt printf format string
|
||||||
*/
|
*/
|
||||||
void printDec(uintmax_t value, const char * fmt);
|
void printDec(uintmax_t value, const char * fmt);
|
||||||
/**
|
/**
|
||||||
* @brief Print unsigned integer in base 2.
|
* @brief Print unsigned integer in base 2.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
* @param digits Number of digits to print
|
* @param digits Number of digits to print
|
||||||
*/
|
*/
|
||||||
void printBin(uintmax_t value, size_t digits);
|
void printBin(uintmax_t value, size_t digits);
|
||||||
/**
|
/**
|
||||||
* @brief Print unsigned integer in base 16.
|
* @brief Print unsigned integer in base 16.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
* @param digits Number of digits to print
|
* @param digits Number of digits to print
|
||||||
*/
|
*/
|
||||||
void printHex(uintmax_t value, size_t digits);
|
void printHex(uintmax_t value, size_t digits);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UART * intf_;
|
UART * intf_;
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,33 +8,35 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Interface for signal objects.
|
* @brief Interface for signal objects.
|
||||||
*/
|
*
|
||||||
class Signal
|
* @ingroup sta_core
|
||||||
{
|
*/
|
||||||
public:
|
class Signal
|
||||||
/**
|
{
|
||||||
* @brief Enter signaled state.
|
public:
|
||||||
*/
|
/**
|
||||||
virtual void notify() = 0;
|
* @brief Enter signaled state.
|
||||||
/**
|
*/
|
||||||
* @brief Check signal state w/o changing it.
|
virtual void notify() = 0;
|
||||||
*
|
/**
|
||||||
* @return True if in signaled state
|
* @brief Check signal state w/o changing it.
|
||||||
*/
|
*
|
||||||
virtual bool peek() = 0;
|
* @return True if in signaled state
|
||||||
/**
|
*/
|
||||||
* @brief Check signal state.
|
virtual bool peek() = 0;
|
||||||
*
|
/**
|
||||||
* @return True if in signaled state
|
* @brief Check signal state.
|
||||||
*/
|
*
|
||||||
virtual bool test() = 0;
|
* @return True if in signaled state
|
||||||
/**
|
*/
|
||||||
* @brief Wait until signaled state is entered.
|
virtual bool test() = 0;
|
||||||
*/
|
/**
|
||||||
virtual void wait() = 0;
|
* @brief Wait until signaled state is entered.
|
||||||
};
|
*/
|
||||||
|
virtual void wait() = 0;
|
||||||
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#define STA_CORE_STM32_CAN_HPP
|
#define STA_CORE_STM32_CAN_HPP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup stm32CAN CAN
|
* @defgroup sta_core_stm32_can CAN
|
||||||
* @ingroup stm32
|
* @ingroup sta_core_stm32
|
||||||
* @brief STM32 CAN module.
|
* @brief STM32 CAN module.
|
||||||
*
|
*
|
||||||
* Check @ref stm32BuildConfig for configuration options.
|
* Check @ref stm32BuildConfig for configuration options.
|
||||||
@ -33,84 +33,84 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of CanController interface using HAL.
|
* @brief Implementation of CanController interface using HAL.
|
||||||
*
|
*
|
||||||
* @ingroup stm32CAN
|
* @ingroup sta_core_stm32_can
|
||||||
*/
|
*/
|
||||||
class STM32CanController : public CanController
|
class STM32CanController : public CanController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t MAX_FILTER_COUNT = 14; /**< Max number of filters */
|
static constexpr uint8_t MAX_FILTER_COUNT = 14; /**< Max number of filters */
|
||||||
static constexpr uint8_t MAX_FIFO_COUNT = 2; /**< Max number of FIFOs */
|
static constexpr uint8_t MAX_FIFO_COUNT = 2; /**< Max number of FIFOs */
|
||||||
static constexpr uint8_t MAX_PAYLOAD_SIZE = 8; /**< Maximum payload size */
|
static constexpr uint8_t MAX_PAYLOAD_SIZE = 8; /**< Maximum payload size */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param handle CAN handle
|
* @param handle CAN handle
|
||||||
*/
|
*/
|
||||||
STM32CanController(CAN_HandleTypeDef * handle);
|
STM32CanController(CAN_HandleTypeDef * handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable RX pending interrupts.
|
* @brief Enable RX pending interrupts.
|
||||||
*/
|
*/
|
||||||
void enableRxInterrupts();
|
void enableRxInterrupts();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start CAN controller.
|
* @brief Start CAN controller.
|
||||||
*/
|
*/
|
||||||
void start();
|
void start();
|
||||||
/**
|
/**
|
||||||
* @brief Stop CAN controller.
|
* @brief Stop CAN controller.
|
||||||
*/
|
*/
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
|
||||||
// RX/TX
|
// RX/TX
|
||||||
//
|
//
|
||||||
|
|
||||||
bool sendFrame(const CanTxHeader & header, const uint8_t * payload) override;
|
bool sendFrame(const CanTxHeader & header, const uint8_t * payload) override;
|
||||||
bool receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload) override;
|
bool receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload) override;
|
||||||
|
|
||||||
uint32_t getRxFifoFlags() override;
|
uint32_t getRxFifoFlags() override;
|
||||||
|
|
||||||
// RX Filter
|
// RX Filter
|
||||||
//
|
//
|
||||||
|
|
||||||
void configureFilter(uint8_t idx, const CanFilter & filter, bool active = false) override;
|
void configureFilter(uint8_t idx, const CanFilter & filter, bool active = false) override;
|
||||||
void enableFilter(uint8_t idx) override;
|
void enableFilter(uint8_t idx) override;
|
||||||
void disableFilter(uint8_t idx) override;
|
void disableFilter(uint8_t idx) override;
|
||||||
void clearFilters() override;
|
void clearFilters() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Initialize filter settings.
|
* @brief Initialize filter settings.
|
||||||
*/
|
*/
|
||||||
void initFilters();
|
void initFilters();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CAN_HandleTypeDef * handle_; /**< CAN handle */
|
CAN_HandleTypeDef * handle_; /**< CAN handle */
|
||||||
CAN_FilterTypeDef filters_[MAX_FILTER_COUNT]; /**< Filter settings */
|
CAN_FilterTypeDef filters_[MAX_FILTER_COUNT]; /**< Filter settings */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(STA_STM32_CAN_GLOBAL) || DOXYGEN
|
#if defined(STA_STM32_CAN_GLOBAL) || DOXYGEN
|
||||||
/**
|
/**
|
||||||
* @brief Global CAN instance.
|
* @brief Global CAN instance.
|
||||||
*
|
*
|
||||||
* @ingroup stm32CAN
|
* @ingroup sta_core_stm32_can
|
||||||
*/
|
*/
|
||||||
extern STM32CanController CanBus;
|
extern STM32CanController CanBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interrupt handler for pending RX frames.
|
* @brief Interrupt handler for pending RX frames.
|
||||||
*
|
*
|
||||||
* May be implemented by application.
|
* May be implemented by application.
|
||||||
*
|
*
|
||||||
* @ingroup stm32CAN
|
* @ingroup sta_core_stm32_can
|
||||||
*/
|
*/
|
||||||
void CanBus_RxPendingCallback();
|
void CanBus_RxPendingCallback();
|
||||||
#endif // STA_STM32_CAN_GLOBAL
|
#endif // STA_STM32_CAN_GLOBAL
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
@ -5,30 +5,33 @@
|
|||||||
#ifndef STA_CORE_STM32_CLOCKS_HPP
|
#ifndef STA_CORE_STM32_CLOCKS_HPP
|
||||||
#define STA_CORE_STM32_CLOCKS_HPP
|
#define STA_CORE_STM32_CLOCKS_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup stm32 STM32
|
// Only enable module on STM32 platform
|
||||||
* @brief Modules implemented for STM32 MCUs.
|
#include <sta/config.hpp>
|
||||||
*/
|
|
||||||
|
|
||||||
|
#if defined(STA_PLATFORM_STM32) || defined(DOXYGEN)
|
||||||
|
|
||||||
|
#include <sta/stm32/hal.hpp>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup stm32BuildConfig Build config
|
* @defgroup sta_core_stm32_clocks Clocks
|
||||||
* @ingroup stm32
|
* @ingroup sta_core_stm32
|
||||||
* @brief Build configuration options.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup stm32Clocks Clocks
|
|
||||||
* @ingroup stm32
|
|
||||||
* @brief STM32 Clock queries.
|
* @brief STM32 Clock queries.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Only enable module on STM32 platform
|
namespace sta
|
||||||
#include <sta/config.hpp>
|
{
|
||||||
#if defined(STA_PLATFORM_STM32) || defined(DOXYGEN)
|
/**
|
||||||
|
* @brief Get peripheral clock frequency.
|
||||||
#include <sta/stm32/hal.hpp>
|
*
|
||||||
|
* @return Clock frequency
|
||||||
|
*/
|
||||||
|
using PCLKFreqFn = uint32_t (*)();
|
||||||
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,14 +11,11 @@
|
|||||||
#ifndef STA_CORE_STM32_DELAY_HPP
|
#ifndef STA_CORE_STM32_DELAY_HPP
|
||||||
#define STA_CORE_STM32_DELAY_HPP
|
#define STA_CORE_STM32_DELAY_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup stm32Delay Delay
|
|
||||||
* @ingroup stm32
|
|
||||||
* @brief STM32 Delay module.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Only enable module on STM32 platform
|
// Only enable module on STM32 platform
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
|
|
||||||
|
|
||||||
#if defined(STA_PLATFORM_STM32) || defined(DOXYGEN)
|
#if defined(STA_PLATFORM_STM32) || defined(DOXYGEN)
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -26,25 +23,32 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Millisecond delay.
|
* @defgroup sta_core_stm32_delay Delay
|
||||||
*
|
* @ingroup sta_core_stm32
|
||||||
* @param ms Milliseconds
|
* @brief STM32 Delay module.
|
||||||
*
|
* @{
|
||||||
* @ingroup stm32Delay
|
*/
|
||||||
*/
|
|
||||||
void delayMs(uint32_t ms);
|
|
||||||
|
/**
|
||||||
|
* @brief Millisecond delay.
|
||||||
|
*
|
||||||
|
* @param ms Milliseconds
|
||||||
|
*/
|
||||||
|
void delayMs(uint32_t ms);
|
||||||
|
|
||||||
#if defined(STA_STM32_DELAY_US_TIM) || defined(DOXYGEN)
|
#if defined(STA_STM32_DELAY_US_TIM) || defined(DOXYGEN)
|
||||||
/**
|
/**
|
||||||
* @brief Microsecond delay.
|
* @brief Microsecond delay.
|
||||||
*
|
*
|
||||||
* @param us Microseconds
|
* @param us Microseconds
|
||||||
*
|
*/
|
||||||
* @ingroup stm32Delay
|
void delayUs(uint32_t us);
|
||||||
*/
|
|
||||||
void delayUs(uint32_t us);
|
|
||||||
#endif // STA_STM32_DELAY_US_TIM
|
#endif // STA_STM32_DELAY_US_TIM
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
#ifndef STA_CORE_STM32_GPIO_PIN_HPP
|
#ifndef STA_CORE_STM32_GPIO_PIN_HPP
|
||||||
#define STA_CORE_STM32_GPIO_PIN_HPP
|
#define STA_CORE_STM32_GPIO_PIN_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup stm32GPIO GPIO
|
|
||||||
* @ingroup stm32
|
|
||||||
* @brief STM32 GPIO module.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Only enable module on STM32 platform w/ HAL GPIO module enabled
|
// Only enable module on STM32 platform w/ HAL GPIO module enabled
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
@ -26,68 +21,81 @@
|
|||||||
#include <sta/gpio_pin.hpp>
|
#include <sta/gpio_pin.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_stm32_gpio GPIO
|
||||||
|
* @ingroup sta_core_stm32
|
||||||
|
* @brief STM32 GPIO module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Container for STM GPIO Pin data.
|
* @ingroup sta_core_stm32_gpio
|
||||||
*
|
* @{
|
||||||
* @ingroup stm32GPIO
|
*/
|
||||||
*/
|
|
||||||
class STM32GpioPin : public GpioPin
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @param port GPIO port
|
|
||||||
* @param pin Pin index
|
|
||||||
*/
|
|
||||||
STM32GpioPin(GPIO_TypeDef * port, uint16_t pin);
|
|
||||||
|
|
||||||
void setState(GpioPinState state) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get GPIO port for pin.
|
|
||||||
*
|
|
||||||
* @return GPIO port
|
|
||||||
*/
|
|
||||||
GPIO_TypeDef * getPort() const;
|
|
||||||
/**
|
|
||||||
* @brief Get pin index for pin.
|
|
||||||
*
|
|
||||||
* @return Pin index
|
|
||||||
*/
|
|
||||||
uint16_t getPin() const;
|
|
||||||
/**
|
|
||||||
* @brief Get GPIO port index for pin.
|
|
||||||
*
|
|
||||||
* @return GPIO port index
|
|
||||||
*/
|
|
||||||
uint8_t getPortIndex() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GPIO_TypeDef * port_; /**< GPIO port */
|
|
||||||
uint16_t pin_; /**< GPIO pin */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interrupt trigger edge.
|
* @brief Container for STM GPIO Pin data.
|
||||||
*/
|
*/
|
||||||
enum class InterruptEdge
|
class STM32GpioPin : public GpioPin
|
||||||
{
|
{
|
||||||
RISING, /**< Rising edge */
|
public:
|
||||||
FALLING, /**< Falling edge */
|
/**
|
||||||
BOTH /**< Rising and falling edge */
|
* @param port GPIO port
|
||||||
};
|
* @param pin Pin index
|
||||||
|
*/
|
||||||
|
STM32GpioPin(GPIO_TypeDef * port, uint16_t pin);
|
||||||
|
|
||||||
/**
|
void setState(GpioPinState state) override;
|
||||||
* @brief Check pin EXIT pin configuration.
|
|
||||||
*
|
/**
|
||||||
* @param pin GPIO pin
|
* @brief Get GPIO port for pin.
|
||||||
* @param edge Interrupt trigger edge
|
*
|
||||||
* @return True if EXIT pin and trigger edge matches
|
* @return GPIO port
|
||||||
*/
|
*/
|
||||||
bool isInterruptEdge(const STM32GpioPin & pin, InterruptEdge edge);
|
GPIO_TypeDef * getPort() const;
|
||||||
|
/**
|
||||||
|
* @brief Get pin index for pin.
|
||||||
|
*
|
||||||
|
* @return Pin index
|
||||||
|
*/
|
||||||
|
uint16_t getPin() const;
|
||||||
|
/**
|
||||||
|
* @brief Get GPIO port index for pin.
|
||||||
|
*
|
||||||
|
* @return GPIO port index
|
||||||
|
*/
|
||||||
|
uint8_t getPortIndex() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GPIO_TypeDef * port_; /**< GPIO port */
|
||||||
|
uint16_t pin_; /**< GPIO pin */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Interrupt trigger edge.
|
||||||
|
*/
|
||||||
|
enum class InterruptEdge
|
||||||
|
{
|
||||||
|
RISING, /**< Rising edge */
|
||||||
|
FALLING, /**< Falling edge */
|
||||||
|
BOTH /**< Rising and falling edge */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check pin EXIT pin configuration.
|
||||||
|
*
|
||||||
|
* @param pin GPIO pin
|
||||||
|
* @param edge Interrupt trigger edge
|
||||||
|
* @return True if EXIT pin and trigger edge matches
|
||||||
|
*/
|
||||||
|
bool isInterruptEdge(const STM32GpioPin & pin, InterruptEdge edge);
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +103,7 @@ namespace sta
|
|||||||
*
|
*
|
||||||
* @param label Pin label
|
* @param label Pin label
|
||||||
*
|
*
|
||||||
* @ingroup stm32GPIO
|
* @ingroup sta_core_stm32_gpio
|
||||||
*/
|
*/
|
||||||
#define STA_STM32_GPIO_PIN(label) sta::STM32GpioPin{label##_GPIO_Port, label##_Pin}
|
#define STA_STM32_GPIO_PIN(label) sta::STM32GpioPin{label##_GPIO_Port, label##_Pin}
|
||||||
|
|
||||||
|
@ -6,6 +6,13 @@
|
|||||||
#define STA_CORE_STM32_HAL_HPP
|
#define STA_CORE_STM32_HAL_HPP
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_stm32 STM32
|
||||||
|
* @ingroup sta_core_platforms
|
||||||
|
* @brief Modules implemented for the STM32 platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Include STM32 HAL headers
|
// Include STM32 HAL headers
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Initialize global HAL objects.
|
* @brief Initialize global HAL objects.
|
||||||
*
|
*
|
||||||
* @ingroup stm32
|
* @ingroup sta_core_stm32
|
||||||
*/
|
*/
|
||||||
void initHAL();
|
void initHAL();
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,12 +5,6 @@
|
|||||||
#ifndef STA_CORE_STM32_UART_HPP
|
#ifndef STA_CORE_STM32_UART_HPP
|
||||||
#define STA_CORE_STM32_UART_HPP
|
#define STA_CORE_STM32_UART_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup stm32UART UART
|
|
||||||
* @ingroup stm32
|
|
||||||
* @brief STM32 UART module.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Only enable module on STM32 platform w/ HAL UART module enabled
|
// Only enable module on STM32 platform w/ HAL UART module enabled
|
||||||
#include <sta/config.hpp>
|
#include <sta/config.hpp>
|
||||||
@ -27,26 +21,33 @@
|
|||||||
#include <sta/uart.hpp>
|
#include <sta/uart.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_stm32_uart UART
|
||||||
|
* @ingroup sta_core_stm32
|
||||||
|
* @brief STM32 UART module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of UART interface using HAL.
|
* @brief Implementation of UART interface using HAL.
|
||||||
*
|
*
|
||||||
* @ingroup stm32UART
|
* @ingroup sta_core_stm32_uart
|
||||||
*/
|
*/
|
||||||
class STM32UART : public UART
|
class STM32UART : public UART
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param handle UART handle
|
* @param handle STM32 HAL handle
|
||||||
*/
|
*/
|
||||||
STM32UART(UART_HandleTypeDef * handle);
|
STM32UART(UART_HandleTypeDef * handle);
|
||||||
|
|
||||||
void write(const uint8_t * buffer, size_t size) override;
|
void write(const uint8_t * buffer, size_t size) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UART_HandleTypeDef * handle_; /**< UART handle */
|
UART_HandleTypeDef * handle_; /**< STM32 HAL handle */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,18 +10,18 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Signature for millisecond precision time.
|
* @brief Signature for millisecond precision time.
|
||||||
*
|
*
|
||||||
* @return Time in milliseconds
|
* @return Time in milliseconds
|
||||||
*/
|
*/
|
||||||
using TimeMsFn = uint32_t (*)();
|
using TimeMsFn = uint32_t (*)();
|
||||||
/**
|
/**
|
||||||
* @brief Signature for microseconds precision time.
|
* @brief Signature for microseconds precision time.
|
||||||
*
|
*
|
||||||
* @return Time in microseconds
|
* @return Time in microseconds
|
||||||
*/
|
*/
|
||||||
using TimeUsFn = uint32_t (*)();
|
using TimeUsFn = uint32_t (*)();
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,41 +9,50 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sta_core_uart UART
|
||||||
|
* @ingroup sta_core
|
||||||
|
* @brief UART interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Interface for %UART.
|
* @brief Interface for %UART.
|
||||||
*/
|
*
|
||||||
class UART
|
* @ingroup sta_core_uart
|
||||||
{
|
*/
|
||||||
public:
|
class UART
|
||||||
/**
|
{
|
||||||
* @brief Write buffer to %UART.
|
public:
|
||||||
*
|
/**
|
||||||
* @param buffer Source buffer
|
* @brief Write buffer to %UART.
|
||||||
* @param size Number of bytes in buffer
|
*
|
||||||
*/
|
* @param buffer Source buffer
|
||||||
virtual void write(const uint8_t * buffer, size_t size) = 0;
|
* @param size Number of bytes in buffer
|
||||||
|
*/
|
||||||
|
virtual void write(const uint8_t * buffer, size_t size) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write unsigned integer to %UART.
|
* @brief Write unsigned integer to %UART.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
*/
|
*/
|
||||||
void write(uint8_t value);
|
void write(uint8_t value);
|
||||||
/**
|
/**
|
||||||
* @brief Write unsigned integer to %UART.
|
* @brief Write unsigned integer to %UART.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
*/
|
*/
|
||||||
void write(uint16_t value);
|
void write(uint16_t value);
|
||||||
/**
|
/**
|
||||||
* @brief Write unsigned integer to %UART.
|
* @brief Write unsigned integer to %UART.
|
||||||
*
|
*
|
||||||
* @param value Unsigned integer value
|
* @param value Unsigned integer value
|
||||||
*/
|
*/
|
||||||
void write(uint32_t value);
|
void write(uint32_t value);
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,23 +7,23 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
STA_WEAK
|
STA_WEAK
|
||||||
void assert_failed(const char * expr, const char * file, uint32_t line)
|
void assert_failed(const char * expr, const char * file, uint32_t line)
|
||||||
{
|
{
|
||||||
// printf("%s:%d: Assertion failed: %s", file, line, expr)
|
// printf("%s:%d: Assertion failed: %s", file, line, expr)
|
||||||
STA_DEBUG_PRINT(file);
|
STA_DEBUG_PRINT(file);
|
||||||
STA_DEBUG_PRINT(':');
|
STA_DEBUG_PRINT(':');
|
||||||
STA_DEBUG_PRINT(line);
|
STA_DEBUG_PRINT(line);
|
||||||
STA_DEBUG_PRINT(": Assertion failed: ");
|
STA_DEBUG_PRINT(": Assertion failed: ");
|
||||||
STA_DEBUG_PRINTLN(expr);
|
STA_DEBUG_PRINTLN(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
STA_WEAK
|
STA_WEAK
|
||||||
void assert_halt()
|
void assert_halt()
|
||||||
{
|
{
|
||||||
STA_BKPT();
|
STA_BKPT();
|
||||||
while (true);
|
while (true);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,19 +4,19 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
AtomicMutex::AtomicMutex()
|
AtomicMutex::AtomicMutex()
|
||||||
: lock_{ATOMIC_FLAG_INIT}
|
: lock_{ATOMIC_FLAG_INIT}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void AtomicMutex::acquire()
|
void AtomicMutex::acquire()
|
||||||
{
|
{
|
||||||
while (lock_.test_and_set());
|
while (lock_.test_and_set());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomicMutex::release()
|
void AtomicMutex::release()
|
||||||
{
|
{
|
||||||
lock_.clear();
|
lock_.clear();
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,29 +4,29 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
AtomicSignal::AtomicSignal()
|
AtomicSignal::AtomicSignal()
|
||||||
: signal_{false}
|
: signal_{false}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void AtomicSignal::notify()
|
void AtomicSignal::notify()
|
||||||
{
|
{
|
||||||
signal_.store(true);
|
signal_.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AtomicSignal::peek()
|
bool AtomicSignal::peek()
|
||||||
{
|
{
|
||||||
return signal_.load();
|
return signal_.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AtomicSignal::test()
|
bool AtomicSignal::test()
|
||||||
{
|
{
|
||||||
return signal_.exchange(false);
|
return signal_.exchange(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomicSignal::wait()
|
void AtomicSignal::wait()
|
||||||
{
|
{
|
||||||
while (!signal_.exchange(false));
|
while (!signal_.exchange(false));
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,24 +3,24 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
bool operator ==(const CanId & lhs, const CanId & rhs)
|
bool operator ==(const CanId & lhs, const CanId & rhs)
|
||||||
{
|
{
|
||||||
return (lhs.sid == rhs.sid && lhs.eid == rhs.eid);
|
return (lhs.sid == rhs.sid && lhs.eid == rhs.eid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const CanId & lhs, const CanId & rhs)
|
bool operator !=(const CanId & lhs, const CanId & rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator ==(const CanFrameId & lhs, const CanFrameId & rhs)
|
bool operator ==(const CanFrameId & lhs, const CanFrameId & rhs)
|
||||||
{
|
{
|
||||||
return (lhs.format == rhs.format && lhs.sid == rhs.sid && lhs.eid == rhs.eid);
|
return (lhs.format == rhs.format && lhs.sid == rhs.sid && lhs.eid == rhs.eid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const CanFrameId & lhs, const CanFrameId & rhs)
|
bool operator !=(const CanFrameId & lhs, const CanFrameId & rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
132
src/can/iter.cpp
132
src/can/iter.cpp
@ -5,91 +5,91 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
CanPendingRxFifos::const_iterator::const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx)
|
CanPendingRxFifos::const_iterator::const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx)
|
||||||
: rxFlags_{rxFlags}, idx_{idx}, endIdx_{endIdx}
|
: rxFlags_{rxFlags}, idx_{idx}, endIdx_{endIdx}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator::const_iterator(const const_iterator & iter)
|
CanPendingRxFifos::const_iterator::const_iterator(const const_iterator & iter)
|
||||||
: rxFlags_{iter.rxFlags_}, idx_{iter.idx_}, endIdx_{iter.endIdx_}
|
: rxFlags_{iter.rxFlags_}, idx_{iter.idx_}, endIdx_{iter.endIdx_}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator=(const const_iterator & iter)
|
CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator=(const const_iterator & iter)
|
||||||
{
|
{
|
||||||
rxFlags_ = iter.rxFlags_;
|
rxFlags_ = iter.rxFlags_;
|
||||||
idx_ = iter.idx_;
|
idx_ = iter.idx_;
|
||||||
endIdx_ = iter.endIdx_;
|
endIdx_ = iter.endIdx_;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CanPendingRxFifos::const_iterator::operator==(const const_iterator & iter) const
|
bool CanPendingRxFifos::const_iterator::operator==(const const_iterator & iter) const
|
||||||
{
|
{
|
||||||
return (rxFlags_ == iter.rxFlags_) && (idx_ == iter.idx_) && (endIdx_ == iter.endIdx_);
|
return (rxFlags_ == iter.rxFlags_) && (idx_ == iter.idx_) && (endIdx_ == iter.endIdx_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanPendingRxFifos::const_iterator::operator!=(const const_iterator & iter) const
|
bool CanPendingRxFifos::const_iterator::operator!=(const const_iterator & iter) const
|
||||||
{
|
{
|
||||||
return !(*this == iter);
|
return !(*this == iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator++()
|
CanPendingRxFifos::const_iterator & CanPendingRxFifos::const_iterator::operator++()
|
||||||
{
|
{
|
||||||
while (idx_ < endIdx_)
|
while (idx_ < endIdx_)
|
||||||
{
|
{
|
||||||
++idx_;
|
++idx_;
|
||||||
if (isRxPending())
|
if (isRxPending())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator CanPendingRxFifos::const_iterator::operator++(int)
|
CanPendingRxFifos::const_iterator CanPendingRxFifos::const_iterator::operator++(int)
|
||||||
{
|
{
|
||||||
uint8_t oldIdx = idx_;
|
uint8_t oldIdx = idx_;
|
||||||
|
|
||||||
while (idx_ < endIdx_)
|
while (idx_ < endIdx_)
|
||||||
{
|
{
|
||||||
++idx_;
|
++idx_;
|
||||||
if (isRxPending())
|
if (isRxPending())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return const_iterator(rxFlags_, oldIdx, endIdx_);
|
return const_iterator(rxFlags_, oldIdx, endIdx_);
|
||||||
}
|
}
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator::reference CanPendingRxFifos::const_iterator::operator*() const
|
CanPendingRxFifos::const_iterator::reference CanPendingRxFifos::const_iterator::operator*() const
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(idx_ != endIdx_, "Dereferencing out-of-bounds iterator");
|
STA_ASSERT_MSG(idx_ != endIdx_, "Dereferencing out-of-bounds iterator");
|
||||||
|
|
||||||
return idx_;
|
return idx_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanPendingRxFifos::const_iterator::isRxPending() const
|
bool CanPendingRxFifos::const_iterator::isRxPending() const
|
||||||
{
|
{
|
||||||
return ( (rxFlags_ >> idx_) & 0x1 );
|
return ( (rxFlags_ >> idx_) & 0x1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CanPendingRxFifos::CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos)
|
CanPendingRxFifos::CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos)
|
||||||
: rxFlags_{rxFlags}, numFifos_{numFifos}
|
: rxFlags_{rxFlags}, numFifos_{numFifos}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator CanPendingRxFifos::begin() const
|
CanPendingRxFifos::const_iterator CanPendingRxFifos::begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(rxFlags_, 0, numFifos_);
|
return const_iterator(rxFlags_, 0, numFifos_);
|
||||||
}
|
}
|
||||||
|
|
||||||
CanPendingRxFifos::const_iterator CanPendingRxFifos::end() const
|
CanPendingRxFifos::const_iterator CanPendingRxFifos::end() const
|
||||||
{
|
{
|
||||||
return const_iterator(rxFlags_, numFifos_, numFifos_);
|
return const_iterator(rxFlags_, numFifos_, numFifos_);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
@ -16,14 +16,14 @@ using PlatformUART = sta::STM32UART;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Create platform specific serial interface
|
// Create platform specific serial interface
|
||||||
PlatformUART platformDebugSerial(&STA_DEBUG_SERIAL_UART);
|
PlatformUART platformDebugSerial(&STA_DEBUG_SERIAL_UART);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
// Create debug serial object using platform specific serial interface
|
// Create debug serial object using platform specific serial interface
|
||||||
PrintableUART DebugSerial(&platformDebugSerial);
|
PrintableUART DebugSerial(&platformDebugSerial);
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,18 +3,18 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Dummy mutex implementation with no access control.
|
* @brief Dummy mutex implementation with no access control.
|
||||||
*/
|
*/
|
||||||
class DummyMutex : public Mutex
|
class DummyMutex : public Mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void acquire() override {}
|
void acquire() override {}
|
||||||
void release() override {}
|
void release() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static DummyMutex dummyMutex;
|
static DummyMutex dummyMutex;
|
||||||
|
|
||||||
|
|
||||||
Mutex * Mutex::ALWAYS_FREE = &dummyMutex;
|
Mutex * Mutex::ALWAYS_FREE = &dummyMutex;
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
@ -10,202 +10,202 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
PrintableUART::PrintableUART(UART * intf)
|
PrintableUART::PrintableUART(UART * intf)
|
||||||
: intf_{intf}
|
: intf_{intf}
|
||||||
{
|
{
|
||||||
STA_ASSERT(intf != nullptr);
|
STA_ASSERT(intf != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintableUART::print(char c)
|
void PrintableUART::print(char c)
|
||||||
{
|
{
|
||||||
print(&c, 1);
|
print(&c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(bool b)
|
void PrintableUART::print(bool b)
|
||||||
{
|
{
|
||||||
print(b ? "true" : "false");
|
print(b ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(double d)
|
void PrintableUART::print(double d)
|
||||||
{
|
{
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
snprintf(buffer, sizeof(buffer), "%f", d);
|
snprintf(buffer, sizeof(buffer), "%f", d);
|
||||||
print(buffer);
|
print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(uint8_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::print(uint8_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
printBase(num, base, "%" PRIu8, sizeof(num));
|
printBase(num, base, "%" PRIu8, sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(uint16_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::print(uint16_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
printBase(num, base, "%" PRIu16, sizeof(num));
|
printBase(num, base, "%" PRIu16, sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(uint32_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::print(uint32_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
printBase(num, base, "%" PRIu32, sizeof(num));
|
printBase(num, base, "%" PRIu32, sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(size_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::print(size_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
printBase(num, base, "%z", sizeof(num));
|
printBase(num, base, "%z", sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(const char * str)
|
void PrintableUART::print(const char * str)
|
||||||
{
|
{
|
||||||
print(str, strlen(str));
|
print(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::print(const char * str, size_t length)
|
void PrintableUART::print(const char * str, size_t length)
|
||||||
{
|
{
|
||||||
intf_->write(reinterpret_cast<const uint8_t *>(str), length);
|
intf_->write(reinterpret_cast<const uint8_t *>(str), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintableUART::println()
|
void PrintableUART::println()
|
||||||
{
|
{
|
||||||
print("\r\n", 2);
|
print("\r\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(char c)
|
void PrintableUART::println(char c)
|
||||||
{
|
{
|
||||||
print(&c, 1);
|
print(&c, 1);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(bool b)
|
void PrintableUART::println(bool b)
|
||||||
{
|
{
|
||||||
print(b);
|
print(b);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(double d)
|
void PrintableUART::println(double d)
|
||||||
{
|
{
|
||||||
print(d);
|
print(d);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(uint8_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::println(uint8_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
print(num, base);
|
print(num, base);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(uint16_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::println(uint16_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
print(num, base);
|
print(num, base);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(uint32_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::println(uint32_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
print(num, base);
|
print(num, base);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(size_t num, IntegerBase base /* = IntegerBase::DEC */)
|
void PrintableUART::println(size_t num, IntegerBase base /* = IntegerBase::DEC */)
|
||||||
{
|
{
|
||||||
print(num, base);
|
print(num, base);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(const char * str)
|
void PrintableUART::println(const char * str)
|
||||||
{
|
{
|
||||||
println(str, strlen(str));
|
println(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::println(const char * str, size_t length)
|
void PrintableUART::println(const char * str, size_t length)
|
||||||
{
|
{
|
||||||
print(str, length);
|
print(str, length);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PrintableUART::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size)
|
void PrintableUART::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size)
|
||||||
{
|
{
|
||||||
switch (base)
|
switch (base)
|
||||||
{
|
{
|
||||||
case IntegerBase::DEC:
|
case IntegerBase::DEC:
|
||||||
printDec(num, fmt);
|
printDec(num, fmt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntegerBase::BIN:
|
case IntegerBase::BIN:
|
||||||
// Digits in base 2 = size in bytes * 8
|
// Digits in base 2 = size in bytes * 8
|
||||||
printBin(num, size * 8);
|
printBin(num, size * 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntegerBase::HEX:
|
case IntegerBase::HEX:
|
||||||
// Digits in base 16 = size in bytes * 2
|
// Digits in base 16 = size in bytes * 2
|
||||||
printHex(num, size * 2);
|
printHex(num, size * 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print("<invalid_base>");
|
print("<invalid_base>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::printDec(uintmax_t num, const char * fmt)
|
void PrintableUART::printDec(uintmax_t num, const char * fmt)
|
||||||
{
|
{
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
snprintf(buffer, sizeof(buffer), fmt, static_cast<uint32_t>(num));
|
snprintf(buffer, sizeof(buffer), fmt, static_cast<uint32_t>(num));
|
||||||
print(buffer);
|
print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::printBin(uintmax_t value, size_t digits)
|
void PrintableUART::printBin(uintmax_t value, size_t digits)
|
||||||
{
|
{
|
||||||
// Need 8 digits for every byte
|
// Need 8 digits for every byte
|
||||||
char buffer[sizeof(value) * 8];
|
char buffer[sizeof(value) * 8];
|
||||||
|
|
||||||
// Check bounds
|
// Check bounds
|
||||||
if (digits > sizeof(buffer))
|
if (digits > sizeof(buffer))
|
||||||
{
|
{
|
||||||
print("<bin_value_too_big>");
|
print("<bin_value_too_big>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
if (digits == 0)
|
if (digits == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < digits; ++i)
|
for (size_t i = 0; i < digits; ++i)
|
||||||
{
|
{
|
||||||
// Convert bit to '0' or '1'
|
// Convert bit to '0' or '1'
|
||||||
// First digit in buffer is MSB in value, so shift from high to low
|
// First digit in buffer is MSB in value, so shift from high to low
|
||||||
buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1);
|
buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
print(buffer, digits);
|
print(buffer, digits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintableUART::printHex(uintmax_t value, size_t digits)
|
void PrintableUART::printHex(uintmax_t value, size_t digits)
|
||||||
{
|
{
|
||||||
// Need 2 digits for every byte
|
// Need 2 digits for every byte
|
||||||
char buffer[sizeof(value) * 2];
|
char buffer[sizeof(value) * 2];
|
||||||
|
|
||||||
// Check bounds
|
// Check bounds
|
||||||
if (digits > sizeof(buffer))
|
if (digits > sizeof(buffer))
|
||||||
{
|
{
|
||||||
print("<hex_value_too_big>");
|
print("<hex_value_too_big>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
if (digits == 0)
|
if (digits == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < digits; ++i)
|
for (size_t i = 0; i < digits; ++i)
|
||||||
{
|
{
|
||||||
// Convert 4 bits to hex
|
// Convert 4 bits to hex
|
||||||
// First digit in buffer is 4 MSBs in value, so shift from high to low
|
// First digit in buffer is 4 MSBs in value, so shift from high to low
|
||||||
uint8_t hex = ((value >> ((digits - 1 - i) * 4)) & 0xF);
|
uint8_t hex = ((value >> ((digits - 1 - i) * 4)) & 0xF);
|
||||||
if (hex > 9)
|
if (hex > 9)
|
||||||
buffer[i] = 'A' + (hex - 10);
|
buffer[i] = 'A' + (hex - 10);
|
||||||
else
|
else
|
||||||
buffer[i] = '0' + hex;
|
buffer[i] = '0' + hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
print(buffer, digits);
|
print(buffer, digits);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
@ -7,167 +7,167 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
STM32CanController::STM32CanController(CAN_HandleTypeDef * handle)
|
STM32CanController::STM32CanController(CAN_HandleTypeDef * handle)
|
||||||
: handle_{handle}
|
: handle_{handle}
|
||||||
{
|
{
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STM32CanController::enableRxInterrupts()
|
void STM32CanController::enableRxInterrupts()
|
||||||
{
|
{
|
||||||
HAL_CAN_ActivateNotification(handle_,
|
HAL_CAN_ActivateNotification(handle_,
|
||||||
CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING
|
CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STM32CanController::start()
|
void STM32CanController::start()
|
||||||
{
|
{
|
||||||
HAL_CAN_Start(handle_);
|
HAL_CAN_Start(handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STM32CanController::stop()
|
void STM32CanController::stop()
|
||||||
{
|
{
|
||||||
HAL_CAN_Stop(handle_);
|
HAL_CAN_Stop(handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool STM32CanController::sendFrame(const CanTxHeader & header, const uint8_t * payload)
|
bool STM32CanController::sendFrame(const CanTxHeader & header, const uint8_t * payload)
|
||||||
{
|
{
|
||||||
STA_ASSERT_MSG(header.payloadLength <= 8, "CAN 2.0B payload size exceeded");
|
STA_ASSERT_MSG(header.payloadLength <= 8, "CAN 2.0B payload size exceeded");
|
||||||
|
|
||||||
CAN_TxHeaderTypeDef halHeader;
|
CAN_TxHeaderTypeDef halHeader;
|
||||||
|
|
||||||
if (header.id.format == CanIdFormat::STD)
|
if (header.id.format == CanIdFormat::STD)
|
||||||
{
|
{
|
||||||
halHeader.StdId = header.id.sid & 0x7FF;
|
halHeader.StdId = header.id.sid & 0x7FF;
|
||||||
halHeader.IDE = CAN_ID_STD;
|
halHeader.IDE = CAN_ID_STD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Combine SID and EID
|
// Combine SID and EID
|
||||||
halHeader.ExtId = ((header.id.sid & 0x7FF) << 18) | (header.id.eid & 0x3FFFF);
|
halHeader.ExtId = ((header.id.sid & 0x7FF) << 18) | (header.id.eid & 0x3FFFF);
|
||||||
halHeader.IDE = CAN_ID_EXT;
|
halHeader.IDE = CAN_ID_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
halHeader.DLC = header.payloadLength;
|
halHeader.DLC = header.payloadLength;
|
||||||
|
|
||||||
uint32_t mailbox; // Don't care
|
uint32_t mailbox; // Don't care
|
||||||
return (HAL_OK == HAL_CAN_AddTxMessage(handle_, &halHeader, const_cast<uint8_t *>(payload), &mailbox));
|
return (HAL_OK == HAL_CAN_AddTxMessage(handle_, &halHeader, const_cast<uint8_t *>(payload), &mailbox));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STM32CanController::receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload)
|
bool STM32CanController::receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload)
|
||||||
{
|
{
|
||||||
// Check if message is available
|
// Check if message is available
|
||||||
if (HAL_CAN_GetRxFifoFillLevel(handle_, fifo) == 0)
|
if (HAL_CAN_GetRxFifoFillLevel(handle_, fifo) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Retrieve message
|
// Retrieve message
|
||||||
CAN_RxHeaderTypeDef halHeader;
|
CAN_RxHeaderTypeDef halHeader;
|
||||||
HAL_CAN_GetRxMessage(handle_, fifo, &halHeader, payload);
|
HAL_CAN_GetRxMessage(handle_, fifo, &halHeader, payload);
|
||||||
|
|
||||||
if (halHeader.IDE == CAN_ID_STD)
|
if (halHeader.IDE == CAN_ID_STD)
|
||||||
{
|
{
|
||||||
header->id.format = CanIdFormat::STD;
|
header->id.format = CanIdFormat::STD;
|
||||||
header->id.sid = halHeader.StdId;
|
header->id.sid = halHeader.StdId;
|
||||||
header->id.eid = 0;
|
header->id.eid = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
header->id.format = CanIdFormat::EXT;
|
header->id.format = CanIdFormat::EXT;
|
||||||
// Separate SID and EID
|
// Separate SID and EID
|
||||||
header->id.sid = (halHeader.ExtId >> 18);
|
header->id.sid = (halHeader.ExtId >> 18);
|
||||||
header->id.eid = halHeader.ExtId & 0x3FFFF;
|
header->id.eid = halHeader.ExtId & 0x3FFFF;
|
||||||
}
|
}
|
||||||
// No conversion required for CAN 2B standard
|
// No conversion required for CAN 2B standard
|
||||||
header->payloadLength = halHeader.DLC;
|
header->payloadLength = halHeader.DLC;
|
||||||
header->timestamp = halHeader.Timestamp;
|
header->timestamp = halHeader.Timestamp;
|
||||||
header->filter = halHeader.FilterMatchIndex;
|
header->filter = halHeader.FilterMatchIndex;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t STM32CanController::getRxFifoFlags()
|
uint32_t STM32CanController::getRxFifoFlags()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
return (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO0) != 0)
|
return (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO0) != 0)
|
||||||
| (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO1) != 0) << 1;
|
| (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO1) != 0) << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STM32CanController::configureFilter(uint8_t idx, const CanFilter & filter, bool active /* = false */)
|
void STM32CanController::configureFilter(uint8_t idx, const CanFilter & filter, bool active /* = false */)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef * config = &filters_[idx];
|
CAN_FilterTypeDef * config = &filters_[idx];
|
||||||
|
|
||||||
if (filter.type == CanFilterIdFormat::STD)
|
if (filter.type == CanFilterIdFormat::STD)
|
||||||
{
|
{
|
||||||
config->FilterIdHigh = 0;
|
config->FilterIdHigh = 0;
|
||||||
config->FilterIdLow = filter.obj.sid & 0x7FF;
|
config->FilterIdLow = filter.obj.sid & 0x7FF;
|
||||||
config->FilterMaskIdHigh = 0;
|
config->FilterMaskIdHigh = 0;
|
||||||
config->FilterMaskIdLow = filter.mask.sid & 0x7FF;
|
config->FilterMaskIdLow = filter.mask.sid & 0x7FF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config->FilterIdHigh = ((filter.obj.sid & 0x7FF) << 2) | ((filter.obj.eid >> 16) & 0x3);
|
config->FilterIdHigh = ((filter.obj.sid & 0x7FF) << 2) | ((filter.obj.eid >> 16) & 0x3);
|
||||||
config->FilterIdLow = filter.obj.eid & 0xFFFF;
|
config->FilterIdLow = filter.obj.eid & 0xFFFF;
|
||||||
config->FilterMaskIdHigh = ((filter.mask.sid & 0x7FF) << 2) | ((filter.mask.eid >> 16) & 0x3);
|
config->FilterMaskIdHigh = ((filter.mask.sid & 0x7FF) << 2) | ((filter.mask.eid >> 16) & 0x3);
|
||||||
config->FilterMaskIdLow = filter.mask.eid & 0xFFFF;
|
config->FilterMaskIdLow = filter.mask.eid & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
config->FilterFIFOAssignment = filter.fifo;
|
config->FilterFIFOAssignment = filter.fifo;
|
||||||
config->FilterActivation = (active ? CAN_FILTER_ENABLE : CAN_FILTER_DISABLE);
|
config->FilterActivation = (active ? CAN_FILTER_ENABLE : CAN_FILTER_DISABLE);
|
||||||
|
|
||||||
HAL_CAN_ConfigFilter(handle_, config);
|
HAL_CAN_ConfigFilter(handle_, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STM32CanController::enableFilter(uint8_t idx)
|
void STM32CanController::enableFilter(uint8_t idx)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef * config = &filters_[idx];
|
CAN_FilterTypeDef * config = &filters_[idx];
|
||||||
|
|
||||||
config->FilterActivation = CAN_FILTER_ENABLE;
|
config->FilterActivation = CAN_FILTER_ENABLE;
|
||||||
|
|
||||||
HAL_CAN_ConfigFilter(handle_, config);
|
HAL_CAN_ConfigFilter(handle_, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STM32CanController::disableFilter(uint8_t idx)
|
void STM32CanController::disableFilter(uint8_t idx)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef * config = &filters_[idx];
|
CAN_FilterTypeDef * config = &filters_[idx];
|
||||||
|
|
||||||
config->FilterActivation = CAN_FILTER_DISABLE;
|
config->FilterActivation = CAN_FILTER_DISABLE;
|
||||||
|
|
||||||
HAL_CAN_ConfigFilter(handle_, config);
|
HAL_CAN_ConfigFilter(handle_, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STM32CanController::clearFilters()
|
void STM32CanController::clearFilters()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < MAX_FILTER_COUNT; ++i)
|
for (uint32_t i = 0; i < MAX_FILTER_COUNT; ++i)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef * config = &filters_[i];
|
CAN_FilterTypeDef * config = &filters_[i];
|
||||||
|
|
||||||
// Only disable active filters
|
// Only disable active filters
|
||||||
if (config->FilterActivation == CAN_FILTER_ENABLE)
|
if (config->FilterActivation == CAN_FILTER_ENABLE)
|
||||||
{
|
{
|
||||||
config->FilterActivation = CAN_FILTER_DISABLE;
|
config->FilterActivation = CAN_FILTER_DISABLE;
|
||||||
HAL_CAN_ConfigFilter(handle_, config);
|
HAL_CAN_ConfigFilter(handle_, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STM32CanController::initFilters()
|
void STM32CanController::initFilters()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < MAX_FILTER_COUNT; ++i)
|
for (uint32_t i = 0; i < MAX_FILTER_COUNT; ++i)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef * config = &filters_[i];
|
CAN_FilterTypeDef * config = &filters_[i];
|
||||||
|
|
||||||
config->FilterBank = i;
|
config->FilterBank = i;
|
||||||
config->FilterMode = CAN_FILTERMODE_IDMASK;
|
config->FilterMode = CAN_FILTERMODE_IDMASK;
|
||||||
config->FilterScale = CAN_FILTERSCALE_32BIT;
|
config->FilterScale = CAN_FILTERSCALE_32BIT;
|
||||||
config->FilterActivation = CAN_FILTER_DISABLE;
|
config->FilterActivation = CAN_FILTER_DISABLE;
|
||||||
config->SlaveStartFilterBank = MAX_FILTER_COUNT;
|
config->SlaveStartFilterBank = MAX_FILTER_COUNT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
@ -177,31 +177,31 @@ namespace sta
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
STM32CanController CanBus(&STA_STM32_CAN_GLOBAL);
|
STM32CanController CanBus(&STA_STM32_CAN_GLOBAL);
|
||||||
|
|
||||||
STA_WEAK
|
STA_WEAK
|
||||||
void CanBus_RxPendingCallback()
|
void CanBus_RxPendingCallback()
|
||||||
{}
|
{}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||||
{
|
{
|
||||||
if (hcan == &STA_STM32_CAN_GLOBAL)
|
if (hcan == &STA_STM32_CAN_GLOBAL)
|
||||||
{
|
{
|
||||||
sta::CanBus_RxPendingCallback();
|
sta::CanBus_RxPendingCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||||
{
|
{
|
||||||
if (hcan == &STA_STM32_CAN_GLOBAL)
|
if (hcan == &STA_STM32_CAN_GLOBAL)
|
||||||
{
|
{
|
||||||
sta::CanBus_RxPendingCallback();
|
sta::CanBus_RxPendingCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // STA_STM32_CAN_GLOBAL
|
#endif // STA_STM32_CAN_GLOBAL
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
void delayMs(uint32_t ms)
|
void delayMs(uint32_t ms)
|
||||||
{
|
{
|
||||||
HAL_Delay(ms);
|
HAL_Delay(ms);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
@ -27,46 +27,46 @@ namespace sta
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
uint32_t gDelayUsMul = 1;
|
uint32_t gDelayUsMul = 1;
|
||||||
|
|
||||||
void delayUs(uint32_t us)
|
void delayUs(uint32_t us)
|
||||||
{
|
{
|
||||||
__HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0);
|
__HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0);
|
||||||
while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul);
|
while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isValidDelayUsTIM()
|
bool isValidDelayUsTIM()
|
||||||
{
|
{
|
||||||
// Get PCLK multiplier for TIM clock
|
// Get PCLK multiplier for TIM clock
|
||||||
uint32_t pclkMul = 1;
|
uint32_t pclkMul = 1;
|
||||||
switch (STA_STM32_DELAY_US_TIM.Init.ClockDivision)
|
switch (STA_STM32_DELAY_US_TIM.Init.ClockDivision)
|
||||||
{
|
{
|
||||||
case TIM_CLOCKDIVISION_DIV1:
|
case TIM_CLOCKDIVISION_DIV1:
|
||||||
pclkMul = 1;
|
pclkMul = 1;
|
||||||
break;
|
break;
|
||||||
case TIM_CLOCKDIVISION_DIV2:
|
case TIM_CLOCKDIVISION_DIV2:
|
||||||
pclkMul = 2;
|
pclkMul = 2;
|
||||||
break;
|
break;
|
||||||
case TIM_CLOCKDIVISION_DIV4:
|
case TIM_CLOCKDIVISION_DIV4:
|
||||||
pclkMul = 4;
|
pclkMul = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
STA_ASSERT(false);
|
STA_ASSERT(false);
|
||||||
STA_UNREACHABLE();
|
STA_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate TIM clock frequency
|
// Calculate TIM clock frequency
|
||||||
uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)();
|
uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)();
|
||||||
// Calculate update frequency based on prescaler value
|
// Calculate update frequency based on prescaler value
|
||||||
uint32_t prescaler = (STA_STM32_DELAY_US_TIM.Init.Prescaler) ? STA_STM32_DELAY_US_TIM.Init.Prescaler : 1;
|
uint32_t prescaler = (STA_STM32_DELAY_US_TIM.Init.Prescaler) ? STA_STM32_DELAY_US_TIM.Init.Prescaler : 1;
|
||||||
uint32_t updateFreq = clkFreq / prescaler;
|
uint32_t updateFreq = clkFreq / prescaler;
|
||||||
|
|
||||||
gDelayUsMul = updateFreq / 1000000;
|
gDelayUsMul = updateFreq / 1000000;
|
||||||
|
|
||||||
// TIM must have at least microsecond precision (>= 1 MHz frequency)
|
// TIM must have at least microsecond precision (>= 1 MHz frequency)
|
||||||
return (updateFreq >= 1000000);
|
return (updateFreq >= 1000000);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
#endif // STA_STM32_DELAY_US_TIM
|
#endif // STA_STM32_DELAY_US_TIM
|
||||||
|
@ -7,76 +7,76 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
STM32GpioPin::STM32GpioPin(GPIO_TypeDef * port, uint16_t pin)
|
STM32GpioPin::STM32GpioPin(GPIO_TypeDef * port, uint16_t pin)
|
||||||
: port_{port}, pin_{pin}
|
: port_{port}, pin_{pin}
|
||||||
{
|
{
|
||||||
STA_ASSERT(port != nullptr);
|
STA_ASSERT(port != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STM32GpioPin::setState(GpioPinState state)
|
void STM32GpioPin::setState(GpioPinState state)
|
||||||
{
|
{
|
||||||
HAL_GPIO_WritePin(port_, pin_, (state == GpioPinState::LOW) ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
HAL_GPIO_WritePin(port_, pin_, (state == GpioPinState::LOW) ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPIO_TypeDef * STM32GpioPin::getPort() const
|
GPIO_TypeDef * STM32GpioPin::getPort() const
|
||||||
{
|
{
|
||||||
return port_;
|
return port_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t STM32GpioPin::getPin() const
|
uint16_t STM32GpioPin::getPin() const
|
||||||
{
|
{
|
||||||
return pin_;
|
return pin_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t STM32GpioPin::getPortIndex() const
|
uint8_t STM32GpioPin::getPortIndex() const
|
||||||
{
|
{
|
||||||
return GPIO_GET_INDEX(port_);
|
return GPIO_GET_INDEX(port_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isInterruptEdge(const STM32GpioPin & gpioPin, InterruptEdge edge)
|
bool isInterruptEdge(const STM32GpioPin & gpioPin, InterruptEdge edge)
|
||||||
{
|
{
|
||||||
uint32_t pin = gpioPin.getPin();
|
uint32_t pin = gpioPin.getPin();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 8 * sizeof(pin); ++i)
|
for (uint32_t i = 0; i < 8 * sizeof(pin); ++i)
|
||||||
{
|
{
|
||||||
uint32_t ioPos = 1U << i;
|
uint32_t ioPos = 1U << i;
|
||||||
if (pin & ioPos)
|
if (pin & ioPos)
|
||||||
{
|
{
|
||||||
// Check input mode
|
// Check input mode
|
||||||
uint32_t mode = (gpioPin.getPort()->MODER >> (2U * i)) & GPIO_MODE;
|
uint32_t mode = (gpioPin.getPort()->MODER >> (2U * i)) & GPIO_MODE;
|
||||||
if (mode != MODE_INPUT)
|
if (mode != MODE_INPUT)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is EXTI configured?
|
// Is EXTI configured?
|
||||||
if (EXTI->IMR & ioPos)
|
if (EXTI->IMR & ioPos)
|
||||||
{
|
{
|
||||||
bool rising = (EXTI->RTSR & ioPos);
|
bool rising = (EXTI->RTSR & ioPos);
|
||||||
bool falling = (EXTI->FTSR & ioPos);
|
bool falling = (EXTI->FTSR & ioPos);
|
||||||
|
|
||||||
switch (edge)
|
switch (edge)
|
||||||
{
|
{
|
||||||
case InterruptEdge::RISING:
|
case InterruptEdge::RISING:
|
||||||
return rising;
|
return rising;
|
||||||
|
|
||||||
case InterruptEdge::FALLING:
|
case InterruptEdge::FALLING:
|
||||||
return falling;
|
return falling;
|
||||||
|
|
||||||
case InterruptEdge::BOTH:
|
case InterruptEdge::BOTH:
|
||||||
return rising && falling;
|
return rising && falling;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
STA_ASSERT(false);
|
STA_ASSERT(false);
|
||||||
STA_UNREACHABLE();
|
STA_UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
void initHAL()
|
void initHAL()
|
||||||
{
|
{
|
||||||
#ifdef STA_STM32_DELAY_US_TIM
|
#ifdef STA_STM32_DELAY_US_TIM
|
||||||
// Validate TIM used for delayUs
|
// Validate TIM used for delayUs
|
||||||
extern bool isValidDelayUsTIM();
|
extern bool isValidDelayUsTIM();
|
||||||
STA_ASSERT(isValidDelayUsTIM());
|
STA_ASSERT(isValidDelayUsTIM());
|
||||||
// Start timer base
|
// Start timer base
|
||||||
HAL_TIM_Base_Start(&STA_STM32_DELAY_US_TIM);
|
HAL_TIM_Base_Start(&STA_STM32_DELAY_US_TIM);
|
||||||
#endif // STA_STM32_DELAY_US_TIM
|
#endif // STA_STM32_DELAY_US_TIM
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
@ -6,19 +6,19 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
STM32UART::STM32UART(UART_HandleTypeDef * handle)
|
STM32UART::STM32UART(UART_HandleTypeDef * handle)
|
||||||
: handle_{handle}
|
: handle_{handle}
|
||||||
{
|
{
|
||||||
STA_ASSERT(handle != nullptr);
|
STA_ASSERT(handle != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STM32UART::write(const uint8_t * buffer, size_t size)
|
void STM32UART::write(const uint8_t * buffer, size_t size)
|
||||||
{
|
{
|
||||||
STA_ASSERT(buffer != nullptr);
|
STA_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
HAL_UART_Transmit(handle_, const_cast<uint8_t *>(buffer), size, HAL_MAX_DELAY);
|
HAL_UART_Transmit(handle_, const_cast<uint8_t *>(buffer), size, HAL_MAX_DELAY);
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
|
|
||||||
|
30
src/uart.cpp
30
src/uart.cpp
@ -9,21 +9,21 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
void UART::write(uint8_t value)
|
void UART::write(uint8_t value)
|
||||||
{
|
{
|
||||||
// TODO Handle endian-ness
|
// TODO Handle endian-ness
|
||||||
write(&value, 1);
|
write(&value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UART::write(uint16_t value)
|
void UART::write(uint16_t value)
|
||||||
{
|
{
|
||||||
// TODO Handle endian-ness
|
// TODO Handle endian-ness
|
||||||
write(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
write(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UART::write(uint32_t value)
|
void UART::write(uint32_t value)
|
||||||
{
|
{
|
||||||
// TODO Handle endian-ness
|
// TODO Handle endian-ness
|
||||||
write(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
write(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
Loading…
x
Reference in New Issue
Block a user