25#include <system_error>
38#include <linux/gpio.h>
40#include <piduino/global.h>
59#define GPIO_MAX_NAME_SIZE 32
67#define GPIO_V2_LINES_MAX 64
73#define GPIO_V2_LINE_NUM_ATTRS_MAX 10
79 enum gpio_v2_line_attr_id {
80 GPIO_V2_LINE_ATTR_ID_FLAGS = 1,
81 GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES = 2,
82 GPIO_V2_LINE_ATTR_ID_DEBOUNCE = 3,
88 enum gpio_v2_line_flag {
89 GPIO_V2_LINE_FLAG_USED = _BITULL (0),
90 GPIO_V2_LINE_FLAG_ACTIVE_LOW = _BITULL (1),
91 GPIO_V2_LINE_FLAG_INPUT = _BITULL (2),
92 GPIO_V2_LINE_FLAG_OUTPUT = _BITULL (3),
93 GPIO_V2_LINE_FLAG_EDGE_RISING = _BITULL (4),
94 GPIO_V2_LINE_FLAG_EDGE_FALLING = _BITULL (5),
95 GPIO_V2_LINE_FLAG_OPEN_DRAIN = _BITULL (6),
96 GPIO_V2_LINE_FLAG_OPEN_SOURCE = _BITULL (7),
97 GPIO_V2_LINE_FLAG_BIAS_PULL_UP = _BITULL (8),
98 GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN = _BITULL (9),
99 GPIO_V2_LINE_FLAG_BIAS_DISABLED = _BITULL (10),
100 GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME = _BITULL (11),
101 GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE = _BITULL (12),
107 enum gpio_v2_line_event_id {
108 GPIO_V2_LINE_EVENT_RISING_EDGE = 1,
109 GPIO_V2_LINE_EVENT_FALLING_EDGE = 2,
121 memset (
this, 0,
sizeof (*
this));
125 char name[GPIO_MAX_NAME_SIZE];
126 char label[GPIO_MAX_NAME_SIZE];
139 memset (
this, 0,
sizeof (*
this));
147 memset (
this, 0,
sizeof (*
this));
172 __aligned_u64 values;
179 __u32 debounce_period_us;
198 memset (
this, 0,
sizeof (*
this));
206 memset (
this, 0,
sizeof (*
this));
207 this->offset = offset;
233 char name[GPIO_MAX_NAME_SIZE];
241 char consumer[GPIO_MAX_NAME_SIZE];
279 memset (
this, 0,
sizeof (*
this));
287 memset (
this, 0,
sizeof (*
this));
332 memset (
this, 0,
sizeof (*
this));
374 memset (
this, 0,
sizeof (*
this));
376 event_buffer_size = 0;
385 memset (
this, 0,
sizeof (*
this));
386 strncpy (this->consumer, consumer.c_str(), GPIO_MAX_NAME_SIZE - 1);
388 event_buffer_size = 0;
399 __u32 offsets[GPIO_V2_LINES_MAX];
406 char consumer[GPIO_MAX_NAME_SIZE];
429 __u32 event_buffer_size;
452 memset (
this, 0,
sizeof (*
this));
461 memset (
this, 0,
sizeof (*
this));
503 memset (
this, 0,
sizeof (*
this));
510 __aligned_u64 timestamp_ns;
580 template<
class ParamType>
581 bool ioCtl (
unsigned long cmd, ParamType *param) {
746 memset (info, 0,
sizeof (*info));
747 info->offset = offset;
748 return ioCtl (GPIO_V2_GET_LINEINFO_IOCTL, info);
757 static std::string
devPath (uint32_t chip_no) {
759 return "/dev/gpiochip" + std::to_string (chip_no);
797 m_req.num_lines = num_lines;
799 memcpy (
m_req.offsets, offsets, num_lines * sizeof (uint32_t));
809 strncpy (
m_req.consumer, dev->consumer().c_str(), sizeof (
m_req.consumer));
867 return m_req.num_lines;
876 uint32_t
offset (uint32_t line_no = 0)
const {
878 if (line_no >=
m_req.num_lines) {
880 throw std::out_of_range (
"Line number out of range");
882 return m_req.offsets[line_no];
911 if (num_lines >
m_req.num_lines) {
912 num_lines =
m_req.num_lines;
915 for (uint32_t i = 0; i < num_lines; ++i) {
917 if (!
m_chip->lineInfo (
m_req.offsets[i], &info[i])) {
941 m_req.config.flags = flags;
942 if (!
m_chip->ioCtl (GPIO_V2_GET_LINE_IOCTL, &
m_req)) {
966 if (!
m_chip->ioCtl (GPIO_V2_GET_LINE_IOCTL, &
m_req)) {
997 std::this_thread::sleep_for (std::chrono::microseconds (1));
1011 return m_req.fd >= 0;
1095 return ( (values.bits & values.mask) != 0);
1099 throw std::system_error (errno, std::system_category(), EXCEPTION_MSG (
"Failed to get line values"));
1121 uint64_t line_mask = 1ULL << line_no;
1122 LineValues values (value ? line_mask : 0, line_mask);
1171 if (debounce_ms > 0) {
1173 debounce.attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
1174 debounce.attr.debounce_period_us = debounce_ms * 1000;
1180 debounce.attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
1181 debounce.attr.debounce_period_us = 0;
1197 return m_req.config.attrs[0].attr.debounce_period_us / 1000;
1212 pfd[0].fd =
m_req.fd;
1213 pfd[0].events = POLLIN | POLLPRI;
Represents a GPIO chip and provides methods to interact with it.
bool open(const char *dev)
Opens the GPIO chip device.
~Chip()
Destructor for the Chip class.
int errorCode() const
Gets the last error code from the IOCTL operation.
std::string name() const
Gets the name of the GPIO chip.
const char * errorMessage() const
Gets the error message corresponding to the last error code.
bool isOpen() const
Checks if the GPIO chip device is open.
bool close()
Closes the GPIO chip device.
bool open(const std::string &dev)
Opens the GPIO chip device using a string.
std::string consumer() const
Gets the consumer label of the GPIO chip.
std::string dev() const
Gets the path to the GPIO chip device.
std::string label() const
Gets the label of the GPIO chip.
bool fillInfo()
Fills the chip information structure with data from the device.
static std::string devPath(uint32_t chip_no)
Gets the path to a GPIO chip device based on its chip number.
Chip(const std::string &consumer=std::string())
Constructor for the Chip class.
uint32_t lines() const
Gets the number of lines available on the GPIO chip.
int result() const
Gets the result of the last IOCTL operation.
bool ioCtl(unsigned long cmd, ParamType *param)
Performs an IOCTL operation on the GPIO chip.
bool lineInfo(uint32_t offset, LineInfo *info)
Retrieves information about a specific GPIO line.
bool open(uint32_t chip_no)
Opens the GPIO chip device using a chip number.
Represents a GPIO line and provides methods to interact with it.
bool setValues(const LineValues &values)
Sets the values of the GPIO line(s).
bool open(uint64_t flags)
Opens the GPIO line with the specified flags.
bool setConfig(const LineConfig &config)
Sets the configuration for the GPIO line.
Line(const Line &)=delete
const LineRequest & request() const
Gets the current line request configuration.
int result() const
Gets the result of the last IOCTL operation.
~Line()
Destructor for the Line class. Closes the line if it is open.
bool close()
Closes the GPIO line.
const LineConfig & config() const
Gets the current line configuration.
bool setDebounce(uint32_t debounce_ms)
Sets the debounce period for the GPIO line.
uint32_t offset(uint32_t line_no=0) const
Gets the offset of a specific line in the request.
uint32_t debounce() const
Gets the debounce period for the GPIO line.
int errorCode() const
Gets the last error code from the IOCTL operation.
uint32_t numLines() const
Gets the number of lines in the request.
bool waitForEvent(LineEvent &event, int timeout_ms=-1)
Waits for an event on the GPIO line.
std::shared_ptr< Chip > m_chip
Line & operator=(const Line &)=delete
bool getValues(LineValues &values) const
Gets the values of the GPIO line(s).
Line(std::shared_ptr< Chip > dev, const LineRequest &request)
Constructor for the Line class with a LineRequest object.
bool setValue(bool value, int line_no=0)
Sets the value of a specific GPIO line.
bool open(const LineConfig &config)
Opens the GPIO line with the specified configuration.
bool getInfo(LineInfo *info, uint32_t num_lines=1)
Retrieves information about GPIO lines.
bool getValue(int line_no=0) const
Gets the value of a specific GPIO line.
Line(std::shared_ptr< Chip > dev, uint32_t num_lines, const uint32_t *offsets)
Constructor for the Line class with multiple lines.
Line(std::shared_ptr< Chip > dev, uint32_t offset)
Constructor for the Line class.
const char * errorMessage() const
Gets the error message corresponding to the last error code.
bool isOpen() const
Checks if the GPIO line is open.
Namespace containing classes and types for GPIO device interaction. Use the kernel GPIO interface ver...
Information about a certain GPIO chip.
ChipInfo()
Default constructor initializes the ChipInfo structure.
a configurable attribute of a line
LineAttribute(uint32_t id)
Constructor initializes the LineAttribute structure with a specific id.
LineAttribute()
Default constructor initializes the LineAttribute structure.
a configuration attribute associated with one or more of the requested lines.
LineConfigAttribute(const LineAttribute &attr)
Constructor initializes the LineConfigAttribute structure with a specific attribute.
LineConfigAttribute()
Default constructor initializes the LineConfigAttribute structure.
Configuration for GPIO lines.
LineConfig(std::uint64_t flags)
Constructor initializes the LineConfig structure with specific flags.
void clear()
Clear the LineConfig structure by zeroing all fields.
LineConfig()
Default constructor initializes the LineConfig structure.
The actual event being pushed to userspace.
LineEvent()
Default constructor initializes the LineEvent structure.
Information about a certain GPIO line.
LineInfo(uint32_t offset)
Constructor initializes the LineInfo structure with a specific offset.
void printAttributes(std::ostream &os=std::cout) const
Print the attributes of this GPIO line to the specified output stream.
friend std::ostream & operator<<(std::ostream &os, const LineInfo &info)
Overloaded output operator to print the LineInfo object.
LineInfo()
Default constructor initializes the LineInfo structure.
Information about a request for GPIO lines.
LineRequest(const std::string &consumer)
Constructor initializes the LineRequest structure with specific consumer label.
LineRequest()
Default constructor initializes the LineRequest structure.
LineValues()
Default constructor initializes the LineValues structure.
LineValues(std::uint64_t bits, std::uint64_t mask)
Constructor initializes the LineValues structure with specific bits and mask.