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 <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-08-27 13:58:19 -04:00
parent 4d60567bc6
commit 16d2ec3a90
6 changed files with 83 additions and 2 deletions

View File

@ -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
}

View File

@ -1,7 +1,7 @@
#ifndef __GENERIC_GPIO_H
#define __GENERIC_GPIO_H
#include <stdint.h>
#include <stdint.h> // uint8_t
struct gpio_out {
uint8_t pin;

View File

@ -3,6 +3,11 @@
if MACH_LINUX
config LINUX_SELECT
bool
default y
select HAVE_GPIO_ADC
config BOARD_DIRECTORY
string
default "linux"

View File

@ -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

61
src/linux/analog.c Normal file
View File

@ -0,0 +1,61 @@
// Read analog values from Linux IIO device
//
// Copyright (C) 2017 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include <fcntl.h> // open
#include <stdio.h> // snprintf
#include <stdlib.h> // atoi
#include <unistd.h> // 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)
{
}

14
src/linux/gpio.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __LINUX_GPIO_H
#define __LINUX_GPIO_H
#include <stdint.h> // 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