SystemAgent/src/drivers/user_gpio_driver.c

108 lines
2.7 KiB
C
Raw Normal View History

2021-03-17 15:37:29 +00:00
#include "utils/user_log_util.h"
#include "drivers/user_gpio_driver.h"
#define CONSUMER_NAME "SA"
2021-03-17 15:37:29 +00:00
int user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset,
uint8_t output_enabled) {
2021-03-17 15:37:29 +00:00
gpio->chip = gpiod_chip_open(chip);
if(gpio->chip == NULL) {
USER_LOG(USER_LOG_ERROR, "Failed to open chip %s.", chip);
2021-03-21 16:01:12 +00:00
return -1;
2021-03-17 15:37:29 +00:00
}
gpio->line = gpiod_chip_get_line(gpio->chip, offset);
if(gpio->line == NULL) {
USER_LOG(USER_LOG_ERROR, "Failed to get GPIO line %d.", offset);
gpiod_chip_close(gpio->chip);
2021-03-21 16:01:12 +00:00
return -1;
2021-03-17 15:37:29 +00:00
}
2021-03-21 16:01:12 +00:00
int ret;
2021-03-17 15:37:29 +00:00
2021-03-21 16:01:12 +00:00
if(output_enabled) {
ret = gpiod_line_request_output(gpio->line, CONSUMER_NAME, 1);
2021-03-21 16:01:12 +00:00
} else {
2021-06-29 18:28:58 +00:00
ret = gpiod_line_request_input(gpio->line, CONSUMER_NAME);
2021-03-21 16:01:12 +00:00
}
2021-03-17 15:37:29 +00:00
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to reserve GPIO line.");
2021-03-21 16:01:12 +00:00
return -1;
2021-03-17 15:37:29 +00:00
}
2021-03-21 16:01:12 +00:00
return 0;
}
int user_gpio_set(user_gpio_t *gpio, uint8_t value) {
int ret = gpiod_line_set_value(gpio->line, value);
2021-03-17 15:37:29 +00:00
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to set GPIO value.");
2021-03-21 16:01:12 +00:00
return -1;
2021-03-17 15:37:29 +00:00
}
2021-03-21 16:01:12 +00:00
return 0;
2021-03-17 15:37:29 +00:00
}
int user_gpio_setup_intr(user_gpio_t *gpio, user_gpio_intr_t type) {
int request_type = 0;
2021-06-28 18:24:54 +00:00
if(type == USER_GPIO_INTR_RISING)
request_type = GPIOD_LINE_REQUEST_EVENT_RISING_EDGE;
2021-06-28 18:24:54 +00:00
else if(type == USER_GPIO_INTR_FALLING)
request_type = GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE;
2021-07-25 15:22:04 +00:00
else if(type == (USER_GPIO_INTR_RISING | USER_GPIO_INTR_FALLING))
request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
2021-06-29 18:28:58 +00:00
const struct gpiod_line_request_config config = {
.consumer = CONSUMER_NAME,
.request_type = request_type,
};
int ret = gpiod_line_request(gpio->line, &config, 0);
if(ret != 0) {
USER_LOG(USER_LOG_ERROR, "Failed to reserve GPIO line for interrupt.");
}
return ret;
}
2021-06-29 18:28:58 +00:00
int user_gpio_intr_poll(user_gpio_t *gpio, uint32_t timeout_ms,
user_gpio_intr_t *event) {
2021-06-28 18:24:54 +00:00
struct timespec ts = {
.tv_sec = timeout_ms / 1000,
2021-06-29 18:28:58 +00:00
.tv_nsec = (timeout_ms % 1000) * 1000000000,
2021-06-28 18:24:54 +00:00
};
2021-06-29 18:28:58 +00:00
struct gpiod_line_event ev;
2021-06-28 18:24:54 +00:00
int ret = gpiod_line_event_wait(gpio->line, &ts);
2021-10-22 21:03:48 +00:00
if(ret <= 0) return ret;
ret = gpiod_line_event_read(gpio->line, &ev);
if(ret < 0) return ret;
2021-06-29 18:28:58 +00:00
if(ev.event_type == GPIOD_LINE_EVENT_RISING_EDGE) {
*event = USER_GPIO_INTR_RISING;
} else {
*event = USER_GPIO_INTR_FALLING;
}
return 0;
}
int user_gpio_get(user_gpio_t *gpio, uint8_t *value) {
2021-03-17 15:37:29 +00:00
*value = gpiod_line_get_value(gpio->line);
2021-03-21 16:01:12 +00:00
return 0;
2021-03-17 15:37:29 +00:00
}
2021-03-21 16:01:12 +00:00
int user_gpio_deinit(user_gpio_t *gpio) {
2021-03-17 15:37:29 +00:00
gpiod_line_release(gpio->line);
gpiod_chip_close(gpio->chip);
2021-03-21 16:01:12 +00:00
return 0;
2021-03-17 15:37:29 +00:00
}