LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [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, broonie, corbet, linux-spi, linux-doc, linux-kernel

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


^ 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	[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	[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	[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	[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
  2015-03-09 13:51   ` Geert Uytterhoeven
  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

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

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

* 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   ` [PATCH 1/4] Cleaned hexadecimal dump Joe Perches
@ 2015-03-09 13:51   ` Geert Uytterhoeven
  2015-03-09 18:40   ` Mark Brown
  3 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, linux-kernel

On Sat, Mar 7, 2015 at 6:56 PM, Adrian Remonda <adrianremonda@gmail.com> 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@linux-m68k.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

^ permalink raw reply	[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
                     ` (2 preceding siblings ...)
  2015-03-09 13:51   ` Geert Uytterhoeven
@ 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
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).