Skip to content

Commit 8e5dd0e

Browse files
committed
Get close to finishing sh2
1 parent 766b064 commit 8e5dd0e

File tree

3 files changed

+202
-6
lines changed

3 files changed

+202
-6
lines changed

common.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from saleae.analyzers import HighLevelAnalyzer, AnalyzerFrame, StringSetting, NumberSetting, ChoicesSetting
33

44
class Packet:
5+
end_times: list
6+
start_times: list
57
is_continuation_header: bool
68
header_idx: int
79
start_time: float
@@ -14,12 +16,15 @@ class Packet:
1416
data: bytearray
1517

1618
def __init__(self, start_time) -> None:
19+
self.end_times = list()
20+
self.start_times = list()
1721
self.is_continuation_header = False
1822
self.length = 0xFFFF
1923
self.header_idx = 0
2024
self.sequence_number = 0xFF
2125
self.channel = 0xFF
2226
self.start_time = start_time
27+
self.end_time = 0
2328
self.data = bytearray()
2429

2530

@@ -69,10 +74,11 @@ def decode(self, frame: AnalyzerFrame):
6974
'length': self.packet.length
7075
},
7176
)
77+
p = self.packet
7278

7379
self.packet = None
7480

75-
return f
81+
return f, p
7682
elif type != 'data':
7783
pass
7884

@@ -92,6 +98,8 @@ def decode(self, frame: AnalyzerFrame):
9298
else:
9399
# print(d)
94100
self.packet.data.extend(d)
101+
self.packet.start_times.append(frame.start_time)
102+
self.packet.end_times.append(frame.end_time)
95103

96104

97105

sh2_analyzer.py

Lines changed: 189 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,209 @@
44
from common import Packet, SHTPParser
55

66

7+
GYRO_REPORT_ID = 0x02
8+
GYRO_REPORT_LEN = 10
9+
10+
LIN_ACCEL_REPORT_ID = 0x04
11+
LIN_ACCEL_REPORT_LEN = 10
12+
13+
ROTV_REPORT_ID = 0x05
14+
ROTV_REPORT_LEN = 14
15+
16+
TIMEBASE_REPORT_ID = 0xFB
17+
TIMEBASE_REPORT_LEN = 5
18+
19+
class Report:
20+
report_type: str
21+
start_time: float
22+
end_time: float
23+
report_id: int
24+
sequence: int
25+
status: int
26+
delay: int
27+
length: int
28+
29+
byte_data: bytearray
30+
31+
def __init__(self):
32+
self.byte_data = bytearray()
33+
34+
def done(self):
35+
# convert to floats
36+
# get quaternions
37+
# etc.
38+
pass
39+
40+
class FixedInt16Data:
41+
lsb: int
42+
msb: int
43+
full: int
44+
q: int
45+
46+
def __init__(self, q):
47+
self.q = q
48+
49+
def getFloating(self):
50+
return 0.0
51+
52+
class GyroReport(Report):
53+
report_id = GYRO_REPORT_ID
54+
length = GYRO_REPORT_LEN
55+
report_type = 'gyro'
56+
57+
x: FixedInt16Data
58+
y: FixedInt16Data
59+
z: FixedInt16Data
60+
61+
def __init__(self):
62+
super().__init__()
63+
self.x = FixedInt16Data(9)
64+
self.y = FixedInt16Data(9)
65+
self.z = FixedInt16Data(9)
66+
67+
class LinAccelReport(Report):
68+
report_id = LIN_ACCEL_REPORT_ID
69+
length = GYRO_REPORT_LEN
70+
report_type = 'accel'
71+
72+
x: FixedInt16Data
73+
y: FixedInt16Data
74+
z: FixedInt16Data
75+
76+
def __init__(self):
77+
super().__init__()
78+
self.x = FixedInt16Data(8)
79+
self.y = FixedInt16Data(8)
80+
self.z = FixedInt16Data(8)
81+
82+
class RotVReport(Report):
83+
report_id = ROTV_REPORT_ID
84+
length = GYRO_REPORT_LEN
85+
report_type = 'rotv'
86+
87+
i: FixedInt16Data
88+
j: FixedInt16Data
89+
k: FixedInt16Data
90+
real: FixedInt16Data
91+
accuracy: FixedInt16Data
92+
93+
roll: float
94+
pitch: float
95+
yaw: float
96+
97+
def __init__(self):
98+
super().__init__()
99+
self.i = FixedInt16Data(14)
100+
self.j = FixedInt16Data(14)
101+
self.k = FixedInt16Data(14)
102+
self.real = FixedInt16Data(14)
103+
self.accuracy = FixedInt16Data(12)
104+
105+
self.roll = 0
106+
self.pitch = 0
107+
self.yaw = 0
108+
109+
class TimebaseReport(Report):
110+
report_id = TIMEBASE_REPORT_ID
111+
length = TIMEBASE_REPORT_LEN
112+
report_type = 'tbase'
113+
114+
delta: int
115+
116+
def __init__(self):
117+
self.delta = 0
118+
super().__init__()
119+
120+
7121
class SH2Hla(HighLevelAnalyzer):
8122
result_types = {
123+
'packet': {
124+
'format': 'CH: {{data.channel}} SEQ: {{data.sequence}} DAT[{{data.length}}]: {{data.contents}}'
125+
},
126+
'tbase': {
127+
'format': 'delta = {{data.delta}}',
128+
},
9129
'accel': {
10130
'format': '[x,y,z] = [{{data.x}} {{data.y}} {{data.z}}]',
11131
},
12132
'gyro': {
13133
'format': '[x,y,z] = [{{data.x}} {{data.y}} {{data.z}}]',
14134
},
15135
'rotv': {
16-
'format': '[r,p,y,a] = [{{data.x}} {{data.y}} {{data.z}} {{data.accuracy}}]',
136+
'format': '[r,p,y,a] = [{{data.roll}} {{data.pitch}} {{data.yaw}} {{data.accuracy}}]',
17137
},
18138
}
19139

20140
def __init__(self):
21141
self.shtp_parser = SHTPParser()
22-
self.packet = None
23-
self.reports = None
142+
self.current_report = None
143+
144+
def execute_parser_step(self, new_data, start_time, end_time):
145+
if self.current_report is None:
146+
if new_data == GYRO_REPORT_ID:
147+
self.current_report = GyroReport()
148+
elif new_data == LIN_ACCEL_REPORT_ID:
149+
self.current_report = LinAccelReport()
150+
elif new_data == ROTV_REPORT_ID:
151+
self.current_report = RotVReport()
152+
elif new_data == TIMEBASE_REPORT_ID:
153+
self.current_report = TimebaseReport()
154+
else:
155+
return False
156+
157+
self.current_report.start_time = start_time
158+
return False
159+
else:
160+
self.current_report.byte_data.extend(new_data.to_bytes(1, 'big'))
161+
162+
if self.current_report.length - 1 == len(self.current_report.byte_data):
163+
self.current_report.end_time = end_time
164+
print('done', self.current_report.report_type, self.current_report.byte_data)
165+
return True
166+
else:
167+
return False
168+
169+
def parse_sh2(self, frame: AnalyzerFrame, p):
170+
frames = []
171+
172+
for i in range(len(p.data)):
173+
is_done = self.execute_parser_step(p.data[i], p.start_times[i], p.end_times[i])
174+
175+
if is_done:
176+
data = dict()
177+
if self.current_report.report_type == 'gyro' or self.current_report.report_type == 'accel':
178+
179+
data['x'] = self.current_report.x.getFloating()
180+
data['y'] = self.current_report.x.getFloating()
181+
data['z'] = self.current_report.x.getFloating()
182+
elif self.current_report.report_type == 'rotv':
183+
data['roll'] = self.current_report.roll
184+
data['pitch'] = self.current_report.pitch
185+
data['yaw'] = self.current_report.yaw
186+
elif self.current_report.report_type == 'tbase':
187+
data['delta'] = self.current_report.delta
188+
189+
f = AnalyzerFrame(
190+
self.current_report.report_type,
191+
self.current_report.start_time,
192+
self.current_report.end_time,
193+
data
194+
)
195+
196+
self.current_report = None
197+
198+
frames.append(f)
199+
200+
201+
return None
24202

25203
def decode(self, frame: AnalyzerFrame):
26-
return self.shtp_parser.decode(frame)
204+
fp = self.shtp_parser.decode(frame)
205+
print(fp)
206+
207+
if fp is not None:
208+
return self.parse_sh2(fp[0], fp[1])
209+
210+
return fp
211+
27212

shtp_analyzer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ def __init__(self):
1414
self.shtp_parser = SHTPParser()
1515

1616
def decode(self, frame: AnalyzerFrame):
17-
return self.shtp_parser.decode(frame)
17+
f = self.shtp_parser.decode(frame)
18+
19+
if f is not None:
20+
return f[0]
1821

0 commit comments

Comments
 (0)