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.
KED/peripherals/gpio/gpio.c

105 lines
2.9 KiB

/**
* @file gpio_linux.c
* @brief GPIO implementation for Linux using libgpiod and internal context management.
*/
#include "../../ked/peripherals/gpio/gpio.h"
#include <gpiod.h>
#include <stdlib.h>
#include <stdio.h>
/**
* @brief Internal Linux GPIO context.
*/
typedef struct {
struct gpiod_chip* chip;
struct gpiod_line* line;
} gpio_linux_ctx_t;
static gpio_linux_ctx_t gpio_ctx;
void ked_gpio_set(gpio_t* gpio, uint8_t value) {
gpiod_line_set_value(gpio_ctx.line, value);
}
uint8_t ked_gpio_read(gpio_t* gpio) {
return (uint8_t)gpiod_line_get_value(gpio_ctx.line);
}
void ked_gpio_toggle(gpio_t* gpio) {
uint8_t current = (uint8_t)gpiod_line_get_value(gpio_ctx.line);
gpiod_line_set_value(gpio_ctx.line, !current);
}
void gpio_linux_deinit(gpio_t* gpio) {
if (gpio_ctx.line) {
gpiod_line_release(gpio_ctx.line);
gpio_ctx.line = NULL;
}
if (gpio_ctx.chip) {
gpiod_chip_close(gpio_ctx.chip);
gpio_ctx.chip = NULL;
}
}
void ked_gpio_handle_error(gpio_error_t err) {
fprintf(stderr, "[GPIO ERROR] Code: %d\n", err);
}
gpio_error_t ked_gpio_init(const gpio_t* gpio) {
gpio_ctx.chip = gpiod_chip_open(gpio->chipname);
if (!gpio_ctx.chip) {
ked_gpio_handle_error(T_GPIO_ERR_NOT_AVAILABLE);
return T_GPIO_ERR_NOT_AVAILABLE;
}
gpio_ctx.line = gpiod_chip_get_line(gpio_ctx.chip, gpio->line_offset);
if (!gpio_ctx.line) {
gpiod_chip_close(gpio_ctx.chip);
ked_gpio_handle_error(T_GPIO_ERR_NOT_AVAILABLE);
return T_GPIO_ERR_NOT_AVAILABLE;
}
struct gpiod_line_request_config req_cfg = {
.consumer = "ked_gpio",
.request_type = (gpio->direction == T_GPIO_DIRECTION_OUTPUT)
? GPIOD_LINE_REQUEST_DIRECTION_OUTPUT
: GPIOD_LINE_REQUEST_DIRECTION_INPUT,
.flags = 0
};
if (gpio->bias == T_GPIO_BIAS_PULL_UP)
req_cfg.flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;
else if (gpio->bias == T_GPIO_BIAS_PULL_DOWN)
req_cfg.flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
else if (gpio->bias == T_GPIO_BIAS_DISABLE)
req_cfg.flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;
else if (gpio->bias == T_GPIO_BIAS_DEFAULT)
req_cfg.request_type = GPIOD_LINE_REQUEST_DIRECTION_AS_IS;
if (gpiod_line_request(gpio_ctx.line, &req_cfg, 0) < 0) {
gpiod_chip_close(gpio_ctx.chip);
ked_gpio_handle_error(T_GPIO_ERR_BUS_BUSY);
return T_GPIO_ERR_BUS_BUSY;
}
}
//3812 340 16 4168 1048 ked_executable
//3816 340 16 4172 104c ked_executable
//3692 332 16 4040 fc8 ked_executable
void ked_gpio_deinit(gpio_t* gpio) {
/*
if (gpio && gpio->deinit) {
gpio->deinit();
gpio->status = T_GPIO_STATUS_NOT_INIT;
}*/
}
gpio_error_t ked_gpio_update(gpio_t* gpio) {
ked_gpio_deinit(gpio);
return ked_gpio_init(gpio);
}