From 16d2ec3a905204dd804831611aff37a4b508e0fa Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 27 Aug 2017 13:58:19 -0400 Subject: [PATCH] linux: Add support for analog IIO devices Add support for reading analog values via the standard Linux IIO interface. This can be used on Replicape boards to sample analog input pins. Signed-off-by: Kevin O'Connor --- klippy/pins.py | 1 + src/generic/gpio.h | 2 +- src/linux/Kconfig | 5 ++++ src/linux/Makefile | 2 +- src/linux/analog.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ src/linux/gpio.h | 14 +++++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/linux/analog.c create mode 100644 src/linux/gpio.h diff --git a/klippy/pins.py b/klippy/pins.py index 46266ed6..5bbaf855 100644 --- a/klippy/pins.py +++ b/klippy/pins.py @@ -37,6 +37,7 @@ MCU_PINS = { "atmega1280": port_pins(12), "atmega2560": port_pins(12), "sam3x8e": port_pins(4, 32), "pru": beaglebone_pins(), + "linux": {"analog%d" % i: i for i in range(8)}, # XXX } diff --git a/src/generic/gpio.h b/src/generic/gpio.h index 4b5dc812..1b649cab 100644 --- a/src/generic/gpio.h +++ b/src/generic/gpio.h @@ -1,7 +1,7 @@ #ifndef __GENERIC_GPIO_H #define __GENERIC_GPIO_H -#include +#include // uint8_t struct gpio_out { uint8_t pin; diff --git a/src/linux/Kconfig b/src/linux/Kconfig index b80ca3a7..651f0874 100644 --- a/src/linux/Kconfig +++ b/src/linux/Kconfig @@ -3,6 +3,11 @@ if MACH_LINUX +config LINUX_SELECT + bool + default y + select HAVE_GPIO_ADC + config BOARD_DIRECTORY string default "linux" diff --git a/src/linux/Makefile b/src/linux/Makefile index 6d432d15..5ab3fc27 100644 --- a/src/linux/Makefile +++ b/src/linux/Makefile @@ -3,7 +3,7 @@ dirs-y += src/linux src/generic src-y += linux/main.c linux/timer.c linux/console.c linux/watchdog.c -src-y += linux/pca9685.c linux/spidev.c +src-y += linux/pca9685.c linux/spidev.c linux/analog.c src-y += generic/crc16_ccitt.c generic/alloc.c CFLAGS_klipper.elf += -lutil diff --git a/src/linux/analog.c b/src/linux/analog.c new file mode 100644 index 00000000..88adc9dd --- /dev/null +++ b/src/linux/analog.c @@ -0,0 +1,61 @@ +// 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 + +DECL_CONSTANT(ADC_MAX, 4095); // Assume 12bit adc + +#define IIO_PATH "/sys/bus/iio/devices/iio:device0/in_voltage%d_raw" + +struct gpio_adc +gpio_adc_setup(uint8_t pin) +{ + char fname[256]; + snprintf(fname, sizeof(fname), IIO_PATH, pin); + + int fd = open(fname, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + report_errno("analog open", fd); + shutdown("Unable to open adc path"); + } + int ret = set_non_blocking(fd); + if (ret < 0) { + report_errno("analog set_non_blocking", ret); + shutdown("Unable to set non blocking on adc path"); + } + return (struct gpio_adc){ .fd = fd }; +} + +uint32_t +gpio_adc_sample(struct gpio_adc g) +{ + return 0; +} + +uint16_t +gpio_adc_read(struct gpio_adc g) +{ + char buf[64]; + int ret = pread(g.fd, buf, sizeof(buf)-1, 0); + if (ret <= 0) { + report_errno("analog read", ret); + shutdown("Error on analog read"); + } + buf[ret] = '\0'; + return atoi(buf); +} + +void +gpio_adc_cancel_sample(struct gpio_adc g) +{ +} diff --git a/src/linux/gpio.h b/src/linux/gpio.h new file mode 100644 index 00000000..a2c92520 --- /dev/null +++ b/src/linux/gpio.h @@ -0,0 +1,14 @@ +#ifndef __LINUX_GPIO_H +#define __LINUX_GPIO_H + +#include // uint8_t + +struct gpio_adc { + int fd; +}; +struct gpio_adc gpio_adc_setup(uint8_t pin); +uint32_t gpio_adc_sample(struct gpio_adc g); +uint16_t gpio_adc_read(struct gpio_adc g); +void gpio_adc_cancel_sample(struct gpio_adc g); + +#endif // gpio.h