blob: df3fdd9e771134bd82ae43610960ed140f40f604 [file] [log] [blame]
Stefan Reinauerc566d202015-08-25 09:52:42 -07001/*
2 * Copyright 2012-2015 Google Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
Stefan Reinauerc566d202015-08-25 09:52:42 -070012 */
13
14#include <stdio.h>
15#include <string.h>
16#include "em100.h"
17
18/* SPI Trace related operations */
19
20/**
21 * reset_spi_trace: clear SPI trace buffer
22 * @param em100: em100 device structure
23 *
24 * out(16 bytes): 0xbd 0 .. 0
25 */
26int reset_spi_trace(struct em100 *em100)
27{
28 unsigned char cmd[16];
29 memset(cmd, 0, 16);
30 cmd[0] = 0xbd; /* reset SPI trace buffer*/
31 if (!send_cmd(em100->dev, cmd)) {
32 return 0;
33 }
34 return 1;
35}
36
37/**
38 * read_spi_trace: fetch SPI trace data
39 * @param em100: em100 device structure
40 * globals: curpos, counter, cmdid
41 *
42 * out(16 bytes): bc 00 00 00 08 00 00 00 00 15 00 00 00 00 00 00
43 * in(8x8192 bytes): 2 bytes (BE) number of records (0..0x3ff),
44 * then records of 8 bytes each
45 */
46static unsigned int counter = 0;
47static unsigned char curpos = 0;
48static unsigned char cmdid = 0xff; // timestamp, so never a valid command id
49
Martin Roth330de302015-09-17 16:33:07 -060050#define REPORT_BUFFER_LENGTH 8192
51#define REPORT_BUFFER_COUNT 8
52
Stefan Reinauerabd3e322019-12-04 18:29:24 -080053static int read_report_buffer(struct em100 *em100,
Martin Roth330de302015-09-17 16:33:07 -060054 unsigned char reportdata[REPORT_BUFFER_COUNT][REPORT_BUFFER_LENGTH])
Stefan Reinauerc566d202015-08-25 09:52:42 -070055{
Martin Roth330de302015-09-17 16:33:07 -060056 unsigned char cmd[16] = {0};
57 int len;
58 unsigned int report;
59
Stefan Reinauerc566d202015-08-25 09:52:42 -070060 cmd[0] = 0xbc; /* read SPI trace buffer*/
61
Stefan Reinauerabd3e322019-12-04 18:29:24 -080062 /*
Martin Roth330de302015-09-17 16:33:07 -060063 * Trace length, unit is 4k according to specs
64 *
65 * cmd1..cmd4 are probably u32BE on how many
66 * reports (8192 bytes each) to fetch
67 */
Stefan Reinauerc566d202015-08-25 09:52:42 -070068 cmd[1] = 0x00;
69 cmd[2] = 0x00;
70 cmd[3] = 0x00;
Martin Roth330de302015-09-17 16:33:07 -060071 cmd[4] = REPORT_BUFFER_COUNT;
Stefan Reinauerc566d202015-08-25 09:52:42 -070072 /* Timeout in ms */
73 cmd[5] = 0x00;
74 cmd[6] = 0x00;
75 cmd[7] = 0x00;
76 cmd[8] = 0x00;
77 /* Trace Config
78 * [1:0] 00 start/stop spi trace according to emulation status
79 * 01 start when TraceConfig[2] == 1
80 * 10 start when trig signal goes high
81 * 11 RFU
82 * [2] When TraceConfig[1:0] == 01 this bit starts the trace
83 * [7:3] RFU
84 */
85 cmd[9] = 0x15;
86
87 if (!send_cmd(em100->dev, cmd)) {
88 printf("sending trace command failed\n");
89 return 0;
90 }
Stefan Reinauerd7f959b2015-09-03 16:03:40 -070091
Martin Roth330de302015-09-17 16:33:07 -060092 for (report = 0; report < REPORT_BUFFER_COUNT; report++) {
Martin Rothb54d6ba2015-09-29 14:49:37 -060093 len = get_response(em100->dev, &reportdata[report][0],
94 REPORT_BUFFER_LENGTH);
Martin Roth330de302015-09-17 16:33:07 -060095 if (len != REPORT_BUFFER_LENGTH) {
96 printf("error, report length = %d instead of %d.\n\n",
97 len, REPORT_BUFFER_LENGTH);
Stefan Reinauerc566d202015-08-25 09:52:42 -070098 return 0;
99 }
Martin Roth330de302015-09-17 16:33:07 -0600100 }
101
102 return 1;
103}
104
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800105typedef enum { ADDR_NONE, ADDR_NO_OFF_3B, ADDR_3B, ADDR_4B, ADDR_DYNAMIC } address_t;
106
Martin Rothe8a72dd2015-09-17 17:14:48 -0600107struct spi_cmd_values {
Stefan Reinauer79533882019-11-22 00:57:29 -0800108 const char *cmd_name;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600109 uint8_t cmd;
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800110 address_t address_type;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600111 uint8_t pad_bytes;
112};
113
114struct spi_cmd_values spi_command_list[] = {
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800115 /* name cmd, addr, pad */
116 {"read SFDP", 0x5a, ADDR_NO_OFF_3B, 0},
117 {"write status register", 0x01, ADDR_NONE, 0},
118 {"page program", 0x02, ADDR_DYNAMIC, 0},
119 {"read", 0x03, ADDR_DYNAMIC, 0},
120 {"write disable", 0x04, ADDR_NONE, 0},
121 {"read status register", 0x05, ADDR_NONE, 0},
122 {"write enable", 0x06, ADDR_NONE, 0},
123 {"fast read", 0x0b, ADDR_DYNAMIC, 1},
124 {"EM100 specific", 0x11, ADDR_NONE, 0},
125 {"fast dual read", 0x3b, ADDR_DYNAMIC, 2},
126 {"chip erase", 0x60, ADDR_NONE, 0},
127 {"read JEDEC ID", 0x9f, ADDR_NONE, 0},
128 {"chip erase c7h", 0xc7, ADDR_NONE, 0},
129 {"chip erase 60h", 0x60, ADDR_NONE, 0},
130 {"sector erase", 0xd8, ADDR_DYNAMIC, 0},
131 {"dual I/O read", 0xbb, ADDR_DYNAMIC, 2},
132 {"quad I/O read", 0xeb, ADDR_DYNAMIC, 0},
133 {"quad read", 0x6b, ADDR_DYNAMIC, 0},
134 {"quad I/O dt read", 0xed, ADDR_DYNAMIC, 0},
135 {"quad page program", 0x38, ADDR_DYNAMIC, 0},
136 {"sector erase", 0x20, ADDR_DYNAMIC, 0},
137 {"block erase 32KB", 0x52, ADDR_DYNAMIC, 0},
138 {"block erase 64KB", 0xd8, ADDR_DYNAMIC, 0},
139 {"enter 4b mode", 0xb7, ADDR_NONE, 0},
140 {"exit 4b mode", 0xe9, ADDR_NONE, 0},
141 {"read 4b", 0x13, ADDR_4B, 0},
142 {"fast read 4b", 0x0c, ADDR_4B, 0},
143 {"dual I/O read 4b", 0xbc, ADDR_4B, 0},
144 {"dual out read 4b", 0x3c, ADDR_4B, 0},
145 {"quad I/O read 4b", 0xec, ADDR_4B, 0},
146 {"quad out read 4b", 0x6c, ADDR_4B, 0},
147 {"quad I/O dt read 4b", 0xee, ADDR_4B, 0},
148 {"page program 4b", 0x12, ADDR_4B, 0},
149 {"quad page program 4b", 0x3e, ADDR_4B, 0},
150 {"block erase 64KB 4b", 0xdc, ADDR_4B, 0},
151 {"block erase 32KB 4b", 0x5c, ADDR_4B, 0},
152 {"sector erase 4b", 0x21, ADDR_4B, 0},
153 {"enter quad I/O mode", 0x35, ADDR_NONE, 0},
154 {"exit quad I/O mode", 0xf5, ADDR_NONE, 0},
Martin Rothe8a72dd2015-09-17 17:14:48 -0600155
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800156 {"unknown command", 0xff, ADDR_NONE, 0}
157
Martin Rothe8a72dd2015-09-17 17:14:48 -0600158};
159
Stefan Reinauerabd3e322019-12-04 18:29:24 -0800160static struct spi_cmd_values * get_command_vals(uint8_t command)
161{
Martin Rothe8a72dd2015-09-17 17:14:48 -0600162 /* cache last command so a search isn't needed every time */
163 static struct spi_cmd_values *spi_cmd = &spi_command_list[3]; /* init to read */
164 int i;
165
166 if (spi_cmd->cmd != command) {
167 for (i = 0; spi_command_list[i].cmd != 0xff; i++) {
168 if (spi_command_list[i].cmd == command)
169 break;
170 }
171 spi_cmd = &spi_command_list[i];
172 }
173
174 return spi_cmd;
175}
176
177#define MAX_TRACE_BLOCKLENGTH 6
Martin Roth712262a2015-09-18 14:01:18 -0600178int read_spi_trace(struct em100 *em100, int display_terminal,
179 unsigned long addr_offset)
Martin Roth330de302015-09-17 16:33:07 -0600180{
Martin Rothb54d6ba2015-09-29 14:49:37 -0600181 unsigned char reportdata[REPORT_BUFFER_COUNT][REPORT_BUFFER_LENGTH] =
182 {{0}};
Martin Roth330de302015-09-17 16:33:07 -0600183 unsigned char *data;
184 unsigned int count, i, report;
185 static int outbytes = 0;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600186 static int additional_pad_bytes = 0;
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800187 static unsigned long address = 0;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600188 static unsigned long long timestamp = 0;
189 static unsigned long long start_timestamp = 0;
190 static struct spi_cmd_values *spi_cmd_vals = &spi_command_list[3];
Martin Roth330de302015-09-17 16:33:07 -0600191
192 if (!read_report_buffer(em100, reportdata))
193 return 0;
194
195 for (report = 0; report < REPORT_BUFFER_COUNT; report++) {
196 data = &reportdata[report][0];
Stefan Reinauerc566d202015-08-25 09:52:42 -0700197 count = (data[0] << 8) | data[1];
Stefan Reinauerd6180e22020-12-11 14:20:57 -0800198 if (!count)
199 continue;
200 if (count > 1023) {
Stefan Reinauer2372d7a2015-10-10 10:46:45 +0000201 printf("Warning: EM100pro sends too much data.\n");
Stefan Reinauerd6180e22020-12-11 14:20:57 -0800202 count = 1023;
Stefan Reinauer2372d7a2015-10-10 10:46:45 +0000203 }
Stefan Reinauerc566d202015-08-25 09:52:42 -0700204 for (i = 0; i < count; i++) {
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800205 int address_bytes = 0;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600206 unsigned int j = additional_pad_bytes;
207 additional_pad_bytes = 0;
Stefan Reinauerc566d202015-08-25 09:52:42 -0700208 unsigned char cmd = data[2 + i*8];
Stefan Reinauerdfb107d2020-12-10 19:22:40 -0800209
210 if (cmd == 0x00) {
211 /* packet without valid data */
212 continue;
213 }
Stefan Reinauerc566d202015-08-25 09:52:42 -0700214 if (cmd == 0xff) {
215 /* timestamp */
Stefan Reinauerc566d202015-08-25 09:52:42 -0700216 timestamp = data[2 + i*8 + 2];
217 timestamp = (timestamp << 8) | data[2 + i*8 + 3];
218 timestamp = (timestamp << 8) | data[2 + i*8 + 4];
219 timestamp = (timestamp << 8) | data[2 + i*8 + 5];
220 timestamp = (timestamp << 8) | data[2 + i*8 + 6];
221 timestamp = (timestamp << 8) | data[2 + i*8 + 7];
Martin Rothdfdff3e2015-09-18 09:42:03 -0600222 if (display_terminal)
223 read_spi_terminal(em100, 1);
Stefan Reinauerc566d202015-08-25 09:52:42 -0700224 continue;
225 }
Martin Rothe8a72dd2015-09-17 17:14:48 -0600226
Stefan Reinauerc566d202015-08-25 09:52:42 -0700227 /* from here, it must be data */
228 if (cmd != cmdid) {
Martin Rothe8a72dd2015-09-17 17:14:48 -0600229 unsigned char spi_command = data[i * 8 + 4];
230 spi_cmd_vals = get_command_vals(spi_command);
231
Stefan Reinauerc566d202015-08-25 09:52:42 -0700232 /* new command */
233 cmdid = cmd;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600234 if (counter == 0)
235 start_timestamp = timestamp;
236
Stefan Reinauerdfb107d2020-12-10 19:22:40 -0800237 /* Special commands */
238 switch (spi_command) {
239 case 0xb7:
240 address_mode = 4;
241 break;
242 case 0xe9:
243 address_mode = 3;
244 break;
245 }
246
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800247 /* skip command byte */
248 j = 1;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600249
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800250 /* Set up address if used by this command */
251 switch (spi_cmd_vals->address_type) {
252 case ADDR_DYNAMIC:
253 address_bytes = address_mode;
254 break;
255 case ADDR_NO_OFF_3B:
256 case ADDR_3B:
257 address_bytes = 3;
258 break;
259 case ADDR_4B:
260 address_bytes = 4;
261 break;
262 case ADDR_NONE:
263 break;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600264 }
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800265
266 if (address_bytes == 3)
267 address = (data[i * 8 + 5] << 16)
268 + (data[i * 8 + 6] << 8)
269 + data[i * 8 + 7];
270 else if (address_bytes == 4)
271 address = (data[i * 8 + 5] << 24)
272 + (data[i * 8 + 6] << 16)
273 + (data[i * 8 + 7] << 8)
274 + data[i * 8 + 8];
275
276 /* skip address bytes and padding */
277 j += address_bytes + spi_cmd_vals->pad_bytes;
278
279 if (j > MAX_TRACE_BLOCKLENGTH) {
280 additional_pad_bytes = j -
281 MAX_TRACE_BLOCKLENGTH;
282 j = MAX_TRACE_BLOCKLENGTH;
283 }
284
Martin Rothe8a72dd2015-09-17 17:14:48 -0600285 printf("\nTime: %06lld.%08lld",
Martin Rothb54d6ba2015-09-29 14:49:37 -0600286 (timestamp - start_timestamp) /
287 100000000,
288 (timestamp - start_timestamp) %
289 100000000);
290 printf(" command # %-6d : 0x%02x - %s",
291 ++counter, spi_command,
292 spi_cmd_vals->cmd_name);
Stefan Reinauerc566d202015-08-25 09:52:42 -0700293 curpos = 0;
Stefan Reinauerd7f959b2015-09-03 16:03:40 -0700294 outbytes = 0;
Stefan Reinauerc566d202015-08-25 09:52:42 -0700295 }
Martin Rothe8a72dd2015-09-17 17:14:48 -0600296
Stefan Reinauerc566d202015-08-25 09:52:42 -0700297 /* this exploits 8bit wrap around in curpos */
298 unsigned char blocklen = (data[2 + i*8 + 1] - curpos);
299 blocklen /= 8;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600300
301 for (; j < blocklen; j++) {
302 if (outbytes == 0) {
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800303 switch (spi_cmd_vals->address_type) {
304 case ADDR_DYNAMIC:
305 case ADDR_3B:
306 case ADDR_4B:
Martin Roth712262a2015-09-18 14:01:18 -0600307 printf("\n%08lx : ",
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800308 addr_offset + address);
309 break;
310 case ADDR_NO_OFF_3B:
311 printf("\n%08lx : ", address);
312 break;
313 case ADDR_NONE:
Martin Rothe8a72dd2015-09-17 17:14:48 -0600314 printf("\n : ");
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800315 break;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600316 }
317 }
318 printf("%02x ", data[i * 8 + 4 + j]);
Stefan Reinauerd7f959b2015-09-03 16:03:40 -0700319 outbytes++;
320 if (outbytes == 16) {
Martin Rothe8a72dd2015-09-17 17:14:48 -0600321 outbytes = 0;
Stefan Reinauer55e9b042020-12-11 13:41:53 -0800322 address += 16;
Stefan Reinauerd7f959b2015-09-03 16:03:40 -0700323 }
Stefan Reinauerc566d202015-08-25 09:52:42 -0700324 }
Martin Rothb54d6ba2015-09-29 14:49:37 -0600325 // this is because the em100 counts funny
326 curpos = data[2 + i*8 + 1] + 0x10;
Martin Rothe8a72dd2015-09-17 17:14:48 -0600327 fflush(stdout);
Stefan Reinauerc566d202015-08-25 09:52:42 -0700328 }
329 }
330 return 1;
331}
Martin Rothdfdff3e2015-09-18 09:42:03 -0600332
Stefan Reinauercafd1512020-12-11 17:36:28 -0800333int read_spi_trace_console(struct em100 *em100, unsigned long addr_offset,
334 unsigned long addr_len)
335{
336 unsigned char reportdata[REPORT_BUFFER_COUNT][REPORT_BUFFER_LENGTH] =
337 {{0}};
338 unsigned char *data;
339 unsigned int count, i, report;
340 static int additional_pad_bytes = 0;
341 static unsigned int address = 0;
342 static int do_write = 0;
343 static struct spi_cmd_values *spi_cmd_vals = &spi_command_list[3];
344 int addr_bytes = 0;
345
346 if (addr_offset == 0) {
347 printf("Address offset for console buffer required\n");
348 return -1;
349 }
350 if (addr_len == 0) {
351 printf("Console buffer length required\n");
352 return -1;
353 }
354
355 if (!read_report_buffer(em100, reportdata))
356 return -1;
357
358 for (report = 0; report < REPORT_BUFFER_COUNT; report++) {
359 data = &reportdata[report][0];
360 count = (data[0] << 8) | data[1];
361 if (!count)
362 continue;
363 if (count > 1023) {
364 printf("Warning: EM100pro sends too much data: %d.\n", count);
365 count = 1023;
366 }
367 for (i = 0; i < count; i++) {
368 unsigned int j = additional_pad_bytes;
369 unsigned int address_bytes = 0;
370 additional_pad_bytes = 0;
371 unsigned char cmd = data[2 + i*8];
372
373 /* from here, it must be data */
374 if (cmd != cmdid) {
375 unsigned char spi_command = data[i * 8 + 4];
376 spi_cmd_vals = get_command_vals(spi_command);
377
378 /* new command */
379 cmdid = cmd;
380
381 /* Special commands */
382 switch (spi_command) {
383 case 0xb7:
384 address_mode = 4;
385 break;
386 case 0xe9:
387 address_mode = 3;
388 break;
389 }
390
391 /* skip command byte */
392 j = 1;
393
394 /* Set up address if used by this command */
395 switch (spi_cmd_vals->address_type) {
396 case ADDR_DYNAMIC:
397 address_bytes = address_mode;
398 break;
399 case ADDR_NO_OFF_3B:
400 case ADDR_3B:
401 address_bytes = 3;
402 break;
403 case ADDR_4B:
404 address_bytes = 4;
405 break;
406 case ADDR_NONE:
407 break;
408 }
409
410 if (address_bytes == 3)
411 address = (data[i * 8 + 5] << 16)
412 + (data[i * 8 + 6] << 8)
413 + data[i * 8 + 7];
414 else if (address_bytes == 4)
415 address = (data[i * 8 + 5] << 24)
416 + (data[i * 8 + 6] << 16)
417 + (data[i * 8 + 7] << 8)
418 + data[i * 8 + 8];
419
420 /* skip address bytes and padding */
421 j += address_bytes + spi_cmd_vals->pad_bytes;
422
423 if (j > MAX_TRACE_BLOCKLENGTH) {
424 additional_pad_bytes = j -
425 MAX_TRACE_BLOCKLENGTH;
426 j = MAX_TRACE_BLOCKLENGTH;
427 }
428
429#if 0
430 if (spi_cmd_vals->address_type != ADDR_NONE)
431 printf("0x%02x @ 0x%08x (%s)\n",
432 spi_command, address, spi_cmd_vals->cmd_name);
433 else
434 printf("0x%02x (%s)\n",
435 spi_command, spi_cmd_vals->cmd_name);
436#endif
437
438 curpos = 0;
439 if (spi_command == 0x02)
440 do_write = 1;
441 else
442 do_write = 0;
443 }
444
445 if (do_write == 0 ||
446 (spi_cmd_vals->address_type == ADDR_NONE ||
447 address < addr_offset ||
448 address > (addr_offset + addr_len))) {
449 curpos = data[2 + i*8 + 1] + 0x10;
450 continue;
451 }
452
453 /* this exploits 8bit wrap around in curpos */
454 unsigned char blocklen = (data[2 + i*8 + 1] - curpos);
455 blocklen /= 8;
456
457 for (; j < blocklen; j++) {
458 printf("%c", data[i * 8 + addr_bytes + j]);
459 }
460
461 /* this is because the em100 counts funny */
462 curpos = data[2 + i*8 + 1] + 0x10;
463 fflush(stdout);
464 }
465 }
466 return 1;
467}
468
Martin Rothdfdff3e2015-09-18 09:42:03 -0600469#define UFIFO_SIZE 512
470#define UFIFO_TIMEOUT 0x00
471
472/*
473 * Polls the uFIFO buffer to see if there's any data. The HT registers don't
474 * seem to ever be updated to reflect that there's data present, and the
475 * Dediprog software doesn't use them either.
Martin Rothc69319c2015-09-29 14:09:40 -0600476 *
Martin Rothdfdff3e2015-09-18 09:42:03 -0600477 * Multiple messages can be in a single uFIFO transfer, so loop through
478 * the data looking for the signature.
479 */
Stefan Reinauerabd3e322019-12-04 18:29:24 -0800480int read_spi_terminal(struct em100 *em100, int show_counter)
481{
Martin Rothdfdff3e2015-09-18 09:42:03 -0600482 unsigned char data[UFIFO_SIZE] = { 0 };
483 static unsigned int msg_counter = 1; /* Number of messages */
Martin Rothc69319c2015-09-29 14:09:40 -0600484 uint16_t data_length;
Martin Rothdfdff3e2015-09-18 09:42:03 -0600485 unsigned char *data_start;
486 unsigned int j, k;
487 struct em100_msg *msg = NULL;
488
489 if (!read_ufifo(em100, UFIFO_SIZE, UFIFO_TIMEOUT, &data[0]))
490 return 0;
491
492 /* the first two bytes are the amount of valid data */
Martin Rothc69319c2015-09-29 14:09:40 -0600493 data_length = (data[0] << 8) + data[1];
494 if (data_length == 0)
Martin Rothdfdff3e2015-09-18 09:42:03 -0600495 return 1;
496
497 /* actual data starts after the length */
498 data_start = &data[sizeof(uint16_t)];
499
500 /* examine data; stop when we run out of message or buffer */
Martin Rothc69319c2015-09-29 14:09:40 -0600501 for (j = 0; j < data_length &&
Martin Rothdfdff3e2015-09-18 09:42:03 -0600502 j < UFIFO_SIZE - sizeof(struct em100_msg_header); j++) {
503
504 msg = (struct em100_msg *)(data_start + j);
505 if (msg->header.signature == EM100_MSG_SIGNATURE) {
506
507 if (show_counter)
508 printf("\nHT%06d: ", msg_counter);
509
510 /* print message byte according to format */
511 for (k = 0; k < msg->header.data_length; k++) {
Martin Rothc69319c2015-09-29 14:09:40 -0600512 if (&msg->data[k] >= data_start + data_length)
Martin Rothdfdff3e2015-09-18 09:42:03 -0600513 break;
514 if (&msg->data[k] >= &data[0] + UFIFO_SIZE)
515 break;
516
517 switch (msg->header.data_type) {
518 case ht_checkpoint_1byte:
519 case ht_checkpoint_2bytes:
520 case ht_checkpoint_4bytes:
521 case ht_hexadecimal_data:
522 case ht_timestamp_data:
523 printf("%02x ", msg->data[k]);
524 break;
525 case ht_ascii_data:
526 printf("%c", msg->data[k]);
527 break;
528 case ht_lookup_table:
529 /* TODO - support lookup table */
530 printf("Lookup unsupported: %02x%02x",
531 msg->data[k], msg->data[k + 1]);
532 k++;
533 break;
534 }
535 }
536
537 /* advance to the end of the message */
Martin Rothb54d6ba2015-09-29 14:49:37 -0600538 j += msg->header.data_length +
539 sizeof(struct em100_msg_header) - 1;
Martin Rothdfdff3e2015-09-18 09:42:03 -0600540 msg_counter++;
541 fflush(stdout);
542 }
543 }
544
545 return 1;
546}
547
548int init_spi_terminal (struct em100 *em100)
549{
550 int retval = 0x01;
551 uint16_t val;
552
553 retval &= write_ht_register(em100, ufifo_data_fmt_reg, 0);
554 retval &= write_ht_register(em100, status_reg, START_SPI_EMULATION);
555
556 /* set em100 to recognize spi command 0x11 */
557 retval &= write_fpga_register(em100, 0x82, EM100_SPECIFIC_CMD);
558 retval &= read_fpga_register(em100, 0x28, &val);
559
560 return retval;
561}