2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2017 Kevin Redon <kingkevin@cuvoodoo.info>
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 class SamplerateError(Exception):
25 # Timing values in us for the signal at regular and overdrive speed.
91 class Decoder(srd
.Decoder
):
94 name
= '1-Wire link layer'
95 longname
= '1-Wire serial communication bus (link layer)'
96 desc
= 'Bidirectional, half-duplex, asynchronous serial bus.'
99 outputs
= ['onewire_link']
100 tags
= ['Embedded/industrial']
102 {'id': 'owr', 'name': 'OWR', 'desc': '1-Wire signal line'},
105 {'id': 'overdrive', 'desc': 'Start in overdrive speed',
106 'default': 'no', 'values': ('yes', 'no')},
110 ('warning', 'Warning'),
112 ('presence', 'Presence'),
113 ('overdrive', 'Overdrive speed notification'),
116 ('bits', 'Bits', (0, 2, 3)),
117 ('info', 'Info', (4,)),
118 ('warnings', 'Warnings', (1,)),
125 self
.samplerate
= None
126 self
.state
= 'INITIAL'
131 self
.overdrive
= False
136 self
.out_python
= self
.register(srd
.OUTPUT_PYTHON
)
137 self
.out_ann
= self
.register(srd
.OUTPUT_ANN
)
138 self
.overdrive
= (self
.options
['overdrive'] == 'yes')
143 def putm(self
, data
):
144 self
.put(0, 0, self
.out_ann
, data
)
146 def putpfs(self
, data
):
147 self
.put(self
.fall
, self
.samplenum
, self
.out_python
, data
)
149 def putfs(self
, data
):
150 self
.put(self
.fall
, self
.samplenum
, self
.out_ann
, data
)
152 def putfr(self
, data
):
153 self
.put(self
.fall
, self
.rise
, self
.out_ann
, data
)
155 def putprs(self
, data
):
156 self
.put(self
.rise
, self
.samplenum
, self
.out_python
, data
)
158 def putrs(self
, data
):
159 self
.put(self
.rise
, self
.samplenum
, self
.out_ann
, data
)
162 # Check if samplerate is appropriate.
163 if self
.options
['overdrive'] == 'yes':
164 if self
.samplerate
< 2000000:
165 self
.putm([1, ['Sampling rate is too low. Must be above ' +
166 '2MHz for proper overdrive mode decoding.']])
167 elif self
.samplerate
< 5000000:
168 self
.putm([1, ['Sampling rate is suggested to be above 5MHz ' +
169 'for proper overdrive mode decoding.']])
171 if self
.samplerate
< 400000:
172 self
.putm([1, ['Sampling rate is too low. Must be above ' +
173 '400kHz for proper normal mode decoding.']])
174 elif self
.samplerate
< 1000000:
175 self
.putm([1, ['Sampling rate is suggested to be above ' +
176 '1MHz for proper normal mode decoding.']])
178 def metadata(self
, key
, value
):
179 if key
!= srd
.SRD_CONF_SAMPLERATE
:
181 self
.samplerate
= value
183 def wait_falling_timeout(self
, start
, t
):
184 # Wait until either a falling edge is seen, and/or the specified
185 # number of samples have been skipped (i.e. time has passed).
186 cnt
= int((t
[self
.overdrive
] / 1000000.0) * self
.samplerate
)
187 samples_to_skip
= (start
+ cnt
) - self
.samplenum
188 samples_to_skip
= samples_to_skip
if (samples_to_skip
> 0) else 0
189 return self
.wait([{0: 'f'}, {'skip': samples_to_skip
}])
192 if not self
.samplerate
:
193 raise SamplerateError('Cannot decode without samplerate.')
197 if self
.state
== 'INITIAL': # Unknown initial state.
198 # Wait until we reach the idle high state.
200 self
.rise
= self
.samplenum
202 elif self
.state
== 'IDLE': # Idle high state.
203 # Wait for falling edge.
205 self
.fall
= self
.samplenum
206 # Get time since last rising edge.
207 time
= ((self
.fall
- self
.rise
) / self
.samplerate
) * 1000000.0
208 if self
.rise
> 0 and \
209 time
< timing
['REC']['min'][self
.overdrive
]:
210 self
.putfr([1, ['Recovery time not long enough'
211 'Recovery too short',
212 'REC < ' + str(timing
['REC']['min'][self
.overdrive
])]])
213 # A reset pulse or slot can start on a falling edge.
215 # TODO: Check minimum recovery time.
216 elif self
.state
== 'LOW': # Reset pulse or slot.
217 # Wait for rising edge.
219 self
.rise
= self
.samplenum
220 # Detect reset or slot base on timing.
221 time
= ((self
.rise
- self
.fall
) / self
.samplerate
) * 1000000.0
222 if time
>= timing
['RSTL']['min'][False]: # Normal reset pulse.
223 if time
> timing
['RSTL']['max'][False]:
224 self
.putfr([1, ['Too long reset pulse might mask interrupt ' +
225 'signalling by other devices',
226 'Reset pulse too long',
227 'RST > ' + str(timing
['RSTL']['max'][False])]])
228 # Regular reset pulse clears overdrive speed.
230 self
.putfr([4, ['Exiting overdrive mode', 'Overdrive off']])
231 self
.overdrive
= False
232 self
.putfr([2, ['Reset', 'Rst', 'R']])
233 self
.state
= 'PRESENCE DETECT HIGH'
234 elif self
.overdrive
== True and \
235 time
>= timing
['RSTL']['min'][self
.overdrive
] and \
236 time
< timing
['RSTL']['max'][self
.overdrive
]:
237 # Overdrive reset pulse.
238 self
.putfr([2, ['Reset', 'Rst', 'R']])
239 self
.state
= 'PRESENCE DETECT HIGH'
240 elif time
< timing
['SLOT']['max'][self
.overdrive
]:
241 # Read/write time slot.
242 if time
< timing
['LOWR']['min'][self
.overdrive
]:
243 self
.putfr([1, ['Low signal not long enough',
245 'LOW < ' + str(timing
['LOWR']['min'][self
.overdrive
])]])
246 if time
< timing
['LOWR']['max'][self
.overdrive
]:
247 self
.bit
= 1 # Short pulse is a 1 bit.
249 self
.bit
= 0 # Long pulse is a 0 bit.
250 # Wait for end of slot.
253 # Timing outside of known states.
254 self
.putfr([1, ['Erroneous signal', 'Error', 'Err', 'E']])
256 elif self
.state
== 'PRESENCE DETECT HIGH': # Wait for slave presence signal.
257 # Wait for a falling edge and/or presence detect signal.
258 self
.wait_falling_timeout(self
.rise
, timing
['PDH']['max'])
260 # Calculate time since rising edge.
261 time
= ((self
.samplenum
- self
.rise
) / self
.samplerate
) * 1000000.0
263 if self
.matched
[0] and not self
.matched
[1]:
265 if time
< timing
['PDH']['min'][self
.overdrive
]:
266 self
.putrs([1, ['Presence detect signal is too early',
267 'Presence detect too early',
268 'PDH < ' + str(timing
['PDH']['min'][self
.overdrive
])]])
269 self
.fall
= self
.samplenum
270 self
.state
= 'PRESENCE DETECT LOW'
271 else: # No presence detected.
272 self
.putrs([3, ['Presence: false', 'Presence', 'Pres', 'P']])
273 self
.putprs(['RESET/PRESENCE', False])
275 elif self
.state
== 'PRESENCE DETECT LOW': # Slave presence signalled.
276 # Wait for end of presence signal (on rising edge).
278 # Calculate time since start of presence signal.
279 time
= ((self
.samplenum
- self
.fall
) / self
.samplerate
) * 1000000.0
280 if time
< timing
['PDL']['min'][self
.overdrive
]:
281 self
.putfs([1, ['Presence detect signal is too short',
282 'Presence detect too short',
283 'PDL < ' + str(timing
['PDL']['min'][self
.overdrive
])]])
284 elif time
> timing
['PDL']['max'][self
.overdrive
]:
285 self
.putfs([1, ['Presence detect signal is too long',
286 'Presence detect too long',
287 'PDL > ' + str(timing
['PDL']['max'][self
.overdrive
])]])
288 if time
> timing
['RSTH']['min'][self
.overdrive
]:
289 self
.rise
= self
.samplenum
290 # Wait for end of presence detect.
291 self
.state
= 'PRESENCE DETECT'
293 # End states (for additional checks).
294 if self
.state
== 'SLOT': # Wait for end of time slot.
295 # Wait for a falling edge and/or end of timeslot.
296 self
.wait_falling_timeout(self
.fall
, timing
['SLOT']['min'])
298 if self
.matched
[0] and not self
.matched
[1]:
299 # Low detected before end of slot.
300 self
.putfs([1, ['Time slot not long enough',
302 'SLOT < ' + str(timing
['SLOT']['min'][self
.overdrive
])]])
303 # Don't output invalid bit.
304 self
.fall
= self
.samplenum
306 else: # End of time slot.
308 self
.putfs([0, ['Bit: %d' % self
.bit
, '%d' % self
.bit
]])
309 self
.putpfs(['BIT', self
.bit
])
311 if self
.bit_count
>= 0:
312 self
.command
+= (self
.bit
<< self
.bit_count
)
314 # Check for overdrive ROM command.
315 if self
.bit_count
>= 8:
316 if self
.command
== 0x3c or self
.command
== 0x69:
317 self
.overdrive
= True
318 self
.put(self
.samplenum
, self
.samplenum
,
320 [4, ['Entering overdrive mode', 'Overdrive on']])
324 if self
.state
== 'PRESENCE DETECT':
325 # Wait for a falling edge and/or end of presence detect.
326 self
.wait_falling_timeout(self
.rise
, timing
['RSTH']['min'])
328 if self
.matched
[0] and not self
.matched
[1]:
329 # Low detected before end of presence detect.
330 self
.putfs([1, ['Presence detect not long enough',
331 'Presence detect too short',
332 'RTSH < ' + str(timing
['RSTH']['min'][self
.overdrive
])]])
333 # Inform about presence detected.
334 self
.putrs([3, ['Slave presence detected', 'Slave present',
336 self
.putprs(['RESET/PRESENCE', True])
337 self
.fall
= self
.samplenum
339 else: # End of time slot.
340 # Inform about presence detected.
341 self
.putrs([3, ['Presence: true', 'Presence', 'Pres', 'P']])
342 self
.putprs(['RESET/PRESENCE', True])
343 self
.rise
= self
.samplenum
344 # Start counting the first 8 bits to get the ROM command.