+ # Pass the complete UART frame to upper layers.
+ es = self.samplenum + ceil(self.bit_width / 2.0)
+ self.putpse(self.frame_start[rxtx], es, ['FRAME', rxtx,
+ (self.datavalue[rxtx], self.frame_valid[rxtx])])
+
+ self.state[rxtx] = 'WAIT FOR START BIT'
+ self.idle_start[rxtx] = self.frame_start[rxtx] + self.frame_len_sample_count
+
+ def handle_break(self, rxtx):
+ self.putpse(self.frame_start[rxtx], self.samplenum,
+ ['BREAK', rxtx, 0])
+ self.putgse(self.frame_start[rxtx], self.samplenum,
+ [rxtx + 14, ['Break condition', 'Break', 'Brk', 'B']])
+ self.state[rxtx] = 'WAIT FOR START BIT'
+
+ def get_wait_cond(self, rxtx, inv):
+ # Return condititions that are suitable for Decoder.wait(). Those
+ # conditions either match the falling edge of the START bit, or
+ # the sample point of the next bit time.
+ state = self.state[rxtx]
+ if state == 'WAIT FOR START BIT':
+ return {rxtx: 'r' if inv else 'f'}
+ if state == 'GET START BIT':
+ bitnum = 0
+ elif state == 'GET DATA BITS':
+ bitnum = 1 + self.cur_data_bit[rxtx]
+ elif state == 'GET PARITY BIT':
+ bitnum = 1 + self.options['data_bits']
+ elif state == 'GET STOP BITS':
+ bitnum = 1 + self.options['data_bits']
+ bitnum += 0 if self.options['parity'] == 'none' else 1
+ want_num = ceil(self.get_sample_point(rxtx, bitnum))
+ return {'skip': want_num - self.samplenum}
+
+ def get_idle_cond(self, rxtx, inv):
+ # Return a condition that corresponds to the (expected) end of
+ # the next frame, assuming that it will be an "idle frame"
+ # (constant high input level for the frame's length).
+ if self.idle_start[rxtx] is None:
+ return None
+ end_of_frame = self.idle_start[rxtx] + self.frame_len_sample_count
+ if end_of_frame < self.samplenum:
+ return None
+ return {'skip': end_of_frame - self.samplenum}
+
+ def inspect_sample(self, rxtx, signal, inv):
+ # Inspect a sample returned by .wait() for the specified UART line.
+ if inv:
+ signal = not signal
+
+ state = self.state[rxtx]
+ if state == 'WAIT FOR START BIT':
+ self.wait_for_start_bit(rxtx, signal)
+ elif state == 'GET START BIT':
+ self.get_start_bit(rxtx, signal)
+ elif state == 'GET DATA BITS':
+ self.get_data_bits(rxtx, signal)
+ elif state == 'GET PARITY BIT':
+ self.get_parity_bit(rxtx, signal)
+ elif state == 'GET STOP BITS':
+ self.get_stop_bits(rxtx, signal)
+
+ def inspect_edge(self, rxtx, signal, inv):
+ # Inspect edges, independently from traffic, to detect break conditions.
+ if inv:
+ signal = not signal
+ if not signal:
+ # Signal went low. Start another interval.
+ self.break_start[rxtx] = self.samplenum
+ return
+ # Signal went high. Was there an extended period with low signal?
+ if self.break_start[rxtx] is None:
+ return
+ diff = self.samplenum - self.break_start[rxtx]
+ if diff >= self.break_min_sample_count:
+ self.handle_break(rxtx)
+ self.break_start[rxtx] = None
+
+ def inspect_idle(self, rxtx, signal, inv):
+ # Check each edge and each period of stable input (either level).
+ # Can derive the "idle frame period has passed" condition.
+ if inv:
+ signal = not signal
+ if not signal:
+ # Low input, cease inspection.
+ self.idle_start[rxtx] = None
+ return
+ # High input, either just reached, or still stable.
+ if self.idle_start[rxtx] is None:
+ self.idle_start[rxtx] = self.samplenum
+ diff = self.samplenum - self.idle_start[rxtx]
+ if diff < self.frame_len_sample_count:
+ return
+ ss, es = self.idle_start[rxtx], self.samplenum
+ self.putpse(ss, es, ['IDLE', rxtx, 0])
+ self.idle_start[rxtx] = self.samplenum
+
+ def decode(self):