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