@@ -76,6 +76,13 @@ public:
*/
line_config& add_line_settings(const line::offsets& offsets, const line_settings& settings);
+ /**
+ * @brief Set output values for a number of lines.
+ * @param values Buffer containing the output values.
+ * @return Reference to self.
+ */
+ line_config& set_output_values(const line::values& values);
+
/**
* @brief Get a mapping of offsets to line settings stored by this
* object.
@@ -31,6 +31,7 @@ map_enum_c_to_cxx(c_enum_type value, const ::std::map<c_enum_type, cxx_enum_type
}
void throw_from_errno(const ::std::string& what);
+::gpiod_line_value map_output_value(line::value value);
template<class T, void F(T*)> struct deleter
{
@@ -100,6 +100,21 @@ GPIOD_CXX_API line_config& line_config::add_line_settings(const line::offsets& o
return *this;
}
+GPIOD_CXX_API line_config& line_config::set_output_values(const line::values& values)
+{
+ ::std::vector<::gpiod_line_value> mapped_values(values.size());
+
+ for (unsigned int i = 0; i < values.size(); i++)
+ mapped_values[i] = map_output_value(values[i]);
+
+ auto ret = ::gpiod_line_config_set_output_values(this->_m_priv->config.get(),
+ mapped_values.data(), mapped_values.size());
+ if (ret)
+ throw_from_errno("unable to set output values");
+
+ return *this;
+}
+
GPIOD_CXX_API ::std::map<line::offset, line_settings> line_config::get_line_settings() const
{
::std::size_t num_offsets = ::gpiod_line_config_get_num_configured_offsets(
@@ -139,6 +139,11 @@ cxx_enum_type get_mapped_value(::gpiod_line_settings* settings,
} /* namespace */
+::gpiod_line_value map_output_value(line::value value)
+{
+ return do_map_value(value, value_mapping);
+}
+
line_settings::impl::impl()
: settings(make_line_settings())
{
@@ -4,12 +4,17 @@
#include <catch2/catch.hpp>
#include <gpiod.hpp>
+#include "gpiosim.hpp"
#include "helpers.hpp"
+using ::gpiosim::make_sim;
using namespace ::std::chrono_literals;
using direction = ::gpiod::line::direction;
using drive = ::gpiod::line::drive;
using edge = ::gpiod::line::edge;
+using simval = ::gpiosim::chip::value;
+using value = ::gpiod::line::value;
+using values = ::gpiod::line::values;
namespace {
@@ -72,6 +77,52 @@ TEST_CASE("line_config can be reset", "[line-config]")
REQUIRE(cfg.get_line_settings().size() == 0);
}
+TEST_CASE("output values can be set globally", "[line-config]")
+{
+ const values vals = { value::ACTIVE, value::INACTIVE, value::ACTIVE, value::INACTIVE };
+
+ auto sim = make_sim()
+ .set_num_lines(4)
+ .build();
+
+ ::gpiod::line_config cfg;
+
+ SECTION("request with globally set output values")
+ {
+ cfg
+ .add_line_settings(
+ {0, 1, 2, 3},
+ ::gpiod::line_settings().set_direction(direction::OUTPUT)
+ )
+ .set_output_values(vals);
+
+ auto request = ::gpiod::chip(sim.dev_path())
+ .prepare_request()
+ .set_line_config(cfg)
+ .do_request();
+
+ REQUIRE(sim.get_value(0) == simval::ACTIVE);
+ REQUIRE(sim.get_value(1) == simval::INACTIVE);
+ REQUIRE(sim.get_value(2) == simval::ACTIVE);
+ REQUIRE(sim.get_value(3) == simval::INACTIVE);
+ }
+
+ SECTION("read back global output values")
+ {
+ cfg
+ .add_line_settings(
+ {0, 1, 2, 3},
+ ::gpiod::line_settings()
+ .set_direction(direction::OUTPUT)
+ .set_output_value(value::ACTIVE)
+ )
+ .set_output_values(vals);
+
+ auto settings = cfg.get_line_settings()[1];
+ REQUIRE(settings.output_value() == value::INACTIVE);
+ }
+}
+
TEST_CASE("line_config stream insertion operator works", "[line-config]")
{
::gpiod::line_config cfg;