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, write to the Free Software
18 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 import sigrokdecode as srd
23 class Decoder(srd.Decoder):
26 name = '1-Wire link layer'
27 longname = '1-Wire serial communication bus (link layer)'
28 desc = 'Bidirectional, half-duplex, asynchronous serial bus.'
31 outputs = ['onewire_link']
33 {'id': 'owr', 'name': 'OWR', 'desc': '1-Wire signal line'},
36 {'id': 'pwr', 'name': 'PWR', 'desc': '1-Wire power supply pin'},
40 'desc': 'Overdrive mode',
42 # Time options (specified in microseconds):
43 {'id': 'cnt_normal_bit',
44 'desc': 'Normal mode sample bit time (μs)',
46 {'id': 'cnt_normal_slot',
47 'desc': 'Normal mode data slot time (μs)',
49 {'id': 'cnt_normal_presence',
50 'desc': 'Normal mode sample presence time (μs)',
52 {'id': 'cnt_normal_reset',
53 'desc': 'Normal mode reset time (μs)',
55 {'id': 'cnt_overdrive_bit',
56 'desc': 'Overdrive mode sample bit time (μs)',
58 {'id': 'cnt_overdrive_slot',
59 'desc': 'Overdrive mode data slot time (μs)',
61 {'id': 'cnt_overdrive_presence',
62 'desc': 'Overdrive mode sample presence time (μs)',
64 {'id': 'cnt_overdrive_reset',
65 'desc': 'Overdrive mode reset time (μs)',
70 ('warnings', 'Warnings'),
72 ('presence', 'Presence'),
73 ('overdrive', 'Overdrive mode notifications'),
76 ('bits', 'Bits', (0, 2, 3)),
77 ('info', 'Info', (4,)),
78 ('warnings', 'Warnings', (1,)),
82 self.put(0, 0, self.out_ann, data)
84 def putpb(self, data):
85 self.put(self.fall, self.samplenum, self.out_python, data)
88 self.put(self.fall, self.samplenum, self.out_ann, data)
91 self.put(self.fall, self.cnt_bit[self.overdrive], self.out_ann, data)
93 def putfr(self, data):
94 self.put(self.fall, self.rise, self.out_ann, data)
96 def putprs(self, data):
97 self.put(self.rise, self.samplenum, self.out_python, data)
99 def putrs(self, data):
100 self.put(self.rise, self.samplenum, self.out_ann, data)
102 def __init__(self, **kwargs):
103 self.samplerate = None
105 self.state = 'WAIT FOR FALLING EDGE'
115 self.out_python = self.register(srd.OUTPUT_PYTHON)
116 self.out_ann = self.register(srd.OUTPUT_ANN)
118 def metadata(self, key, value):
119 if key != srd.SRD_CONF_SAMPLERATE:
121 self.samplerate = value
123 # Check if samplerate is appropriate.
124 if self.options['overdrive'] == 'yes':
125 if self.samplerate < 2000000:
126 self.putm([1, ['Sampling rate is too low. Must be above ' +
127 '2MHz for proper overdrive mode decoding.']])
128 elif self.samplerate < 5000000:
129 self.putm([1, ['Sampling rate is suggested to be above 5MHz ' +
130 'for proper overdrive mode decoding.']])
132 if self.samplerate < 400000:
133 self.putm([1, ['Sampling rate is too low. Must be above ' +
134 '400kHz for proper normal mode decoding.']])
135 elif (self.samplerate < 1000000):
136 self.putm([1, ['Sampling rate is suggested to be above ' +
137 '1MHz for proper normal mode decoding.']])
139 # The default 1-Wire time base is 30us. This is used to calculate
141 samplerate = float(self.samplerate)
143 x = float(self.options['cnt_normal_bit']) / 1000000.0
144 self.cnt_normal_bit = int(samplerate * x) - 1
145 x = float(self.options['cnt_normal_slot']) / 1000000.0
146 self.cnt_normal_slot = int(samplerate * x) - 1
147 x = float(self.options['cnt_normal_presence']) / 1000000.0
148 self.cnt_normal_presence = int(samplerate * x) - 1
149 x = float(self.options['cnt_normal_reset']) / 1000000.0
150 self.cnt_normal_reset = int(samplerate * x) - 1
151 x = float(self.options['cnt_overdrive_bit']) / 1000000.0
152 self.cnt_overdrive_bit = int(samplerate * x) - 1
153 x = float(self.options['cnt_overdrive_slot']) / 1000000.0
154 self.cnt_overdrive_slot = int(samplerate * x) - 1
155 x = float(self.options['cnt_overdrive_presence']) / 1000000.0
156 self.cnt_overdrive_presence = int(samplerate * x) - 1
157 x = float(self.options['cnt_overdrive_reset']) / 1000000.0
158 self.cnt_overdrive_reset = int(samplerate * x) - 1
160 # Organize values into lists.
161 self.cnt_bit = [self.cnt_normal_bit, self.cnt_overdrive_bit]
162 self.cnt_presence = [self.cnt_normal_presence, self.cnt_overdrive_presence]
163 self.cnt_reset = [self.cnt_normal_reset, self.cnt_overdrive_reset]
164 self.cnt_slot = [self.cnt_normal_slot, self.cnt_overdrive_slot]
166 # Check if sample times are in the allowed range.
168 time_min = float(self.cnt_normal_bit) / self.samplerate
169 time_max = float(self.cnt_normal_bit + 1) / self.samplerate
170 if (time_min < 0.000005) or (time_max > 0.000015):
171 self.putm([1, ['The normal mode data sample time interval ' +
172 '(%2.1fus-%2.1fus) should be inside (5.0us, 15.0us).'
173 % (time_min * 1000000, time_max * 1000000)]])
175 time_min = float(self.cnt_normal_presence) / self.samplerate
176 time_max = float(self.cnt_normal_presence + 1) / self.samplerate
177 if (time_min < 0.0000681) or (time_max > 0.000075):
178 self.putm([1, ['The normal mode presence sample time interval ' +
179 '(%2.1fus-%2.1fus) should be inside (68.1us, 75.0us).'
180 % (time_min * 1000000, time_max * 1000000)]])
182 time_min = float(self.cnt_overdrive_bit) / self.samplerate
183 time_max = float(self.cnt_overdrive_bit + 1) / self.samplerate
184 if (time_min < 0.000001) or (time_max > 0.000002):
185 self.putm([1, ['The overdrive mode data sample time interval ' +
186 '(%2.1fus-%2.1fus) should be inside (1.0us, 2.0us).'
187 % (time_min * 1000000, time_max * 1000000)]])
189 time_min = float(self.cnt_overdrive_presence) / self.samplerate
190 time_max = float(self.cnt_overdrive_presence + 1) / self.samplerate
191 if (time_min < 0.0000073) or (time_max > 0.000010):
192 self.putm([1, ['The overdrive mode presence sample time interval ' +
193 '(%2.1fus-%2.1fus) should be inside (7.3us, 10.0us).'
194 % (time_min*1000000, time_max*1000000)]])
196 def decode(self, ss, es, data):
197 if self.samplerate is None:
198 raise Exception("Cannot decode without samplerate.")
199 for (self.samplenum, (owr, pwr)) in data:
201 if self.state == 'WAIT FOR FALLING EDGE':
202 # The start of a cycle is a falling edge.
205 # Save the sample number for the falling edge.
206 self.fall = self.samplenum
207 # Go to waiting for sample time.
208 self.state = 'WAIT FOR DATA SAMPLE'
209 elif self.state == 'WAIT FOR DATA SAMPLE':
211 t = self.samplenum - self.fall
212 if t == self.cnt_bit[self.overdrive]:
214 self.state = 'WAIT FOR DATA SLOT END'
215 elif self.state == 'WAIT FOR DATA SLOT END':
216 # A data slot ends in a recovery period, otherwise, this is
218 t = self.samplenum - self.fall
219 if t != self.cnt_slot[self.overdrive]:
223 # This seems to be a reset slot, wait for its end.
224 self.state = 'WAIT FOR RISING EDGE'
227 self.putb([0, ['Bit: %d' % self.bit, '%d' % self.bit]])
228 self.putpb(['BIT', self.bit])
230 # Checking the first command to see if overdrive mode
232 if self.bit_cnt <= 8:
233 self.command |= (self.bit << self.bit_cnt)
234 elif self.bit_cnt == 8 and self.command in [0x3c, 0x69]:
235 self.putx([4, ['Entering overdrive mode', 'Overdrive on']])
236 # Increment the bit counter.
238 # Wait for next slot.
239 self.state = 'WAIT FOR FALLING EDGE'
240 elif self.state == 'WAIT FOR RISING EDGE':
241 # The end of a cycle is a rising edge.
245 # Check if this was a reset cycle.
246 t = self.samplenum - self.fall
247 if t > self.cnt_normal_reset:
248 # Save the sample number for the rising edge.
249 self.rise = self.samplenum
250 self.putfr([2, ['Reset', 'Rst', 'R']])
251 self.state = 'WAIT FOR PRESENCE DETECT'
252 # Exit overdrive mode.
254 self.putx([4, ['Exiting overdrive mode', 'Overdrive off']])
256 # Clear command bit counter and data register.
259 elif (t > self.cnt_overdrive_reset) and self.overdrive:
260 # Save the sample number for the rising edge.
261 self.rise = self.samplenum
262 self.putfr([2, ['Reset', 'Rst', 'R']])
263 self.state = "WAIT FOR PRESENCE DETECT"
264 # Otherwise this is assumed to be a data bit.
266 self.state = "WAIT FOR FALLING EDGE"
267 elif self.state == 'WAIT FOR PRESENCE DETECT':
268 # Sample presence status.
269 t = self.samplenum - self.rise
270 if t == self.cnt_presence[self.overdrive]:
272 self.state = 'WAIT FOR RESET SLOT END'
273 elif self.state == 'WAIT FOR RESET SLOT END':
274 # A reset slot ends in a long recovery period.
275 t = self.samplenum - self.rise
276 if t != self.cnt_reset[self.overdrive]:
280 # This seems to be a reset slot, wait for its end.
281 self.state = 'WAIT FOR RISING EDGE'
284 p = 'false' if self.present else 'true'
285 self.putrs([3, ['Presence: %s' % p, 'Presence', 'Pres', 'P']])
286 self.putprs(['RESET/PRESENCE', not self.present])
288 # Wait for next slot.
289 self.state = 'WAIT FOR FALLING EDGE'
291 raise Exception('Invalid state: %s' % self.state)