Skip to content

Commit a0e3dbb

Browse files
committed
Add license and add documentation
1 parent 6fedbd8 commit a0e3dbb

File tree

5 files changed

+72
-14
lines changed

5 files changed

+72
-14
lines changed

LICENSE.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright 2022 Roberts Kalnins
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1-
# SHTP
2-
3-
Packet parser for decoding SHTP traffic in Logic 2.
1+
# SHTP and SH2 HLA
2+
3+
SHTP and SH2 are the Sensor Hub Transport Protocol and Sensor Hub 2 protocols from CEVA designed
4+
to be used with sensor hub devices.
5+
6+
SHTP packet parser is done but the SH2 HLA only supports a small portion of the protocol. This parser
7+
was written to test communication with the Bosch BNO085 IMU and the project only needed 3 of the many sensor reports.
8+
The only supported reports currently are the time base, time rebase, gyroscope (calibrated), linear acceleration, and
9+
rotation vector reports.
10+
11+
SH2 internally layers SH2 on top of SHTP.
12+
13+
## Roadmap
14+
15+
### SHTP
16+
17+
Nothing yet.
18+
19+
### SH2
20+
21+
- [ ] Display floating point result
22+
- [ ] Add other sensor report types
23+
24+
## Licensing
25+
26+
Released under MIT license.
27+
28+
## Contributing
29+
30+
Any contributions welcome. This tool was written to facilitate testing in a capstone project in the University
31+
of Michigan's EECS 473 Advanced Embedded Systems course and only covers the portions of SH2 that were needed.

common.py

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

44
class Packet:
5+
"""
6+
SHTP packet
7+
"""
58
end_times: list
69
start_times: list
710
is_continuation_header: bool
@@ -34,18 +37,24 @@ def __init__(self):
3437

3538
def fill_header(self, d):
3639
if self.packet.header_idx == 0:
40+
# first byte is length LSB
3741
self.packet.length_lsb = d[0]
3842
elif self.packet.header_idx == 1:
43+
# second byte is length MSB
3944
self.packet.length_msb = d[0]
4045
length = self.packet.length_lsb | (self.packet.length_msb << 8)
46+
47+
# erase continuation bit
4148
length = length & 0x7FFF
4249

4350
print("len: ", length)
4451

4552
self.packet.length = length
4653
elif self.packet.header_idx == 2:
54+
# third byte is channel index
4755
self.packet.channel = d[0]
4856
elif self.packet.header_idx == 3:
57+
# fourth byte is sequence number
4958
self.packet.sequence_number = d[0]
5059

5160
self.packet.header_idx += 1
@@ -57,10 +66,14 @@ def decode(self, frame: AnalyzerFrame):
5766
if type == 'start' and self.packet is None:
5867
self.packet = Packet(frame.start_time)
5968
elif type == 'start':
69+
# packet is continuation in another transaction
6070
self.packet.is_continuation_header = True
6171
self.packet.header_idx = 0
6272
elif (type == 'stop' or type == 'data') and self.packet is not None:
73+
# transaction is over
74+
6375
if self.packet.length - 4 == len(self.packet.data):
76+
# packet is done if length matches initial length from header
6477
self.packet.end_time = frame.end_time
6578

6679
f = AnalyzerFrame(
@@ -85,18 +98,21 @@ def decode(self, frame: AnalyzerFrame):
8598

8699
if self.packet is not None:
87100
if type == 'data':
101+
# skip continuation headers
88102
if self.packet.is_continuation_header:
89103
self.packet.header_idx += 1
90-
104+
105+
# continuation header is over
91106
if self.packet.header_idx >= 4:
92107
self.packet.is_continuation_header = False
93108
else:
94109
d = frame.data['data']
95110

111+
# parse initial SHTP packet header
96112
if self.packet.header_idx < 4:
97113
self.fill_header(d)
98114
else:
99-
# print(d)
115+
# handle internal byte
100116
self.packet.data.extend(d)
101117
self.packet.start_times.append(frame.start_time)
102118
self.packet.end_times.append(frame.end_time)

sh2_analyzer.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ class Report:
3434
def __init__(self):
3535
self.byte_data = bytearray()
3636

37-
def done(self):
38-
# convert to floats
39-
# get quaternions
40-
# etc.
41-
pass
42-
4337
class FixedInt16Data:
4438
lsb: int
4539
msb: int
@@ -109,6 +103,11 @@ def __init__(self):
109103
self.pitch = 0
110104
self.yaw = 0
111105

106+
def get_rpy():
107+
# TODO: convert fixed pt to quaternion RPY
108+
return self.roll, self.pitch, self.yaw
109+
110+
112111
class TimebaseReport(Report):
113112
report_id = TIMEBASE_REPORT_ID
114113
length = TIMEBASE_REPORT_LEN
@@ -159,6 +158,9 @@ def __init__(self):
159158
self.current_report = None
160159

161160
def execute_parser_step(self, new_data, start_time, end_time):
161+
# parse data in packet by report type
162+
163+
# start new report
162164
if self.current_report is None:
163165
if new_data == GYRO_REPORT_ID:
164166
self.current_report = GyroReport()
@@ -177,7 +179,8 @@ def execute_parser_step(self, new_data, start_time, end_time):
177179
return False
178180
else:
179181
self.current_report.byte_data.extend(new_data.to_bytes(1, 'big'))
180-
182+
183+
# report is complete
181184
if self.current_report.length - 1 == len(self.current_report.byte_data):
182185
self.current_report.end_time = end_time
183186
print('done', self.current_report.report_type, self.current_report.byte_data)
@@ -186,13 +189,15 @@ def execute_parser_step(self, new_data, start_time, end_time):
186189
return False
187190

188191
def parse_sh2(self, frame: AnalyzerFrame, p):
192+
# all frames generated from parsing reports from this SHTP packet
189193
frames = []
190194

191195
for i in range(len(p.data)):
192196
is_done = self.execute_parser_step(p.data[i], p.start_times[i], p.end_times[i])
193197

194198
if is_done:
195199
data = dict()
200+
# read data from reports based on type and generate correct report output
196201
if self.current_report.report_type == 'gyro' or self.current_report.report_type == 'accel':
197202
data['x'] = self.current_report.x.getFloating()
198203
data['y'] = self.current_report.x.getFloating()
@@ -213,17 +218,18 @@ def parse_sh2(self, frame: AnalyzerFrame, p):
213218
)
214219

215220
self.current_report = None
216-
221+
222+
# multiple SH2 reports can exist per SHTP packet, each report is one frame
217223
frames.append(f)
218224

219225

220226
return frames
221227

222228
def decode(self, frame: AnalyzerFrame):
223229
fp = self.shtp_parser.decode(frame)
224-
print(fp)
225230

226231
if fp is not None:
232+
# wait for shtp packet to be compelte
227233
return self.parse_sh2(fp[0], fp[1])
228234

229235
return fp

shtp_analyzer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from common import Packet, SHTPParser
44

55
class SHTPHla(HighLevelAnalyzer):
6+
# analyzer output format
67
result_types = {
78
'packet': {
89
'format': 'CH: {{data.channel}} SEQ: {{data.sequence}} DAT[{{data.length}}]: {{data.contents}}'

0 commit comments

Comments
 (0)