Project

General

Profile

Feature #981 » SPI.cpp

tin, 03/10/2014 06:20 PM

 
1
#include <vector>
2

    
3
using namespace std;
4

    
5
#include "SPI.h"
6
#include <stdbool.h>
7
#include <stdio.h>
8
#include <fcntl.h>
9
#include <io.h>
10
#include <stdarg.h>
11
#include <windows.h>
12
#include <time.h>
13
#include <errno.h>
14

    
15

    
16
//#define WITH_DEBUG
17

    
18
/*********************************************************
19
		Globals signal setup
20
*********************************************************/
21

    
22

    
23
static FILE *logfile = NULL;
24

    
25

    
26
const char *modeinfo_names[MODEINFO_MAX] = {
27
	"MAX_BUS",
28
	"MAX_GROUP",
29
	"MAX_MODE",
30
	"3",
31
	"GETNAME"
32
};
33

    
34

    
35
const int bustable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
36

    
37
//Define groups (4 signals)
38
const struct groupinfo groupinfo[] = { { "SPI", 0, 0, 0, 0, 4, 0 },
39
                                 { "Traffic" , 0, 0, 2, 1, 0x80, sizeof("Traffic")-1 } };
40

    
41
const struct businfo businfo[] = { { 0, 0, 0, 0, 0, 0x20000, NULL, 0 } };
42

    
43
//Define settings
44
const char *onoff[] = { "0", "1", NULL, NULL };
45
const char *sel_mode[] = { "LOW", "HIGH", "Don't care", NULL };
46
const char *bit_widths[]={"4", "5", "6", "7", "8", "9","10","11","12","13","14","15","16", NULL};
47
const char *btit_widths[]={"4", "5", "6", "7", "8", "9","10","11","12","13","14","15","16", NULL};
48

    
49
const struct modeinfo modeinfo[] = { { "CPOL", onoff, 0, 1 },
50
																{ "CPHA", onoff, 0, 1 },
51
																{ "SEL", sel_mode, 0, 2 },
52
																{ "BITS", bit_widths, 0, 12 }};
53

    
54
/*********************************************************
55
		SPI analysis data
56
*********************************************************/
57

    
58
//aray to translate between settings and bit width
59
const int bit_width_idx[]={4,5,6,7,8,9,10,11,12,13,14,15,16};
60

    
61
static TSPIData SPIData[1];		//found data
62

    
63
//settings
64
static int set_cpol;
65
static int set_cpha;
66
static int set_sel;
67
static int set_bits;		//how many bits are in one sequence
68

    
69
static int processing_done;
70

    
71

    
72
TVSeqData SeqDataVector;		//vector with results
73

    
74
/*********************************************************
75
		Helpers
76
*********************************************************/
77
#ifdef WITH_DEBUG
78
static void LogDebug(struct pctx *pctx, int level, const char *fmt, ...)
79
{
80
        char buf[4096];
81
	va_list ap;
82
        va_start(ap, fmt);
83
        vsnprintf(buf, sizeof(buf), fmt, ap);
84
        va_end(ap);
85
        OutputDebugString(buf);
86
}
87

    
88
#else
89

    
90
#define LogDebug(...)
91

    
92
#endif
93

    
94

    
95
/*********************************************************
96
		DLL functions
97
*********************************************************/
98

    
99

    
100
struct pctx  *ParseReinit(struct pctx *pctx, struct lactx *lactx, struct lafunc *func)
101
{
102
	//Called upon DLL startup and refreshing the data
103
	struct pctx *ret;
104

    
105
	SeqDataVector.clear();
106
	processing_done=0;
107

    
108
	//Check if already initialized
109
	if (pctx!=NULL)
110
		{
111
		return pctx;	//already initialized -> exit
112
		}
113

    
114
	if (!(ret=(struct pctx*) func->rda_calloc(1, sizeof(struct pctx))))
115
		{
116
		func->LAError(0, 9, "Out of Memory");
117
		return NULL;
118
		}
119

    
120
	ret->lactx=lactx;
121
	ret->func.LAGroupValue=func->LAGroupValue;
122
	ret->func.rda_calloc=func->rda_calloc;
123
	ret->func.rda_free=func->rda_free;
124
	ret->func.LAInfo=func->LAInfo;
125

    
126
	//defaults
127
	set_cpol=0;
128
	set_cpha=0;
129
	set_sel=2;
130
	set_bits=8;
131
	SeqDataVector.clear();
132
	processing_done=0;
133

    
134
	LogDebug(ret, 0, "Initialization finished");
135
	return ret;
136
}
137

    
138

    
139
int  ParseExtInfo_(struct pctx *pctx)
140
{
141
	LogDebug(pctx, 0, "%s", __FUNCTION__);
142
	return 0;
143
}
144

    
145
int  ParseFinish(struct pctx *pctx)
146
{
147
	LogDebug(pctx, 0, "%s", __FUNCTION__);
148
	SeqDataVector.clear();
149
	pctx->func.rda_free(pctx);
150
	return 0;
151
}
152

    
153
struct sequence *ParseSeq(struct pctx *pctx, int initseq)
154
{
155
	//This function is called for each data sample. The sample
156
	//is identified by initseq. The order is more or less random.
157
	//When this function is called for the first time, all data
158
	//is procesed and stored in a vector. After that the
159
	//information is read from the vector.
160

    
161
	bool sel_active; //true when select signal is used
162
	bool clock_pos; //true when pos. edge of clk is used
163
	int sel_mask; //XOR mask for sel signal
164
	int last_data=0;	//previous sample
165

    
166

    
167
	TSeqData	SeqData;	//array to hold the new vector element.
168
	TVSeqData::iterator it;
169

    
170
	struct sequence *seqinfo=NULL;
171
	int value, firstseq, lastseq, seq;
172

    
173
	if (pctx == NULL)
174
		{
175
		LogDebug(pctx, 0, "pctx NULL");
176
		return NULL;
177
		}
178

    
179
	if (processing_done==0)
180
		{
181
		processing_done=1;
182

    
183
		//process the input data
184
		firstseq=pctx->func.LAInfo(pctx->lactx, TLA_INFO_FIRST_SEQUENCE, -1);
185
		lastseq=pctx->func.LAInfo(pctx->lactx, TLA_INFO_LAST_SEQUENCE, -1);
186

    
187
		LogDebug(pctx, 0, "initseq: %d, firstseq: %d, last seq: %d", initseq,
188
			firstseq, lastseq);
189
		snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "init %d, first %d, last %d", initseq, firstseq, lastseq);
190

    
191

    
192
		//First determine the settings
193
		//is sel don't care?
194
		sel_mask=0;
195
		if (set_sel == 2)
196
			{
197
			sel_active=false;
198
			sel_mask=0xff;
199
			LogDebug(pctx, 0, "SEL not active");
200
			snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "SEL not active");
201
			}
202
		else
203
			{
204
			sel_active=true;
205
			LogDebug(pctx, 0, "SEL active");
206
			snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "SEL active");
207

    
208
			if (set_sel == 0)
209
				{
210
				sel_mask=0;
211
				}
212
			else
213
				{
214
				sel_mask=SPI_SEL;
215
				}
216
			}
217

    
218
		//determine clock edge
219
		if ((set_cpol ^ set_cpha) == 0)
220
			{
221
			clock_pos=true;
222
			}
223
		else
224
			{
225
			clock_pos=false;
226
			}
227

    
228
		memset(SPIData, 0, sizeof(SPIData));	//initialise analyses data
229

    
230
		//now loop through all the samples
231
		for (seq=firstseq; seq <= lastseq; seq++)
232
			{
233
			value=pctx->func.LAGroupValue(pctx->lactx, seq, 0);
234

    
235

    
236
			if ((sel_active == false) || ((value & SPI_SEL) == sel_mask) )
237
				{
238
				LogDebug(pctx, 9, "%s seg: %d value %x", __FUNCTION__, seq, value);
239
				LogDebug(pctx, 9, "%s: decode", __FUNCTION__);
240
		    		snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "%s decode", __FUNCTION__);
241
				//we must decode this
242
				if ((value & SPI_CLK) != (last_data & SPI_CLK))
243
					{
244
					//we have a clock edge
245
					if ((((value & SPI_CLK) != 0) && (clock_pos == true)) || (((value
246
							& SPI_CLK) == 0) && (clock_pos == false)))
247
						{
248

    
249
						LogDebug(pctx, 9, "%s: clock", __FUNCTION__);
250

    
251
						//shift data
252
						if (SPIData[0].bit_count == 0)
253
							{
254
							SPIData[0].sequence=seq; //mark beginning
255
							}
256
						SPIData[0].miso_data<<=1;
257
						SPIData[0].mosi_data<<=1;
258

    
259
						if ((value & SPI_MISO) != 0)
260
							{
261
							SPIData[0].miso_data|=1;
262
							}
263
						if ((value & SPI_MOSI) != 0)
264
							{
265
							SPIData[0].mosi_data|=1;
266
							}
267

    
268
						SPIData[0].bit_count++;
269
						if (SPIData[0].bit_count == set_bits)
270
							{
271
							//we have a complete frame!
272
							SPIData[0].bit_count=0; //reset bit count
273
							LogDebug(pctx, 9, "%s: got data %x", __FUNCTION__,
274
									SPIData[0].mosi_data);
275

    
276
							//create information element
277
							memset(&SeqData,0, sizeof(SeqData));
278

    
279

    
280
							snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "MISO %X MOSI %X",
281
									SPIData[0].miso_data, SPIData[0].mosi_data);
282
							SeqData.seq_data.flags=1;
283
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
284
							SeqData.seq_number=SPIData[0].sequence;
285

    
286
							SeqDataVector.push_back(SeqData);	//add data to vector
287

    
288
							SPIData[0].miso_data=0;
289
							SPIData[0].mosi_data=0;
290
							}
291
						}
292

    
293
					}
294
				}
295
			else
296
				{
297
				//Create an event if there are less than the required number
298
				//of bits during the active phase of select.
299
				if ((sel_active==true) && (SPIData[0].bit_count>0))
300
					{
301
					snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "MISO %X MOSI %X",
302
								SPIData[0].miso_data, SPIData[0].mosi_data);
303
					SeqData.seq_data.flags=4;	//make it red!
304
					LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
305
					SeqData.seq_number=SPIData[0].sequence;
306

    
307
					SeqDataVector.push_back(SeqData);	//add data to vector
308

    
309
					}
310

    
311
			//reset bit count
312
				SPIData[0].bit_count=0; //reset bit count
313
				SPIData[0].miso_data=0;
314
				SPIData[0].mosi_data=0;
315

    
316
				}
317
			last_data=value;	//save previous value to detect edges
318

    
319
			}
320

    
321
		//sort out the text pointers
322
		it=SeqDataVector.begin();
323
		while(it!=SeqDataVector.end())
324
			{
325
			it->seq_data.textp=it->seq_data.text;
326
			it->seq_data.text2=it->seq_data.text2_buf;
327
			it++;
328
			}
329
		}
330

    
331

    
332
	//This could be done smarter if we keep track of the order the LA is
333
	//requesting the sequences. The next item we need is either the next
334
	//or the previous.
335
	it=SeqDataVector.begin();
336
	while( (it!=SeqDataVector.end()) && (seqinfo==NULL))
337
		{
338
		if (it->seq_number==initseq)
339
			{
340
			seqinfo=&(it->seq_data);
341

    
342
			LogDebug(pctx, 9, "%s: seq: %d text: [%s]", __FUNCTION__,
343
					initseq, seqinfo->textp);
344
			}
345
		it++;
346
		}
347

    
348
	return seqinfo;
349
}
350

    
351

    
352
int  ParseMarkNext(struct pctx *pctx, int seq, int a3)
353
{
354
	LogDebug(pctx, 9, "%s: sequence %d, a3 %d", __FUNCTION__, seq, a3);
355
	return 0;
356
}
357

    
358

    
359
int  ParseMarkSet(struct pctx *pctx, int seq, int a3)
360
{
361
	LogDebug(pctx, 9, "%s", __FUNCTION__);
362
	return 0;
363
}
364

    
365

    
366
int  ParseMarkGet(struct pctx *pctx, int seq)
367
{
368
	LogDebug(pctx, 9, "%s: sequence %d", __FUNCTION__, seq);
369
	return seq;
370
}
371

    
372

    
373
int  ParseMarkMenu(struct pctx *pctx, int seq, int a3, int a4, int a5)
374
{
375
	LogDebug(pctx, 0, "%s: sequence %d, a3: %08x, a4: %08x, a5: %08x", __FUNCTION__, seq, a3, a4, a5);
376
	return 0;
377
}
378

    
379

    
380
int  ParseInfo(struct pctx *pctx, unsigned int request)
381
{
382
	LogDebug(pctx, 6, "%s: %s", __FUNCTION__,
383
		request > ARRAY_SIZE(modeinfo_names) ? "invalid" : modeinfo_names[request]);
384

    
385
	switch(request) {
386
		case MODEINFO_MAX_BUS:
387
			return ARRAY_SIZE(businfo);
388
		case MODEINFO_MAX_GROUP:
389
			return ARRAY_SIZE(groupinfo);
390
		case MODEINFO_GETNAME:
391
			return (int)"SPI";
392
		case 3:
393
			return 1;
394
		case MODEINFO_MAX_MODE:
395
			return ARRAY_SIZE(modeinfo);
396
		default:
397
			LogDebug(pctx, 9, "%s: invalid request: %d", __FUNCTION__, request);
398
			return 0;
399
	}	
400
	return 0;
401
}
402

    
403

    
404
struct businfo  *ParseBusInfo(struct pctx *pctx, uint16_t bus)
405
{
406
	LogDebug(pctx, 6, "%s: %08x", __FUNCTION__, bus);
407

    
408
	//This function gets called before parsing sequences after a
409
	//new acquisition so lets use it as a reset for parsing data
410
	SeqDataVector.clear();
411
	processing_done=0;
412

    
413
	if (bus >= ARRAY_SIZE(businfo))
414
		return NULL;
415
	return (struct businfo*) businfo+bus;
416
}
417

    
418

    
419
struct groupinfo  *ParseGroupInfo(struct pctx *pctx, uint16_t group)
420
{
421
	LogDebug(pctx, 9, "%s: %08x", __FUNCTION__, group);
422

    
423
	if (group > ARRAY_SIZE(groupinfo))
424
			return NULL;
425
	return (struct groupinfo*) groupinfo+group;
426
}
427

    
428

    
429
struct modeinfo  *ParseModeInfo(struct pctx *pctx, uint16_t mode)
430
{
431
	LogDebug(pctx, 9, "%s: %d", __FUNCTION__, mode);
432
	if (mode > ARRAY_SIZE(modeinfo))
433
			return NULL;
434
	return (struct modeinfo*) modeinfo+mode;
435
}
436

    
437

    
438
int  ParseModeGetPut(struct pctx *pctx, int mode, int value, int request)
439
{
440
	int i;
441
	LogDebug(pctx, 9, "%s: mode: %d value: %d request: %d ", __FUNCTION__,
442
			mode, value, request);
443

    
444
	//mode is an index to the setting
445
	//value is the selected index
446
	//request= 0=read, 1=write, 2=write/read (in that order!)
447

    
448
	//write values?
449
	if ((request == 1) || (request==2))
450
		{
451
		//set values
452
		switch (mode)
453
			{
454
			case 0:
455
				//CPOL setting
456
				set_cpol=value;
457
				break;
458

    
459
			case 1:
460
				//CPHA setting
461
				set_cpha=value;
462
				break;
463

    
464
			case 2:
465
				//SEL setting
466
				set_sel=value;
467
				break;
468

    
469
			case 3:
470
				//bit width setting
471
				if ((value>=0) && (value<ARRAY_SIZE(bit_width_idx)))	//check range
472
					{
473
					set_bits=bit_width_idx[value];
474
					}
475
				break;
476

    
477
			default:
478
				break;
479
			}
480
		}
481

    
482
	//read values?
483
	if ((request == 0) || (request==2))
484
		{
485
		//request=0
486
		//read values
487
		value=0;	//choose default value
488
		switch (mode)
489
			{
490
			case 0:
491
				//CPOL setting
492
				value=set_cpol;
493
				break;
494

    
495
			case 1:
496
				//CPHA setting
497
				value=set_cpha;
498
				break;
499

    
500
			case 2:
501
				//SEL setting
502
				value=set_sel;
503
				break;
504

    
505
			case 3:
506
				//bit width setting
507
				//This one is tricky; we must find the index
508
				for(i=0; i<ARRAY_SIZE(bit_width_idx); i++ )
509
					{
510
					if (bit_width_idx[i]==set_bits)
511
						{
512
						value=i;
513
						break;
514
						}
515
					}
516
				break;
517

    
518
			default:
519
				value=0;
520
				break;
521
			}
522
		}
523
	LogDebug(pctx, 9, "%s: cpol: %d cpha: %d sel: %d bits: %d ", __FUNCTION__,
524
			set_cpol,  set_cpha, set_sel, set_bits);
525

    
526

    
527
	return value;
528
}
529

    
530

    
531
int  ParseDisasmReinit(struct pctx *pctx, int request)
532
{
533
	//Initialize parsing??
534
	LogDebug(pctx, 9, "%s: pctx %08x, request=%d", __FUNCTION__, pctx, request);
535

    
536
	return 1;
537
}
(1-1/7)