* [PATCH 0/4] spi: spidev_test: Added functionalities @ 2015-03-07 17:56 Adrian Remonda 2015-03-07 17:56 ` [PATCH 1/4] Cleaned hexadecimal dump Adrian Remonda 0 siblings, 1 reply; 11+ messages in thread From: Adrian Remonda @ 2015-03-07 17:56 UTC (permalink / raw) Cc: adrianremonda-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A, corbet-T1hC0tSOHrs, linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA This is a patch series add functionalities to the spidev_test tool found in Documentation/spi/spidev_test.c. - Cleaned hexadecimal dump - Added verbose mode to see the transmitting sequence - Added input buffer from the terminal. Now it is possible to send string and hexadecimal data as an input parameter: Example that shows verbose mode and a sending sequence: root@microZed:~# ./a.out -D /dev/spidev32766.1 -p "\x23ab1" -v spi mode: 0x0 bits per word: 8 max speed: 500000 Hz (500 KHz) TX | 23 61 62 31 __ __ __ __ | #ab1 RX | FF FF FF FF __ __ __ __ | .... Adrian Remonda (4): Cleaned hexadecimal dump Added verbose output Added input buffer from the terminal. Created spi directory in tools Documentation/spi/spidev_test.c | 243 ------------------------------ tools/spi/spidev_test.c | 318 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 318 insertions(+), 243 deletions(-) delete mode 100644 Documentation/spi/spidev_test.c create mode 100644 tools/spi/spidev_test.c -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] Cleaned hexadecimal dump 2015-03-07 17:56 [PATCH 0/4] spi: spidev_test: Added functionalities Adrian Remonda @ 2015-03-07 17:56 ` Adrian Remonda 2015-03-07 17:56 ` [PATCH 2/4] Added verbose output Adrian Remonda ` (3 more replies) 0 siblings, 4 replies; 11+ messages in thread From: Adrian Remonda @ 2015-03-07 17:56 UTC (permalink / raw) Cc: adrianremonda, broonie, corbet, linux-spi, linux-doc, linux-kernel Signed-off-by: Adrian Remonda <adrianremonda@gmail.com> --- Documentation/spi/spidev_test.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 3a2f9d59edab..533050ced9f1 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -15,6 +15,7 @@ #include <unistd.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <getopt.h> #include <fcntl.h> #include <sys/ioctl.h> @@ -35,6 +36,33 @@ static uint8_t bits = 8; static uint32_t speed = 500000; static uint16_t delay; +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) +{ + int i = 0; + char *address = (char *)src; + char *line = (char *)address; + unsigned char c; + + printf("%s | ", prefix); + while (length-- > 0) { + printf("%02X ", (unsigned char)*address++); + if (!(++i % bLine) || (length == 0 && i % bLine)) { + if (length == 0) { + while (i++ % bLine) + printf("__ "); + } + printf(" | "); /* right close */ + while (line < address) { + c = *line++; + printf("%c", (c < 33 || c == 255) ? 0x2E : c); + } + printf("\n"); + if (length > 0) + printf("%s | ", prefix); + } + } +} + static void transfer(int fd) { int ret; @@ -76,12 +104,7 @@ static void transfer(int fd) if (ret < 1) pabort("can't send spi message"); - for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { - if (!(ret % 6)) - puts(""); - printf("%.2X ", rx[ret]); - } - puts(""); + hexDump(rx, ARRAY_SIZE(tx), 32, "RX"); } static void print_usage(const char *prog) -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/4] Added verbose output 2015-03-07 17:56 ` [PATCH 1/4] Cleaned hexadecimal dump Adrian Remonda @ 2015-03-07 17:56 ` Adrian Remonda 2015-03-07 17:56 ` [PATCH 3/4] Added input buffer from the terminal Adrian Remonda 2015-03-08 2:22 ` [PATCH 1/4] Cleaned hexadecimal dump Joe Perches ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Adrian Remonda @ 2015-03-07 17:56 UTC (permalink / raw) Cc: adrianremonda, broonie, corbet, linux-spi, linux-doc, linux-kernel Signed-off-by: Adrian Remonda <adrianremonda@gmail.com> --- Documentation/spi/spidev_test.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 533050ced9f1..a247b3dbf65a 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -35,6 +35,7 @@ static uint32_t mode; static uint8_t bits = 8; static uint32_t speed = 500000; static uint16_t delay; +static int verbose; static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) { @@ -104,7 +105,9 @@ static void transfer(int fd) if (ret < 1) pabort("can't send spi message"); - hexDump(rx, ARRAY_SIZE(tx), 32, "RX"); + if (verbose) + hexDump(tx, ARRAY_SIZE(tx), 32, "TX"); + hexDump(rx, ARRAY_SIZE(rx), 32, "RX"); } static void print_usage(const char *prog) @@ -120,6 +123,7 @@ static void print_usage(const char *prog) " -L --lsb least significant bit first\n" " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n" + " -v --verbose Verbose (show tx buffer)\n" " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -2 --dual dual transfer\n" @@ -144,12 +148,13 @@ static void parse_opts(int argc, char *argv[]) { "no-cs", 0, 0, 'N' }, { "ready", 0, 0, 'R' }, { "dual", 0, 0, '2' }, + { "verbose", 0, 0, 'v' }, { "quad", 0, 0, '4' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24:v", lopts, NULL); if (c == -1) break; @@ -188,6 +193,9 @@ static void parse_opts(int argc, char *argv[]) case 'N': mode |= SPI_NO_CS; break; + case 'v': + verbose = 1; + break; case 'R': mode |= SPI_READY; break; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/4] Added input buffer from the terminal. 2015-03-07 17:56 ` [PATCH 2/4] Added verbose output Adrian Remonda @ 2015-03-07 17:56 ` Adrian Remonda 2015-03-07 17:56 ` [PATCH 4/4] Moved spidev_tools.c to tools/spi Adrian Remonda 2015-03-09 18:38 ` [PATCH 3/4] Added input buffer from the terminal Mark Brown 0 siblings, 2 replies; 11+ messages in thread From: Adrian Remonda @ 2015-03-07 17:56 UTC (permalink / raw) Cc: adrianremonda, broonie, corbet, linux-spi, linux-doc, linux-kernel Now it is possible to send string and hexadecimal data as an input parameter modified: Documentation/spi/spidev_test.c Signed-off-by: Adrian Remonda <adrianremonda@gmail.com> --- Documentation/spi/spidev_test.c | 76 ++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index a247b3dbf65a..5660cd5fd18f 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -37,6 +37,18 @@ static uint32_t speed = 500000; static uint16_t delay; static int verbose; +uint8_t default_tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0D, +}; + +uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; +char *input_tx; + static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) { int i = 0; @@ -64,23 +76,38 @@ static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) } } -static void transfer(int fd) +/* + * Unescape - process hexadecimal escape character + * converts shell input "\x23" -> 0x23 + */ +int unespcape(char *dst, char *src, size_t len) +{ + int ret = 0; + char *pSrc = src; + char *pDst = dst; + unsigned int ch; + + while (*pSrc) { + if (*pSrc == '\\' && *(pSrc+1) == 'x') { + sscanf(pSrc + 2, "%2x", &ch); + pSrc += 4; + *pDst++ = (unsigned char)ch; + } else { + *pDst++ = *pSrc++; + } + ret++; + } + return ret; +} + +static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) { int ret; - uint8_t tx[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, - 0xF0, 0x0D, - }; - uint8_t rx[ARRAY_SIZE(tx)] = {0, }; + struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, - .len = ARRAY_SIZE(tx), + .len = len, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, @@ -106,8 +133,8 @@ static void transfer(int fd) pabort("can't send spi message"); if (verbose) - hexDump(tx, ARRAY_SIZE(tx), 32, "TX"); - hexDump(rx, ARRAY_SIZE(rx), 32, "RX"); + hexDump(tx, len, 32, "TX"); + hexDump(rx, len, 32, "RX"); } static void print_usage(const char *prog) @@ -124,6 +151,7 @@ static void print_usage(const char *prog) " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n" " -v --verbose Verbose (show tx buffer)\n" + " -p Send data (e.g. \"1234\\xde\\xad\")\n" " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -2 --dual dual transfer\n" @@ -154,7 +182,7 @@ static void parse_opts(int argc, char *argv[]) }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24:v", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); if (c == -1) break; @@ -199,6 +227,9 @@ static void parse_opts(int argc, char *argv[]) case 'R': mode |= SPI_READY; break; + case 'p': + input_tx = optarg; + break; case '2': mode |= SPI_TX_DUAL; break; @@ -222,6 +253,9 @@ int main(int argc, char *argv[]) { int ret = 0; int fd; + uint8_t *tx; + uint8_t *rx; + int size; parse_opts(argc, argv); @@ -266,7 +300,17 @@ int main(int argc, char *argv[]) printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - transfer(fd); + if (input_tx) { + size = strlen(input_tx+1); + tx = (uint8_t *)malloc(size); + rx = (uint8_t *)malloc(size); + size = unespcape((char *)tx, input_tx, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); + } else { + transfer(fd, default_tx, default_rx, sizeof(default_tx)); + } close(fd); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/4] Moved spidev_tools.c to tools/spi 2015-03-07 17:56 ` [PATCH 3/4] Added input buffer from the terminal Adrian Remonda @ 2015-03-07 17:56 ` Adrian Remonda 2015-03-09 18:38 ` [PATCH 3/4] Added input buffer from the terminal Mark Brown 1 sibling, 0 replies; 11+ messages in thread From: Adrian Remonda @ 2015-03-07 17:56 UTC (permalink / raw) Cc: adrianremonda, broonie, corbet, linux-spi, linux-doc, linux-kernel Moved spidev_tool.c to tools/spi renamed: Documentation/spi/spidev_test.c -> tools/spi/spidev_test.c Signed-off-by: Adrian Remonda <adrianremonda@gmail.com> --- Documentation/spi/spidev_test.c | 318 --------------------------------------- tools/spi/spidev_test.c | 318 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 318 insertions(+), 318 deletions(-) delete mode 100644 Documentation/spi/spidev_test.c create mode 100644 tools/spi/spidev_test.c diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c deleted file mode 100644 index 5660cd5fd18f..000000000000 --- a/Documentation/spi/spidev_test.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * SPI testing utility (using spidev driver) - * - * Copyright (c) 2007 MontaVista Software, Inc. - * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * Cross-compile with cross-gcc -I/path/to/cross-kernel/include - */ - -#include <stdint.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/types.h> -#include <linux/spi/spidev.h> - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -static void pabort(const char *s) -{ - perror(s); - abort(); -} - -static const char *device = "/dev/spidev1.1"; -static uint32_t mode; -static uint8_t bits = 8; -static uint32_t speed = 500000; -static uint16_t delay; -static int verbose; - -uint8_t default_tx[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF0, 0x0D, -}; - -uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; -char *input_tx; - -static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) -{ - int i = 0; - char *address = (char *)src; - char *line = (char *)address; - unsigned char c; - - printf("%s | ", prefix); - while (length-- > 0) { - printf("%02X ", (unsigned char)*address++); - if (!(++i % bLine) || (length == 0 && i % bLine)) { - if (length == 0) { - while (i++ % bLine) - printf("__ "); - } - printf(" | "); /* right close */ - while (line < address) { - c = *line++; - printf("%c", (c < 33 || c == 255) ? 0x2E : c); - } - printf("\n"); - if (length > 0) - printf("%s | ", prefix); - } - } -} - -/* - * Unescape - process hexadecimal escape character - * converts shell input "\x23" -> 0x23 - */ -int unespcape(char *dst, char *src, size_t len) -{ - int ret = 0; - char *pSrc = src; - char *pDst = dst; - unsigned int ch; - - while (*pSrc) { - if (*pSrc == '\\' && *(pSrc+1) == 'x') { - sscanf(pSrc + 2, "%2x", &ch); - pSrc += 4; - *pDst++ = (unsigned char)ch; - } else { - *pDst++ = *pSrc++; - } - ret++; - } - return ret; -} - -static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) -{ - int ret; - - struct spi_ioc_transfer tr = { - .tx_buf = (unsigned long)tx, - .rx_buf = (unsigned long)rx, - .len = len, - .delay_usecs = delay, - .speed_hz = speed, - .bits_per_word = bits, - }; - - if (mode & SPI_TX_QUAD) - tr.tx_nbits = 4; - else if (mode & SPI_TX_DUAL) - tr.tx_nbits = 2; - if (mode & SPI_RX_QUAD) - tr.rx_nbits = 4; - else if (mode & SPI_RX_DUAL) - tr.rx_nbits = 2; - if (!(mode & SPI_LOOP)) { - if (mode & (SPI_TX_QUAD | SPI_TX_DUAL)) - tr.rx_buf = 0; - else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL)) - tr.tx_buf = 0; - } - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - if (ret < 1) - pabort("can't send spi message"); - - if (verbose) - hexDump(tx, len, 32, "TX"); - hexDump(rx, len, 32, "RX"); -} - -static void print_usage(const char *prog) -{ - printf("Usage: %s [-DsbdlHOLC3]\n", prog); - puts(" -D --device device to use (default /dev/spidev1.1)\n" - " -s --speed max speed (Hz)\n" - " -d --delay delay (usec)\n" - " -b --bpw bits per word \n" - " -l --loop loopback\n" - " -H --cpha clock phase\n" - " -O --cpol clock polarity\n" - " -L --lsb least significant bit first\n" - " -C --cs-high chip select active high\n" - " -3 --3wire SI/SO signals shared\n" - " -v --verbose Verbose (show tx buffer)\n" - " -p Send data (e.g. \"1234\\xde\\xad\")\n" - " -N --no-cs no chip select\n" - " -R --ready slave pulls low to pause\n" - " -2 --dual dual transfer\n" - " -4 --quad quad transfer\n"); - exit(1); -} - -static void parse_opts(int argc, char *argv[]) -{ - while (1) { - static const struct option lopts[] = { - { "device", 1, 0, 'D' }, - { "speed", 1, 0, 's' }, - { "delay", 1, 0, 'd' }, - { "bpw", 1, 0, 'b' }, - { "loop", 0, 0, 'l' }, - { "cpha", 0, 0, 'H' }, - { "cpol", 0, 0, 'O' }, - { "lsb", 0, 0, 'L' }, - { "cs-high", 0, 0, 'C' }, - { "3wire", 0, 0, '3' }, - { "no-cs", 0, 0, 'N' }, - { "ready", 0, 0, 'R' }, - { "dual", 0, 0, '2' }, - { "verbose", 0, 0, 'v' }, - { "quad", 0, 0, '4' }, - { NULL, 0, 0, 0 }, - }; - int c; - - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); - - if (c == -1) - break; - - switch (c) { - case 'D': - device = optarg; - break; - case 's': - speed = atoi(optarg); - break; - case 'd': - delay = atoi(optarg); - break; - case 'b': - bits = atoi(optarg); - break; - case 'l': - mode |= SPI_LOOP; - break; - case 'H': - mode |= SPI_CPHA; - break; - case 'O': - mode |= SPI_CPOL; - break; - case 'L': - mode |= SPI_LSB_FIRST; - break; - case 'C': - mode |= SPI_CS_HIGH; - break; - case '3': - mode |= SPI_3WIRE; - break; - case 'N': - mode |= SPI_NO_CS; - break; - case 'v': - verbose = 1; - break; - case 'R': - mode |= SPI_READY; - break; - case 'p': - input_tx = optarg; - break; - case '2': - mode |= SPI_TX_DUAL; - break; - case '4': - mode |= SPI_TX_QUAD; - break; - default: - print_usage(argv[0]); - break; - } - } - if (mode & SPI_LOOP) { - if (mode & SPI_TX_DUAL) - mode |= SPI_RX_DUAL; - if (mode & SPI_TX_QUAD) - mode |= SPI_RX_QUAD; - } -} - -int main(int argc, char *argv[]) -{ - int ret = 0; - int fd; - uint8_t *tx; - uint8_t *rx; - int size; - - parse_opts(argc, argv); - - fd = open(device, O_RDWR); - if (fd < 0) - pabort("can't open device"); - - /* - * spi mode - */ - ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode); - if (ret == -1) - pabort("can't set spi mode"); - - ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode); - if (ret == -1) - pabort("can't get spi mode"); - - /* - * bits per word - */ - ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); - if (ret == -1) - pabort("can't set bits per word"); - - ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); - if (ret == -1) - pabort("can't get bits per word"); - - /* - * max speed hz - */ - ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - if (ret == -1) - pabort("can't set max speed hz"); - - ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); - if (ret == -1) - pabort("can't get max speed hz"); - - printf("spi mode: 0x%x\n", mode); - printf("bits per word: %d\n", bits); - printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - - if (input_tx) { - size = strlen(input_tx+1); - tx = (uint8_t *)malloc(size); - rx = (uint8_t *)malloc(size); - size = unespcape((char *)tx, input_tx, size); - transfer(fd, tx, rx, size); - free(rx); - free(tx); - } else { - transfer(fd, default_tx, default_rx, sizeof(default_tx)); - } - - close(fd); - - return ret; -} diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c new file mode 100644 index 000000000000..5660cd5fd18f --- /dev/null +++ b/tools/spi/spidev_test.c @@ -0,0 +1,318 @@ +/* + * SPI testing utility (using spidev driver) + * + * Copyright (c) 2007 MontaVista Software, Inc. + * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * Cross-compile with cross-gcc -I/path/to/cross-kernel/include + */ + +#include <stdint.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/types.h> +#include <linux/spi/spidev.h> + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static void pabort(const char *s) +{ + perror(s); + abort(); +} + +static const char *device = "/dev/spidev1.1"; +static uint32_t mode; +static uint8_t bits = 8; +static uint32_t speed = 500000; +static uint16_t delay; +static int verbose; + +uint8_t default_tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0D, +}; + +uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; +char *input_tx; + +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) +{ + int i = 0; + char *address = (char *)src; + char *line = (char *)address; + unsigned char c; + + printf("%s | ", prefix); + while (length-- > 0) { + printf("%02X ", (unsigned char)*address++); + if (!(++i % bLine) || (length == 0 && i % bLine)) { + if (length == 0) { + while (i++ % bLine) + printf("__ "); + } + printf(" | "); /* right close */ + while (line < address) { + c = *line++; + printf("%c", (c < 33 || c == 255) ? 0x2E : c); + } + printf("\n"); + if (length > 0) + printf("%s | ", prefix); + } + } +} + +/* + * Unescape - process hexadecimal escape character + * converts shell input "\x23" -> 0x23 + */ +int unespcape(char *dst, char *src, size_t len) +{ + int ret = 0; + char *pSrc = src; + char *pDst = dst; + unsigned int ch; + + while (*pSrc) { + if (*pSrc == '\\' && *(pSrc+1) == 'x') { + sscanf(pSrc + 2, "%2x", &ch); + pSrc += 4; + *pDst++ = (unsigned char)ch; + } else { + *pDst++ = *pSrc++; + } + ret++; + } + return ret; +} + +static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) +{ + int ret; + + struct spi_ioc_transfer tr = { + .tx_buf = (unsigned long)tx, + .rx_buf = (unsigned long)rx, + .len = len, + .delay_usecs = delay, + .speed_hz = speed, + .bits_per_word = bits, + }; + + if (mode & SPI_TX_QUAD) + tr.tx_nbits = 4; + else if (mode & SPI_TX_DUAL) + tr.tx_nbits = 2; + if (mode & SPI_RX_QUAD) + tr.rx_nbits = 4; + else if (mode & SPI_RX_DUAL) + tr.rx_nbits = 2; + if (!(mode & SPI_LOOP)) { + if (mode & (SPI_TX_QUAD | SPI_TX_DUAL)) + tr.rx_buf = 0; + else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL)) + tr.tx_buf = 0; + } + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if (verbose) + hexDump(tx, len, 32, "TX"); + hexDump(rx, len, 32, "RX"); +} + +static void print_usage(const char *prog) +{ + printf("Usage: %s [-DsbdlHOLC3]\n", prog); + puts(" -D --device device to use (default /dev/spidev1.1)\n" + " -s --speed max speed (Hz)\n" + " -d --delay delay (usec)\n" + " -b --bpw bits per word \n" + " -l --loop loopback\n" + " -H --cpha clock phase\n" + " -O --cpol clock polarity\n" + " -L --lsb least significant bit first\n" + " -C --cs-high chip select active high\n" + " -3 --3wire SI/SO signals shared\n" + " -v --verbose Verbose (show tx buffer)\n" + " -p Send data (e.g. \"1234\\xde\\xad\")\n" + " -N --no-cs no chip select\n" + " -R --ready slave pulls low to pause\n" + " -2 --dual dual transfer\n" + " -4 --quad quad transfer\n"); + exit(1); +} + +static void parse_opts(int argc, char *argv[]) +{ + while (1) { + static const struct option lopts[] = { + { "device", 1, 0, 'D' }, + { "speed", 1, 0, 's' }, + { "delay", 1, 0, 'd' }, + { "bpw", 1, 0, 'b' }, + { "loop", 0, 0, 'l' }, + { "cpha", 0, 0, 'H' }, + { "cpol", 0, 0, 'O' }, + { "lsb", 0, 0, 'L' }, + { "cs-high", 0, 0, 'C' }, + { "3wire", 0, 0, '3' }, + { "no-cs", 0, 0, 'N' }, + { "ready", 0, 0, 'R' }, + { "dual", 0, 0, '2' }, + { "verbose", 0, 0, 'v' }, + { "quad", 0, 0, '4' }, + { NULL, 0, 0, 0 }, + }; + int c; + + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); + + if (c == -1) + break; + + switch (c) { + case 'D': + device = optarg; + break; + case 's': + speed = atoi(optarg); + break; + case 'd': + delay = atoi(optarg); + break; + case 'b': + bits = atoi(optarg); + break; + case 'l': + mode |= SPI_LOOP; + break; + case 'H': + mode |= SPI_CPHA; + break; + case 'O': + mode |= SPI_CPOL; + break; + case 'L': + mode |= SPI_LSB_FIRST; + break; + case 'C': + mode |= SPI_CS_HIGH; + break; + case '3': + mode |= SPI_3WIRE; + break; + case 'N': + mode |= SPI_NO_CS; + break; + case 'v': + verbose = 1; + break; + case 'R': + mode |= SPI_READY; + break; + case 'p': + input_tx = optarg; + break; + case '2': + mode |= SPI_TX_DUAL; + break; + case '4': + mode |= SPI_TX_QUAD; + break; + default: + print_usage(argv[0]); + break; + } + } + if (mode & SPI_LOOP) { + if (mode & SPI_TX_DUAL) + mode |= SPI_RX_DUAL; + if (mode & SPI_TX_QUAD) + mode |= SPI_RX_QUAD; + } +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int fd; + uint8_t *tx; + uint8_t *rx; + int size; + + parse_opts(argc, argv); + + fd = open(device, O_RDWR); + if (fd < 0) + pabort("can't open device"); + + /* + * spi mode + */ + ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode); + if (ret == -1) + pabort("can't set spi mode"); + + ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode); + if (ret == -1) + pabort("can't get spi mode"); + + /* + * bits per word + */ + ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't set bits per word"); + + ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't get bits per word"); + + /* + * max speed hz + */ + ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't set max speed hz"); + + ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't get max speed hz"); + + printf("spi mode: 0x%x\n", mode); + printf("bits per word: %d\n", bits); + printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); + + if (input_tx) { + size = strlen(input_tx+1); + tx = (uint8_t *)malloc(size); + rx = (uint8_t *)malloc(size); + size = unespcape((char *)tx, input_tx, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); + } else { + transfer(fd, default_tx, default_rx, sizeof(default_tx)); + } + + close(fd); + + return ret; +} -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 3/4] Added input buffer from the terminal. 2015-03-07 17:56 ` [PATCH 3/4] Added input buffer from the terminal Adrian Remonda 2015-03-07 17:56 ` [PATCH 4/4] Moved spidev_tools.c to tools/spi Adrian Remonda @ 2015-03-09 18:38 ` Mark Brown 1 sibling, 0 replies; 11+ messages in thread From: Mark Brown @ 2015-03-09 18:38 UTC (permalink / raw) To: Adrian Remonda; +Cc: corbet, linux-spi, linux-doc, linux-kernel [-- Attachment #1: Type: text/plain, Size: 396 bytes --] On Sat, Mar 07, 2015 at 12:56:34PM -0500, Adrian Remonda wrote: > + int ret = 0; > + char *pSrc = src; The kernel coding style doesn't use Hungarian notation... > + if (input_tx) { > + size = strlen(input_tx+1); > + tx = (uint8_t *)malloc(size); > + rx = (uint8_t *)malloc(size); You should never need to cast the return value of malloc() - if it's needed it's masking some other problem. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Cleaned hexadecimal dump 2015-03-07 17:56 ` [PATCH 1/4] Cleaned hexadecimal dump Adrian Remonda 2015-03-07 17:56 ` [PATCH 2/4] Added verbose output Adrian Remonda @ 2015-03-08 2:22 ` Joe Perches 2015-03-08 10:53 ` Andy Shevchenko [not found] ` <1425750995-18176-2-git-send-email-adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2015-03-09 18:40 ` Mark Brown 3 siblings, 1 reply; 11+ messages in thread From: Joe Perches @ 2015-03-08 2:22 UTC (permalink / raw) To: Adrian Remonda; +Cc: broonie, corbet, linux-spi, linux-doc, linux-kernel On Sat, 2015-03-07 at 12:56 -0500, Adrian Remonda wrote: > Signed-off-by: Adrian Remonda <adrianremonda@gmail.com> [] > diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c [] > +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) > +{ Is there something necessary that print_hex_dump can't do? > + int i = 0; > + char *address = (char *)src; > + char *line = (char *)address; > + unsigned char c; > + > + printf("%s | ", prefix); > + while (length-- > 0) { > + printf("%02X ", (unsigned char)*address++); > + if (!(++i % bLine) || (length == 0 && i % bLine)) { > + if (length == 0) { > + while (i++ % bLine) > + printf("__ "); > + } > + printf(" | "); /* right close */ > + while (line < address) { > + c = *line++; > + printf("%c", (c < 33 || c == 255) ? 0x2E : c); > + } > + printf("\n"); > + if (length > 0) > + printf("%s | ", prefix); > + } > + } > +} ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Cleaned hexadecimal dump 2015-03-08 2:22 ` [PATCH 1/4] Cleaned hexadecimal dump Joe Perches @ 2015-03-08 10:53 ` Andy Shevchenko 2015-03-08 16:20 ` Joe Perches 0 siblings, 1 reply; 11+ messages in thread From: Andy Shevchenko @ 2015-03-08 10:53 UTC (permalink / raw) To: Joe Perches Cc: Adrian Remonda, Mark Brown, corbet, linux-spi, Linux Documentation List, linux-kernel@vger.kernel.org On Sun, Mar 8, 2015 at 4:22 AM, Joe Perches <joe@perches.com> wrote: > On Sat, 2015-03-07 at 12:56 -0500, Adrian Remonda wrote: >> +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) >> +{ > > Is there something necessary that print_hex_dump can't do? As far as I can see the tool is running in user space. Do we have possibility to use print_hex_dump() in user space? -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Cleaned hexadecimal dump 2015-03-08 10:53 ` Andy Shevchenko @ 2015-03-08 16:20 ` Joe Perches 0 siblings, 0 replies; 11+ messages in thread From: Joe Perches @ 2015-03-08 16:20 UTC (permalink / raw) To: Andy Shevchenko Cc: Adrian Remonda, Mark Brown, corbet, linux-spi, Linux Documentation List, linux-kernel@vger.kernel.org On Sun, 2015-03-08 at 12:53 +0200, Andy Shevchenko wrote: > On Sun, Mar 8, 2015 at 4:22 AM, Joe Perches <joe@perches.com> wrote: > > On Sat, 2015-03-07 at 12:56 -0500, Adrian Remonda wrote: > > >> +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) > > Is there something necessary that print_hex_dump can't do? > As far as I can see the tool is running in user space. OK, I skipped over that bit. Nevermind. > Do we have > possibility to use print_hex_dump() in user space? No. ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <1425750995-18176-2-git-send-email-adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH 1/4] Cleaned hexadecimal dump [not found] ` <1425750995-18176-2-git-send-email-adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2015-03-09 13:51 ` Geert Uytterhoeven 0 siblings, 0 replies; 11+ messages in thread From: Geert Uytterhoeven @ 2015-03-09 13:51 UTC (permalink / raw) To: Adrian Remonda Cc: Mark Brown, Jonathan Corbet, linux-spi, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Sat, Mar 7, 2015 at 6:56 PM, Adrian Remonda <adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c > index 3a2f9d59edab..533050ced9f1 100644 > --- a/Documentation/spi/spidev_test.c > +++ b/Documentation/spi/spidev_test.c > @@ -15,6 +15,7 @@ > #include <unistd.h> > #include <stdio.h> > #include <stdlib.h> > +#include <string.h> > #include <getopt.h> > #include <fcntl.h> > #include <sys/ioctl.h> > @@ -35,6 +36,33 @@ static uint8_t bits = 8; > static uint32_t speed = 500000; > static uint16_t delay; > > +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) > +{ > + int i = 0; > + char *address = (char *)src; If you use "const char *address", you don't need the cast. If you use "const unsigned char *address", one more cast below can be dropped. > + char *line = (char *)address; "const unsigned char *line", and drop the cast. > + unsigned char c; > + > + printf("%s | ", prefix); > + while (length-- > 0) { > + printf("%02X ", (unsigned char)*address++); > @@ -76,12 +104,7 @@ static void transfer(int fd) > if (ret < 1) > pabort("can't send spi message"); > > - for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { > - if (!(ret % 6)) > - puts(""); > - printf("%.2X ", rx[ret]); > - } > - puts(""); > + hexDump(rx, ARRAY_SIZE(tx), 32, "RX"); I know rx and tx have the same size, but please switch to "ARRAY_SIZE(RX)" while at it. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Cleaned hexadecimal dump 2015-03-07 17:56 ` [PATCH 1/4] Cleaned hexadecimal dump Adrian Remonda ` (2 preceding siblings ...) [not found] ` <1425750995-18176-2-git-send-email-adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2015-03-09 18:40 ` Mark Brown 3 siblings, 0 replies; 11+ messages in thread From: Mark Brown @ 2015-03-09 18:40 UTC (permalink / raw) To: Adrian Remonda; +Cc: corbet, linux-spi, linux-doc, linux-kernel [-- Attachment #1: Type: text/plain, Size: 330 bytes --] On Sat, Mar 07, 2015 at 12:56:32PM -0500, Adrian Remonda wrote: > +static void hexDump(const void *src, size_t length, size_t bLine, char *prefix) > +{ Please call this hex_dump or something - that's more in line with the kernel coding style. Please also don't vUse aHungarian nNotation, it's also not the kernel coding style. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-03-09 18:40 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-03-07 17:56 [PATCH 0/4] spi: spidev_test: Added functionalities Adrian Remonda 2015-03-07 17:56 ` [PATCH 1/4] Cleaned hexadecimal dump Adrian Remonda 2015-03-07 17:56 ` [PATCH 2/4] Added verbose output Adrian Remonda 2015-03-07 17:56 ` [PATCH 3/4] Added input buffer from the terminal Adrian Remonda 2015-03-07 17:56 ` [PATCH 4/4] Moved spidev_tools.c to tools/spi Adrian Remonda 2015-03-09 18:38 ` [PATCH 3/4] Added input buffer from the terminal Mark Brown 2015-03-08 2:22 ` [PATCH 1/4] Cleaned hexadecimal dump Joe Perches 2015-03-08 10:53 ` Andy Shevchenko 2015-03-08 16:20 ` Joe Perches [not found] ` <1425750995-18176-2-git-send-email-adrianremonda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2015-03-09 13:51 ` Geert Uytterhoeven 2015-03-09 18:40 ` Mark Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).