diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2019-08-06 11:44:29 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2019-08-06 18:56:53 -0400 |
commit | c2a08962b79ccdb4b33b26becefa247506a7fd40 (patch) | |
tree | a3cb44e1d877f9af05bce7fb5dc22c7ae3221227 /src | |
parent | 30bd7c0e47ddf495db54448d1fdf085ab480efea (diff) | |
download | kutter-c2a08962b79ccdb4b33b26becefa247506a7fd40.tar.gz kutter-c2a08962b79ccdb4b33b26becefa247506a7fd40.tar.xz kutter-c2a08962b79ccdb4b33b26becefa247506a7fd40.zip |
spicmds: Rework spi config commands
Rework the spi_config commands so that bus configuration and shutdown
message configuration is done separately from the main "config_spi"
command. This makes the spi configuration more flexible. It's now
possible to use software spi without a CS pin. It's now possible to
define multiple SPI messages to send on a shutdown event.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/atsamd/spi.c | 2 | ||||
-rw-r--r-- | src/basecmd.c | 2 | ||||
-rw-r--r-- | src/basecmd.h | 2 | ||||
-rw-r--r-- | src/linux/spidev.c | 4 | ||||
-rw-r--r-- | src/spi_software.c | 34 | ||||
-rw-r--r-- | src/spicmds.c | 119 | ||||
-rw-r--r-- | src/spicmds.h | 4 |
7 files changed, 86 insertions, 81 deletions
diff --git a/src/atsamd/spi.c b/src/atsamd/spi.c index 67c68cea..02aad5d3 100644 --- a/src/atsamd/spi.c +++ b/src/atsamd/spi.c @@ -6,9 +6,7 @@ // This file may be distributed under the terms of the GNU GPLv3 license. #include "internal.h" // enable_pclock -#include "command.h" // shutdown #include "gpio.h" // spi_setup -#include "sched.h" // sched_shutdown void spi_init(uint32_t bus, SercomSpi *ss, uint32_t ctrla, uint32_t baud) diff --git a/src/basecmd.c b/src/basecmd.c index 95511885..7b402ca1 100644 --- a/src/basecmd.c +++ b/src/basecmd.c @@ -27,7 +27,7 @@ alloc_init(void) DECL_INIT(alloc_init); // Allocate an area of memory -static void * +void * alloc_chunk(size_t size) { if (alloc_end + size > dynmem_end()) diff --git a/src/basecmd.h b/src/basecmd.h index 21555bf8..f4ea1cc7 100644 --- a/src/basecmd.h +++ b/src/basecmd.h @@ -1,8 +1,10 @@ #ifndef __BASECMD_H #define __BASECMD_H +#include <stddef.h> // size_t #include <stdint.h> // uint8_t +void *alloc_chunk(size_t size); void move_free(void *m); void *move_alloc(void); void move_request_size(int size); diff --git a/src/linux/spidev.c b/src/linux/spidev.c index 5c613cba..764541e3 100644 --- a/src/linux/spidev.c +++ b/src/linux/spidev.c @@ -97,13 +97,13 @@ spi_transfer(struct spi_config config, uint8_t receive_data int ret = ioctl(config.fd, SPI_IOC_MESSAGE(1), &transfer); if (ret < 0) { report_errno("spi ioctl", ret); - shutdown("Unable to issue spi ioctl"); + try_shutdown("Unable to issue spi ioctl"); } } else { int ret = write(config.fd, data, len); if (ret < 0) { report_errno("write spi", ret); - shutdown("Unable to write to spi"); + try_shutdown("Unable to write to spi"); } } } diff --git a/src/spi_software.c b/src/spi_software.c index 2d086f78..345e2f81 100644 --- a/src/spi_software.c +++ b/src/spi_software.c @@ -9,39 +9,33 @@ #include "basecmd.h" // oid_alloc #include "command.h" // DECL_COMMAND #include "sched.h" // sched_shutdown +#include "spicmds.h" // spidev_set_software_bus struct spi_software { - struct gpio_out sclk, mosi; struct gpio_in miso; + struct gpio_out mosi, sclk; uint8_t mode; }; void -command_config_software_spi(uint32_t *args) +command_spi_set_software_bus(uint32_t *args) { - uint8_t oid = args[0], sclk_pin = args[1], mosi_pin = args[2]; - uint8_t miso_pin = args[3], mode = args[4]; + uint8_t mode = args[4]; if (mode > 3) - shutdown("Invalid spi mode"); + shutdown("Invalid spi config"); - struct spi_software *spi = oid_alloc(oid, command_config_software_spi - , sizeof(*spi)); - - spi->sclk = gpio_out_setup(sclk_pin, 0); - spi->mosi = gpio_out_setup(mosi_pin, 0); - spi->miso = gpio_in_setup(miso_pin, 1); - spi->mode = mode; + struct spidev_s *spi = spidev_oid_lookup(args[0]); + struct spi_software *ss = alloc_chunk(sizeof(*ss)); + ss->miso = gpio_in_setup(args[1], 1); + ss->mosi = gpio_out_setup(args[2], 0); + ss->sclk = gpio_out_setup(args[3], 0); + ss->mode = mode; + spidev_set_software_bus(spi, ss); } -DECL_COMMAND(command_config_software_spi, - "config_software_spi oid=%c sclk_pin=%u mosi_pin=%u miso_pin=%u" +DECL_COMMAND(command_spi_set_software_bus, + "spi_set_software_bus oid=%c miso_pin=%u mosi_pin=%u sclk_pin=%u" " mode=%u rate=%u"); -struct spi_software * -spi_software_oid_lookup(uint8_t oid) -{ - return oid_lookup(oid, command_config_software_spi); -} - void spi_software_prepare(struct spi_software *ss) { diff --git a/src/spicmds.c b/src/spicmds.c index 527cb0af..654e9436 100644 --- a/src/spicmds.c +++ b/src/spicmds.c @@ -1,6 +1,6 @@ // Commands for sending messages on an SPI bus // -// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net> +// Copyright (C) 2016-2019 Kevin O'Connor <kevin@koconnor.net> // // This file may be distributed under the terms of the GNU GPLv3 license. @@ -20,80 +20,64 @@ struct spidev_s { }; struct gpio_out pin; uint8_t flags; - uint8_t shutdown_msg_len; - uint8_t shutdown_msg[]; }; enum { - SF_HAVE_PIN = 1, SF_SOFTWARE = 2, + SF_HAVE_PIN = 1, SF_SOFTWARE = 2, SF_HARDWARE = 4, }; void command_config_spi(uint32_t *args) { - uint8_t mode = args[3], shutdown_msg_len = args[5]; - if (mode > 3) - shutdown("Invalid spi mode"); - struct spidev_s *spi = oid_alloc(args[0], command_config_spi - , sizeof(*spi) + shutdown_msg_len); - spi->pin = gpio_out_setup(args[2], 1); - spi->flags = SF_HAVE_PIN; - spi->spi_config = spi_setup(args[1], mode, args[4]); - spi->shutdown_msg_len = shutdown_msg_len; - uint8_t *shutdown_msg = (void*)(size_t)args[6]; - memcpy(spi->shutdown_msg, shutdown_msg, shutdown_msg_len); + struct spidev_s *spi = oid_alloc(args[0], command_config_spi, sizeof(*spi)); + spi->pin = gpio_out_setup(args[1], 1); + spi->flags |= SF_HAVE_PIN; } -DECL_COMMAND(command_config_spi, - "config_spi oid=%c spi_bus=%u pin=%u mode=%u rate=%u" - " shutdown_msg=%*s"); +DECL_COMMAND(command_config_spi, "config_spi oid=%c pin=%u"); void command_config_spi_without_cs(uint32_t *args) { - uint8_t mode = args[2], shutdown_msg_len = args[4]; - if (mode > 3) - shutdown("Invalid spi mode"); - struct spidev_s *spi = oid_alloc(args[0], command_config_spi - , sizeof(*spi) + shutdown_msg_len); - spi->spi_config = spi_setup(args[1], mode, args[3]); - spi->shutdown_msg_len = shutdown_msg_len; - uint8_t *shutdown_msg = (void*)(size_t)args[5]; - memcpy(spi->shutdown_msg, shutdown_msg, shutdown_msg_len); + struct spidev_s *spi = oid_alloc(args[0], command_config_spi, sizeof(*spi)); +} +DECL_COMMAND(command_config_spi_without_cs, "config_spi_without_cs oid=%c"); + +struct spidev_s * +spidev_oid_lookup(uint8_t oid) +{ + return oid_lookup(oid, command_config_spi); } -DECL_COMMAND(command_config_spi_without_cs, - "config_spi_without_cs oid=%c spi_bus=%u mode=%u rate=%u" - " shutdown_msg=%*s"); void -command_config_spi_from_software(uint32_t *args) +command_spi_set_bus(uint32_t *args) { - uint8_t shutdown_msg_len = args[3]; - struct spi_software *sspi = spi_software_oid_lookup(args[1]); - struct spidev_s *spi = oid_alloc(args[0], command_config_spi - , sizeof(*spi) + shutdown_msg_len); - spi->pin = gpio_out_setup(args[2], 1); - spi->flags = SF_HAVE_PIN | SF_SOFTWARE; - spi->spi_software = sspi; - spi->shutdown_msg_len = shutdown_msg_len; - uint8_t *shutdown_msg = (void*)(size_t)args[4]; - memcpy(spi->shutdown_msg, shutdown_msg, shutdown_msg_len); + struct spidev_s *spi = spidev_oid_lookup(args[0]); + uint8_t mode = args[2]; + if (mode > 3 || spi->flags & (SF_SOFTWARE|SF_HARDWARE)) + shutdown("Invalid spi config"); + spi->spi_config = spi_setup(args[1], mode, args[3]); + spi->flags |= SF_HARDWARE; } -#if CONFIG_HAVE_GPIO_BITBANGING -DECL_COMMAND(command_config_spi_from_software, - "config_spi_from_software oid=%c sw_oid=%u pin=%u" - " shutdown_msg=%*s"); -#endif +DECL_COMMAND(command_spi_set_bus, + "spi_set_bus oid=%c spi_bus=%u mode=%u rate=%u"); -struct spidev_s * -spidev_oid_lookup(uint8_t oid) +void +spidev_set_software_bus(struct spidev_s *spi, struct spi_software *ss) { - return oid_lookup(oid, command_config_spi); + if (spi->flags & (SF_SOFTWARE|SF_HARDWARE)) + shutdown("Invalid spi config"); + spi->spi_software = ss; + spi->flags |= SF_SOFTWARE; } void spidev_transfer(struct spidev_s *spi, uint8_t receive_data , uint8_t data_len, uint8_t *data) { + if (!(spi->flags & (SF_SOFTWARE|SF_HARDWARE))) + // Not yet initialized + return; + if (CONFIG_HAVE_GPIO_BITBANGING && spi->flags & SF_SOFTWARE) spi_software_prepare(spi->spi_software); else @@ -115,7 +99,7 @@ void command_spi_transfer(uint32_t *args) { uint8_t oid = args[0]; - struct spidev_s *spi = oid_lookup(oid, command_config_spi); + struct spidev_s *spi = spidev_oid_lookup(oid); uint8_t data_len = args[1]; uint8_t *data = (void*)(size_t)args[2]; spidev_transfer(spi, 1, data_len, data); @@ -126,14 +110,39 @@ DECL_COMMAND(command_spi_transfer, "spi_transfer oid=%c data=%*s"); void command_spi_send(uint32_t *args) { - uint8_t oid = args[0]; - struct spidev_s *spi = oid_lookup(oid, command_config_spi); + struct spidev_s *spi = spidev_oid_lookup(args[0]); uint8_t data_len = args[1]; uint8_t *data = (void*)(size_t)args[2]; spidev_transfer(spi, 0, data_len, data); } DECL_COMMAND(command_spi_send, "spi_send oid=%c data=%*s"); + +/**************************************************************** + * Shutdown handling + ****************************************************************/ + +struct spidev_shutdown_s { + struct spidev_s *spi; + uint8_t shutdown_msg_len; + uint8_t shutdown_msg[]; +}; + +void +command_config_spi_shutdown(uint32_t *args) +{ + struct spidev_s *spi = spidev_oid_lookup(args[1]); + uint8_t shutdown_msg_len = args[2]; + struct spidev_shutdown_s *sd = oid_alloc( + args[0], command_config_spi_shutdown, sizeof(*sd) + shutdown_msg_len); + sd->spi = spi; + sd->shutdown_msg_len = shutdown_msg_len; + uint8_t *shutdown_msg = (void*)(size_t)args[3]; + memcpy(sd->shutdown_msg, shutdown_msg, shutdown_msg_len); +} +DECL_COMMAND(command_config_spi_shutdown, + "config_spi_shutdown oid=%c spi_oid=%c shutdown_msg=%*s"); + void spidev_shutdown(void) { @@ -146,9 +155,9 @@ spidev_shutdown(void) } // Send shutdown messages - foreach_oid(oid, spi, command_config_spi) { - if (spi->shutdown_msg_len) - spidev_transfer(spi, 0, spi->shutdown_msg_len, spi->shutdown_msg); + struct spidev_shutdown_s *sd; + foreach_oid(oid, sd, command_config_spi_shutdown) { + spidev_transfer(sd->spi, 0, sd->shutdown_msg_len, sd->shutdown_msg); } } DECL_SHUTDOWN(spidev_shutdown); diff --git a/src/spicmds.h b/src/spicmds.h index dee50665..959fddb9 100644 --- a/src/spicmds.h +++ b/src/spicmds.h @@ -4,7 +4,9 @@ #include <stdint.h> // uint8_t struct spidev_s *spidev_oid_lookup(uint8_t oid); +struct spi_software; +void spidev_set_software_bus(struct spidev_s *spi, struct spi_software *ss); void spidev_transfer(struct spidev_s *spi, uint8_t receive_data , uint8_t data_len, uint8_t *data); -#endif // stepper.h +#endif // spicmds.h |