mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/sta-core.git
synced 2025-08-06 10:27:34 +00:00
Added I2C support for raspi & first rework of debugging
This commit is contained in:
115
include/sta/bus/can/controller.hpp
Normal file
115
include/sta/bus/can/controller.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief CAN controller driver interface.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_CONTROLLER_HPP
|
||||
#define STA_CORE_CAN_CONTROLLER_HPP
|
||||
|
||||
/**
|
||||
* @defgroup sta_core_can CAN
|
||||
* @ingroup sta_core
|
||||
* @brief CAN controller driver interface.
|
||||
*/
|
||||
|
||||
|
||||
#include <sta/bus/can/filter.hpp>
|
||||
#include <sta/bus/can/headers.hpp>
|
||||
#include <sta/bus/can/iter.hpp>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief CAN controller driver interface.
|
||||
*
|
||||
* @ingroup sta_core_can
|
||||
*/
|
||||
class CanController
|
||||
{
|
||||
public:
|
||||
// RX/TX
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Send frame to CAN controller for transmission.
|
||||
*
|
||||
* @param header CAN frame TX header
|
||||
* @param payload CAN frame payload
|
||||
* @return True on success
|
||||
*/
|
||||
virtual bool sendFrame(const CanTxHeader & header, const uint8_t * payload) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get received frame from the CAN controller.
|
||||
*
|
||||
* @param[in] fifo FIFO storing frame
|
||||
* @param[out] header CAN frame RX header destination
|
||||
* @param[out] payload CAN frame payload destination
|
||||
* @return True on success
|
||||
*/
|
||||
virtual bool receiveFrame(uint8_t fifo, CanRxHeader * header, uint8_t * payload) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get RX FIFO flags.
|
||||
*
|
||||
* @return FIFO flags
|
||||
*/
|
||||
virtual uint32_t getRxFifoFlags() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get list of RX FIFO indices with pending messages.
|
||||
*/
|
||||
virtual CanPendingRxFifos getPendingRxFifos() = 0;
|
||||
|
||||
|
||||
// RX filter
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Change filter settings.
|
||||
*
|
||||
* @param idx Filter index
|
||||
* @param filter Filter configuration
|
||||
* @param active Enable filter after applying settings
|
||||
*/
|
||||
virtual void configureFilter(uint8_t idx, const CanFilter & filter, bool active = false) = 0;
|
||||
/**
|
||||
* @brief Enable filter.
|
||||
*
|
||||
* @param idx Filter index
|
||||
*/
|
||||
virtual void enableFilter(uint8_t idx) = 0;
|
||||
/**
|
||||
* @brief Disable filter.
|
||||
*
|
||||
* @param idx Filter index
|
||||
*/
|
||||
virtual void disableFilter(uint8_t idx) = 0;
|
||||
/**
|
||||
* @brief Disable and clear all filters.
|
||||
*/
|
||||
virtual void clearFilters() = 0;
|
||||
|
||||
|
||||
// Info
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Get number of available filters.
|
||||
*/
|
||||
virtual uint8_t maxFilterCount() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get number of available FIFOs.
|
||||
*/
|
||||
virtual uint8_t maxFifoCount() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get maximum supported payload size.
|
||||
*/
|
||||
virtual uint8_t maxPayloadSize() const = 0;
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_CONTROLLER_HPP
|
49
include/sta/bus/can/filter.hpp
Normal file
49
include/sta/bus/can/filter.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief CAN message filter types.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_FILTER_HPP
|
||||
#define STA_CORE_CAN_FILTER_HPP
|
||||
|
||||
#include <sta/bus/can/id.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @defgroup sta_core_can_filters Filters
|
||||
* @ingroup sta_core_can
|
||||
* @brief CAN message filter types.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief ID format matched by CAN filter.
|
||||
*/
|
||||
enum class CanFilterIdFormat
|
||||
{
|
||||
ANY, /**< Match both ID formats */
|
||||
STD, /**< Match standard format IDs */
|
||||
EXT /**< Match extended format IDs */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CAN filter settings.
|
||||
*/
|
||||
struct CanFilter
|
||||
{
|
||||
CanId obj; /**< ID object */
|
||||
CanId mask; /**< ID mask */
|
||||
CanFilterIdFormat type; /**< ID format to match */
|
||||
uint8_t fifo; /**< FIFO to store matches */
|
||||
};
|
||||
|
||||
|
||||
/** @} */
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_FILTER_HPP
|
48
include/sta/bus/can/headers.hpp
Normal file
48
include/sta/bus/can/headers.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief CAN frame headers.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_HEADERS_HPP
|
||||
#define STA_CORE_CAN_HEADERS_HPP
|
||||
|
||||
#include <sta/bus/can/id.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @defgroup sta_core_can_headers Frame headers
|
||||
* @ingroup sta_core_can
|
||||
* @brief CAN header types for transmitted / received frames.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN TX frame header.
|
||||
*/
|
||||
struct CanTxHeader
|
||||
{
|
||||
CanFrameId id; /**< Frame ID */
|
||||
uint8_t payloadLength; /**< Size of data to send */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CAN RX frame header.
|
||||
*/
|
||||
struct CanRxHeader
|
||||
{
|
||||
CanFrameId id; /**< Frame ID */
|
||||
uint8_t payloadLength; /**< Size of received data */
|
||||
uint32_t timestamp; /**< RX timestamp */
|
||||
uint8_t filter; /**< RX filter match */
|
||||
};
|
||||
|
||||
|
||||
/** @} */
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_HEADERS_HPP
|
110
include/sta/bus/can/id.hpp
Normal file
110
include/sta/bus/can/id.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief CAN frame ID types.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_ID_HPP
|
||||
#define STA_CORE_CAN_ID_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @defgroup sta_core_can_ids Frame IDs
|
||||
* @ingroup sta_core_can
|
||||
* @brief Types for working with CAN ID values and formats.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN frame ID format.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
enum class CanIdFormat : uint8_t
|
||||
{
|
||||
STD, /**< Standard format */
|
||||
EXT /**< Extended format */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN frame ID.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
struct CanId
|
||||
{
|
||||
uint32_t sid; /**< Standard ID field (11 bits) */
|
||||
uint32_t eid; /**< Extended ID field (18 bits) */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN frame ID and format.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
struct CanFrameId
|
||||
{
|
||||
CanIdFormat format; /**< ID format */
|
||||
uint32_t sid; /**< Standard ID field (11 bits) */
|
||||
uint32_t eid; /**< Extended ID field (18 bits) */
|
||||
};
|
||||
|
||||
|
||||
// Comparison operators
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Equal to operator.
|
||||
*
|
||||
* @param lhs Left hand side CAN ID
|
||||
* @param rhs Right hand side CAN ID
|
||||
* @return True if CAN IDs are equal
|
||||
*/
|
||||
bool operator ==(const CanId & lhs, const CanId & rhs);
|
||||
/**
|
||||
* @brief Not equal to operator.
|
||||
*
|
||||
* @param lhs Left hand side CAN ID
|
||||
* @param rhs Right hand side CAN ID
|
||||
* @return True if CAN IDs are not equal
|
||||
*/
|
||||
bool operator !=(const CanId & lhs, const CanId & rhs);
|
||||
|
||||
/**
|
||||
* @brief Equal to operator.
|
||||
*
|
||||
* @param lhs Left hand side CAN Frame ID
|
||||
* @param rhs Right hand side CAN Frame ID
|
||||
* @return True if CAN Frame IDs are equal
|
||||
*/
|
||||
bool operator ==(const CanFrameId & lhs, const CanFrameId & rhs);
|
||||
/**
|
||||
* @brief Not equal to operator.
|
||||
*
|
||||
* @param lhs Left hand side CAN Frame ID
|
||||
* @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);
|
||||
} // namespace sta
|
||||
|
||||
|
||||
/**
|
||||
* @brief Maximum CAN standard ID value.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
#define CAN_SID_MAX UINT32_C(0x7FF)
|
||||
/**
|
||||
* @brief Maximum CAN extended ID value.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
#define CAN_EID_MAX UINT32_C(0x3FFFF)
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_ID_HPP
|
82
include/sta/bus/can/iter.hpp
Normal file
82
include/sta/bus/can/iter.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Custom iterators for CAN controllers.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_ITER_HPP
|
||||
#define STA_CORE_CAN_ITER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Iterable container interface for CAN RX flags.
|
||||
*
|
||||
* @ingroup sta_core_can_ids
|
||||
*/
|
||||
class CanPendingRxFifos
|
||||
{
|
||||
public:
|
||||
using value_type = uint8_t;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using size_type = uint8_t;
|
||||
|
||||
/**
|
||||
* @brief Custom iterator for active RX queues.
|
||||
*/
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
using value_type = CanPendingRxFifos::value_type;
|
||||
using reference = const_reference;
|
||||
using pointer = const value_type *;
|
||||
|
||||
public:
|
||||
const_iterator(const const_iterator & iter);
|
||||
|
||||
const_iterator & operator=(const const_iterator & iter);
|
||||
|
||||
bool operator==(const const_iterator & iter) const;
|
||||
bool operator!=(const const_iterator & iter) const;
|
||||
|
||||
const_iterator & operator++();
|
||||
const_iterator operator++(int);
|
||||
|
||||
reference operator*() const;
|
||||
|
||||
private:
|
||||
const_iterator(uint32_t rxFlags, uint8_t idx, uint8_t endIdx);
|
||||
|
||||
/**
|
||||
* @brief Check if current RX queue has pending data.
|
||||
*/
|
||||
bool isRxPending() const;
|
||||
|
||||
friend class CanPendingRxFifos;
|
||||
|
||||
private:
|
||||
uint32_t rxFlags_; /**< RX flag bits */
|
||||
uint8_t idx_; /**< Current flag index */
|
||||
uint8_t endIdx_; /**< Iterator end index */
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param rxFlags RX flag bits
|
||||
* @param numFifos Number of RX FIFOs
|
||||
*/
|
||||
CanPendingRxFifos(uint32_t rxFlags, uint8_t numFifos);
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
private:
|
||||
uint32_t rxFlags_; /**< RX flag bits */
|
||||
uint8_t numFifos_; /**< Number of RX FIFOs */
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_ITER_HPP
|
102
include/sta/bus/can/subscribable.hpp
Normal file
102
include/sta/bus/can/subscribable.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Subscription interface for CAN controller drivers.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_SUBSCRIBABLE_HPP
|
||||
#define STA_CORE_CAN_SUBSCRIBABLE_HPP
|
||||
|
||||
#include <sta/bus/can/filter.hpp>
|
||||
#include <sta/bus/can/headers.hpp>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @defgroup sta_core_can_sub Subscription
|
||||
* @ingroup sta_core_can
|
||||
* @brief Subscription interface for CAN controller drivers.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback for handling received frames.
|
||||
*
|
||||
* @param header Frame header
|
||||
* @param buffer Frame payload buffer
|
||||
*/
|
||||
using CanRxCallback = void (*) (const CanRxHeader & header, const uint8_t * buffer);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Filter configuration and message handler.
|
||||
*/
|
||||
struct CanFilterConfig
|
||||
{
|
||||
CanFilter filter; /**< Filter handled by callback */
|
||||
CanRxCallback callback; /**< Callback for message handling */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN controller with subscriptions.
|
||||
*
|
||||
* @tparam T Implementation of CanController interface
|
||||
*/
|
||||
template <typename T>
|
||||
class SubscribableCanController : public T
|
||||
{
|
||||
public:
|
||||
using T::T;
|
||||
|
||||
// Subscriptions
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Subscribe to specific message types.
|
||||
*
|
||||
* @param subscriptions Array of message filters and handlers
|
||||
* @param num Number of array entries
|
||||
*/
|
||||
bool subscribe(const CanFilterConfig * subscriptions, uint8_t num);
|
||||
|
||||
/**
|
||||
* @brief Subscribe to all messages.
|
||||
*
|
||||
* @param callback Called when message is received
|
||||
* @param fifo FIFO used for received messages
|
||||
*/
|
||||
void subscribeAll(CanRxCallback callback, uint8_t fifo);
|
||||
|
||||
/**
|
||||
* @brief Unsubscribe from all messages.
|
||||
*
|
||||
* No more messages will be received.
|
||||
*/
|
||||
void unsubscribeAll();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read message from RX FIFO and notify subscriber.
|
||||
*/
|
||||
void receiveAndNotify(uint8_t fifo);
|
||||
|
||||
/**
|
||||
* @brief Process pending frames from RX FIFOs.
|
||||
*/
|
||||
void processMessages();
|
||||
|
||||
|
||||
private:
|
||||
CanRxCallback filterCallbacks_[T::MAX_FILTER_COUNT]; /**< Callbacks for RX filters */
|
||||
};
|
||||
|
||||
|
||||
/** @} */
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#include <sta/bus/can/subscribable.tpp>
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_SUBSCRIBABLE_HPP
|
120
include/sta/bus/can/subscribable.tpp
Normal file
120
include/sta/bus/can/subscribable.tpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @brief Implementation of template class CanController<T>.
|
||||
*/
|
||||
#ifndef STA_CORE_CAN_SUBSCRIBABLE_TPP
|
||||
#define STA_CORE_CAN_SUBSCRIBABLE_TPP
|
||||
|
||||
#ifndef STA_CORE_CAN_SUBSCRIBABLE_HPP
|
||||
#error "Direct use of internal header. Use <sta/can/subscribable.hpp> instead"
|
||||
#endif // !STA_CORE_CAN_SUBSCRIBABLE_HPP
|
||||
|
||||
#ifndef STA_STDLIB_DISABLE
|
||||
# include <algorithm> // fill_n
|
||||
#endif // !STA_STDLIB_DISABLE
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
template <typename T>
|
||||
bool SubscribableCanController<T>::subscribe(const CanFilterConfig * subscriptions, uint8_t num)
|
||||
{
|
||||
// Check bounds
|
||||
if (num > T::MAX_FILTER_COUNT)
|
||||
return false;
|
||||
|
||||
// Clear previous subscriptions
|
||||
unsubscribeAll();
|
||||
|
||||
for (uint8_t i = 0; i < num; ++i)
|
||||
{
|
||||
// Save handler callback
|
||||
filterCallbacks_[i] = subscriptions[i].callback;
|
||||
|
||||
// Configure and enable filter
|
||||
T::configureFilter(i, subscriptions[i].filter, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SubscribableCanController<T>::subscribeAll(CanRxCallback callback, uint8_t fifo)
|
||||
{
|
||||
uint8_t filterIdx = 0;
|
||||
|
||||
// Clear previous subscriptions
|
||||
unsubscribeAll();
|
||||
|
||||
// Setup default filter
|
||||
CanFilter filter{};
|
||||
filter.type = CanFilterIdFormat::ANY;
|
||||
filter.fifo = fifo;
|
||||
|
||||
// Store callback
|
||||
filterCallbacks_[filterIdx] = callback;
|
||||
|
||||
// Configure and enable default filter
|
||||
T::configureFilter(filterIdx, filter, true);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SubscribableCanController<T>::unsubscribeAll()
|
||||
{
|
||||
// Disable all filters
|
||||
T::clearFilters();
|
||||
|
||||
// Clear filter callbacks
|
||||
#ifndef STA_STDLIB_DISABLE
|
||||
std::fill_n(filterCallbacks_, T::MAX_FILTER_COUNT, nullptr);
|
||||
#else // STA_STDLIB_DISABLE
|
||||
for (uint8_t i = 0; i < T::MAX_FILTER_COUNT; ++i)
|
||||
{
|
||||
filterCallbacks_[i] = nullptr;
|
||||
}
|
||||
#endif // STA_STDLIB_DISABLE
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SubscribableCanController<T>::receiveAndNotify(uint8_t fifo)
|
||||
{
|
||||
CanRxHeader header;
|
||||
uint8_t payload[T::MAX_PAYLOAD_SIZE];
|
||||
|
||||
if (T::receiveFrame(fifo, &header, payload))
|
||||
{
|
||||
//displayFrameUART(frame);
|
||||
|
||||
// Forward frame to filter callback
|
||||
if (fifo <= T::MAX_FILTER_COUNT && filterCallbacks_[header.filter])
|
||||
{
|
||||
filterCallbacks_[header.filter](header, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SubscribableCanController<T>::processMessages()
|
||||
{
|
||||
// Read RX interrupt flags
|
||||
uint32_t RFIF = T::getRxFifoFlags();
|
||||
|
||||
if (RFIF != 0)
|
||||
{
|
||||
// Check all flags
|
||||
for (uint8_t fifo = 0; fifo < T::MAX_FIFO_COUNT; ++fifo)
|
||||
{
|
||||
// Process messages if flag is set
|
||||
if (RFIF & 0x1)
|
||||
{
|
||||
receiveAndNotify(fifo);
|
||||
}
|
||||
|
||||
// Shift next RX flag to LSB
|
||||
RFIF >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_CAN_SUBSCRIBABLE_TPP
|
98
include/sta/bus/device.hpp
Normal file
98
include/sta/bus/device.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#ifndef STA_CORE_BUS_SERIAL_DEVICE_HPP
|
||||
#define STA_CORE_BUS_SERIAL_DEVICE_HPP
|
||||
|
||||
#include <sta/bus/interface.hpp>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Abstract device for serial communication.
|
||||
*/
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param intf %SPI hardware interface
|
||||
* @param csPin Chip select pin
|
||||
*/
|
||||
Device(Interface * intf);
|
||||
|
||||
/**
|
||||
* @brief Start transmission with device.
|
||||
*
|
||||
* Must be called before any I/O operations.
|
||||
*/
|
||||
void beginTransmission();
|
||||
|
||||
/**
|
||||
* @brief End transmission with device.
|
||||
*
|
||||
* Must be called after last I/O operation.
|
||||
*/
|
||||
void endTransmission();
|
||||
|
||||
/**
|
||||
* @brief Send single byte of data.
|
||||
*
|
||||
* @param value 8-bit value
|
||||
*/
|
||||
void transfer(uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Send two bytes of data.
|
||||
*
|
||||
* @param value 16-bit value
|
||||
*/
|
||||
void transfer16(uint16_t value);
|
||||
|
||||
/**
|
||||
* @brief Send data from buffer.
|
||||
*
|
||||
* @param buffer Source buffer
|
||||
* @param size Number of bytes to transfer
|
||||
*/
|
||||
void transfer(const uint8_t * buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Send and receive data simultaneously.
|
||||
*
|
||||
* @param txBuffer Send buffer
|
||||
* @param rxBuffer Receive buffer
|
||||
* @param size Number of bytes to transfer
|
||||
*/
|
||||
void transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Read incoming data to buffer.
|
||||
*
|
||||
* @param buffer Destination buffer
|
||||
* @param size Number of bytes to read
|
||||
*/
|
||||
void receive(uint8_t * buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Send byte value repeatedly.
|
||||
*
|
||||
* @param value 8-bit value to repeat
|
||||
* @param count Number of repetitions
|
||||
*/
|
||||
void fill(uint8_t value, size_t count);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Activate device..
|
||||
*/
|
||||
virtual void select() = 0;
|
||||
|
||||
/**
|
||||
* @brief Deactivate device..
|
||||
*/
|
||||
virtual void deselect() = 0;
|
||||
|
||||
private:
|
||||
Interface * intf_;
|
||||
bool selected_ = false;
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
#endif // STA_CORE_BUS_SERIAL_DEVICE_HPP
|
37
include/sta/bus/i2c/device.hpp
Normal file
37
include/sta/bus/i2c/device.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef STA_CORE_I2C_DEVICE_HPP
|
||||
#define STA_CORE_I2C_DEVICE_HPP
|
||||
|
||||
#include <sta/bus/i2c/i2c.hpp>
|
||||
#include <sta/bus/device.hpp>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Peripheral device connected via I2c.
|
||||
*
|
||||
* @ingroup sta_core_i2c
|
||||
*/
|
||||
class I2cDevice : public Device
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param intf %I2C hardware interface
|
||||
* @param csPin The peripheral's address.
|
||||
*/
|
||||
I2cDevice(I2c * intf, int addr);
|
||||
|
||||
protected:
|
||||
void select() override;
|
||||
|
||||
void deselect() override;
|
||||
|
||||
private:
|
||||
int addr_; /**< device address */
|
||||
};
|
||||
|
||||
} // namespace sta
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // STA_CORE_I2C_DEVICE_HPP
|
33
include/sta/bus/i2c/i2c.hpp
Normal file
33
include/sta/bus/i2c/i2c.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef STA_CORE_I2C_I2C_HPP
|
||||
#define STA_CORE_I2C_I2C_HPP
|
||||
|
||||
#include <sta/bus/interface.hpp>
|
||||
#include <sta/mutex.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Interface class for %I2C hardware.
|
||||
*
|
||||
* Represents a single %I2C bus that can be shared by multiple devices.
|
||||
*
|
||||
* @ingroup sta_core_i2c
|
||||
*/
|
||||
class I2c : public Interface
|
||||
{
|
||||
public:
|
||||
I2c(Mutex * mutex=nullptr);
|
||||
|
||||
/**
|
||||
* @brief Address selection for the I2C bus.
|
||||
*
|
||||
* @param address The address to select.
|
||||
*/
|
||||
virtual void selectAddress(uint16_t address) = 0;
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
#endif // STA_CORE_I2C_I2C_HPP
|
86
include/sta/bus/interface.hpp
Normal file
86
include/sta/bus/interface.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef STA_CORE_BUS_SERIAL_INTERFACE_HPP
|
||||
#define STA_CORE_BUS_SERIAL_INTERFACE_HPP
|
||||
|
||||
#include <sta/mutex.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Abstract interface for serial communication.
|
||||
*/
|
||||
class Interface
|
||||
{
|
||||
public:
|
||||
Interface(Mutex * mutex);
|
||||
|
||||
/**
|
||||
* @brief Send single byte of data.
|
||||
*
|
||||
* @param value 8-bit value
|
||||
*/
|
||||
virtual void transfer(uint8_t value) = 0;
|
||||
/**
|
||||
* @brief Send two bytes of data.
|
||||
*
|
||||
* @param value 16-bit value
|
||||
*/
|
||||
virtual void transfer16(uint16_t value) = 0;
|
||||
/**
|
||||
* @brief Send data from buffer.
|
||||
*
|
||||
* @param buffer Source buffer
|
||||
* @param size Number of bytes to transfer
|
||||
*/
|
||||
virtual void transfer(const uint8_t * buffer, size_t size) = 0;
|
||||
/**
|
||||
* @brief Send and receive data simultaneously.
|
||||
*
|
||||
* @param txBuffer Send buffer
|
||||
* @param rxBuffer Receive buffer
|
||||
* @param size Number of bytes to transfer
|
||||
*/
|
||||
virtual void transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) = 0;
|
||||
/**
|
||||
* @brief Read incoming data to buffer.
|
||||
*
|
||||
* @param buffer Destination buffer
|
||||
* @param size Number of bytes to read
|
||||
*/
|
||||
virtual void receive(uint8_t * buffer, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* @brief Send byte value repeatedly.
|
||||
*
|
||||
* @param value 8-bit value to repeat
|
||||
* @param count Number of repetitions
|
||||
*/
|
||||
virtual void fill(uint8_t value, size_t count) = 0;
|
||||
|
||||
/**
|
||||
* @brief Acquire usage rights to use the interface.
|
||||
*
|
||||
* Must be called before any I/O operations are executed.
|
||||
*/
|
||||
virtual void acquire();
|
||||
/**
|
||||
* @brief Release usage rights for interface.
|
||||
*
|
||||
* Must be called after last I/O operation.
|
||||
*/
|
||||
virtual void release();
|
||||
|
||||
/**
|
||||
* @returns true if the interface has been aquired.
|
||||
*/
|
||||
bool isAquired();
|
||||
private:
|
||||
Mutex * mutex_;
|
||||
bool aquired_ = false;
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_BUS_SERIAL_INTERFACE_HPP
|
51
include/sta/bus/spi/device.hpp
Normal file
51
include/sta/bus/spi/device.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SPI bus peripheral device.
|
||||
*/
|
||||
#ifndef STA_CORE_SPI_DEVICE_HPP
|
||||
#define STA_CORE_SPI_DEVICE_HPP
|
||||
|
||||
#include <sta/bus/device.hpp>
|
||||
#include <sta/bus/spi/spi.hpp>
|
||||
#include <sta/gpio_pin.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Peripheral device connected via SPI.
|
||||
*
|
||||
* @ingroup sta_core_spi
|
||||
*/
|
||||
class SPIDevice : public Device
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param intf %SPI hardware interface
|
||||
* @param csPin Chip select pin
|
||||
*/
|
||||
SPIDevice(SPI * intf, GpioPin * csPin);
|
||||
|
||||
/**
|
||||
* @brief Get %SPI interface settings.
|
||||
*
|
||||
* @return SPI settings
|
||||
*/
|
||||
const SPISettings & settings() const;
|
||||
|
||||
protected:
|
||||
void select() override;
|
||||
|
||||
void deselect() override;
|
||||
|
||||
private:
|
||||
SPI * intf_; /**< %SPI hardware interface */
|
||||
GpioPin * csPin_; /**< Chip select pin */
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_SPI_DEVICE_HPP
|
112
include/sta/bus/spi/settings.hpp
Normal file
112
include/sta/bus/spi/settings.hpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SPI bus settings.
|
||||
*/
|
||||
#ifndef STA_CORE_SPI_SETTINGS_HPP
|
||||
#define STA_CORE_SPI_SETTINGS_HPP
|
||||
|
||||
/**
|
||||
* @defgroup sta_core_spi SPI
|
||||
* @ingroup sta_core
|
||||
* @brief SPI interface.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @ingroup sta_core_spi
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief %SPI clock polarity.
|
||||
*/
|
||||
enum class SPIClkPolarity
|
||||
{
|
||||
LOW, /**< Low idle clock */
|
||||
HIGH /**< High idle clock */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief %SPI clock phase.
|
||||
*/
|
||||
enum class SPIClkPhase
|
||||
{
|
||||
EDGE_1, /**< Sample on first edge, shift out on second edge */
|
||||
EDGE_2 /**< Shift out on first edge, sample on second edge */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief %SPI clock mode.
|
||||
*/
|
||||
enum class SPIMode
|
||||
{
|
||||
MODE_0, /**< Low idle clock, sample on rising edge, shift out on falling edge */
|
||||
MODE_1, /**< Low idle clock, sample on falling edge, shift out on rising edge */
|
||||
MODE_2, /**< High idle clock, sample on rising edge, shift out on falling edge */
|
||||
MODE_3 /**< High idle clock, sample on falling edge, shift out on rising edge */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief %SPI data size.
|
||||
*/
|
||||
enum class SPIDataSize
|
||||
{
|
||||
SIZE_8, /**< 8-bit data size */
|
||||
SIZE_16 /**< 16-bit data size */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief %SPI bit order.
|
||||
*/
|
||||
enum class SPIBitOrder
|
||||
{
|
||||
MSB, /**< Send most significant bit first */
|
||||
LSB /**< Send least significant bit first */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief %SPI settings.
|
||||
*/
|
||||
struct SPISettings
|
||||
{
|
||||
SPIMode mode; /**< %SPI clock mode */
|
||||
SPIDataSize dataSize; /**< %SPI data size */
|
||||
SPIBitOrder bitOrder; /**< %SPI bit order */
|
||||
uint32_t clkSpeed; /**< %SPI clock speed */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get %SPI clock polarity from clock mode.
|
||||
*
|
||||
* @param mode %SPI clock mode
|
||||
* @return %SPI clock polarity
|
||||
*/
|
||||
SPIClkPolarity getSPIClkPolarity(SPIMode mode);
|
||||
/**
|
||||
* @brief Get %SPI clock phase from clock mode.
|
||||
*
|
||||
* @param mode %SPI clock mode
|
||||
* @return %SPI clock phase
|
||||
*/
|
||||
SPIClkPhase getSPIClkPhase(SPIMode mode);
|
||||
/**
|
||||
* @brief Get %SPI clock mode from clock phase and polarity.
|
||||
*
|
||||
* @param polarity %SPI clock polarity
|
||||
* @param phase %SPI clock phase
|
||||
* @return %SPI clock mode
|
||||
*/
|
||||
SPIMode getSPIMode(SPIClkPolarity polarity, SPIClkPhase phase);
|
||||
|
||||
|
||||
/** @} */
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_SPI_SETTINGS_HPP
|
47
include/sta/bus/spi/spi.hpp
Normal file
47
include/sta/bus/spi/spi.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SPI bus software interface.
|
||||
*/
|
||||
#ifndef STA_CORE_SPI_SPI_HPP
|
||||
#define STA_CORE_SPI_SPI_HPP
|
||||
|
||||
#include <sta/bus/interface.hpp>
|
||||
#include <sta/bus/spi/settings.hpp>
|
||||
#include <sta/mutex.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace sta
|
||||
{
|
||||
/**
|
||||
* @brief Interface class for %SPI hardware.
|
||||
*
|
||||
* Represents a single %SPI bus that can be shared by multiple devices.
|
||||
*
|
||||
* @ingroup sta_core_spi
|
||||
*/
|
||||
class SPI : public Interface
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param settings %SPI bus settings
|
||||
* @param mutex Mutex object for managing shared access. Pass nullptr for no access control
|
||||
*/
|
||||
SPI(const SPISettings & settings, Mutex * mutex = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get %SPI interface settings.
|
||||
*
|
||||
* @return %SPI settings
|
||||
*/
|
||||
const SPISettings & settings();
|
||||
|
||||
private:
|
||||
SPISettings settings_; /**< %SPI settings */
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
|
||||
#endif // STA_CORE_SPI_SPI_HPP
|
24
include/sta/bus/uart/settings.hpp
Normal file
24
include/sta/bus/uart/settings.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef STA_CORE_UART_SETTINGS_HPP
|
||||
#define STA_CORE_UART_SETTINGS_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
enum class UARTMode
|
||||
{
|
||||
RX,
|
||||
TX,
|
||||
RX_TX
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief %UART settings.
|
||||
*/
|
||||
struct UARTSettings
|
||||
{
|
||||
UARTMode mode;
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
#endif // STA_CORE_UART_SETTINGS_HPP
|
25
include/sta/bus/uart/uart.hpp
Normal file
25
include/sta/bus/uart/uart.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef STA_CORE_UART_UART_HPP
|
||||
#define STA_CORE_UART_UART_HPP
|
||||
|
||||
#include <sta/bus/interface.hpp>
|
||||
#include <sta/bus/uart/settings.hpp>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
class UART : public Interface
|
||||
{
|
||||
public:
|
||||
UART(const UARTSettings & settings, Mutex * mutex=nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get %UART interface settings.
|
||||
*
|
||||
* @return %UART settings
|
||||
*/
|
||||
const UARTSettings & settings();
|
||||
private:
|
||||
UARTSettings settings_; /**< %UART settings */
|
||||
};
|
||||
} // namespace sta
|
||||
|
||||
#endif // STA_CORE_UART_UART_HPP
|
Reference in New Issue
Block a user