Project

General

Profile

RE: SPI Comm - can transmit data from Linux, but not receive ยป spidev_test.c

Michael Williamson, 03/13/2017 05:17 PM

 
1
/*
2
 * SPI testing utility (using spidev driver)
3
 *
4
 * Copyright (c) 2011  Critical Link LLC
5
 * 
6
 * This code is based on the software from the following:
7
 *
8
 * Copyright (c) 2007  MontaVista Software, Inc.
9
 * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License.
14
 *
15
 * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
16
 */
17

    
18
#include <sys/types.h>
19
#include <stdint.h>
20
#include <unistd.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <getopt.h>
24
#include <fcntl.h>
25
#include <sys/ioctl.h>
26
#include <linux/types.h>
27
#include <linux/spi/spidev.h>
28
#include <unistd.h>
29

    
30

    
31
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
32

    
33
static void pabort(const char *s)
34
{
35
	perror(s);
36
	abort();
37
}
38

    
39
static const char *device = "/dev/spidev1.1";
40
static uint8_t mode;
41
static uint8_t bits = 8;
42
static uint32_t numbytes = 38;
43
static uint32_t speed = 500000;
44
static uint16_t delay;
45
static uint8_t loopback = 0;
46
static uint32_t loops = 1;
47
static uint8_t quiet = 0;
48

    
49
static int transfer(int fd)
50
{
51
	int ret, i, rv = 0;
52
	uint8_t tx[512];
53
	uint8_t rx[ARRAY_SIZE(tx)];
54
	struct spi_ioc_transfer tr = {
55
		.tx_buf = (unsigned long)tx,
56
		.rx_buf = (unsigned long)rx,
57
		.len = numbytes,
58
		.delay_usecs = delay,
59
		.speed_hz = speed,
60
		.bits_per_word = bits,
61
	};
62

    
63
	for (i = 0; i < ARRAY_SIZE(tx); i++)
64
	{
65
		tx[i] = i&0x0FF;
66
		rx[i] = ~tx[i];
67
	}
68

    
69
	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
70
	if (ret == 1)
71
		pabort("can't send spi message");
72

    
73
	for (ret = 0; ret < numbytes; ret++) {
74
		if (loopback && (tx[ret] != rx[ret]))
75
		{
76
			rv = -1;
77
			break;
78
		}
79
	}
80

    
81
	if (!quiet || rv) 
82
	{
83
		for (ret = 0; ret < numbytes; ret++) {
84
			if (!(ret % 8))
85
				puts("");
86
			printf("%.2X ", rx[ret]);
87
		}
88
		puts("");
89
	}
90

    
91
	if (rv)
92
		printf("ERROR DETECTED IN RECEIVE STREAM\n");
93

    
94
	return rv;
95
}
96

    
97
static void print_usage(const char *prog)
98
{
99
	printf("Usage: %s [-DsqrbndlHOLC3]\n", prog);
100
	puts("  -D --device   device to use (default /dev/spidev1.1)\n"
101
	     "  -s --speed    max speed (Hz)\n"
102
	     "  -d --delay    delay (usec)\n"
103
	     "  -b --bpw      bits per word \n"
104
	     "  -l --loop     loopback\n"
105
	     "  -r --repeat   number of cycles to repeat\n"
106
	     "  -H --cpha     clock phase\n"
107
	     "  -O --cpol     clock polarity\n"
108
	     "  -L --lsb      least significant bit first\n"
109
	     "  -C --cs-high  chip select active high\n"
110
	     "  -n --numbytes number of bytes to send\n"
111
	     "  -q --quiet    don't display results\n"
112
	     "  -3 --3wire    SI/SO signals shared\n");
113
	exit(1);
114
}
115

    
116
static void parse_opts(int argc, char *argv[])
117
{
118
	while (1) {
119
		static const struct option lopts[] = {
120
			{ "device",  1, 0, 'D' },
121
			{ "speed",   1, 0, 's' },
122
			{ "delay",   1, 0, 'd' },
123
			{ "bpw",     1, 0, 'b' },
124
			{ "numbytes",1, 0, 'n' },
125
			{ "repeat",  1, 0, 'r' },
126
			{ "loop",    0, 0, 'l' },
127
			{ "cpha",    0, 0, 'H' },
128
			{ "cpol",    0, 0, 'O' },
129
			{ "lsb",     0, 0, 'L' },
130
			{ "cs-high", 0, 0, 'C' },
131
			{ "3wire",   0, 0, '3' },
132
			{ "no-cs",   0, 0, 'N' },
133
			{ "ready",   0, 0, 'R' },
134
			{ "quiet",   0, 0, 'q' },
135
			{ NULL, 0, 0, 0 },
136
		};
137
		int c;
138

    
139
		c = getopt_long(argc, argv, "D:s:d:b:n:r:lqHOLC3NR", lopts, NULL);
140

    
141
		if (c == -1)
142
			break;
143

    
144
		switch (c) {
145
		case 'D':
146
			device = optarg;
147
			break;
148
		case 's':
149
			speed = atoi(optarg);
150
			break;
151
		case 'd':
152
			delay = atoi(optarg);
153
			break;
154
		case 'b':
155
			bits = atoi(optarg);
156
			break;
157
		case 'r':
158
			loops = atoi(optarg);
159
			if (loops <= 0) loops = 1;
160
			printf("running %d loops\n", loops);
161
			break;
162
		case 'n':
163
			numbytes = atoi(optarg);
164
			if (numbytes <= 0) numbytes = 38;
165
			if (numbytes > 512) numbytes = 512;
166
			break;
167
		case 'l':
168
			mode |= SPI_LOOP;
169
			loopback = 1;
170
			break;
171
		case 'H':
172
			mode |= SPI_CPHA;
173
			break;
174
		case 'O':
175
			mode |= SPI_CPOL;
176
			break;
177
		case 'L':
178
			mode |= SPI_LSB_FIRST;
179
			break;
180
		case 'C':
181
			mode |= SPI_CS_HIGH;
182
			break;
183
		case '3':
184
			mode |= SPI_3WIRE;
185
			break;
186
		case 'N':
187
			mode |= SPI_NO_CS;
188
			break;
189
		case 'R':
190
			mode |= SPI_READY;
191
			break;
192
		case 'q':
193
			quiet = 1;
194
			break;
195
		default:
196
			print_usage(argv[0]);
197
			break;
198
		}
199
	}
200
}
201

    
202
int main(int argc, char *argv[])
203
{
204
	int ret = 0;
205
	int fd, i;
206

    
207
	parse_opts(argc, argv);
208

    
209
	fd = open(device, O_RDWR);
210
	if (fd < 0)
211
		pabort("can't open device");
212

    
213
	/*
214
	 * spi mode
215
	 */
216
	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
217
	if (ret == -1)
218
		pabort("can't set spi mode");
219

    
220
	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
221
	if (ret == -1)
222
		pabort("can't get spi mode");
223

    
224
	/*
225
	 * bits per word
226
	 */
227
	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
228
	if (ret == -1)
229
		pabort("can't set bits per word");
230

    
231
	ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
232
	if (ret == -1)
233
		pabort("can't get bits per word");
234

    
235
	/*
236
	 * max speed hz
237
	 */
238
	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
239
	if (ret == -1)
240
		pabort("can't set max speed hz");
241

    
242
	ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
243
	if (ret == -1)
244
		pabort("can't get max speed hz");
245

    
246
	printf("spi mode: %d\n", mode);
247
	printf("bits per word: %d\n", bits);
248
	printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
249

    
250
	for (i = 1; i <= loops; i++)
251
	{
252
		ret = transfer(fd);
253
		if (ret) {
254
			printf("Failed after %d cycles\n",i);
255
			break;
256
		}
257
		if (!(i % 10))
258
			printf(".");	
259
		if (!(i % 400))
260
			printf("\n");
261
	}
262

    
263
	if (!ret)
264
		printf("%d cycles run\n", i-1);
265

    
266
	close(fd);
267

    
268
	return ret;
269
}
    (1-1/1)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)