blob: 5848b47f240731db0f5ff1abfb781eccfab0bb89 [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.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include "em100.h"
21
22/* SPI Trace related operations */
23
24/**
25 * reset_spi_trace: clear SPI trace buffer
26 * @param em100: em100 device structure
27 *
28 * out(16 bytes): 0xbd 0 .. 0
29 */
30int reset_spi_trace(struct em100 *em100)
31{
32 unsigned char cmd[16];
33 memset(cmd, 0, 16);
34 cmd[0] = 0xbd; /* reset SPI trace buffer*/
35 if (!send_cmd(em100->dev, cmd)) {
36 return 0;
37 }
38 return 1;
39}
40
41/**
42 * read_spi_trace: fetch SPI trace data
43 * @param em100: em100 device structure
44 * globals: curpos, counter, cmdid
45 *
46 * out(16 bytes): bc 00 00 00 08 00 00 00 00 15 00 00 00 00 00 00
47 * in(8x8192 bytes): 2 bytes (BE) number of records (0..0x3ff),
48 * then records of 8 bytes each
49 */
50static unsigned int counter = 0;
51static unsigned char curpos = 0;
52static unsigned char cmdid = 0xff; // timestamp, so never a valid command id
53
54int read_spi_trace(struct em100 *em100)
55{
56 unsigned char cmd[16];
57 unsigned char data[8192];
58 unsigned int count, i, report;
Stefan Reinauerd7f959b2015-09-03 16:03:40 -070059 static int outbytes = 0;
Stefan Reinauerc566d202015-08-25 09:52:42 -070060 memset(cmd, 0, 16);
61 cmd[0] = 0xbc; /* read SPI trace buffer*/
62
63 /* Trace length, unit is 4k according to specs */
64 cmd[1] = 0x00;
65 cmd[2] = 0x00;
66 cmd[3] = 0x00;
67 cmd[4] = 0x08; /* cmd1..cmd4 are probably u32BE on how many
68 reports (8192 bytes each) to fetch */
69 /* Timeout in ms */
70 cmd[5] = 0x00;
71 cmd[6] = 0x00;
72 cmd[7] = 0x00;
73 cmd[8] = 0x00;
74 /* Trace Config
75 * [1:0] 00 start/stop spi trace according to emulation status
76 * 01 start when TraceConfig[2] == 1
77 * 10 start when trig signal goes high
78 * 11 RFU
79 * [2] When TraceConfig[1:0] == 01 this bit starts the trace
80 * [7:3] RFU
81 */
82 cmd[9] = 0x15;
83
84 if (!send_cmd(em100->dev, cmd)) {
85 printf("sending trace command failed\n");
86 return 0;
87 }
Stefan Reinauerd7f959b2015-09-03 16:03:40 -070088
Stefan Reinauerc566d202015-08-25 09:52:42 -070089 for (report = 0; report < 8; report++) {
90 memset(data, 0, sizeof(data));
91 int len = get_response(em100->dev, data, sizeof(data));
92 if (len != sizeof(data)) {
93 /* FIXME: handle error: device reset? */
94 printf("error, len = %d instead of %zd. bailing out\n\n", len, sizeof(data));
95 return 0;
96 }
97 count = (data[0] << 8) | data[1];
98 for (i = 0; i < count; i++) {
99 unsigned int j;
100 unsigned char cmd = data[2 + i*8];
101 if (cmd == 0xff) {
102 /* timestamp */
103 unsigned long long timestamp = 0;
104 timestamp = data[2 + i*8 + 2];
105 timestamp = (timestamp << 8) | data[2 + i*8 + 3];
106 timestamp = (timestamp << 8) | data[2 + i*8 + 4];
107 timestamp = (timestamp << 8) | data[2 + i*8 + 5];
108 timestamp = (timestamp << 8) | data[2 + i*8 + 6];
109 timestamp = (timestamp << 8) | data[2 + i*8 + 7];
110 printf("\ntimestamp: %lld.%lld", timestamp / 100000000, timestamp % 100000000);
111 continue;
112 }
113#if 0
114 printf("{(%d)", curpos);
115 for (j = 0; j < 8; j++) {
116 printf("%02x ", data[2 + i*8 + j]);
117 }
118 printf("}");
119#endif
120 /* from here, it must be data */
121 if (cmd != cmdid) {
122 /* new command */
123 cmdid = cmd;
124 printf("\nspi command %6d: ", ++counter);
125 curpos = 0;
Stefan Reinauerd7f959b2015-09-03 16:03:40 -0700126 outbytes = 0;
Stefan Reinauerc566d202015-08-25 09:52:42 -0700127 }
128 /* this exploits 8bit wrap around in curpos */
129 unsigned char blocklen = (data[2 + i*8 + 1] - curpos);
130 blocklen /= 8;
131 for (j = 0; j < blocklen; j++) {
132 printf("%02x ", data[2 + i*8 + 2 + j]);
Stefan Reinauerd7f959b2015-09-03 16:03:40 -0700133 outbytes++;
134 if (outbytes == 16) {
135 outbytes=0;
136 printf("\n ");
137 }
Stefan Reinauerc566d202015-08-25 09:52:42 -0700138 }
139 curpos = data[2 + i*8 + 1] + 0x10; // this is because the em100 counts funny
140 }
141 }
142 return 1;
143}