#include #include #include #include #include #include #include #include #include #define SMALL 2 #define BIG 120 #define NB 3 const int FILL_BYTE = 0xaa; const int RX_BYTE = 0xFF; const unsigned int MAX_LOOPS = 50; struct spi_ioc_transfer xfer[NB]; char rx_header[SMALL]; char rx_buffer[BIG]; char rx_footer[SMALL]; char tx_header[SMALL]; char tx_buffer[BIG]; char tx_footer[SMALL]; void dump(char *buf, unsigned int len) { unsigned int i; for (i = 0; i < len; i++) { printf("%2.2x ", buf[i]); if (((i + 1) % 16) == 0) printf("\n"); } printf("\n"); } /* * Checks if the buffer buf is filled with val bytes * return 0 if it is, 1 if a byte is != val */ int check_buf(char *buf, unsigned int len, unsigned int val) { while (len--) if (buf[len] != RX_BYTE) return 1; return 0; } void usage(const char *progname) { printf("Usage: %s spidev\n", progname); } int main(int argc, char **argv) { const char *spi_dev_name; int err = 0; int fd; unsigned int i; unsigned int loops = MAX_LOOPS; if (argc < 2) { usage(argv[0]); err = -1; goto out; } spi_dev_name = argv[1]; fd = open(spi_dev_name, O_RDWR); if (fd < 0) { perror("open"); err = -1; goto out; } xfer[0].tx_buf = (unsigned long)tx_header; xfer[0].rx_buf = (unsigned long)rx_header; xfer[0].len = SMALL; xfer[1].tx_buf = (unsigned long)tx_buffer; xfer[1].rx_buf = (unsigned long)rx_buffer; xfer[1].len = BIG; xfer[2].tx_buf = (unsigned long)tx_footer; xfer[2].rx_buf = (unsigned long)rx_footer; xfer[2].len = SMALL; while (loops--) { for (i = 0; i < NB; i++) { memset((void *)xfer[i].tx_buf, FILL_BYTE, xfer[i].len); memset((void *)xfer[i].rx_buf, FILL_BYTE, xfer[i].len); } err = ioctl(fd, SPI_IOC_MESSAGE(NB), xfer); if (err < 0) { perror("ioctl"); break; } if (err != (sizeof(rx_buffer) + sizeof(rx_footer) + sizeof(rx_header))) { printf("message too short: %d bytes\n", err); break; } for (i = 0; i < NB; i++) { err = check_buf((char *)(xfer[i].rx_buf), xfer[i].len, RX_BYTE); if (err) dump((char *)(xfer[i].rx_buf), xfer[i].len); } } (void) close(fd); out: return err; }