#include #include #include #include #include #include #include #include "gpio.h" #include "timespec.h" #include "ping_pong.h" #define LAST_PONG_TIMEOUT (PING_INTERVAL * 3) /* 17 red (11) 27 green (13) 22 blue (15) */ #define RED 0b001 #define GREEN 0b010 #define BLUE 0b100 int gpio_open(const char * path, struct gpio_state * gpio_state) { gpio_state->chip_fd = open(path, O_RDWR); if (gpio_state->chip_fd == -1) { perror("open gpio"); return -1; } struct gpio_v2_line_request request = { .offsets = { 17, 27, 22 }, .consumer = "timer", .config = { .flags = GPIO_V2_LINE_FLAG_OUTPUT, }, .num_lines = 3, }; int ret = ioctl(gpio_state->chip_fd, GPIO_V2_GET_LINE_IOCTL, &request); assert(ret != -1); gpio_state->req_fd = request.fd; return 0; } void gpio_set_values(struct gpio_state * gpio_state, uint64_t bits) { struct gpio_v2_line_values values = { .bits = bits, .mask = 0b111, }; int ret = ioctl(gpio_state->req_fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); assert(ret != -1); } void gpio_set_values_from_link_state(struct gpio_state * gpio_state, struct link_state * link_state) { struct timespec now; int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &now); assert(ret != -1); struct timespec delta = timespec_sub(&now, &link_state->last_pong); if (delta.tv_sec >= LAST_PONG_TIMEOUT) { printf("gpio pong timeout %ld\n", delta.tv_sec); if (gpio_state->chip_fd != -1) gpio_set_values(gpio_state, RED); } else { printf("gpio pong ok %ld\n", delta.tv_sec); if (gpio_state->chip_fd != -1) gpio_set_values(gpio_state, GREEN); } } /* int main() { struct gpio_state gpio_state; gpio_open("/dev/gpiochip0", &gpio_state); set_gpio_values(&gpio_state, 0b000); } */