Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions core/include/librmcs/data/datas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <cstdint>
#include <span>

#include <librmcs/spec/gpio.hpp>

namespace librmcs::data {

enum class DataId : uint8_t {
Expand Down Expand Up @@ -43,12 +45,10 @@ struct UartDataView {
};

struct GpioDigitalDataView {
uint8_t channel;
bool high;
};

struct GpioAnalogDataView {
uint8_t channel;
uint16_t value;
};

Expand All @@ -59,12 +59,20 @@ enum class GpioPull : uint8_t {
};

struct GpioReadConfigView {
uint8_t channel;
uint16_t period_ms = 0;
bool asap = false;
bool rising_edge = false;
bool falling_edge = false;
GpioPull pull = GpioPull::kNone;

[[nodiscard]] constexpr bool supported(const spec::GpioDescriptor& gpio) const noexcept {
return (!asap || gpio.supports(spec::GpioCapability::kDigitalReadOnce))
&& (!period_ms || gpio.supports(spec::GpioCapability::kDigitalReadPeriodic))
&& ((!rising_edge && !falling_edge)
|| gpio.supports(spec::GpioCapability::kDigitalReadInterrupt))
&& (pull != GpioPull::kUp || gpio.supports(spec::GpioCapability::kPullUp))
&& (pull != GpioPull::kDown || gpio.supports(spec::GpioCapability::kPullDown));
}
};

struct AccelerometerDataView {
Expand Down Expand Up @@ -93,9 +101,11 @@ class DataCallback {

virtual bool uart_receive_callback(DataId id, const UartDataView& data) = 0;

virtual void gpio_digital_read_result_callback(const GpioDigitalDataView& data) = 0;
virtual void gpio_digital_read_result_callback(
uint8_t channel_index, const GpioDigitalDataView& data) = 0;

virtual void gpio_analog_read_result_callback(const GpioAnalogDataView& data) = 0;
virtual void
gpio_analog_read_result_callback(uint8_t channel_index, const GpioAnalogDataView& data) = 0;

virtual void accelerometer_receive_callback(const AccelerometerDataView& data) = 0;

Expand Down
70 changes: 70 additions & 0 deletions core/include/librmcs/spec/c_board/gpio.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <iterator>

#include <librmcs/spec/gpio.hpp>

namespace librmcs::spec::c_board {

namespace internal {
class GpioDescriptors;
}

// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class GpioDescriptor : public spec::GpioDescriptor {
friend internal::GpioDescriptors;
constexpr GpioDescriptor(uint8_t channel_index, GpioCapability capability_mask)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
: spec::GpioDescriptor(channel_index, capability_mask) {}

public:
GpioDescriptor(const GpioDescriptor&) = delete;
GpioDescriptor& operator=(const GpioDescriptor&) = delete;
GpioDescriptor(GpioDescriptor&&) = delete;
GpioDescriptor& operator=(GpioDescriptor&&) = delete;

[[nodiscard]] constexpr bool operator==(const GpioDescriptor& other) const noexcept {
return channel_index == other.channel_index;
}
};

namespace internal {
class GpioDescriptors {
static constexpr GpioDescriptor kArray[]{
{0, kPwmCapabilities},
{1, kPwmCapabilities},
{2, kPwmCapabilities},
{3, kPwmCapabilities},
{4, kPwmCapabilities},
{5, kPwmCapabilities & ~GpioCapability::kDigitalReadInterrupt},
{6, kPwmCapabilities}
};
static_assert(channel_indices_match_indices(kArray));

public:
constexpr GpioDescriptors() = default;

static constexpr std::size_t size() noexcept { return std::size(kArray); }

static constexpr const GpioDescriptor& operator[](std::size_t channel_index) noexcept {
return kArray[channel_index];
}

static constexpr const GpioDescriptor* begin() noexcept { return std::begin(kArray); }

static constexpr const GpioDescriptor* end() noexcept { return std::end(kArray); }

static constexpr const GpioDescriptor& kPwm1 = kArray[0];
static constexpr const GpioDescriptor& kPwm2 = kArray[1];
static constexpr const GpioDescriptor& kPwm3 = kArray[2];
static constexpr const GpioDescriptor& kPwm4 = kArray[3];
static constexpr const GpioDescriptor& kPwm5 = kArray[4];
static constexpr const GpioDescriptor& kPwm6 = kArray[5];
static constexpr const GpioDescriptor& kPwm7 = kArray[6];
};
} // namespace internal

inline constexpr internal::GpioDescriptors kGpioDescriptors{};

} // namespace librmcs::spec::c_board
58 changes: 58 additions & 0 deletions core/include/librmcs/spec/gpio.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once

#include <cstddef>
#include <cstdint>

namespace librmcs::spec {

enum class GpioCapability : std::uint8_t {
kNone = 0,
kDigitalWrite = 1U << 0,
kAnalogWrite = 1U << 1,
kDigitalReadOnce = 1U << 2,
kDigitalReadPeriodic = 1U << 3,
kDigitalReadInterrupt = 1U << 4,
kPullUp = 1U << 5,
kPullDown = 1U << 6,
};

constexpr GpioCapability operator|(GpioCapability a, GpioCapability b) noexcept {
return static_cast<GpioCapability>(static_cast<std::uint8_t>(a) | static_cast<std::uint8_t>(b));
}

constexpr GpioCapability operator&(GpioCapability a, GpioCapability b) noexcept {
return static_cast<GpioCapability>(static_cast<std::uint8_t>(a) & static_cast<std::uint8_t>(b));
}

constexpr GpioCapability operator~(GpioCapability a) noexcept {
return static_cast<GpioCapability>(~static_cast<std::uint8_t>(a));
}

inline constexpr GpioCapability kDigitalCapabilities =
GpioCapability::kDigitalWrite | GpioCapability::kDigitalReadOnce
| GpioCapability::kDigitalReadPeriodic | GpioCapability::kDigitalReadInterrupt
| GpioCapability::kPullUp | GpioCapability::kPullDown;

inline constexpr GpioCapability kPwmCapabilities =
kDigitalCapabilities | GpioCapability::kAnalogWrite;

struct GpioDescriptor {
std::uint8_t channel_index;
GpioCapability capability_mask = GpioCapability::kNone;

[[nodiscard]] constexpr bool supports(GpioCapability capability) const noexcept {
return (capability_mask & capability) == capability;
}
};

template <typename Descriptor, std::size_t n>
[[nodiscard]] consteval bool
channel_indices_match_indices(const Descriptor (&descriptors)[n]) noexcept {
for (std::size_t index = 0; index < n; ++index) {
if (descriptors[index].channel_index != index)
return false;
}
return true;
}

} // namespace librmcs::spec
66 changes: 66 additions & 0 deletions core/include/librmcs/spec/rmcs_board_lite/gpio.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <iterator>

#include <librmcs/spec/gpio.hpp>

namespace librmcs::spec::rmcs_board_lite {

namespace internal {
class GpioDescriptors;
}

// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class GpioDescriptor : public spec::GpioDescriptor {
friend internal::GpioDescriptors;
constexpr GpioDescriptor(uint8_t channel_index, GpioCapability capability_mask)
Comment thread
qzhhhi marked this conversation as resolved.
: spec::GpioDescriptor(channel_index, capability_mask) {}

public:
GpioDescriptor(const GpioDescriptor&) = delete;
GpioDescriptor& operator=(const GpioDescriptor&) = delete;
GpioDescriptor(GpioDescriptor&&) = delete;
GpioDescriptor& operator=(GpioDescriptor&&) = delete;

[[nodiscard]] constexpr bool operator==(const GpioDescriptor& other) const noexcept {
return channel_index == other.channel_index;
}
};

namespace internal {

class GpioDescriptors {
static constexpr GpioDescriptor kArray[]{
{0, kDigitalCapabilities},
{1, kDigitalCapabilities},
{2, kDigitalCapabilities},
{3, kDigitalCapabilities},
};
static_assert(channel_indices_match_indices(kArray));

public:
constexpr GpioDescriptors() = default;

static constexpr std::size_t size() noexcept { return std::size(kArray); }

static constexpr const GpioDescriptor& operator[](std::size_t channel_index) noexcept {
return kArray[channel_index];
}

static constexpr const GpioDescriptor* begin() noexcept { return std::begin(kArray); }

static constexpr const GpioDescriptor* end() noexcept { return std::end(kArray); }

static constexpr const GpioDescriptor& kUart0Rx = kArray[0];
static constexpr const GpioDescriptor& kUart0Tx = kArray[1];
static constexpr const GpioDescriptor& kUart1Rx = kArray[2];
static constexpr const GpioDescriptor& kUart1Tx = kArray[3];
};

} // namespace internal

inline constexpr internal::GpioDescriptors kGpioDescriptors{};

} // namespace librmcs::spec::rmcs_board_lite
94 changes: 94 additions & 0 deletions core/include/librmcs/spec/rmcs_board_pro/gpio.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <iterator>

#include <librmcs/spec/gpio.hpp>

namespace librmcs::spec::rmcs_board_pro {

namespace internal {
class GpioDescriptors;
}

// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class GpioDescriptor : public spec::GpioDescriptor {
friend internal::GpioDescriptors;
constexpr GpioDescriptor(uint8_t channel_index, GpioCapability capability_mask)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
: spec::GpioDescriptor(channel_index, capability_mask) {}

public:
GpioDescriptor(const GpioDescriptor&) = delete;
GpioDescriptor& operator=(const GpioDescriptor&) = delete;
GpioDescriptor(GpioDescriptor&&) = delete;
GpioDescriptor& operator=(GpioDescriptor&&) = delete;

[[nodiscard]] constexpr bool operator==(const GpioDescriptor& other) const noexcept {
return channel_index == other.channel_index;
}
};

namespace internal {

class GpioDescriptors {
static constexpr GpioDescriptor kArray[]{
{ 0, kPwmCapabilities},
{ 1, kPwmCapabilities},
{ 2, kPwmCapabilities},
{ 3, kPwmCapabilities},
{ 4, kDigitalCapabilities},
{ 5, kDigitalCapabilities},
{ 6, kDigitalCapabilities},
{ 7, kDigitalCapabilities},
{ 8, kDigitalCapabilities},
{ 9, kDigitalCapabilities},
{10, kDigitalCapabilities},
{11, kDigitalCapabilities},
{12, kDigitalCapabilities},
{13, kDigitalCapabilities},
{14, kDigitalCapabilities},
{15, kDigitalCapabilities},
{16, kDigitalCapabilities},
};
static_assert(channel_indices_match_indices(kArray));

public:
constexpr GpioDescriptors() = default;

static constexpr std::size_t size() noexcept { return std::size(kArray); }

static constexpr const GpioDescriptor& operator[](std::size_t channel_index) noexcept {
return kArray[channel_index];
}

static constexpr const GpioDescriptor* begin() noexcept { return std::begin(kArray); }

static constexpr const GpioDescriptor* end() noexcept { return std::end(kArray); }

static constexpr const GpioDescriptor& kPwm0 = kArray[0];
static constexpr const GpioDescriptor& kPwm1 = kArray[1];
static constexpr const GpioDescriptor& kPwm2 = kArray[2];
static constexpr const GpioDescriptor& kPwm3 = kArray[3];

static constexpr const GpioDescriptor& kSpiI2cSocket0 = kArray[4];
static constexpr const GpioDescriptor& kSpiI2cSocket1 = kArray[5];
static constexpr const GpioDescriptor& kSpiI2cSocket2 = kArray[6];
static constexpr const GpioDescriptor& kSpiI2cSocket3 = kArray[7];
static constexpr const GpioDescriptor& kSpiI2cSocket4 = kArray[8];
static constexpr const GpioDescriptor& kSpiI2cSocket5 = kArray[9];
static constexpr const GpioDescriptor& kSpiI2cSocket6 = kArray[10];

static constexpr const GpioDescriptor& kUart0Rx = kArray[11];
static constexpr const GpioDescriptor& kUart0Tx = kArray[12];
static constexpr const GpioDescriptor& kUart1Rx = kArray[13];
static constexpr const GpioDescriptor& kUart1Tx = kArray[14];
static constexpr const GpioDescriptor& kUart2Rx = kArray[15];
static constexpr const GpioDescriptor& kUart2Tx = kArray[16];
};

} // namespace internal

inline constexpr internal::GpioDescriptors kGpioDescriptors{};

} // namespace librmcs::spec::rmcs_board_pro
Loading
Loading