Skip to content

Commit

Permalink
refactor: simplify libgpiod implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bgilby59 committed Mar 15, 2023
1 parent 0a08d87 commit 4177c90
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 48 deletions.
17 changes: 5 additions & 12 deletions include/sensor_trigger/jetson_gpio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define BUFFER_SIZE 64
#define GPIO_OUTPUT 1
#define GPIO_INPUT 0
#define GPIO_OUTPUT gpiod::line_request::DIRECTION_OUTPUT

Check warning on line 28 in include/sensor_trigger/jetson_gpio.hpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
#define GPIO_INPUT gpiod::line_request::DIRECTION_INPUT

Check warning on line 29 in include/sensor_trigger/jetson_gpio.hpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
#define GPIO_HIGH 1
#define GPIO_LOW 0

Expand All @@ -35,29 +35,22 @@ typedef int gpio_state;

namespace jetson_gpio
{
// Mapping of GPIO number to pin number for ROSCubeX
// Note: pin 5->216 is pin 5 on the DB50 connector, run by GPIO chip 216 (starting at GPIO number
// 216)
static std::map<int, int> pin_gpio_mapping{{5, 216}, {51, 408}, {52, 350}, {53, 446}, {54, 445}};

class JetsonGpio
{
public:
JetsonGpio() : state_file_descriptor_(-1) {}
JetsonGpio() = default;
~JetsonGpio();
bool init_gpio_pin(unsigned int gpio_chip, unsigned int gpio_line, gpio_direction direction);
bool set_gpio_pin_state(gpio_state state);

protected:
bool export_gpio();
bool unexport_gpio();
bool close_gpio();
bool set_gpio_direction(gpio_direction direction);

int state_file_descriptor_;
int gpio_;

gpiod::chip gpio_chip_;

Check warning on line 52 in include/sensor_trigger/jetson_gpio.hpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
gpiod::line_bulk gpio_lines_;
gpiod::line gpio_line_;

Check warning on line 53 in include/sensor_trigger/jetson_gpio.hpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
gpiod::line_request gpio_request_;

Check warning on line 54 in include/sensor_trigger/jetson_gpio.hpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
};
} // namespace jetson_gpio
Expand Down
42 changes: 9 additions & 33 deletions src/jetson_gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ namespace jetson_gpio
{
JetsonGpio::~JetsonGpio()
{
if (state_file_descriptor_ > -1) {
close(state_file_descriptor_);
}

// Regardless of the existence of other processes that uses the same GPIO pin
// (incl. zombie GPIO port opening because of failure exit),
// this unexport closes the target GPIO pin anyway.
// this function closes the target GPIO pin anyway.
// This behavior intends to make next try to use this GPIO pin success.
unexport_gpio();
close_gpio();
}

bool JetsonGpio::init_gpio_pin(
Expand All @@ -39,49 +35,29 @@ bool JetsonGpio::init_gpio_pin(
std::string gpio_character_device = "/dev/gpiochip" + std::to_string(gpio_chip);

Check warning on line 35 in src/jetson_gpio.cpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiochip)

gpio_chip_ = gpiod::chip(gpio_character_device);

Check warning on line 37 in src/jetson_gpio.cpp

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (gpiod)
gpio_lines_ = gpio_chip_.get_lines(
std::vector<unsigned int>({gpio_line})); // XXX: 143 = Anvil misc.I/O GP_Out_1, 108 = PWM_Out_0
gpio_line_ = gpio_chip_.get_line(gpio_line);
gpio_request_ = {
"sensor_trigger", // consumer name. XXX: fixed name may conflict for multiple instances
gpiod::line_request::DIRECTION_OUTPUT, // request_type
0 // flag
"sensor_trigger", // consumer name
direction, // request_type
0 // flag
};

if (!set_gpio_direction(direction)) {
return false;
}

gpio_lines_.request(gpio_request_, std::vector<int>({GPIO_LOW}));
gpio_line_.request(gpio_request_, GPIO_LOW);

return true;
}

bool JetsonGpio::export_gpio() { return true; }

bool JetsonGpio::unexport_gpio()
bool JetsonGpio::close_gpio()
{
gpio_chip_.~chip();

return true;
}

bool JetsonGpio::set_gpio_direction(gpio_direction direction)
{
switch (direction) {
case GPIO_INPUT:
gpio_request_.request_type = gpiod::line_request::DIRECTION_INPUT;
break;
case GPIO_OUTPUT:
gpio_request_.request_type = gpiod::line_request::DIRECTION_OUTPUT;
break;
}

return true;
}

bool JetsonGpio::set_gpio_pin_state(gpio_state state)
{
gpio_lines_.set_values(std::vector<int>({state}));
gpio_line_.set_value(state);

return true;
}
Expand Down
5 changes: 2 additions & 3 deletions src/sensor_trigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,13 @@ void SensorTrigger::run()
target_nsec = start_nsec;
wait_nsec = 1e9 - now_nsec + start_nsec - 1e7;
}
// Keep waiting for half the remaining time until the last millisecond.
// Keep waiting for half the remaining time until the last 10 milliseconds.
// This is required as sleep_for tends to oversleep significantly
if (wait_nsec > 1e7) {
rclcpp::sleep_for(std::chrono::nanoseconds(wait_nsec / 2));
}
} while (wait_nsec > 1e7);
// std::lock_guard<std::mutex> guard(iomutex_);
// Block the last millisecond
// Block the last 10 milliseconds
now_nsec = rclcpp::Clock{RCL_SYSTEM_TIME}.now().nanoseconds() % (uint64_t)1e9;
if (start_nsec == end_nsec) {
while (now_nsec > 1e7) {
Expand Down

0 comments on commit 4177c90

Please sign in to comment.