'''
1-Wire protocol decoder.
+The 1-Wire protocol enables bidirectional communication over a single wire (and
+ground) between a single master and one or multiple slaves. The protocol is
+layered, the provided parser decodes the next layers:
+- Link layer (reset, presence detection, reading/writing bits)
+- Network layer (skip, search, match device ROM addresses)
+The higher layers (transport, presentation) are not decoded, since they are
+mostly device specific and it would take a lot of code to interpret them.
+
+Probes:
+1-Wire requires a single signal, but some master implementations might have a
+separate signal use to deliver power to the bus during temperature conversion
+as an example. This power signal is currently not parsed.
+- owr (1-Wire bus)
+- pwr (1-Wire power)
+
+Options:
+1-Wire is an asynchronous protocol, so the decoder must know the sample rate.
+The timing for sampling bits, presence and reset is calculated by the decoder,
+but in case the user wishes to use different values, it is possible to
+configure the next timing values (number of sample rate periods):
+- overdrive (if active the decoder will be prepared for overdrive)
+- cnt_normal_bit (time for normal mode sample bit)
+- cnt_normal_presence (time for normal mode sample presence)
+- cnt_normal_reset (time for normal mode reset)
+- cnt_overdrive_bit (time for overdrive mode sample bit)
+- cnt_overdrive_presence (time for overdrive mode sample presence)
+- cnt_overdrive_reset (time for overdrive mode reset)
+This options should be configured only on very rare cases and the user should
+read the decoder source code to understand them correctly.
+
+Annotations:
+Annotations can be shown for each layer of the protocol separately:
+- link (the value of each transmitted bit is shown separately)
+- network (the ROM command, and address are shown)
+- transport (only transport layer byte transfers are shown)
+If link layer annotations are shown, possible issues with sample rate and sample
+timing are also shown.
+
TODO:
- fix annotations to have event duration instead of begin end time
- add CRC checks for network layer
ANN_NETWORK = 1
ANN_TRANSPORT = 2
+# a dictionary of ROM commands and their names
+rom_command = {0x33: "READ ROM",
+ 0x0f: "CONDITIONAL READ ROM",
+ 0xcc: "SKIP ROM",
+ 0x55: "MATCH ROM",
+ 0xf0: "SEARCH ROM",
+ 0xec: "CONDITIONAL SEARCH ROM",
+ 0x3c: "OVERDRIVE SKIP ROM",
+ 0x6d: "OVERDRIVE MATCH ROM"}
+
class Decoder(srd.Decoder):
api_version = 1
id = 'onewire'
raise Exception('Invalid lnk_state: %d' % self.lnk_state)
# Network layer
-
+
# State machine.
if (self.lnk_event == "RESET"):
self.net_state = "COMMAND"
elif (self.net_state == "COMMAND"):
# Receiving and decoding a ROM command
if (self.onewire_collect(8)):
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: 0x%02x' % self.net_data]])
- if (self.net_data == 0x33):
- # READ ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'READ ROM\'']])
+ self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: 0x%02x \'%s\'' % (self.net_data, rom_command[self.net_data])]])
+ if (self.net_data == 0x33): # READ ROM
self.net_state = "GET ROM"
- elif (self.net_data == 0x0f):
- # CONDITIONAL READ ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'CONDITIONAL READ ROM\'']])
+ elif (self.net_data == 0x0f): # CONDITIONAL READ ROM
self.net_state = "GET ROM"
- elif (self.net_data == 0xcc):
- # SKIP ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'SKIP ROM\'']])
+ elif (self.net_data == 0xcc): # SKIP ROM
self.net_state = "TRANSPORT"
- elif (self.net_data == 0x55):
- # MATCH ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'MATCH ROM\'']])
+ elif (self.net_data == 0x55): # MATCH ROM
self.net_state = "GET ROM"
- elif (self.net_data == 0xf0):
- # SEARCH ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'SEARCH ROM\'']])
+ elif (self.net_data == 0xf0): # SEARCH ROM
self.net_state = "SEARCH ROM"
- elif (self.net_data == 0xec):
- # CONDITIONAL SEARCH ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'CONDITIONAL SEARCH ROM\'']])
+ elif (self.net_data == 0xec): # CONDITIONAL SEARCH ROM
self.net_state = "SEARCH ROM"
- elif (self.net_data == 0x3c):
- # OVERDRIVE SKIP ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'OVERDRIVE SKIP ROM\'']])
+ elif (self.net_data == 0x3c): # OVERDRIVE SKIP ROM
self.lnk_overdrive = 1
self.net_state = "TRANSPORT"
- elif (self.net_data == 0x69):
- # OVERDRIVE MATCH ROM
- self.put(self.net_beg, self.net_end, self.out_ann, [ANN_NETWORK, ['ROM COMMAND: \'OVERDRIVE MATCH ROM\'']])
+ elif (self.net_data == 0x69): # OVERDRIVE MATCH ROM
self.lnk_overdrive = 1
self.net_state = "GET ROM"
elif (self.net_state == "GET ROM"):