Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package spi-tools for openSUSE:Factory checked in at 2021-12-10 21:52:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/spi-tools (Old) and /work/SRC/openSUSE:Factory/.spi-tools.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "spi-tools" Fri Dec 10 21:52:57 2021 rev:5 rq:939163 version:1.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/spi-tools/spi-tools.changes 2021-05-12 19:32:28.442979639 +0200 +++ /work/SRC/openSUSE:Factory/.spi-tools.new.2520/spi-tools.changes 2021-12-10 21:53:31.910922996 +0100 @@ -1,0 +2,9 @@ +Fri Dec 10 14:38:47 UTC 2021 - Guillaume GARDET <[email protected]> + +- Update to version 1.0.1: + * support --bits config option in spi-pipe + * Support SPI mode option in spi-pipe + * Support all configuration options in spi-pipe + * Default block-size to 1 instead of -1 + +------------------------------------------------------------------- Old: ---- spi-tools-0.8.7.tar.gz New: ---- spi-tools-1.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ spi-tools.spec ++++++ --- /var/tmp/diff_new_pack.N5TBrR/_old 2021-12-10 21:53:32.350923191 +0100 +++ /var/tmp/diff_new_pack.N5TBrR/_new 2021-12-10 21:53:32.350923191 +0100 @@ -17,7 +17,7 @@ Name: spi-tools -Version: 0.8.7 +Version: 1.0.1 Release: 0 Summary: A set of SPI tools for Linux License: GPL-2.0-or-later ++++++ spi-tools-0.8.7.tar.gz -> spi-tools-1.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/README.md new/spi-tools-1.0.1/README.md --- old/spi-tools-0.8.7/README.md 2021-01-07 17:19:24.000000000 +0100 +++ new/spi-tools-1.0.1/README.md 2021-11-27 09:58:21.000000000 +0100 @@ -1,41 +1,54 @@ -spi-tools -========= +# spi-tools This package contains some simple command line tools to help using Linux spidev devices. -Content -------- +Version 1.0.1 + +## Content ### `spi-config` + Query or set the SPI configuration (mode, speed, bits per word, etc.) ### `spi-pipe` + Send and receive data simultaneously to and from a SPI device. -License -------- +## License + The tools are released under the GPLv2 license. See `LICENSE` file for details. -Author ------- +## Author + Christophe Blaess http://www.blaess.fr/christophe -Installation ------------- -First, get the latest version on https://github.com/cpb-/spi-tools.git - - # autoreconf -fim - # ./configure - -Simply do a `make` to build the tools, then `make install` to install them and the man pages. -If you have to use a cross-compilation toolchain, simply fill the `CROSS_COMPILE` environment variable with the cross-compiler prefix. -You can use `make uninstall` to remove the installed files. +## Installation + +First, get the latest version on https://github.com/cpb-/spi-tools.git. +Then enter the directory and execute: + +``` +$ autoreconf -fim +$ ./configure +$ make +``` + +Then you can run `make install` (probably with `sudo`) to install them and the man pages. + +If you have to use a cross-compilation toolchain, add the `--host` option to +the `./configure` command, as in `./configure --host=arm-linux`. This is the +prefix to be inserted before all the toolchain commands (giving for example +`arm-linux-gcc`). + +You can use `make uninstall` (with `sudo`) to remove the installed files. + +## Usage -Usage ------ ### spi-config usage + #### options + * `-d --device=<dev>` use the given spi-dev character device. * `-q --query` print the current configuration. * `-m --mode=[0-3]` use the selected spi mode. @@ -79,15 +92,22 @@ ``` ### spi-pipe usage + #### Options + * `-d --device=<dev>` use the given spi-dev character device. +* `-m --mode=[0-3]` use the selected spi mode. * `-s --speed=<speed>` Maximum SPI clock rate (in Hz). +* `-l --lsb={0,1}` LSB first (1) or MSB first (0). +* `-B --bits=[7...]` bits per word. +* `-r --spirdy={0,1}` set the SPI_READY spi mode flag. * `-b --blocksize=<int>` transfer block size in byte. * `-n --number=<int>` number of blocks to transfer. * `-h --help` help screen. * `-v --version` display the version number. #### Send and receive simultaneously + Sending data from `command-1` to SPI link and receiving data from SPI link to `command-2` ``` @@ -96,7 +116,7 @@ Note that `command_1`, `command_2` and `spi-pipe` run simultaneously in three parallel processes. -#### Send data to the SPI link +#### Send data through the SPI link ``` $ command_1 | spi-pipe -d /dev/spidev0.0 @@ -111,8 +131,17 @@ You can also use `command_2 < /dev/spidev0.0` but with `spi-pipe` you control what is sent to the device (always `0` in this case). #### Read 40 blocks of 4 bytes from the SPI link + ``` $ spi-pipe -d /dev/spidev0.0 -b 4 -n 40 < /dev/zero | command_2 ``` +#### Send binary commands through the SPI link + +You can use the shell `printf` command to format binary data to send. + +For example, to send the bytes sequence 0x01-0x82-0xF3 and see the reply, use: +``` +$ printf '\x01\x82\F3' | spi-pipe -d /dev/spidev0.0 | hexdump -C +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/configure.ac new/spi-tools-1.0.1/configure.ac --- old/spi-tools-0.8.7/configure.ac 2021-01-07 17:19:24.000000000 +0100 +++ new/spi-tools-1.0.1/configure.ac 2021-11-27 09:58:21.000000000 +0100 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.60]) -AC_INIT(spi-tools, 0.8.7, Christophe Blaess) +AC_INIT(spi-tools, 1.0.1, Christophe Blaess) AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE([disable]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/src/Makefile.am new/spi-tools-1.0.1/src/Makefile.am --- old/spi-tools-0.8.7/src/Makefile.am 2021-01-07 17:19:24.000000000 +0100 +++ new/spi-tools-1.0.1/src/Makefile.am 2021-11-27 09:58:21.000000000 +0100 @@ -1,7 +1,7 @@ bin_PROGRAMS = spi-config spi-pipe -spi_config_SOURCES = spi-config.c +spi_config_SOURCES = spi-config.c spi-tools.c spi_config_LDADD = -spi_pipe_SOURCES = spi-pipe.c +spi_pipe_SOURCES = spi-pipe.c spi-tools.c spi_pipe_LDADD = \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/src/spi-config.c new/spi-tools-1.0.1/src/spi-config.c --- old/spi-tools-0.8.7/src/spi-config.c 2021-01-07 17:19:24.000000000 +0100 +++ new/spi-tools-1.0.1/src/spi-config.c 2021-11-27 09:58:21.000000000 +0100 @@ -20,24 +20,14 @@ #include <fcntl.h> #include <getopt.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <linux/spi/spidev.h> -#include <sys/ioctl.h> #include "config.h" -static char * project = "spi-config"; +#include "spi-tools.h" - -typedef struct spi_config { - int mode; // [0-3] (-1 when not configured). - int lsb; // {0,1} (-1 when not configured). - int bits; // [7...] (-1 when not configured). - uint32_t speed; // 0 when not configured. - int spiready; // {0,1} (-1 when not configured). -} spi_config_t; +static char *project = "spi-config"; @@ -82,16 +72,20 @@ {0, 0, 0, 0 } }; - spi_config_t new_config = { -1, -1, -1, 0, -1 }; - spi_config_t config; char * device = NULL; + spi_config_t new_config; + spi_config_t config; int fd; int val; - uint8_t byte; - uint32_t u32; int query_only = 0; int wait = 0; + new_config.spi_mode = -1; + new_config.lsb_first = -1; + new_config.bits_per_word = -1; + new_config.spi_speed = -1; + new_config.spi_ready = -1; + while ((opt = getopt_long(argc, argv, "d:qhvwm:l:b:s:r:", options, &long_index)) >= 0) { switch(opt) { case 'q': @@ -102,6 +96,9 @@ exit(EXIT_SUCCESS); case 'v': fprintf(stderr, "%s - %s\n", project, VERSION); + fprintf(stderr, "Copyright (c) 2014-2021 Christophe Blaess. (license GPLv2)\n"); + fprintf(stderr, "This is free software. You are free to change and redistribute it.\n"); + fprintf(stderr, "There is NO WARRANTY, to the extent permitted by law.\n"); exit(EXIT_SUCCESS); case 'd': device = optarg; @@ -110,49 +107,32 @@ wait = 1; break; case 'm': - if ((sscanf(optarg, "%d", & val) != 1) - || (val < 0) || (val > 3)) { - fprintf(stderr, "%s: wrong SPI mode ([0-3])\n", argv[0]); + if (Parse_spi_mode(optarg, &new_config) != 0) exit(EXIT_FAILURE); - } - new_config.mode = val; break; case 'l': - if ((sscanf(optarg, "%d", & val) != 1) - || (val < 0) || (val > 1)) { - fprintf(stderr, "%s: wrong LSB first value ([0,1])\n", argv[0]); + if (Parse_lsb_first(optarg, &new_config) != 0) exit(EXIT_FAILURE); - } - new_config.lsb = val; break; case 'b': - if ((sscanf(optarg, "%d", & val) != 1) + if ((sscanf(optarg, "%d", &val) != 1) || (val < 7)) { fprintf(stderr, "%s: wrong bits per word value [7...]\n", argv[0]); exit(EXIT_FAILURE); } - new_config.bits = val; + new_config.bits_per_word = val; break; case 's': - if ((sscanf(optarg, "%d", & val) != 1) - || (val < 10) - || (val > 100000000)) { - fprintf(stderr, "%s: wrong speed value (Hz)\n", argv[0]); + if (Parse_spi_speed(optarg, &new_config) != 0) exit(EXIT_FAILURE); - } - new_config.speed = val; break; case 'r': - if ((sscanf(optarg, "%d", & val) != 1) - || (val < 0) || (val > 1)) { - fprintf(stderr, "%s: wrong SPI_RDY value ([0,1])\n", argv[0]); + if (Parse_spi_ready(optarg, &new_config) != 0) exit(EXIT_FAILURE); - } - new_config.spiready = val; break; default: @@ -172,81 +152,38 @@ exit(EXIT_FAILURE); } - // Read the previous configuration. - if (ioctl(fd, SPI_IOC_RD_MODE, & byte) < 0) { - perror("SPI_IOC_RD_MODE"); + if (Read_spi_configuration(fd, &config) != 0) exit(EXIT_FAILURE); - } - config.mode = byte; - config.spiready = ((config.mode & SPI_READY) ? 1 : 0); - // clear the upper flag bits to be left with mode number - config.mode &= 0x3; - if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, & byte) < 0) { - perror("SPI_IOC_RD_LSB_FIRST"); - exit(EXIT_FAILURE); - } - config.lsb = (byte == SPI_LSB_FIRST ? 1 : 0); - if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, & byte) < 0) { - perror("SPI_IOC_RD_BITS_PER_WORD"); - exit(EXIT_FAILURE); - } - config.bits = (byte == 0 ? 8 : byte); - if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, & u32) < 0) { - perror("SPI_IOC_RD_MAX_SPEED_HZ"); - exit(EXIT_FAILURE); - } - config.speed = u32; if (query_only) { fprintf(stdout, "%s: mode=%d, lsb=%d, bits=%d, speed=%d, spiready=%d\n", - device, config.mode, config.lsb, config.bits, config.speed, config.spiready); + device, config.spi_mode, config.lsb_first, config.bits_per_word, + config.spi_speed, config.spi_ready); exit(EXIT_SUCCESS); } - // Set the new configuration. - if ((config.spiready != new_config.spiready) && (new_config.spiready == 1)) { - new_config.mode |= SPI_READY; - } - if ((config.mode != new_config.mode) || (config.spiready != new_config.spiready)) { - // In case only the spiready flag was changed - if (new_config.mode == -1) { - new_config.mode = config.mode; - } - if (new_config.spiready == 1) { - new_config.mode |= SPI_READY; - } - byte = new_config.mode; - if (ioctl(fd, SPI_IOC_WR_MODE, & byte) < 0) { - perror("SPI_IOC_WR_MODE"); - exit(EXIT_FAILURE); - } - } - if ((config.lsb != new_config.lsb) && (new_config.lsb != -1)) { - byte = (new_config.lsb ? SPI_LSB_FIRST : 0); - if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, & byte) < 0) { - perror("SPI_IOC_WR_LSB_FIRST"); - exit(EXIT_FAILURE); - } - } - if ((config.bits != new_config.bits) && (new_config.bits != -1)) { - byte = new_config.bits; - if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, & byte) < 0) { - fprintf(stderr, "Unable to set bits to %d\n", byte); - perror("SPI_IOC_WR_BITS_PER_WORD"); - exit(EXIT_FAILURE); - } - } - if ((config.speed != new_config.speed) && (new_config.speed != 0)) { - u32 = new_config.speed; - if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, & u32) < 0) { - perror("SPI_IOC_WR_MAX_SPEED_HZ"); - fprintf(stderr, "Failed to set speed to %d\n", u32); - exit(EXIT_FAILURE); - } - } + if (new_config.spi_mode == -1) + new_config.spi_mode = config.spi_mode; + + if (new_config.lsb_first == -1) + new_config.lsb_first = config.lsb_first; + + if (new_config.bits_per_word == -1) + new_config.bits_per_word = config.bits_per_word; + + if (new_config.spi_speed == -1) + new_config.spi_speed = config.spi_speed; + + if (new_config.spi_ready == -1) + new_config.spi_ready = config.spi_ready; + + if (Write_spi_configuration(fd, &new_config) != 0) + exit(EXIT_FAILURE); + if (wait) for (;;) pause(); + return EXIT_SUCCESS; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/src/spi-pipe.c new/spi-tools-1.0.1/src/spi-pipe.c --- old/spi-tools-0.8.7/src/spi-pipe.c 2021-01-07 17:19:24.000000000 +0100 +++ new/spi-tools-1.0.1/src/spi-pipe.c 2021-11-27 09:58:21.000000000 +0100 @@ -1,7 +1,7 @@ /* * spidev data transfer tool. * - * (c) 2014 Christophe BLAESS <[email protected]> + * (c) 2014-2021 Christophe BLAESS <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -25,27 +25,34 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <linux/ioctl.h> -#include <linux/spi/spidev.h> -#include <sys/ioctl.h> #include "config.h" +#include "spi-tools.h" -static char * project = "spi-pipe"; +static char *project = "spi-pipe"; - -static void display_usage(const char * name) +static void display_usage(const char *name) { fprintf(stderr, "usage: %s options...\n", name); fprintf(stderr, " options:\n"); - fprintf(stderr, " -d --device=<dev> use the given spi-dev character device.\n"); + fprintf(stderr, " -d --device=<dev> Use the given spi-dev character device.\n"); + fprintf(stderr, " -m --mode=[0-3] Use the selected spi mode:\n"); + fprintf(stderr, " 0: low idle level, sample on leading edge,\n"); + fprintf(stderr, " 1: low idle level, sample on trailing edge,\n"); + fprintf(stderr, " 2: high idle level, sample on leading edge,\n"); + fprintf(stderr, " 3: high idle level, sample on trailing edge.\n"); fprintf(stderr, " -s --speed=<speed> Maximum SPI clock rate (in Hz).\n"); + fprintf(stderr, " -l --lsb={0,1} LSB first (1) or MSB first (0).\n"); + fprintf(stderr, " -B --bits=[7...] Bits per word.\n"); fprintf(stderr, " -b --blocksize=<int> transfer block size in byte.\n"); fprintf(stderr, " -n --number=<int> number of blocks to transfer (-1 = infinite).\n"); fprintf(stderr, " -h --help this screen.\n"); fprintf(stderr, " -v --version display the version number.\n"); } -int main (int argc, char * argv[]) + + + +int main (int argc, char *argv[]) { int opt; int long_index = 0; @@ -55,59 +62,86 @@ {"speed", required_argument, NULL, 's' }, {"blocksize", required_argument, NULL, 'b' }, {"number", required_argument, NULL, 'n' }, + {"lsb", required_argument, NULL, 'l' }, + {"mode", required_argument, NULL, 'm' }, + {"bits", required_argument, NULL, 'B' }, {"help", no_argument, NULL, 'h' }, {"version", no_argument, NULL, 'v' }, {0, 0, 0, 0 } }; - int fd; - char * device = NULL; - uint8_t * rx_buffer = NULL; - uint8_t * tx_buffer = NULL; - int blocksize = 1; - int blocknumber = -1; - int offset = 0; - int nb = 0; - int speed = -1; - int orig_speed = -1; - - struct spi_ioc_transfer transfer = { - .tx_buf = 0, - .rx_buf = 0, - .len = 0, - .delay_usecs = 0, - .speed_hz = 0, - .bits_per_word = 0, - }; + int fd; + char *device = NULL; + uint8_t *rx_buffer = NULL; + uint8_t *tx_buffer = NULL; + spi_config_t prev_config; + spi_config_t new_config; + + int block_size = 1; + int blocks_count = -1; + int offset = 0; + int nb = 0; + + new_config.spi_mode = -1; + new_config.lsb_first = -1; + new_config.bits_per_word = -1; + new_config.spi_speed = -1; + new_config.spi_ready = -1; + - while ((opt = getopt_long(argc, argv, "d:s:b:n:rhv", options, &long_index)) >= 0) { + while ((opt = getopt_long(argc, argv, "d:s:b:l:m:n:B:rhv", options, &long_index)) >= 0) { switch(opt) { case 'h': display_usage(argv[0]); exit(EXIT_SUCCESS); + case 'v': fprintf(stderr, "%s - %s\n", project, VERSION); + fprintf(stderr, "Copyright (c) 2014-2021 Christophe Blaess. (license GPLv2)\n"); + fprintf(stderr, "This is free software. You are free to change and redistribute it.\n"); + fprintf(stderr, "There is NO WARRANTY, to the extent permitted by law.\n"); exit(EXIT_SUCCESS); + case 'd': device = optarg; break; - case 'b': - if ((sscanf(optarg, "%d", & blocksize) != 1) - || (blocksize <= 0)) { - fprintf(stderr, "%s: wrong blocksize\n", argv[0]); + + case 'm': + if (Parse_spi_mode(optarg, &new_config) != 0) exit(EXIT_FAILURE); - } break; + + case 'l': + if (Parse_lsb_first(optarg, &new_config) != 0) + exit(EXIT_FAILURE); + break; + case 's': - if ((sscanf(optarg, "%d", & speed) != 1) - || (speed < 10) || (speed > 100000000)) { - fprintf(stderr, "%s: Invalid speed\n", argv[0]); + if (Parse_spi_speed(optarg, &new_config) != 0) + exit(EXIT_FAILURE); + break; + + case 'r': + if (Parse_spi_ready(optarg, &new_config) != 0) + exit(EXIT_FAILURE); + break; + + case 'B': + if (Parse_spi_bits_per_word(optarg, &new_config) != 0) + exit(EXIT_FAILURE); + break; + + case 'b': + if ((sscanf(optarg, "%d", &block_size) != 1) + || (block_size <= 0)) { + fprintf(stderr, "%s: wrong blocksize\n", argv[0]); exit(EXIT_FAILURE); } break; + case 'n': - if ((sscanf(optarg, "%d", & blocknumber) != 1) - || (blocknumber < -1)) { + if ((sscanf(optarg, "%d", &blocks_count) != 1) + || (blocks_count < -1)) { fprintf(stderr, "%s: wrong block number\n", argv[0]); exit(EXIT_FAILURE); } @@ -119,19 +153,15 @@ } } - if (((rx_buffer = malloc(blocksize)) == NULL) - || ((tx_buffer = malloc(blocksize)) == NULL)) { + if (((rx_buffer = malloc(block_size)) == NULL) + || ((tx_buffer = malloc(block_size)) == NULL)) { fprintf(stderr, "%s: not enough memory to allocate two %d bytes buffers\n", - argv[0], blocksize); + argv[0], block_size); exit(EXIT_FAILURE); } - memset(rx_buffer, 0, blocksize); - memset(tx_buffer, 0, blocksize); - - transfer.rx_buf = (unsigned long)rx_buffer; - transfer.tx_buf = (unsigned long)tx_buffer; - transfer.len = blocksize; + memset(rx_buffer, 0, block_size); + memset(tx_buffer, 0, block_size); if (device == NULL) { fprintf(stderr, "%s: no device specified (use option -h for help).\n", argv[0]); @@ -144,49 +174,54 @@ exit(EXIT_FAILURE); } - if (speed != -1) { - if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, & orig_speed) < 0) { - perror("SPI_IOC_RD_MAX_SPEED_HZ"); - exit(EXIT_FAILURE); - } + if (Read_spi_configuration(fd, &prev_config) != 0) + exit(EXIT_FAILURE); - if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, & speed) < 0) { - perror("SPI_IOC_WR_MAX_SPEED_HZ"); - exit(EXIT_FAILURE); - } - } + if (new_config.spi_mode == -1) + new_config.spi_mode = prev_config.spi_mode; + + if (new_config.lsb_first == -1) + new_config.lsb_first = prev_config.lsb_first; + + if (new_config.bits_per_word == -1) + new_config.bits_per_word = prev_config.bits_per_word; + + if (new_config.spi_speed == -1) + new_config.spi_speed = prev_config.spi_speed; - while ((blocknumber > 0) || (blocknumber == -1)) { - for (offset = 0; offset < blocksize; offset += nb) { - nb = read(STDIN_FILENO, & (tx_buffer[offset]), blocksize - offset); + if (new_config.spi_ready == -1) + new_config.spi_ready = prev_config.spi_ready; + + if (Write_spi_configuration(fd, &new_config) != 0) + exit(EXIT_FAILURE); + + while ((blocks_count > 0) || (blocks_count == -1)) { + for (offset = 0; offset < block_size; offset += nb) { + nb = read(STDIN_FILENO, & (tx_buffer[offset]), block_size - offset); if (nb <= 0) break; } if ((nb <= 0) && (offset == 0)) break; - transfer.len = offset; - if (ioctl(fd, SPI_IOC_MESSAGE(1), & transfer) < 0) { + if (Transfer_spi_buffers(fd, tx_buffer, rx_buffer, offset) != 0) { perror("SPI_IOC_MESSAGE"); break; } if (write(STDOUT_FILENO, rx_buffer, offset) <= 0) break; - if (blocknumber > 0) - blocknumber --; - } - - if (orig_speed != -1) { - if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, & orig_speed) < 0) { - perror("SPI_IOC_WR_MAX_SPEED_HZ"); - exit(EXIT_FAILURE); - } + if (blocks_count > 0) + blocks_count --; } free(rx_buffer); free(tx_buffer); - if (blocknumber != 0) + + if (Write_spi_configuration(fd, &prev_config) != 0) + exit(EXIT_FAILURE); + + if (blocks_count != 0) return EXIT_FAILURE; + return EXIT_SUCCESS; } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/src/spi-tools.c new/spi-tools-1.0.1/src/spi-tools.c --- old/spi-tools-0.8.7/src/spi-tools.c 1970-01-01 01:00:00.000000000 +0100 +++ new/spi-tools-1.0.1/src/spi-tools.c 2021-11-27 09:58:21.000000000 +0100 @@ -0,0 +1,181 @@ +/* + * spidev tools. + * + * (c) 2014-2021 Christophe BLAESS <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + + +#include <stdint.h> +#include <stdio.h> + +#include <linux/spi/spidev.h> +#include <sys/ioctl.h> + +#include "spi-tools.h" + + + +int Read_spi_configuration(int fd, spi_config_t *config) +{ + uint8_t u8; + uint32_t u32; + + if (ioctl(fd, SPI_IOC_RD_MODE, &u8) < 0) { + perror("SPI_IOC_RD_MODE"); + return -1; + } + config->spi_mode = u8 & 0x03; + config->spi_ready = ((config->spi_mode & SPI_READY) ? 1 : 0); + + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &u8) < 0) { + perror("SPI_IOC_RD_LSB_FIRST"); + return -1; + } + config->lsb_first = (u8 == SPI_LSB_FIRST ? 1 : 0); + + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &u8) < 0) { + perror("SPI_IOC_RD_BITS_PER_WORD"); + return -1; + } + config->bits_per_word = (u8 == 0 ? 8 : u8); + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &u32) < 0) { + perror("SPI_IOC_RD_MAX_SPEED_HZ"); + return -1; + } + config->spi_speed = u32; + + return 0; +} + + + +int Write_spi_configuration(int fd, spi_config_t *config) +{ + uint8_t u8; + uint32_t u32; + + u8 = config->spi_mode; + if (config->spi_ready == 1) + u8 |= SPI_READY; + if (ioctl(fd, SPI_IOC_WR_MODE, &u8) < 0) { + perror("SPI_IOC_WR_MODE"); + return -1; + } + + u8 = (config->lsb_first ? SPI_LSB_FIRST : 0); + if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, &u8) < 0) { + perror("SPI_IOC_WR_LSB_FIRST"); + return -1; + } + + u8 = config->bits_per_word; + if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &u8) < 0) { + perror("SPI_IOC_WR_BITS_PER_WORD"); + return -1; + } + + u32 = config->spi_speed; + if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &u32) < 0) { + perror("SPI_IOC_WR_MAX_SPEED_HZ"); + return -1; + } + + return 0; +} + + +int Parse_spi_mode(const char *optarg, spi_config_t *config) +{ + if ((sscanf(optarg, "%d", &(config->spi_mode)) != 1) + || (config->spi_mode < 0) || (config->spi_mode > 3)) { + fprintf(stderr, "Error: wrong SPI mode ([0-3]): %s\n", optarg); + return -1; + } + return 0; +} + + + +int Parse_lsb_first(const char *optarg, spi_config_t *config) +{ + if ((sscanf(optarg, "%d", &(config->lsb_first)) != 1) + || (config->lsb_first < 0) || (config->lsb_first > 1)) { + fprintf(stderr, "Error: wrong LSB value ([0,1]): %s\n", optarg); + return -1; + } + return 0; +} + + + +int Parse_spi_speed(const char *optarg, spi_config_t *config) +{ + if ((sscanf(optarg, "%d", &(config->spi_speed)) != 1) + || (config->spi_speed < 0) || (config->spi_speed > 100000000)) { + fprintf(stderr, "Error: invalid SPI speed ([0-100000000]): %s\n", optarg); + return -1; + } + return 0; +} + + + +int Parse_spi_ready(const char *optarg, spi_config_t *config) +{ + if ((sscanf(optarg, "%d", &(config->spi_ready)) != 1) + || (config->spi_ready < 0) || (config->spi_ready > 1)) { + fprintf(stderr, "Error: wrong SPI-ready value ([0, 1]): %s\n", optarg); + return -1; + } + return 0; +} + + + +int Parse_spi_bits_per_word(const char *optarg, spi_config_t *config) +{ + if ((sscanf(optarg, "%d", &(config->bits_per_word)) != 1) + || (config->bits_per_word < 7)) { + fprintf(stderr, "Error: wrong bits-per-word value ([0, 1]): %s\n", optarg); + return -1; + } + return 0; +} + + + +int Transfer_spi_buffers(int fd, void *tx_buffer, void *rx_buffer, size_t length) +{ + struct spi_ioc_transfer transfer = { + .tx_buf = 0, + .rx_buf = 0, + .len = 0, + .delay_usecs = 0, + .speed_hz = 0, + .bits_per_word = 0, + }; + + transfer.rx_buf = (unsigned long)rx_buffer; + transfer.tx_buf = (unsigned long)tx_buffer; + transfer.len = length; + + if (ioctl(fd, SPI_IOC_MESSAGE(1), & transfer) < 0) + return -1; + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spi-tools-0.8.7/src/spi-tools.h new/spi-tools-1.0.1/src/spi-tools.h --- old/spi-tools-0.8.7/src/spi-tools.h 1970-01-01 01:00:00.000000000 +0100 +++ new/spi-tools-1.0.1/src/spi-tools.h 2021-11-27 09:58:21.000000000 +0100 @@ -0,0 +1,53 @@ +/* + * spidev tools. + * + * (c) 2014-2021 Christophe BLAESS <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef SPI_TOOLS_H +#define SPI_TOOLS_H + + +typedef struct spi_config { + + int spi_mode; // [0-3] (-1 when not configured). + int lsb_first; // {0,1} (-1 when not configured). + int bits_per_word; // [7...] (-1 when not configured). + int spi_speed; // 0 when not configured. + int spi_ready; // {0,1} (-1 when not configured). + +} spi_config_t; + + +int Read_spi_configuration(int fd, spi_config_t *config); + +int Write_spi_configuration(int fd, spi_config_t *config); + +int Parse_spi_mode(const char *optarg, spi_config_t *config); + +int Parse_lsb_first(const char *optarg, spi_config_t *config); + +int Parse_spi_speed(const char *optarg, spi_config_t *config); + +int Parse_spi_ready(const char *optarg, spi_config_t *config); + +int Parse_spi_bits_per_word(const char *optarg, spi_config_t *config); + +int Transfer_spi_buffers(int fd, void *tx_buffer, void *rx_buffer, size_t length); + + +#endif
