Skip to content

Commit

Permalink
documentation: move spidev_fdx example to its own source file
Browse files Browse the repository at this point in the history
Move sample source code to its own source file so that it can be used
easier and build-tested/check/maintained by anyone.

(Makefile changes are in a separate patch for all of Documentation/.)

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Randy Dunlap authored and Linus Torvalds committed Apr 28, 2008
1 parent cf43369 commit 31a1629
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 166 deletions.
168 changes: 2 additions & 166 deletions Documentation/spi/spidev
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ NOTES:
FULL DUPLEX CHARACTER DEVICE API
================================

See the sample program below for one example showing the use of the full
duplex programming interface. (Although it doesn't perform a full duplex
See the spidev_fdx.c sample program for one example showing the use of the
full duplex programming interface. (Although it doesn't perform a full duplex
transfer.) The model is the same as that used in the kernel spi_sync()
request; the individual transfers offer the same capabilities as are
available to kernel drivers (except that it's not asynchronous).
Expand All @@ -141,167 +141,3 @@ and bitrate for each transfer segment.)

To make a full duplex request, provide both rx_buf and tx_buf for the
same transfer. It's even OK if those are the same buffer.


SAMPLE PROGRAM
==============

-------------------------------- CUT HERE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <linux/types.h>
#include <linux/spi/spidev.h>


static int verbose;

static void do_read(int fd, int len)
{
unsigned char buf[32], *bp;
int status;

/* read at least 2 bytes, no more than 32 */
if (len < 2)
len = 2;
else if (len > sizeof(buf))
len = sizeof(buf);
memset(buf, 0, sizeof buf);

status = read(fd, buf, len);
if (status < 0) {
perror("read");
return;
}
if (status != len) {
fprintf(stderr, "short read\n");
return;
}

printf("read(%2d, %2d): %02x %02x,", len, status,
buf[0], buf[1]);
status -= 2;
bp = buf + 2;
while (status-- > 0)
printf(" %02x", *bp++);
printf("\n");
}

static void do_msg(int fd, int len)
{
struct spi_ioc_transfer xfer[2];
unsigned char buf[32], *bp;
int status;

memset(xfer, 0, sizeof xfer);
memset(buf, 0, sizeof buf);

if (len > sizeof buf)
len = sizeof buf;

buf[0] = 0xaa;
xfer[0].tx_buf = (__u64) buf;
xfer[0].len = 1;

xfer[1].rx_buf = (__u64) buf;
xfer[1].len = len;

status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
if (status < 0) {
perror("SPI_IOC_MESSAGE");
return;
}

printf("response(%2d, %2d): ", len, status);
for (bp = buf; len; len--)
printf(" %02x", *bp++);
printf("\n");
}

static void dumpstat(const char *name, int fd)
{
__u8 mode, lsb, bits;
__u32 speed;

if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
perror("SPI rd_mode");
return;
}
if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
perror("SPI rd_lsb_fist");
return;
}
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
perror("SPI bits_per_word");
return;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
perror("SPI max_speed_hz");
return;
}

printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
name, mode, bits, lsb ? "(lsb first) " : "", speed);
}

int main(int argc, char **argv)
{
int c;
int readcount = 0;
int msglen = 0;
int fd;
const char *name;

while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
switch (c) {
case 'm':
msglen = atoi(optarg);
if (msglen < 0)
goto usage;
continue;
case 'r':
readcount = atoi(optarg);
if (readcount < 0)
goto usage;
continue;
case 'v':
verbose++;
continue;
case 'h':
case '?':
usage:
fprintf(stderr,
"usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
argv[0]);
return 1;
}
}

if ((optind + 1) != argc)
goto usage;
name = argv[optind];

fd = open(name, O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}

dumpstat(name, fd);

if (msglen)
do_msg(fd, msglen);

if (readcount)
do_read(fd, readcount);

close(fd);
return 0;
}
158 changes: 158 additions & 0 deletions Documentation/spi/spidev_fdx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <linux/types.h>
#include <linux/spi/spidev.h>


static int verbose;

static void do_read(int fd, int len)
{
unsigned char buf[32], *bp;
int status;

/* read at least 2 bytes, no more than 32 */
if (len < 2)
len = 2;
else if (len > sizeof(buf))
len = sizeof(buf);
memset(buf, 0, sizeof buf);

status = read(fd, buf, len);
if (status < 0) {
perror("read");
return;
}
if (status != len) {
fprintf(stderr, "short read\n");
return;
}

printf("read(%2d, %2d): %02x %02x,", len, status,
buf[0], buf[1]);
status -= 2;
bp = buf + 2;
while (status-- > 0)
printf(" %02x", *bp++);
printf("\n");
}

static void do_msg(int fd, int len)
{
struct spi_ioc_transfer xfer[2];
unsigned char buf[32], *bp;
int status;

memset(xfer, 0, sizeof xfer);
memset(buf, 0, sizeof buf);

if (len > sizeof buf)
len = sizeof buf;

buf[0] = 0xaa;
xfer[0].tx_buf = (__u64) buf;
xfer[0].len = 1;

xfer[1].rx_buf = (__u64) buf;
xfer[1].len = len;

status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
if (status < 0) {
perror("SPI_IOC_MESSAGE");
return;
}

printf("response(%2d, %2d): ", len, status);
for (bp = buf; len; len--)
printf(" %02x", *bp++);
printf("\n");
}

static void dumpstat(const char *name, int fd)
{
__u8 mode, lsb, bits;
__u32 speed;

if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
perror("SPI rd_mode");
return;
}
if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
perror("SPI rd_lsb_fist");
return;
}
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
perror("SPI bits_per_word");
return;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
perror("SPI max_speed_hz");
return;
}

printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
name, mode, bits, lsb ? "(lsb first) " : "", speed);
}

int main(int argc, char **argv)
{
int c;
int readcount = 0;
int msglen = 0;
int fd;
const char *name;

while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
switch (c) {
case 'm':
msglen = atoi(optarg);
if (msglen < 0)
goto usage;
continue;
case 'r':
readcount = atoi(optarg);
if (readcount < 0)
goto usage;
continue;
case 'v':
verbose++;
continue;
case 'h':
case '?':
usage:
fprintf(stderr,
"usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
argv[0]);
return 1;
}
}

if ((optind + 1) != argc)
goto usage;
name = argv[optind];

fd = open(name, O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}

dumpstat(name, fd);

if (msglen)
do_msg(fd, msglen);

if (readcount)
do_read(fd, readcount);

close(fd);
return 0;
}

0 comments on commit 31a1629

Please sign in to comment.