/** * @file gpio_linux.c * @brief GPIO implementation for Linux using libgpiod and internal context management. */ #include "../../ked/peripherals/gpio/gpio.h" #include #include #include /** * @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); }