From: Gerhard Sittig Date: Sat, 23 Apr 2022 17:20:42 +0000 (+0200) Subject: uart: handle two stop bits configuration X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=1fc5b8a515eb06e759e109728b6f18ccdef0c686;p=libsigrokdecode.git uart: handle two stop bits configuration Sample and process multiple STOP bits as specified, add 2.0 to the list of supported configurations. This implementation works as expected with integer numbers of STOP bits (0, 1, 2). For half-bits the sample point as well as the annotation position will be incorrect (as a result of an internal implementation detail of the existing decoder which is not easy to address). This commit reduces the diff size, and remains backwards bug-compatible. Fixing the bit boundaries in annotations including support for half-bits is more involved, and remains for a later commit. --- diff --git a/decoders/uart/pd.py b/decoders/uart/pd.py index a2e1f7f..66bcba8 100644 --- a/decoders/uart/pd.py +++ b/decoders/uart/pd.py @@ -114,7 +114,7 @@ class Decoder(srd.Decoder): {'id': 'parity', 'desc': 'Parity', 'default': 'none', 'values': ('none', 'odd', 'even', 'zero', 'one', 'ignore')}, {'id': 'stop_bits', 'desc': 'Stop bits', 'default': 1.0, - 'values': (0.0, 0.5, 1.0, 1.5)}, + 'values': (0.0, 0.5, 1.0, 1.5, 2.0)}, {'id': 'bit_order', 'desc': 'Bit order', 'default': 'lsb-first', 'values': ('lsb-first', 'msb-first')}, {'id': 'format', 'desc': 'Data format', 'default': 'hex', @@ -211,7 +211,7 @@ class Decoder(srd.Decoder): self.cur_data_bit = [0, 0] self.datavalue = [0, 0] self.paritybit = [-1, -1] - self.stopbit1 = [-1, -1] + self.stopbits = [[], []] self.startsample = [-1, -1] self.state = ['WAIT FOR START BIT', 'WAIT FOR START BIT'] self.databits = [[], []] @@ -269,9 +269,13 @@ class Decoder(srd.Decoder): self.advance_state(rxtx, signal, fatal = True, idle = es) return + # Reset internal state for the pending UART frame. self.cur_data_bit[rxtx] = 0 self.datavalue[rxtx] = 0 + self.paritybit[rxtx] = -1 + self.stopbits[rxtx].clear() self.startsample[rxtx] = -1 + self.databits[rxtx].clear() self.putp(['STARTBIT', rxtx, self.startbit[rxtx]]) self.putg([Ann.RX_START + rxtx, ['Start bit', 'Start', 'S']]) @@ -398,20 +402,21 @@ class Decoder(srd.Decoder): self.advance_state(rxtx, signal) - # TODO: Currently only supports 1 stop bit. def get_stop_bits(self, rxtx, signal): - self.stopbit1[rxtx] = signal + self.stopbits[rxtx].append(signal) # Stop bits must be 1. If not, we report an error. - if self.stopbit1[rxtx] != 1: - self.putp(['INVALID STOPBIT', rxtx, self.stopbit1[rxtx]]) + if signal != 1: + self.putp(['INVALID STOPBIT', rxtx, signal]) self.putg([Ann.RX_WARN + rxtx, ['Frame error', 'Frame err', 'FE']]) self.frame_valid[rxtx] = False - self.putp(['STOPBIT', rxtx, self.stopbit1[rxtx]]) + self.putp(['STOPBIT', rxtx, signal]) self.putg([Ann.RX_STOP + rxtx, ['Stop bit', 'Stop', 'T']]) - # Postprocess the UART frame + # Postprocess the UART frame after all STOP bits were seen. + if len(self.stopbits[rxtx]) < self.options['stop_bits']: + return self.advance_state(rxtx, signal) def advance_state(self, rxtx, signal = None, fatal = False, idle = None): @@ -497,8 +502,10 @@ class Decoder(srd.Decoder): elif state == 'GET PARITY BIT': bitnum = 1 + self.options['data_bits'] elif state == 'GET STOP BITS': + # TODO: Currently does not support half STOP bits. bitnum = 1 + self.options['data_bits'] bitnum += 0 if self.options['parity'] == 'none' else 1 + bitnum += len(self.stopbits[rxtx]) want_num = ceil(self.get_sample_point(rxtx, bitnum)) return {'skip': want_num - self.samplenum}