-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Serial-Over-I2C Protocol Analyzer
- Loading branch information
0 parents
commit 09ce7db
Showing
9 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
# Blues Serial-Over-I2C Protocol Analyzer | ||
# For more information and documentation, please go to https://dev.blues.io/guides-and-tutorials/notecard-guides/serial-over-i2c-protocol/ | ||
|
||
from saleae.analyzers import HighLevelAnalyzer, AnalyzerFrame, NumberSetting | ||
|
||
# High level analyzers must subclass the HighLevelAnalyzer class. | ||
class Hla(HighLevelAnalyzer): | ||
|
||
# Parameters | ||
notecard_i2c_addr = NumberSetting(min_value=0, max_value=127) | ||
|
||
# An optional list of types this analyzer produces, providing a way to customize the way frames are displayed in Logic 2. | ||
result_types = { | ||
'addr': { | ||
'format': '{{data.sender}}' | ||
}, | ||
'hdr': { | ||
'format': '{{data.action}}: {{data.length}}' | ||
}, | ||
'note': { | ||
'format': '{{data.Note}}' | ||
}, | ||
'query': { | ||
'format': 'Query Notecard' | ||
}, | ||
'request': { | ||
'format': 'Request: {{data.length}}' | ||
} | ||
} | ||
|
||
def __init__(self): | ||
|
||
self.data = { | ||
'note': [], | ||
'start_time': None | ||
} | ||
self.hdr1 = None | ||
self.hdr2 = None | ||
self.ignore = False | ||
self.request_start_time = None | ||
self.read = None | ||
|
||
if self.notecard_i2c_addr == 0x00: | ||
self.notecard_i2c_addr = 0x17 | ||
|
||
print(f"=======================================") | ||
print(f"Blues Serial-Over-I2C Protocol Analyzer") | ||
print() | ||
print('Settings:') | ||
print(f"- Notecard I2C Address: 0x{int(self.notecard_i2c_addr):02X}") | ||
print() | ||
print(f"https://dev.blues.io/guides-and-tutorials/notecard-guides/serial-over-i2c-protocol/") | ||
|
||
def decode(self, frame: AnalyzerFrame): | ||
|
||
if frame.type == 'start': | ||
# /--------------------------------------/ | ||
# /------/ START FRAME DATA ITEMS /------/ | ||
# /--------------------------------------/ | ||
# /--------------------------------------/ | ||
|
||
self.data = { | ||
'note': [], | ||
'start_time': None | ||
} | ||
self.hdr1 = None | ||
self.hdr2 = None | ||
self.ignore = False | ||
self.request_start_time = None | ||
self.read = None | ||
|
||
elif frame.type == 'address': | ||
# /----------------------------------------/ | ||
# /------/ ADDRESS FRAME DATA ITEMS /------/ | ||
# /----------------------------------------/ | ||
# Key: ack, Value: True | ||
# Key: address, Value: b'\x17' | ||
# Key: read, Value: False | ||
# /----------------------------------------/ | ||
if (frame.data['address'][0] != self.notecard_i2c_addr): | ||
self.ignore = True | ||
return None | ||
|
||
print(f"=======================================") | ||
self.read = frame.data['read'] | ||
|
||
sender = 'Host MCU' if not frame.data['read'] else 'Notecard' | ||
print(f"Sender: {sender}") | ||
return AnalyzerFrame('addr', frame.start_time, frame.end_time, { | ||
'sender': sender | ||
}) | ||
|
||
elif frame.type == 'data': | ||
# /-------------------------------------/ | ||
# /------/ DATA FRAME DATA ITEMS /------/ | ||
# /-------------------------------------/ | ||
# Key: ack, Value: True | ||
# Key: data, Value: b'^' | ||
# /-------------------------------------/ | ||
if self.ignore: | ||
return None | ||
|
||
if self.read: # Notecard Response | ||
# Special Handling for Header Byte 1 | ||
if self.hdr1 == None: | ||
self.hdr1 = frame.data['data'][0] | ||
|
||
# Handle Notecard Response | ||
print(f"Queued: {self.hdr1}") | ||
return AnalyzerFrame('hdr', frame.start_time, frame.end_time, { | ||
'action': 'Queued', | ||
'length': self.hdr1 | ||
}) | ||
|
||
# Special Handling for Header Byte 2 | ||
elif self.hdr2 == None: | ||
self.hdr2 = frame.data['data'][0] | ||
|
||
# Handle Notecard Response | ||
print(f"Sending: {self.hdr2}") | ||
return AnalyzerFrame('hdr', frame.start_time, frame.end_time, { | ||
'action': 'Sending', | ||
'length': self.hdr2 | ||
}) | ||
|
||
else: # Host MCU Request | ||
# Special Handling for Header Byte 1 | ||
if self.hdr1 == None: | ||
self.hdr1 = frame.data['data'][0] | ||
|
||
# Handle Host MCU Request | ||
if self.hdr1 == 0: | ||
self.request_start_time = frame.start_time | ||
return None | ||
else: | ||
print(f"Sending: {self.hdr1}") | ||
return AnalyzerFrame('hdr', frame.start_time, frame.end_time, { | ||
'action': 'Sending', | ||
'length': self.hdr1 | ||
}) | ||
|
||
# Special Handling for Header Byte 2 | ||
elif self.hdr2 == None: | ||
self.hdr2 = frame.data['data'][0] | ||
|
||
# Handle Host MCU Request | ||
if self.request_start_time != None: | ||
if self.hdr2 == 0: | ||
# Handle Query Request | ||
print(f"Query Notecard") | ||
return AnalyzerFrame('query', self.request_start_time, frame.end_time, None) | ||
else: | ||
# Handle Request Bytes | ||
print(f"Request: {self.hdr2}") | ||
return AnalyzerFrame('request', self.request_start_time, frame.end_time, { | ||
'length': self.hdr2 | ||
}) | ||
|
||
# Handle Note Bytes (Request or Response) | ||
if self.data['start_time'] == None: | ||
self.data['start_time'] = frame.start_time | ||
|
||
self.data['note'].append(frame.data['data']) | ||
|
||
elif frame.type == 'stop': | ||
# /-------------------------------------/ | ||
# /------/ STOP FRAME DATA ITEMS /------/ | ||
# /-------------------------------------/ | ||
# /-------------------------------------/ | ||
|
||
if len(self.data['note']) > 0: | ||
note = ''.join([byte.decode('ascii') for byte in self.data['note']]).rstrip('\n') | ||
print(f"Note: {note}") | ||
return AnalyzerFrame('note', self.data['start_time'], frame.end_time, { | ||
'Note': note | ||
}) | ||
else: | ||
return None | ||
|
||
# Return the data frame itself | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 Blues Inc. | ||
|
||
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: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Serial-over-I2C Protocol Analyzer | ||
================================= | ||
|
||
This repository provides an extension to the Saleae Logic application to support on the wire inspection of the Blues Serial-over-I2C protocol. | ||
|
||
Getting started | ||
--------------- | ||
|
||
To install the extension, navigate to the "Extensions" tab in Saleae Logic application. | ||
|
||
 | ||
|
||
This extension is known as a High Level Analyzer. This means the analyzer performs further analysis beyond a Low Level Analyzer (i.e. I2C). | ||
|
||
In order to use this extension, you must first enable the I2C analyzer. Then you may enable this extension and bind it to the I2C analyzer in the settings pane. | ||
|
||
 | ||
|
||
> _**NOTE:** When enabling the extension, you will be prompted to enter the I2C Address of the Notecard. If you wish to use the Notecard's default address (23), you can leave this value marked zero (0)._ | ||
> _**WARNING:** If the I2C address of the Notecard does not match the value supplied to the extension, then all traffic will be ignored._ | ||
Using the extension | ||
------------------- | ||
|
||
Once you have enabled the extension, you will see a new row in the UI that describes the behavior of the Serial-Over-I2C protocol. | ||
|
||
 | ||
|
||
You may also look at the Terminal output of the Analyzers panel to see the dialogue between the Notecard and Host MCU. | ||
|
||
 | ||
|
||
Having Trouble? | ||
--------------- | ||
|
||
If you encounter any problems, you may file an issue on the [GitHub repository](https://github.com/blues/saleae-logic-extension.git), or ask any questions in our [Community Forum](https://discuss.blues.com/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"name": "Blues Serial-Over-I2C Analyzer", | ||
"apiVersion": "1.0.0", | ||
"author": "Blues", | ||
"version": "1.0.0", | ||
"description": "A High Level Analyzer for the Blues Serial-Over-I2C protocol", | ||
"extensions": { | ||
"Serial-Over-I2C Protocol": { | ||
"type": "HighLevelAnalyzer", | ||
"entryPoint": "BluesSerialOverI2CAnalyzer.Hla" | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.