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>
This commit is contained in:
parent
73a1c9d249
commit
4d60567bc6
|
@ -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
|
||||
|
|
|
@ -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");
|
Loading…
Reference in New Issue