Files
templates/python/logic_analyzer/decoders/transistor_pair.py

57 lines
2.9 KiB
Python

"""Independent complementary transistor input timing; no ACK/Vstat dependency."""
import math
from .gate_timing import InputTimingChecker, format_ns
class PairTimingChecker(InputTimingChecker):
def __init__(self, samplerate, vin1_active_high=True, vin2_active_high=True,
vin1_mintime_ns=0, vin2_mintime_ns=0,
deadtime_12_ns=0, deadtime_21_ns=0,
vin1_minoff_ns=0, vin2_minoff_ns=0):
super().__init__(samplerate, vin1_active_high, vin2_active_high,
vin1_mintime_ns, vin2_mintime_ns)
self.deadtime_min = (float(deadtime_12_ns), float(deadtime_21_ns))
self.minoff = (float(vin1_minoff_ns), float(vin2_minoff_ns))
if any(not math.isfinite(v) or v < 0 for v in self.deadtime_min + self.minoff):
raise ValueError('Timing limits must be finite and non-negative')
self.last_on = [None, None]
self.last_off = [None, None]
def update(self, sample, vin1, vin2):
sample = int(sample)
previous = self.levels[:] if self.levels is not None else None
events = super().update(sample, vin1, vin2)
for event in events:
if event['kind'] == 'deadtime':
source = event['from_channel'] - 1
limit = self.deadtime_min[source]
if event['duration_ns'] < limit:
event['kind'] = 'deadtime_fail'
event['text'] = 'FAULT: ' + event['text'] + ' < minimum ' + format_ns(limit)
event['short'] = 'FAULT: deadtime'
if previous is None:
return events
for i in range(2):
if previous[i] and not self.levels[i]:
self.last_off[i] = sample
elif not previous[i] and self.levels[i]:
off = self.last_off[i]
on = self.last_on[i]
if off is not None:
duration = (sample - off) * 1e9 / self.samplerate
failed = duration < self.minoff[i]
events.append(self._event('off_fail' if failed else 'off_time', off, sample,
'%s: Vin%d OFF (minimum %s)' %
('FAULT' if failed else 'OK', i + 1, format_ns(self.minoff[i])), channel=i+1))
if on is not None and off is not None and on < off < sample:
period = sample - on
frequency = self.samplerate / period
duty = 100.0 * (off - on) / period
text = 'Vin%d: period %s, %.3f Hz, duty %.2f%%' % (
i + 1, format_ns(period * 1e9 / self.samplerate), frequency, duty)
events.append(dict(kind='period', start=on, end=sample, text=text,
short='%.3f Hz / %.2f%%' % (frequency, duty),
channel=i+1, frequency_hz=frequency, duty_percent=duty))
self.last_on[i] = sample
return events