DistributedEmbeddedSystemsL.../03_io_access/lib/io.c

117 lines
3.0 KiB
C

#include <fcntl.h> // For open()
#include <gpiod.h> // For libgpiod functions
#include <stdio.h> // For perror()
#include <stdlib.h> // For atof()
#include <unistd.h> // For close()
#include "io.h"
// Global variables for GPIO chip and lines
static struct gpiod_chip *chip = NULL;
static struct gpiod_line *led_line = NULL;
static struct gpiod_line *button_line = NULL;
// Error handling function
static int handle_error(const char *msg) {
perror(msg);
return -1;
}
// Helper function to initialize a GPIO line
static struct gpiod_line* init_gpio_line(int pin, const char *consumer, int direction) {
struct gpiod_line *line = gpiod_chip_get_line(chip, pin);
if (!line) {
handle_error("Failed to get GPIO line");
return NULL;
}
int request_result;
if (direction == GPIOD_LINE_DIRECTION_OUTPUT) {
request_result = gpiod_line_request_output(line, consumer, 0);
} else {
request_result = gpiod_line_request_input(line, consumer);
}
if (request_result < 0) {
handle_error("Failed to request GPIO line");
return NULL;
}
return line;
}
// Initialize GPIO chip and lines
// Call cleanup_gpio() to release resources
int initialize_gpio(const char *chip_name, int led_pin, int button_pin) {
chip = gpiod_chip_open_by_name(chip_name);
if (!chip) return handle_error("Failed to open GPIO chip");
led_line = init_gpio_line(led_pin, "gpio-led", GPIOD_LINE_DIRECTION_OUTPUT);
if (!led_line) return -1;
button_line = init_gpio_line(button_pin, "gpio-button", GPIOD_LINE_DIRECTION_INPUT);
if (!button_line) return -1;
return 0;
}
// Set LED state
void set_led_state(int state) {
if (led_line) {
gpiod_line_set_value(led_line, state);
}
}
// Read button state
int read_button_state() {
if (button_line) {
return gpiod_line_get_value(button_line);
}
return -1; // Return an error if button_line is not initialized
}
// Cleanup GPIO resources
void cleanup_gpio() {
if (led_line) {
gpiod_line_release(led_line);
led_line = NULL;
}
if (button_line) {
gpiod_line_release(button_line);
button_line = NULL;
}
if (chip) {
gpiod_chip_close(chip);
chip = NULL;
}
}
// Error handling function for temperature reading
static float handle_temp_error(const char *msg) {
perror(msg);
return -1.0;
}
// Read temperature from sensor
float read_temperature(const char *sensor_path) {
int fd;
float temperature;
char buf[16]; // Large enough to hold the temperature string
fd = open(sensor_path, O_RDONLY);
if (fd == -1) {
return handle_temp_error("Failed to open temperature file");
}
ssize_t numRead = read(fd, buf, sizeof(buf) - 1);
if (numRead == -1) {
close(fd);
return handle_temp_error("Failed to read temperature file");
}
buf[numRead] = '\0'; // Null-terminate the string
temperature = atof(buf) / 1000.0; // Convert the string to a float
close(fd);
return temperature;
}