readout software for 2 channels [0 and 1] of the tdc-gpx2 board with raspberry pi 3B SPI readout. This code is a fork of the original design by marvin.peter@physik.uni-giessen.de https://github.com/marvin5300/tdc-gpx2_software
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

128 lines
3.1 KiB

#ifndef GPIO_H
#define GPIO_H
#include <vector>
#include <mutex>
#include <shared_mutex>
#include <chrono>
#include <future>
#include <map>
#include <memory>
#include <linux/gpio.h>
#include <gpiod.h>
// TODO: check correctness of mutex'
// TODO: implement and check init, step, shutdown, write functions
enum class PinBias : std::uint8_t {
OpenDrain = 0x01,
OpenSource = 0x02,
ActiveLow = 0x04,
PullDown = 0x10,
PullUp = 0x20
};
class gpio
{
public:
constexpr static auto standard_timeout = std::chrono::seconds{10};
struct event
{
enum Type
{
Invalid,
Rising,
Falling
} type{ Invalid };
std::size_t pin{};
timespec ts;
inline operator bool()
{
return type != Invalid;
}
};
struct setting
{
[[nodiscard]] auto matches(const event& e) const -> bool;
std::vector<unsigned> gpio_pins;
};
class callback
{
friend class gpio;
public:
[[nodiscard]] auto wait_async(std::chrono::milliseconds timeout)->std::future<event>;
[[nodiscard]] auto wait(std::chrono::milliseconds timeout)->event;
[[nodiscard]] auto write_async(const event& e)->std::future<bool>;
[[nodiscard]] auto write(const event& e) -> bool;
[[nodiscard]] auto read(unsigned pin_num) -> int;
callback(setting s, gpio& handler);
private:
void notify(const event& e);
setting m_setting{};
event m_event {};
std::condition_variable m_wait{};
std::mutex m_wait_mutex{};
std::shared_mutex m_access_mutex{};
gpio& m_handler;
};
gpio(std::string consumer = "gpio", std::string chipname = "gpiochip0")
: m_consumer{std::move(consumer)}
, m_chipname{std::move(chipname)}
{};
virtual ~gpio();
void start();
void stop();
void join();
[[nodiscard]] auto list_callback(setting s)->std::shared_ptr<callback>;
void remove_callback(std::size_t id);
private:
[[nodiscard]] auto setup() -> int;
[[nodiscard]] auto step() -> int;
[[nodiscard]] auto shutdown() -> int;
[[nodiscard]] auto write(const event& e) -> bool;
[[nodiscard]] auto read(unsigned pin_num) -> int;
void notify_all(event e);
std::string m_consumer;
std::string m_chipname;
const timespec c_wait_timeout{1,0};
//std::shared_ptr<::gpiod_chip> chip{nullptr};
//std::shared_ptr<::gpiod_line_bulk> lines{nullptr};
gpiod_chip* chip{nullptr};
gpiod_line_bulk* lines{nullptr};
std::map< unsigned, gpiod_line* > other_lines{}; // map of other initialized lines which are requested but have no active event listening going on
std::vector<unsigned> pins_used_by_listeners{};
//inline static std::size_t global_id_counter{ 0 };
std::size_t global_id_counter{ 0 };
std::map < std::size_t, std::shared_ptr<callback> > m_callback{};
std::future<int> m_result{};
std::chrono::microseconds m_timeout{ 10 };
std::atomic<bool> m_run{ true };
std::vector<setting> m_settings{};
};
#endif // GPIO_H