diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-08-13 21:06:14 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-09-20 12:55:28 -0400 |
commit | 4d60567bc66417c48e7c3095ceded6c24ec1888f (patch) | |
tree | 56f8afc8c1e6181314855ac517894e5ab5190129 /src | |
parent | 73a1c9d249170a2edc842af7f852e60c427f0f6d (diff) | |
download | kutter-4d60567bc66417c48e7c3095ceded6c24ec1888f.tar.gz kutter-4d60567bc66417c48e7c3095ceded6c24ec1888f.tar.xz kutter-4d60567bc66417c48e7c3095ceded6c24ec1888f.zip |
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 <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/linux/Makefile | 2 | ||||
-rw-r--r-- | src/linux/spidev.c | 68 |
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"); |