Project

General

Profile

Feature #980 » I2C.cpp

tin, 03/10/2014 06:18 PM

 
1
#include <vector>
2

    
3
using namespace std;
4

    
5
#include "I2C.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[] = { { "I2C", 0, 0, 0, 0, 2, 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

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

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

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

    
60
//static TI2CData I2CData[1];		//found data
61

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

    
68
static int processing_done;
69

    
70

    
71
TVSeqData SeqDataVector;		//vector with results
72

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

    
87
#else
88

    
89
#define LogDebug(...)
90

    
91
#endif
92

    
93

    
94
/*********************************************************
95
		DLL functions
96
*********************************************************/
97

    
98

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

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

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

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

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

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

    
133
	LogDebug(ret, 9, "Initialization finished");
134
	return ret;
135
}
136

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

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

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

    
159
	int last_value=I2C_MASK;	//previous sample
160

    
161

    
162
	TSeqData	SeqData;	//array to hold the new vector element.
163
	TVSeqData::iterator it;
164

    
165
	struct sequence *seqinfo=NULL;
166
	int value, firstseq, lastseq, seq, bitcnt, is_address;
167

    
168
	int sda,scl;
169
	int last_sda,last_scl;
170
	uint32_t i2c_data;
171

    
172
	EI2CState I2CState=I2C_IDLE;
173
	bitcnt=0;
174
	is_address=1;
175
	i2c_data=0;
176

    
177

    
178
	if (pctx == NULL)
179
		{
180
		LogDebug(pctx, 9, "pctx NULL");
181
		return NULL;
182
		}
183

    
184
	if (processing_done==0)
185
		{
186
		processing_done=1;
187

    
188
		//process the input data
189
		firstseq=pctx->func.LAInfo(pctx->lactx, TLA_INFO_FIRST_SEQUENCE, -1);
190
		lastseq=pctx->func.LAInfo(pctx->lactx, TLA_INFO_LAST_SEQUENCE, -1);
191

    
192
		LogDebug(pctx, 9, "initseq: %d, firstseq: %d, last seq: %d", initseq,
193
			firstseq, lastseq);
194

    
195
		//now loop through all the samples
196
		for (seq=firstseq; seq <= lastseq; seq++)
197
			{
198
			value=pctx->func.LAGroupValue(pctx->lactx, seq, 0);
199

    
200
			if (value!=last_value)
201
      	{
202
				//signals have changed
203
				scl=value & I2C_SCL;
204
				sda=value & I2C_SDA;
205

    
206
				LogDebug(pctx, 0, "%s: sequence %d sda: %d scl: %d", __FUNCTION__, seq, sda, scl);
207

    
208
				last_scl=last_value & I2C_SCL;
209
				last_sda=last_value & I2C_SDA;
210

    
211
				switch(I2CState)
212
					{
213
					case I2C_IDLE:
214
						if ((last_sda!=0) && (sda==0) && (scl!=0))
215
							{
216
							//sda goes low while scl=1 -> start condition
217
							memset(&SeqData,0, sizeof(SeqData));
218
							snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "I2C Start");
219
							SeqData.seq_data.flags=2;
220
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
221
							SeqData.seq_number=seq;
222
							SeqDataVector.push_back(SeqData);	//add data to vector
223

    
224
							bitcnt=0;
225
							is_address=1;
226
							i2c_data=0;
227
							I2CState=I2C_DATA;
228
							}
229
						break;
230

    
231
					case I2C_DATA:
232
						if ((last_sda==0) && (sda!=0) && (scl!=0))
233
							{
234
							//stop condition
235
							memset(&SeqData,0, sizeof(SeqData));
236
							snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "I2C Stop");
237
							SeqData.seq_data.flags=4;
238
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
239
							SeqData.seq_number=seq;
240
							SeqDataVector.push_back(SeqData);	//add data to vector
241
							I2CState=I2C_IDLE;
242
							}
243

    
244
						if ((last_sda!=0) && (sda==0) && (scl!=0))
245
							{
246
							//sda goes low while scl=1 -> restart condition
247
							memset(&SeqData,0, sizeof(SeqData));
248
							snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "I2C Start");
249
							SeqData.seq_data.flags=2;
250
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
251
							SeqData.seq_number=seq;
252
							SeqDataVector.push_back(SeqData);	//add data to vector
253

    
254
							is_address=1;
255
							bitcnt=0;
256
							i2c_data=0;
257
							}
258

    
259

    
260
						if ((last_scl==0) && (scl!=0))
261
							{
262
							//rising edge on scl -> data bit
263

    
264
							LogDebug(pctx, 0, "%s: bit %d", __FUNCTION__, bitcnt);
265

    
266
							i2c_data<<=1;	//shift
267
							if (sda!=0) i2c_data|=1;	//shift a 1 in
268

    
269
							bitcnt++;
270
							if (bitcnt>=8)
271
								{
272
								I2CState=I2C_ACK;
273
								}
274
							}
275
						break;
276

    
277
					case I2C_ACK:
278
						if ((last_sda==0) && (sda!=0) && (scl!=0))
279
							{
280
							//stop condition
281
							memset(&SeqData,0, sizeof(SeqData));
282
							snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "I2C Stop");
283
							SeqData.seq_data.flags=4;
284
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
285
							SeqData.seq_number=seq;
286
							SeqDataVector.push_back(SeqData);	//add data to vector
287
							I2CState=I2C_IDLE;
288
							}
289

    
290
						if ((last_scl==0) && (scl!=0))
291
							{
292
							LogDebug(pctx, 0, "%s: ack %d", __FUNCTION__, bitcnt);
293
							//rising edge on scl -> ack bit
294
							if (is_address!=0)
295
								{
296
								//we are in the address phase
297
								if ((i2c_data == 0x92) || (i2c_data == 0x93)) {
298
										snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "%s 0x%02x %s",
299
										i2c_data & 0x01 ? "MCU READ" : "MCU WRITE",
300
										i2c_data & 0xfe,
301
										(sda!=0) ? "NAK" : "ACK");
302
								} else {
303
										snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "%s 0x%02x %s",
304
										i2c_data & 0x01 ? "READ" : "WRITE",
305
										i2c_data & 0xfe,
306
										(sda!=0) ? "NAK" : "ACK");
307
									}
308
								}
309
							else
310
								{
311
								snprintf(SeqData.seq_data.text, sizeof(SeqData.seq_data.text), "DATA 0x%02x %s", i2c_data, (sda!=0) ? "NAK" : "ACK");
312
								}
313
							SeqData.seq_data.flags=8;
314
							LogDebug(pctx, 0, "%s: sequence %s", __FUNCTION__, SeqData.seq_data.text);
315
							SeqData.seq_number=seq;
316
							SeqDataVector.push_back(SeqData);	//add data to vector
317
							is_address=0;
318

    
319
							//reset bitcount and shift reg.
320
							i2c_data=0;
321
							bitcnt=0;
322

    
323
							I2CState=I2C_DATA;
324
							}
325
						break;
326

    
327
					default:
328
						I2CState=I2C_IDLE;
329
						break;
330

    
331
					}
332
				last_value=value;	//save previous value to detect edges
333
      	}
334
			}
335

    
336
		//sort out the text pointers
337
		it=SeqDataVector.begin();
338
		while(it!=SeqDataVector.end())
339
			{
340
			it->seq_data.textp=it->seq_data.text;
341
			it->seq_data.text2=it->seq_data.text2_buf;
342
			it++;
343
			}
344
		}
345

    
346

    
347
	//This could be done smarter if we keep track of the order the LA is
348
	//requesting the sequences. The next item we need is either the next
349
	//or the previous.
350
	it=SeqDataVector.begin();
351
	while( (it!=SeqDataVector.end()) && (seqinfo==NULL))
352
		{
353
		if (it->seq_number==initseq)
354
			{
355
			seqinfo=&(it->seq_data);
356

    
357
			LogDebug(pctx, 9, "%s: seq: %d text: [%s]", __FUNCTION__,
358
					initseq, seqinfo->textp);
359
			}
360
		it++;
361
		}
362

    
363
	return seqinfo;
364
}
365

    
366

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

    
373

    
374
int  ParseMarkSet(struct pctx *pctx, int seq, int a3)
375
{
376
	LogDebug(pctx, 9, "%s", __FUNCTION__);
377
	return 0;
378
}
379

    
380

    
381
int  ParseMarkGet(struct pctx *pctx, int seq)
382
{
383
	LogDebug(pctx, 9, "%s: sequence %d", __FUNCTION__, seq);
384
	return seq;
385
}
386

    
387

    
388
int  ParseMarkMenu(struct pctx *pctx, int seq, int a3, int a4, int a5)
389
{
390
	LogDebug(pctx, 0, "%s: sequence %d, a3: %08x, a4: %08x, a5: %08x", __FUNCTION__, seq, a3, a4, a5);
391
	return 0;
392
}
393

    
394

    
395
int  ParseInfo(struct pctx *pctx, unsigned int request)
396
{
397
	LogDebug(pctx, 6, "%s: %s", __FUNCTION__,
398
		request > ARRAY_SIZE(modeinfo_names) ? "invalid" : modeinfo_names[request]);
399

    
400
	switch(request) {
401
		case MODEINFO_MAX_BUS:
402
			return ARRAY_SIZE(businfo);
403
		case MODEINFO_MAX_GROUP:
404
			return ARRAY_SIZE(groupinfo);
405
		case MODEINFO_GETNAME:
406
			return (int)"I2C";
407
		case 3:
408
			return 1;
409
		case MODEINFO_MAX_MODE:
410
			return 0;	//no modeinfo
411
			//return ARRAY_SIZE(modeinfo);
412
		default:
413
			LogDebug(pctx, 9, "%s: invalid request: %d", __FUNCTION__, request);
414
			return 0;
415
	}	
416
	return 0;
417
}
418

    
419

    
420
struct businfo  *ParseBusInfo(struct pctx *pctx, uint16_t bus)
421
{
422
	LogDebug(pctx, 6, "%s: %08x", __FUNCTION__, bus);
423

    
424
	//This function gets called before parsing sequences after a
425
	//new acquisition so lets use it as a reset for parsing data
426
	SeqDataVector.clear();
427
	processing_done=0;
428

    
429
	if (bus >= ARRAY_SIZE(businfo))
430
		return NULL;
431
	return (struct businfo*) businfo+bus;
432
}
433

    
434

    
435
struct groupinfo  *ParseGroupInfo(struct pctx *pctx, uint16_t group)
436
{
437
	LogDebug(pctx, 9, "%s: %08x", __FUNCTION__, group);
438

    
439
	if (group > ARRAY_SIZE(groupinfo))
440
			return NULL;
441
	return (struct groupinfo*) groupinfo+group;
442
}
443

    
444

    
445
struct modeinfo  *ParseModeInfo(struct pctx *pctx, uint16_t mode)
446
{
447
	LogDebug(pctx, 9, "%s: %d", __FUNCTION__, mode);
448

    
449
	return NULL;	//no modeinfo
450
	/*
451
	if (mode > ARRAY_SIZE(modeinfo))
452
			return NULL;
453
	return (struct modeinfo*) modeinfo+mode;
454
	*/
455
}
456

    
457

    
458
int  ParseModeGetPut(struct pctx *pctx, int mode, int value, int request)
459
{
460
	//int i;
461
	LogDebug(pctx, 9, "%s: mode: %d value: %d request: %d ", __FUNCTION__,
462
			mode, value, request);
463
/*
464
	//mode is an index to the setting
465
	//value is the selected index
466
	//request= 0=read, 1=write, 2=write/read (in that order!)
467

    
468
	//write values?
469
	if ((request == 1) || (request==2))
470
		{
471
		//set values
472
		switch (mode)
473
			{
474
			case 0:
475
				//CPOL setting
476
				set_cpol=value;
477
				break;
478

    
479
			case 1:
480
				//CPHA setting
481
				set_cpha=value;
482
				break;
483

    
484
			case 2:
485
				//SEL setting
486
				set_sel=value;
487
				break;
488

    
489
			case 3:
490
				//bit width setting
491
				if ((value>=0) && (value<ARRAY_SIZE(bit_width_idx)))	//check range
492
					{
493
					set_bits=bit_width_idx[value];
494
					}
495
				break;
496

    
497
			default:
498
				break;
499
			}
500
		}
501

    
502
	//read values?
503
	if ((request == 0) || (request==2))
504
		{
505
		//request=0
506
		//read values
507
		value=0;	//choose default value
508
		switch (mode)
509
			{
510
			case 0:
511
				//CPOL setting
512
				value=set_cpol;
513
				break;
514

    
515
			case 1:
516
				//CPHA setting
517
				value=set_cpha;
518
				break;
519

    
520
			case 2:
521
				//SEL setting
522
				value=set_sel;
523
				break;
524

    
525
			case 3:
526
				//bit width setting
527
				//This one is tricky; we must find the index
528
				for(i=0; i<ARRAY_SIZE(bit_width_idx); i++ )
529
					{
530
					if (bit_width_idx[i]==set_bits)
531
						{
532
						value=i;
533
						break;
534
						}
535
					}
536
				break;
537

    
538
			default:
539
				value=0;
540
				break;
541
			}
542
		}
543
	LogDebug(pctx, 9, "%s: cpol: %d cpha: %d sel: %d bits: %d ", __FUNCTION__,
544
			set_cpol,  set_cpha, set_sel, set_bits);
545

    
546
*/
547
	return 0;
548
	//return value;
549
}
550

    
551

    
552
int  ParseDisasmReinit(struct pctx *pctx, int request)
553
{
554
	//Initialize parsing??
555
	LogDebug(pctx, 9, "%s: pctx %08x, request=%d", __FUNCTION__, pctx, request);
556

    
557
	return 1;
558
}
(1-1/5)