Skip to content

Commit

Permalink
Related to night mode
Browse files Browse the repository at this point in the history
- Tested both GPIO modes to be fully working
- Magic factor to bring timings closer to real life calls to set/usleep/clear
  • Loading branch information
wberube committed Jun 20, 2024
1 parent dd2df7c commit 80ac656
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 45 deletions.
99 changes: 59 additions & 40 deletions src/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ void gpio_deinit(void) {
}

int gpio_init(void) {
while (*path++) {
if (access(*path, 0)) continue;
fd_gpio = open(*path, O_RDWR);
if (fd_gpio < 0)
GPIO_ERROR("Unable to open the GPIO device!\n");
while (*path) {
if (access(*path++, F_OK)) continue;
if ((fd_gpio = open(*(path - 1), O_RDWR)) < 0)
GPIO_ERROR("Unable to open the device %s!\n", *(path - 1));
else break;
}

Expand All @@ -36,18 +35,18 @@ int gpio_init(void) {
}

int gpio_read(char pin, bool *value) {
struct gpiohandle_request req = { .lineoffsets = { pin }, .lines = 1,
struct gpiohandle_request req = { .lineoffsets[0] = pin, .lines = 1,
.flags = GPIOHANDLE_REQUEST_INPUT };

int ret = ioctl(fd_gpio, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1)
GPIO_ERROR("Unable to request a read on GPIO pin %d!\n", pin);
GPIO_ERROR("Unable to request a read on GPIO pin %d (error #%d)!\n", pin, errno);

struct gpiohandle_data data;
ret = ioctl(fd_gpio, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
close(req.fd);
GPIO_ERROR("Unable to read the value of GPIO pin %d!\n", pin);
GPIO_ERROR("Unable to read the value of GPIO pin %d (error #%d)!\n", pin, errno);
}

*value = data.values[0];
Expand All @@ -56,21 +55,15 @@ int gpio_read(char pin, bool *value) {
}

int gpio_write(char pin, bool value) {
struct gpiohandle_request req = { .lineoffsets = { pin }, .lines = 1,
.flags = GPIOHANDLE_REQUEST_OUTPUT };
struct gpiohandle_request req = { .default_values[0] = value, .lineoffsets[0] = pin,
.lines = 1, .flags = GPIOHANDLE_REQUEST_OUTPUT };

int ret = ioctl(fd_gpio, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1)
GPIO_ERROR("Unable to request a write on GPIO pin %d!\n", pin);

struct gpiohandle_data data = { .values = { value } };
ret = ioctl(fd_gpio, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
close(req.fd);
GPIO_ERROR("Unable to write a value to GPIO pin %d!\n", pin);
}
GPIO_ERROR("Unable to request a write on GPIO pin %d (error #%d)!\n", pin, errno);

close(req.fd);

return EXIT_SUCCESS;
}
#else
Expand All @@ -83,55 +76,81 @@ int gpio_init(void) {
static inline int gpio_direction(char pin, char *mode) {
char path[40];
sprintf(path, "/sys/class/gpio/gpio%d/direction", pin);
FILE *fd = fopen(path, "w");
int fd = open(path, O_WRONLY);
if (!fd)
GPIO_ERROR("Unable to control the direction of GPIO pin %d!\n", pin);
fwrite(mode, 1, sizeof(mode), fd);
fclose(fd);
if (write(fd, mode, strlen(mode)) < 0) {
close(fd);
GPIO_ERROR("Unable to set the direction of GPIO pin %d!\n", pin);
}

close(fd);
return EXIT_SUCCESS;
}

static inline int gpio_export(char pin, bool create) {
char path[40];
FILE *fd = fopen(create ? "/sys/class/gpio/export" :
"/sys/class/gpio/unexport" , "w");
int fd = open(create ? "/sys/class/gpio/export" :
"/sys/class/gpio/unexport", O_WRONLY);
if (!fd)
GPIO_ERROR("Unable to %sexport GPIO pin %d!\n",
GPIO_ERROR("Unable to (un)export a GPIO pin!\n");

char val[4];
sprintf(val, "%d", pin);
if (write(fd, val, strlen(val)) < 0) {
close(fd);
GPIO_ERROR("Unable to %s GPIO pin %d!\n",
create ? "export" : "unexport", pin);
fprintf(fd, "%d", pin);
fclose(fd);
}

close(fd);
return EXIT_SUCCESS;
}

int gpio_read(char pin, bool *value) {
if (!gpio_export(pin, true)) return EXIT_FAILURE;
if (!gpio_direction(pin, "in")) return EXIT_FAILURE;
gpio_export(pin, true);
if (gpio_direction(pin, "in")) return EXIT_FAILURE;

char path[40];
sprintf(path, "/sys/class/gpio/gpio%d/value", pin);
FILE *fd = fopen(path, "r");
int fd = open(path, O_RDONLY);
if (!fd)
GPIO_ERROR("Unable to read from GPIO pin %d!\n", pin);
*value = fgetc(fd) == '1';
fclose(fd);

if (!gpio_direction(pin, "out")) return EXIT_FAILURE;
if (!gpio_export(pin, false)) return EXIT_FAILURE;
char val = 0;
lseek(fd, 0, SEEK_SET);
read(fd, &val, 0);
if (!val) {
close(fd);
GPIO_ERROR("Unable to read from GPIO pin %d!\n", pin);
}
*value = val - 0x30;
close(fd);

if (gpio_direction(pin, "out")) return EXIT_FAILURE;
if (gpio_export(pin, false)) return EXIT_FAILURE;

return EXIT_SUCCESS;
}

int gpio_write(char pin, bool value) {
if (!gpio_export(pin, true)) return EXIT_FAILURE;
if (!gpio_direction(pin, "out")) return EXIT_FAILURE;
gpio_export(pin, true);
if (gpio_direction(pin, "out")) return EXIT_FAILURE;

char path[40];
sprintf(path, "/sys/class/gpio/gpio%d/value", pin);
FILE *fd = fopen(path, "w");
int fd = open(path, O_WRONLY);
if (!fd)
GPIO_ERROR("Unable to write to GPIO pin %d!\n", pin);
fprintf(fd, "%c", value ? "1" : "0");
fclose(fd);

if (!gpio_export(pin, false)) return EXIT_FAILURE;
char val = value ? '1' : '0';
if (write(fd, &val, 1) < 0) {
close(fd);
GPIO_ERROR("Unable to write to GPIO pin %d!\n", pin);
}
close(fd);

if (gpio_export(pin, false)) return EXIT_FAILURE;

return EXIT_SUCCESS;
}
Expand Down
3 changes: 3 additions & 0 deletions src/gpio.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/version.h>
#include <stdbool.h>
Expand All @@ -9,6 +10,8 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
#include <linux/gpio.h>
#include <sys/ioctl.h>
#else
#include <string.h>
#endif

#define GPIO_ERROR(x, ...) \
Expand Down
14 changes: 9 additions & 5 deletions src/night.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ pthread_t nightPid = 0;

bool night_mode_is_enabled() { return night_mode; }

void ircut_on() {
void ircut_off() {
gpio_write(app_config.ir_cut_pin1, false);
gpio_write(app_config.ir_cut_pin2, true);
usleep(app_config.pin_switch_delay_us);
usleep(app_config.pin_switch_delay_us * 100);
gpio_write(app_config.ir_cut_pin1, false);
gpio_write(app_config.ir_cut_pin2, false);
}

void ircut_off() {
void ircut_on() {
gpio_write(app_config.ir_cut_pin1, true);
gpio_write(app_config.ir_cut_pin2, false);
usleep(app_config.pin_switch_delay_us);
usleep(app_config.pin_switch_delay_us * 100);
gpio_write(app_config.ir_cut_pin1, false);
gpio_write(app_config.ir_cut_pin2, false);
}
Expand All @@ -45,7 +45,9 @@ void set_night_mode(bool night) {
}

void *night_thread(void) {
usleep(1000);
gpio_init();
usleep(10000);

set_night_mode(night_mode);

if (app_config.adc_device[0]) {
Expand Down Expand Up @@ -89,6 +91,8 @@ void *night_thread(void) {
sleep(app_config.check_interval_s);
}
}
usleep(10000);
gpio_deinit();
printf(tag "Night mode thread is closing...\n");
}

Expand Down

0 comments on commit 80ac656

Please sign in to comment.