// Read analog values from Linux IIO device // // Copyright (C) 2017 Kevin O'Connor // // This file may be distributed under the terms of the GNU GPLv3 license. #include // open #include // snprintf #include // atoi #include // read #include "command.h" // shutdown #include "gpio.h" // gpio_adc_setup #include "internal.h" // report_errno #include "sched.h" // sched_shutdown // ODROID-C5 DECL_CONSTANT("ADC_MAX", 1800); #define ANALOG_START (1<<12) DECL_ENUMERATION_RANGE("pin", "analog0", ANALOG_START, 8); // ODROID-C5 #define IIO_PATH "/sys/bus/iio/devices/iio:device0/in_voltage0_raw" #define SCALE_PATH "/sys/bus/iio/devices/iio:device0/in_voltage_scale" #define OFFSET_PATH "/sys/bus/iio/devices/iio:device0/in_voltage_offset" struct gpio_adc gpio_adc_setup(uint32_t pin) { struct gpio_adc g; int fd; char buf[64]; int ret; fd = open(SCALE_PATH, O_RDONLY); ret = read(fd, buf, sizeof(buf)-1); if (ret <= 0) { goto fail; } buf[ret] = '\0'; g.scale = atof(buf) * 1000; close(fd); fd = open(OFFSET_PATH, O_RDONLY); ret = read(fd, buf, sizeof(buf)-1); if (ret <= 0) { goto fail; } buf[ret] = '\0'; g.offset = atoi(buf); close(fd); fd = open(IIO_PATH, O_RDONLY|O_CLOEXEC); if (fd < 0) { report_errno("analog open", fd); goto fail; } ret = set_non_blocking(fd); if (ret < 0) goto fail; g.fd = fd; return g; fail: if (fd >= 0) close(fd); shutdown("Unable to open adc device"); } uint32_t gpio_adc_sample(struct gpio_adc g) { return 0; } uint16_t gpio_adc_read(struct gpio_adc g) { char buf[64]; int voltage; int ret = pread(g.fd, buf, sizeof(buf)-1, 0); if (ret <= 0) { report_errno("analog read", ret); try_shutdown("Error on analog read"); return 0; } buf[ret] = '\0'; voltage = atoi(buf) + g.offset; voltage = voltage > 0 ? voltage : 0; voltage = voltage * g.scale; voltage = voltage < 1800000 ? voltage : 1800000; voltage /= 1000; return voltage; } void gpio_adc_cancel_sample(struct gpio_adc g) { }