From bd50ceb314e4607e596c98c534aafcfe142a73b6 Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Wed, 4 Dec 2019 21:21:03 +0100 Subject: [PATCH] uart: allow arbitrary sample positions for UART bit values (1-99%) The previous implementation of the UART decoder used to sample bit values strictly at the center position within a bit time. This commit introduces support to sample bit values at arbitrary positions in the range of 1-99% of the bit time. This allows to work around glitches in existing captures as well as using the decoder for UART like protocols which don't sample bit values at the center position (like EIB aka KNX). This implementation is incomplete (on purpose). Although this version improves the ability to extract data from captures, it also introduces inaccuracies in the annotation positions for non-default values of the sample point position. Addressing this issue is left for later, assuming that it'll be a byproduct of another commit series that is being worked on (general annotation position adjustment and stop bits support). --- decoders/uart/pd.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/decoders/uart/pd.py b/decoders/uart/pd.py index 4ce6ef9..9ffcb56 100644 --- a/decoders/uart/pd.py +++ b/decoders/uart/pd.py @@ -114,6 +114,7 @@ class Decoder(srd.Decoder): 'values': ('yes', 'no')}, {'id': 'invert_tx', 'desc': 'Invert TX', 'default': 'no', 'values': ('yes', 'no')}, + {'id': 'sample_point', 'desc': 'Sample point (%)', 'default': 50}, {'id': 'rx_packet_delim', 'desc': 'RX packet delimiter (decimal)', 'default': -1}, {'id': 'tx_packet_delim', 'desc': 'TX packet delimiter (decimal)', @@ -224,12 +225,15 @@ class Decoder(srd.Decoder): def get_sample_point(self, rxtx, bitnum): # Determine absolute sample number of a bit slot's sample point. - # bitpos is the samplenumber which is in the middle of the - # specified UART bit (0 = start bit, 1..x = data, x+1 = parity bit - # (if used) or the first stop bit, and so on). - # The samples within bit are 0, 1, ..., (bit_width - 1), therefore - # index of the middle sample within bit window is (bit_width - 1) / 2. - bitpos = self.frame_start[rxtx] + (self.bit_width - 1) / 2.0 + # Counts for UART bits start from 0 (0 = start bit, 1..x = data, + # x+1 = parity bit (if used) or the first stop bit, and so on). + # Accept a position in the range of 1.99% of the full bit width. + # Assume 50% for invalid input specs for backwards compatibility. + perc = self.options['sample_point'] or 50 + if not perc or perc not in range(1, 100): + perc = 50 + bitpos = (self.bit_width - 1) * perc / 100 + bitpos += self.frame_start[rxtx] bitpos += bitnum * self.bit_width return bitpos -- 2.30.2