From 4d60567bc66417c48e7c3095ceded6c24ec1888f Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 13 Aug 2017 21:06:14 -0400 Subject: [PATCH] linux: Add support for spidev devices Add support for sending SPI messages to devices via the standard Linux SPI interface. This can be used to configure the shift registers on Replicape boards. Signed-off-by: Kevin O'Connor --- src/linux/Makefile | 2 +- src/linux/spidev.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/linux/spidev.c diff --git a/src/linux/Makefile b/src/linux/Makefile index 7fe17395..6d432d15 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 +src-y += linux/pca9685.c linux/spidev.c src-y += generic/crc16_ccitt.c generic/alloc.c CFLAGS_klipper.elf += -lutil diff --git a/src/linux/spidev.c b/src/linux/spidev.c new file mode 100644 index 00000000..d68f9861 --- /dev/null +++ b/src/linux/spidev.c @@ -0,0 +1,68 @@ +// Communicating with an SPI device via linux spidev +// +// Copyright (C) 2017 Kevin O'Connor +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include // open +#include // snprintf +#include // write +#include "command.h" // DECL_COMMAND +#include "internal.h" // report_errno +#include "sched.h" // shutdown + +struct spi_s { + uint32_t bus, dev; + int fd; +}; +static struct spi_s devices[16]; +static int devices_count; + +static int +spi_open(uint32_t bus, uint32_t dev) +{ + // Find existing device (if already opened) + int i; + for (i=0; i= ARRAY_SIZE(devices)) + shutdown("Too many spi devices"); + char fname[256]; + snprintf(fname, sizeof(fname), "/dev/spidev%d.%d", bus, dev); + int fd = open(fname, O_RDWR|O_CLOEXEC); + if (fd < 0) { + report_errno("open spi", fd); + shutdown("Unable to open spi device"); + } + int ret = set_non_blocking(fd); + if (ret < 0) + shutdown("Unable to set non-blocking on spi device"); + + devices[devices_count].bus = bus; + devices[devices_count].dev = dev; + devices[devices_count].fd = fd; + return fd; +} + +static void +spi_write(int fd, char *data, int len) +{ + int ret = write(fd, data, len); + if (ret < 0) { + report_errno("write spi", ret); + shutdown("Unable to write to spi"); + } +} + +void +command_send_spi(uint32_t *args) +{ + int fd = spi_open(args[0], args[1]); + uint8_t len = args[2]; + char *msg = (void*)(size_t)args[3]; + spi_write(fd, msg, len); +} +DECL_COMMAND(command_send_spi, "send_spi bus=%u dev=%u msg=%*s");