1#include <stdio.h> 2#include <unistd.h> 3#include <stdlib.h> 4#include <fcntl.h> 5#include <string.h> 6 7#include <sys/ioctl.h> 8#include <sys/types.h> 9#include <sys/stat.h> 10 11#include <linux/types.h> 12#include <linux/spi/spidev.h> 13 14 15static int verbose; 16 17static void do_read(int fd, int len) 18{ 19 unsigned char buf[32], *bp; 20 int status; 21 22 /* read at least 2 bytes, no more than 32 */ 23 if (len < 2) 24 len = 2; 25 else if (len > sizeof(buf)) 26 len = sizeof(buf); 27 memset(buf, 0, sizeof buf); 28 29 status = read(fd, buf, len); 30 if (status < 0) { 31 perror("read"); 32 return; 33 } 34 if (status != len) { 35 fprintf(stderr, "short read\n"); 36 return; 37 } 38 39 printf("read(%2d, %2d): %02x %02x,", len, status, 40 buf[0], buf[1]); 41 status -= 2; 42 bp = buf + 2; 43 while (status-- > 0) 44 printf(" %02x", *bp++); 45 printf("\n"); 46} 47 48static void do_msg(int fd, int len) 49{ 50 struct spi_ioc_transfer xfer[2]; 51 unsigned char buf[32], *bp; 52 int status; 53 54 memset(xfer, 0, sizeof xfer); 55 memset(buf, 0, sizeof buf); 56 57 if (len > sizeof buf) 58 len = sizeof buf; 59 60 buf[0] = 0xaa; 61 xfer[0].tx_buf = (unsigned long)buf; 62 xfer[0].len = 1; 63 64 xfer[1].rx_buf = (unsigned long) buf; 65 xfer[1].len = len; 66 67 status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer); 68 if (status < 0) { 69 perror("SPI_IOC_MESSAGE"); 70 return; 71 } 72 73 printf("response(%2d, %2d): ", len, status); 74 for (bp = buf; len; len--) 75 printf(" %02x", *bp++); 76 printf("\n"); 77} 78 79static void dumpstat(const char *name, int fd) 80{ 81 __u8 lsb, bits; 82 __u32 mode, speed; 83 84 if (ioctl(fd, SPI_IOC_RD_MODE32, &mode) < 0) { 85 perror("SPI rd_mode"); 86 return; 87 } 88 if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) { 89 perror("SPI rd_lsb_fist"); 90 return; 91 } 92 if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) { 93 perror("SPI bits_per_word"); 94 return; 95 } 96 if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) { 97 perror("SPI max_speed_hz"); 98 return; 99 } 100 101 printf("%s: spi mode 0x%x, %d bits %sper word, %d Hz max\n", 102 name, mode, bits, lsb ? "(lsb first) " : "", speed); 103} 104 105int main(int argc, char **argv) 106{ 107 int c; 108 int readcount = 0; 109 int msglen = 0; 110 int fd; 111 const char *name; 112 113 while ((c = getopt(argc, argv, "hm:r:v")) != EOF) { 114 switch (c) { 115 case 'm': 116 msglen = atoi(optarg); 117 if (msglen < 0) 118 goto usage; 119 continue; 120 case 'r': 121 readcount = atoi(optarg); 122 if (readcount < 0) 123 goto usage; 124 continue; 125 case 'v': 126 verbose++; 127 continue; 128 case 'h': 129 case '?': 130usage: 131 fprintf(stderr, 132 "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n", 133 argv[0]); 134 return 1; 135 } 136 } 137 138 if ((optind + 1) != argc) 139 goto usage; 140 name = argv[optind]; 141 142 fd = open(name, O_RDWR); 143 if (fd < 0) { 144 perror("open"); 145 return 1; 146 } 147 148 dumpstat(name, fd); 149 150 if (msglen) 151 do_msg(fd, msglen); 152 153 if (readcount) 154 do_read(fd, readcount); 155 156 close(fd); 157 return 0; 158} 159