2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2012 Iztok Jeras <iztok.jeras@gmail.com>
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
20 import sigrokdecode
as srd
22 # Dictionary of ROM commands and their names, next state.
24 0x33: ['Read ROM' , 'GET ROM' ],
25 0x0f: ['Conditional read ROM' , 'GET ROM' ],
26 0xcc: ['Skip ROM' , 'TRANSPORT' ],
27 0x55: ['Match ROM' , 'GET ROM' ],
28 0xf0: ['Search ROM' , 'SEARCH ROM'],
29 0xec: ['Conditional search ROM' , 'SEARCH ROM'],
30 0x3c: ['Overdrive skip ROM' , 'TRANSPORT' ],
31 0x69: ['Overdrive match ROM' , 'GET ROM' ],
32 0xa5: ['Resume' , 'TRANSPORT' ],
33 0x96: ['DS2408: Disable Test Mode' , 'GET ROM' ],
36 class Decoder(srd
.Decoder
):
38 id = 'onewire_network'
39 name
= '1-Wire network layer'
40 longname
= '1-Wire serial communication bus (network layer)'
41 desc
= 'Bidirectional, half-duplex, asynchronous serial bus.'
43 inputs
= ['onewire_link']
44 outputs
= ['onewire_network']
45 tags
= ['Embedded/industrial']
56 self
.state
= 'COMMAND'
62 self
.rom
= 0x0000000000000000
65 self
.out_python
= self
.register(srd
.OUTPUT_PYTHON
)
66 self
.out_ann
= self
.register(srd
.OUTPUT_ANN
)
69 # Helper function for most annotations.
70 self
.put(self
.ss_block
, self
.es_block
, self
.out_ann
, data
)
73 # Helper function for most protocol packets.
74 self
.put(self
.ss_block
, self
.es_block
, self
.out_python
, data
)
76 def decode(self
, ss
, es
, data
):
80 if code
== 'RESET/PRESENCE':
83 self
.put(ss
, es
, self
.out_ann
,
84 [0, ['Reset/presence: %s' % ('true' if val
else 'false')]])
85 self
.put(ss
, es
, self
.out_python
, ['RESET/PRESENCE', val
])
86 self
.state
= 'COMMAND'
89 # For now we're only interested in 'RESET/PRESENCE' and 'BIT' packets.
93 if self
.state
== 'COMMAND':
94 # Receiving and decoding a ROM command.
95 if self
.onewire_collect(8, val
, ss
, es
) == 0:
97 if self
.data
in command
:
98 self
.putx([0, ['ROM command: 0x%02x \'%s\''
99 % (self
.data
, command
[self
.data
][0])]])
100 self
.state
= command
[self
.data
][1]
102 self
.putx([0, ['ROM command: 0x%02x \'%s\''
103 % (self
.data
, 'unrecognized')]])
104 self
.state
= 'COMMAND ERROR'
105 elif self
.state
== 'GET ROM':
106 # A 64 bit device address is selected.
107 # Family code (1 byte) + serial number (6 bytes) + CRC (1 byte)
108 if self
.onewire_collect(64, val
, ss
, es
) == 0:
110 self
.rom
= self
.data
& 0xffffffffffffffff
111 self
.putx([0, ['ROM: 0x%016x' % self
.rom
]])
112 self
.puty(['ROM', self
.rom
])
113 self
.state
= 'TRANSPORT'
114 elif self
.state
== 'SEARCH ROM':
115 # A 64 bit device address is searched for.
116 # Family code (1 byte) + serial number (6 bytes) + CRC (1 byte)
117 if self
.onewire_search(64, val
, ss
, es
) == 0:
119 self
.rom
= self
.data
& 0xffffffffffffffff
120 self
.putx([0, ['ROM: 0x%016x' % self
.rom
]])
121 self
.puty(['ROM', self
.rom
])
122 self
.state
= 'TRANSPORT'
123 elif self
.state
== 'TRANSPORT':
124 # The transport layer is handled in byte sized units.
125 if self
.onewire_collect(8, val
, ss
, es
) == 0:
127 self
.putx([0, ['Data: 0x%02x' % self
.data
]])
128 self
.puty(['DATA', self
.data
])
129 elif self
.state
== 'COMMAND ERROR':
130 # Since the command is not recognized, print raw data.
131 if self
.onewire_collect(8, val
, ss
, es
) == 0:
133 self
.putx([0, ['ROM error data: 0x%02x' % self
.data
]])
136 def onewire_collect(self
, length
, val
, ss
, es
):
137 # Storing the sample this sequence begins with.
138 if self
.bit_cnt
== 0:
140 self
.data
= self
.data
& ~
(1 << self
.bit_cnt
) |
(val
<< self
.bit_cnt
)
142 # Storing the sample this sequence ends with.
143 # In case the full length of the sequence is received, return 1.
144 if self
.bit_cnt
== length
:
146 self
.data
= self
.data
& ((1 << length
) - 1)
153 def onewire_search(self
, length
, val
, ss
, es
):
154 # Storing the sample this sequence begins with.
155 if (self
.bit_cnt
== 0) and (self
.search
== 'P'):
158 if self
.search
== 'P':
159 # Master receives an original address bit.
160 self
.data_p
= self
.data_p
& ~
(1 << self
.bit_cnt
) | \
161 (val
<< self
.bit_cnt
)
163 elif self
.search
== 'N':
164 # Master receives a complemented address bit.
165 self
.data_n
= self
.data_n
& ~
(1 << self
.bit_cnt
) | \
166 (val
<< self
.bit_cnt
)
168 elif self
.search
== 'D':
169 # Master transmits an address bit.
170 self
.data
= self
.data
& ~
(1 << self
.bit_cnt
) |
(val
<< self
.bit_cnt
)
174 # Storing the sample this sequence ends with.
175 # In case the full length of the sequence is received, return 1.
176 if self
.bit_cnt
== length
:
178 self
.data_p
= self
.data_p
& ((1 << length
) - 1)
179 self
.data_n
= self
.data_n
& ((1 << length
) - 1)
180 self
.data
= self
.data
& ((1 << length
) - 1)