Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <stdio.h>
0003 #include <unistd.h>
0004 #include <stdlib.h>
0005 #include <fcntl.h>
0006 #include <string.h>
0007 
0008 #include <sys/ioctl.h>
0009 #include <sys/types.h>
0010 #include <sys/stat.h>
0011 
0012 #include <linux/types.h>
0013 #include <linux/spi/spidev.h>
0014 
0015 
0016 static int verbose;
0017 
0018 static void do_read(int fd, int len)
0019 {
0020     unsigned char   buf[32], *bp;
0021     int     status;
0022 
0023     /* read at least 2 bytes, no more than 32 */
0024     if (len < 2)
0025         len = 2;
0026     else if (len > sizeof(buf))
0027         len = sizeof(buf);
0028     memset(buf, 0, sizeof buf);
0029 
0030     status = read(fd, buf, len);
0031     if (status < 0) {
0032         perror("read");
0033         return;
0034     }
0035     if (status != len) {
0036         fprintf(stderr, "short read\n");
0037         return;
0038     }
0039 
0040     printf("read(%2d, %2d): %02x %02x,", len, status,
0041         buf[0], buf[1]);
0042     status -= 2;
0043     bp = buf + 2;
0044     while (status-- > 0)
0045         printf(" %02x", *bp++);
0046     printf("\n");
0047 }
0048 
0049 static void do_msg(int fd, int len)
0050 {
0051     struct spi_ioc_transfer xfer[2];
0052     unsigned char       buf[32], *bp;
0053     int         status;
0054 
0055     memset(xfer, 0, sizeof xfer);
0056     memset(buf, 0, sizeof buf);
0057 
0058     if (len > sizeof buf)
0059         len = sizeof buf;
0060 
0061     buf[0] = 0xaa;
0062     xfer[0].tx_buf = (unsigned long)buf;
0063     xfer[0].len = 1;
0064 
0065     xfer[1].rx_buf = (unsigned long) buf;
0066     xfer[1].len = len;
0067 
0068     status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
0069     if (status < 0) {
0070         perror("SPI_IOC_MESSAGE");
0071         return;
0072     }
0073 
0074     printf("response(%2d, %2d): ", len, status);
0075     for (bp = buf; len; len--)
0076         printf(" %02x", *bp++);
0077     printf("\n");
0078 }
0079 
0080 static void dumpstat(const char *name, int fd)
0081 {
0082     __u8    lsb, bits;
0083     __u32   mode, speed;
0084 
0085     if (ioctl(fd, SPI_IOC_RD_MODE32, &mode) < 0) {
0086         perror("SPI rd_mode");
0087         return;
0088     }
0089     if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
0090         perror("SPI rd_lsb_fist");
0091         return;
0092     }
0093     if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
0094         perror("SPI bits_per_word");
0095         return;
0096     }
0097     if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
0098         perror("SPI max_speed_hz");
0099         return;
0100     }
0101 
0102     printf("%s: spi mode 0x%x, %d bits %sper word, %d Hz max\n",
0103         name, mode, bits, lsb ? "(lsb first) " : "", speed);
0104 }
0105 
0106 int main(int argc, char **argv)
0107 {
0108     int     c;
0109     int     readcount = 0;
0110     int     msglen = 0;
0111     int     fd;
0112     const char  *name;
0113 
0114     while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
0115         switch (c) {
0116         case 'm':
0117             msglen = atoi(optarg);
0118             if (msglen < 0)
0119                 goto usage;
0120             continue;
0121         case 'r':
0122             readcount = atoi(optarg);
0123             if (readcount < 0)
0124                 goto usage;
0125             continue;
0126         case 'v':
0127             verbose++;
0128             continue;
0129         case 'h':
0130         case '?':
0131 usage:
0132             fprintf(stderr,
0133                 "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
0134                 argv[0]);
0135             return 1;
0136         }
0137     }
0138 
0139     if ((optind + 1) != argc)
0140         goto usage;
0141     name = argv[optind];
0142 
0143     fd = open(name, O_RDWR);
0144     if (fd < 0) {
0145         perror("open");
0146         return 1;
0147     }
0148 
0149     dumpstat(name, fd);
0150 
0151     if (msglen)
0152         do_msg(fd, msglen);
0153 
0154     if (readcount)
0155         do_read(fd, readcount);
0156 
0157     close(fd);
0158     return 0;
0159 }