diff --git a/src/linux/analog.c b/src/linux/analog.c index 7ca1ee2d..94c97347 100644 --- a/src/linux/analog.c +++ b/src/linux/analog.c @@ -14,30 +14,54 @@ #include "sched.h" // sched_shutdown // ODROID-C5 -DECL_CONSTANT("ADC_MAX", 1800); // Assume 12bit adc +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_voltage%d_input" +#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) { - char fname[256]; - snprintf(fname, sizeof(fname), IIO_PATH, pin-ANALOG_START); + struct gpio_adc g; + int fd; + char buf[64]; + int ret; - int fd = open(fname, O_RDONLY|O_CLOEXEC); + 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; } - int ret = set_non_blocking(fd); + ret = set_non_blocking(fd); if (ret < 0) goto fail; - return (struct gpio_adc){ .fd = fd }; + + g.fd = fd; + return g; fail: if (fd >= 0) close(fd); @@ -54,6 +78,7 @@ 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); @@ -61,7 +86,14 @@ gpio_adc_read(struct gpio_adc g) return 0; } buf[ret] = '\0'; - return atoi(buf); + + voltage = atoi(buf) + g.offset; + voltage = voltage > 0 ? voltage : 0; + voltage = voltage * g.scale; + voltage = voltage < 1800000 ? voltage : 1800000; + voltage /= 1000; + + return voltage; } void diff --git a/src/linux/gpio.h b/src/linux/gpio.h index d72007c2..302063b1 100644 --- a/src/linux/gpio.h +++ b/src/linux/gpio.h @@ -20,6 +20,8 @@ void gpio_in_reset(struct gpio_in g, int8_t pull_up); uint8_t gpio_in_read(struct gpio_in g); struct gpio_adc { + int scale; + int offset; int fd; }; struct gpio_adc gpio_adc_setup(uint32_t pin);