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 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 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).