Project

General

Profile

SPI interface for ADC5560 (MityDSP L138F) » arm_ADS5560.cpp

Vivek Ponnani, 06/30/2017 01:18 PM

 
1
/**
2
 * @file 		arm_ADS5560.cpp
3
 * @author		James Thesing <james.thesing@criticallink.com>
4
 * @version		1.0
5
 *
6
 * @section LICENSE
7
 *
8
 *
9
 *    o  0
10
 *    | /       Copyright (c) 2005-2011
11
 *  (CL)---o   Critical Link, LLC
12
 *    \
13
 *     O
14
 *
15
 *
16
 * @section DESCRIPTION
17
 *
18
 * This class handles exercising the ADS5560 on the ARM. The ARM
19
 * sets up the ADS556- through a SPIDev and then communicates to
20
 * a DSPAPP to collect data over upp. Data collected is written to
21
 * a file "results.dat"
22
 */
23

    
24
#include "dspapp.h"
25
#include <stdio.h>
26
#include <string.h>
27
#include <unistd.h>
28
#include <stdlib.h>
29
#include <sys/types.h>
30
#include <stdint.h>
31
#include <getopt.h>
32
#include <fcntl.h>
33
#include <sys/ioctl.h>
34
#include <linux/types.h>
35
#include <linux/spi/spidev.h>
36

    
37

    
38
#include "ipc_inbound.h"
39
#include "ipc_outbound.h"
40

    
41
using namespace MityDSP;
42

    
43

    
44
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
45

    
46

    
47

    
48
//spidev interface requirements
49
static const char *device = "/dev/spidev1.4";
50
static uint8_t mode;
51
static uint8_t bits = 8;
52
static uint32_t numbytes = 2;
53
static uint32_t speed = 10000000;
54
static uint16_t delay = 0;
55
static uint8_t loopback = 0;
56
static uint32_t loops = 1;
57
static uint8_t tx[2];
58
static uint8_t rx[2];
59

    
60
//point for file IO
61
FILE *fp;
62

    
63

    
64
// Forward declarations
65
int handleInboundMessage(void *Buffer, uint16_t Length, void *UserArg);
66
void SPISetup(int fd);
67
static int transfer( int fd );
68

    
69
volatile bool gbDone = false;
70

    
71
/**
72
 * used to report errors
73
 * @param s char array representing error
74
 */
75
static void pabort(const char *s)
76
{
77
	perror(s);
78
	abort();
79
}
80

    
81
/**
82
 * Initializes spidev
83
 * @param fd int value of spidev
84
 */
85
void SPISetup(int fd)
86
{
87
	int ret;
88
	mode = 0;
89

    
90
	/*
91
		* spi mode
92
		*/
93
		ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
94
		if (ret == -1)
95
			pabort("can't set spi mode");
96

    
97
		ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
98
		if (ret == -1)
99
			pabort("can't get spi mode");
100

    
101
		/*
102
		 * bits per word
103
		 */
104
		ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
105
		if (ret == -1)
106
			pabort("can't set bits per word");
107

    
108
		ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
109
		if (ret == -1)
110
			pabort("can't get bits per word");
111

    
112
		/*
113
		 * max speed hz
114
		 */
115
		ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
116
		if (ret == -1)
117
			pabort("can't set max speed hz");
118

    
119
		ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
120
		if (ret == -1)
121
			pabort("can't get max speed hz");
122

    
123
		printf("spi mode: %d\n", mode);
124
		printf("bits per word: %d\n", bits);
125
		printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
126
}
127

    
128
/**
129
 * Sends a packet of data through a spi dev
130
 * @param fd int value of spidev
131
 * @return -1 on failure/ 0 on success
132
 *
133
 */
134
static int transfer(int fd)
135
{
136
	int ret, rv = 0;
137
	uint8_t rx[ARRAY_SIZE(tx)];
138

    
139
	struct spi_ioc_transfer tr;
140
	tr.tx_buf = (unsigned long)tx;
141
	tr.rx_buf = (unsigned long)rx;
142
	tr.len = numbytes;
143
	tr.delay_usecs = delay;
144
	tr.speed_hz = speed;
145
	tr.bits_per_word = bits;
146

    
147
	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
148

    
149
	if (ret == 1)
150
		pabort("can't send spi message");
151

    
152
	for (ret = 0; ret < numbytes; ret++) {
153
		if (loopback && (tx[ret] != rx[ret]))
154
		{
155
			rv = -1;
156
			break;
157
		}
158
	}
159

    
160
	if (rv)
161
		printf("ERROR DETECTED IN RECEIVE STREAM\n");
162

    
163
	return rv;
164
}
165
/**
166
 * main routine for ARM. Initializes SPI, creates DSP link,
167
 * starts communitcation to DSP, and writes return data to file
168
 */
169
int main(int argc, char* argv[])
170
{
171
	fp = fopen("results.dat", "w");
172
	int fd, i, ret;
173

    
174
	if (fp == NULL)
175
	{
176
		printf("I couldn't open results.dat for writing.\n");
177
	    exit(0);
178
	}
179
	fd = open(device, O_RDWR);
180
	SPISetup(fd);
181

    
182
	// tcDspApp class for booting and loading the DSP
183
	tcDspApp* 		lpDspApp = NULL;
184
	// Used to setup handling of inbound messages from DSP
185
	tcIPCInbound* 	lpMessageInbound  = NULL;
186
	// Used to send messages to the DSP
187
	tcIPCOutbound* 	lpMessageOutbound  = NULL;
188
	// Message to send to the DSP
189
	char			lpMessage[] = "Convert";
190
	// Pointer to buffer obtained from dsplink
191
	char*			lpMessageBuffer = NULL;
192

    
193

    
194
	// Check application usage
195
	if (argc < 2)
196
	{
197
		printf("usage: <ADS5560.out>\n");
198
		return -1;
199
	}
200

    
201
	// Create the DspApp object
202
	printf("Creating DSPApp object.\n");
203
	lpDspApp = new tcDspApp();
204

    
205
	// Load the DSP.out file
206
	printf("Loading file %s\n", argv[1]);
207
	lpDspApp->LoadApp(argv[1]);
208

    
209
	printf("Starting application.\n");
210

    
211
	// Create the object to handle incoming messages from the DSP
212
	lpMessageInbound =  new tcIPCInbound((char*)"GPPMSGQ1");
213

    
214
	if (NULL != lpMessageInbound)
215
	{
216
		// Register the callback for handling messages from the DSP
217
		lpMessageInbound->Register(handleInboundMessage, (void*)NULL);
218

    
219
		// Intiailize the inbound controller to create the thread that handles the callbacks
220
		lpMessageInbound->Initialize();
221
	}
222

    
223
	// Create the object used to send messages to the DSP
224
	lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
225

    
226
	// Wait for the DSP to finish initialization
227
	while(false == gbDone);
228

    
229

    
230
	// Reset bool in prep for next receive message from DSP
231
	gbDone = false;
232

    
233
	//software reset of ADC
234
	tx[0] = 0x6e;
235
	tx[1] = 0x01;
236
	for (i = 1; i <= loops; i++)
237
		{
238
			ret = transfer(fd);
239
			if (ret) {
240
				printf("Failed after %d cycles\n",i);
241
				break;
242
			}
243
			if (!(i % 10))
244
				printf(".");
245
			if (!(i % 400))
246
				printf("\n");
247
		}
248
	//test pattern
249
	/*
250
	//tx[0] = 0x65;
251
	//tx[1] = 0x20; //all 1's
252
	//tx[1] = 0x40; //all 0's
253
	//Stx[1] = 0x60; //toggle 1/0
254
	//tx[1] = 0x80; //ramp 0x0000 -> 0xFFFF
255

    
256
	for (i = 1; i <= loops; i++)
257
		{
258
			ret = transfer(fd);
259
			if (ret) {
260
				printf("Failed after %d cycles\n",i);
261
				break;
262
			}
263
			if (!(i % 10))
264
				printf(".");
265
			if (!(i % 400))
266
				printf("\n");
267
		}
268
	 */
269
	// Get a buffer for a message to the DSP
270
	lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(strlen(lpMessage)+1);
271

    
272
	// Copy the message to the dsplink buffer
273
	strcpy(lpMessageBuffer, lpMessage);
274

    
275
	/*unsigned short *ptr = ( unsigned short* )0x66000202;
276
	*ptr =  1;
277
	printf ("the value of 0x66000202 is: %d\n", *ptr);*/
278

    
279
	// Send the message to the DSP
280
	printf("Sending a message to the DSP to start receive.\n");
281
	lpMessageOutbound->SendMessage(lpMessageBuffer);
282

    
283
	// Wait for a message to be received from the DSP or for user to quit
284

    
285
	printf("Waiting for DSP response (type \'q\' to quit)...\n");
286
	while(!gbDone){}
287

    
288
	printf("Exiting application.\n");
289

    
290
	// Stop the DSP application from running
291
	lpDspApp->StopApp();
292

    
293

    
294
	// Cleanup
295
	delete lpDspApp;
296
	delete lpMessageInbound;
297
	delete lpMessageOutbound;
298
	fclose(fp);
299

    
300
	return 0;
301
}
302

    
303
/**
304
 *	Handle inbound messages from the DSP.
305
 *
306
 *	@param apBuffer		Pointer to the buffer containing the message.
307
 *	@param anLength 	The length of the message.
308
 *	@param apUserArg	User defined argument.
309
 *
310
 *	\return 0.
311
 */
312
int handleInboundMessage(void *apBuffer, uint16_t anLength, void *apUserArg)
313
{
314

    
315
    printf("size of buffer is: %d\n", anLength);
316
	if (anLength > 1000){
317
		for( int i = 0; i < 32000; i++ )
318
		{
319
			fprintf( fp, "%d\n", ((int16_t*)apBuffer)[i] );
320
			//printf( "Value %d is : %d\n", i, ((int16_t*)apBuffer)[i] );
321

    
322
		}
323
		return 0;
324
	}
325
	else
326
	{
327

    
328
	printf("ARM received a message from the DSP:\n");
329

    
330
	// Print the message we received
331
	printf("\tDSP Message = \"%s\"\n", (char *)apBuffer);
332

    
333
	// Notify the main function that we have received a message from the DSP and are done
334
	gbDone = true;
335

    
336
	}
337
	return 0;
338
}
339

    
340

    
341

    
342

    
343

    
344

    
(1-1/3) Go to top
Add picture from clipboard (Maximum size: 1 GB)