aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/linux/Makefile2
-rw-r--r--src/linux/spidev.c68
2 files changed, 69 insertions, 1 deletions
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 <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 <unistd.h> // 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<devices_count; i++)
+ if (devices[i].bus == bus && devices[i].dev == dev)
+ return devices[i].fd;
+
+ // Setup new SPI device
+ if (devices_count >= 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");