X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=decoders%2Fuart%2Fpd.py;h=e767699250ce0ff70a8b5ce495816542ae1c15b8;hp=0e6e548cfc08aa3ccc5a50981daa66e4c441d2aa;hb=4539e9ca58966ce3c9cad4801b16c315e86ace01;hpb=92b7b49f6964f57a7d6fc4473645c993cfa4ba52 diff --git a/decoders/uart/pd.py b/decoders/uart/pd.py index 0e6e548..e767699 100644 --- a/decoders/uart/pd.py +++ b/decoders/uart/pd.py @@ -14,8 +14,7 @@ ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## along with this program; if not, see . ## import sigrokdecode as srd @@ -31,7 +30,7 @@ This is the list of s and their respective values: - 'STARTBIT': The data is the (integer) value of the start bit (0/1). - 'DATA': This is always a tuple containing two items: - 1st item: the (integer) value of the UART data. Valid values - range from 0 to 512 (as the data can be up to 9 bits in size). + range from 0 to 511 (as the data can be up to 9 bits in size). - 2nd item: the list of individual data bits and their ss/es numbers. - 'PARITYBIT': The data is the (integer) value of the parity bit (0/1). - 'STOPBIT': The data is the (integer) value of the stop bit (0 or 1). @@ -102,7 +101,7 @@ class Decoder(srd.Decoder): 'values': (0.0, 0.5, 1.0, 1.5)}, {'id': 'bit_order', 'desc': 'Bit order', 'default': 'lsb-first', 'values': ('lsb-first', 'msb-first')}, - {'id': 'format', 'desc': 'Data format', 'default': 'ascii', + {'id': 'format', 'desc': 'Data format', 'default': 'hex', 'values': ('ascii', 'dec', 'hex', 'oct', 'bin')}, {'id': 'invert_rx', 'desc': 'Invert RX?', 'default': 'no', 'values': ('yes', 'no')}, @@ -166,7 +165,7 @@ class Decoder(srd.Decoder): self.frame_start = [-1, -1] self.startbit = [-1, -1] self.cur_data_bit = [0, 0] - self.databyte = [0, 0] + self.datavalue = [0, 0] self.paritybit = [-1, -1] self.stopbit1 = [-1, -1] self.startsample = [-1, -1] @@ -179,6 +178,7 @@ class Decoder(srd.Decoder): self.out_python = self.register(srd.OUTPUT_PYTHON) self.out_binary = self.register(srd.OUTPUT_BINARY) self.out_ann = self.register(srd.OUTPUT_ANN) + self.bw = (self.options['num_data_bits'] + 7) // 8 def metadata(self, key, value): if key == srd.SRD_CONF_SAMPLERATE: @@ -223,14 +223,16 @@ class Decoder(srd.Decoder): self.startbit[rxtx] = signal - # The startbit must be 0. If not, we report an error. + # The startbit must be 0. If not, we report an error and wait + # for the next start bit (assuming this one was spurious). if self.startbit[rxtx] != 0: self.putp(['INVALID STARTBIT', rxtx, self.startbit[rxtx]]) self.putg([rxtx + 10, ['Frame error', 'Frame err', 'FE']]) - # TODO: Abort? Ignore rest of the frame? + self.state[rxtx] = 'WAIT FOR START BIT' + return self.cur_data_bit[rxtx] = 0 - self.databyte[rxtx] = 0 + self.datavalue[rxtx] = 0 self.startsample[rxtx] = -1 self.state[rxtx] = 'GET DATA BITS' @@ -249,12 +251,12 @@ class Decoder(srd.Decoder): # Get the next data bit in LSB-first or MSB-first fashion. if self.options['bit_order'] == 'lsb-first': - self.databyte[rxtx] >>= 1 - self.databyte[rxtx] |= \ + self.datavalue[rxtx] >>= 1 + self.datavalue[rxtx] |= \ (signal << (self.options['num_data_bits'] - 1)) else: - self.databyte[rxtx] <<= 1 - self.databyte[rxtx] |= (signal << 0) + self.datavalue[rxtx] <<= 1 + self.datavalue[rxtx] |= (signal << 0) self.putg([rxtx + 12, ['%d' % signal]]) @@ -270,25 +272,60 @@ class Decoder(srd.Decoder): self.state[rxtx] = 'GET PARITY BIT' self.putpx(rxtx, ['DATA', rxtx, - (self.databyte[rxtx], self.databits[rxtx])]) - - b, f = self.databyte[rxtx], self.options['format'] - if f == 'ascii': - c = chr(b) if b in range(30, 126 + 1) else '[%02X]' % b - self.putx(rxtx, [rxtx, [c]]) - elif f == 'dec': - self.putx(rxtx, [rxtx, [str(b)]]) - elif f == 'hex': - self.putx(rxtx, [rxtx, [hex(b)[2:].zfill(2).upper()]]) - elif f == 'oct': - self.putx(rxtx, [rxtx, [oct(b)[2:].zfill(3)]]) - elif f == 'bin': - self.putx(rxtx, [rxtx, [bin(b)[2:].zfill(8)]]) - - self.putbin(rxtx, [rxtx, bytes([b])]) - self.putbin(rxtx, [2, bytes([b])]) + (self.datavalue[rxtx], self.databits[rxtx])]) + + b = self.datavalue[rxtx] + formatted = self.format_value(b) + if formatted is not None: + self.putx(rxtx, [rxtx, [formatted]]) + + bdata = b.to_bytes(self.bw, byteorder='big') + self.putbin(rxtx, [rxtx, bdata]) + self.putbin(rxtx, [2, bdata]) + + self.databits[rxtx] = [] + + def format_value(self, v): + # Format value 'v' according to configured options. + # Reflects the user selected kind of representation, as well as + # the number of data bits in the UART frames. + + fmt, bits = self.options['format'], self.options['num_data_bits'] + + # Assume "is printable" for values from 32 to including 126, + # below 32 is "control" and thus not printable, above 127 is + # "not ASCII" in its strict sense, 127 (DEL) is not printable, + # fall back to hex representation for non-printables. + if fmt == 'ascii': + if v in range(32, 126 + 1): + return chr(v) + hexfmt = "[{:02X}]" if bits <= 8 else "[{:03X}]" + return hexfmt.format(v) + + # Mere number to text conversion without prefix and padding + # for the "decimal" output format. + if fmt == 'dec': + return "{:d}".format(v) + + # Padding with leading zeroes for hex/oct/bin formats, but + # without a prefix for density -- since the format is user + # specified, there is no ambiguity. + if fmt == 'hex': + digits = (bits + 4 - 1) // 4 + fmtchar = "X" + elif fmt == 'oct': + digits = (bits + 3 - 1) // 3 + fmtchar = "o" + elif fmt == 'bin': + digits = bits + fmtchar = "b" + else: + fmtchar = None + if fmtchar is not None: + fmt = "{{:0{:d}{:s}}}".format(digits, fmtchar) + return fmt.format(v) - self.databits = [[], []] + return None def get_parity_bit(self, rxtx, signal): # If no parity is used/configured, skip to the next state immediately. @@ -305,7 +342,7 @@ class Decoder(srd.Decoder): self.state[rxtx] = 'GET STOP BITS' if parity_ok(self.options['parity_type'], self.paritybit[rxtx], - self.databyte[rxtx], self.options['num_data_bits']): + self.datavalue[rxtx], self.options['num_data_bits']): self.putp(['PARITYBIT', rxtx, self.paritybit[rxtx]]) self.putg([rxtx + 4, ['Parity bit', 'Parity', 'P']]) else: