X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fieee488%2Fpd.py;h=0451c14f4f0edb494e66a258278dd060cbd76b42;hb=f697102ece64f8e99bfd26bbc2dedadaa037a0e5;hp=ed3d39b5fb2b1a459d7de9ac9d57989308680bc2;hpb=08198247a57a4352c3a1f1201da7b52e0ede15c4;p=libsigrokdecode.git diff --git a/decoders/ieee488/pd.py b/decoders/ieee488/pd.py index ed3d39b..0451c14 100644 --- a/decoders/ieee488/pd.py +++ b/decoders/ieee488/pd.py @@ -255,7 +255,7 @@ class Decoder(srd.Decoder): api_version = 3 id = 'ieee488' name = 'IEEE-488' - longname = 'General Purpose Interface Bus' + longname = 'IEEE-488 GPIB/HPIB/IEC' desc = 'IEEE-488 General Purpose Interface Bus (GPIB/HPIB or IEC).' license = 'gplv2+' inputs = ['logic'] @@ -286,6 +286,10 @@ class Decoder(srd.Decoder): options = ( {'id': 'iec_periph', 'desc': 'Decode Commodore IEC bus peripherals details', 'default': 'no', 'values': ('no', 'yes')}, + {'id': 'delim', 'desc': 'Payload data delimiter', + 'default': 'eol', 'values': ('none', 'eol')}, + {'id': 'atn_parity', 'desc': 'ATN commands use parity', + 'default': 'no', 'values': ('no', 'yes')}, ) annotations = ( ('bit', 'IEC bit'), @@ -298,7 +302,7 @@ class Decoder(srd.Decoder): ('eoi', 'EOI'), ('text', 'Talker text'), ('periph', 'IEC bus peripherals'), - ('warn', 'Warning'), + ('warning', 'Warning'), ) annotation_rows = ( ('bits', 'IEC bits', (ANN_RAW_BIT,)), @@ -307,7 +311,7 @@ class Decoder(srd.Decoder): ('eois', 'EOI', (ANN_EOI,)), ('texts', 'Talker texts', (ANN_TEXT,)), ('periphs', 'IEC peripherals', (ANN_IEC_PERIPH,)), - ('warns', 'Warnings', (ANN_WARN,)), + ('warnings', 'Warnings', (ANN_WARN,)), ) binary = ( ('raw', 'Raw bytes'), @@ -374,12 +378,38 @@ class Decoder(srd.Decoder): self.accu_text = [] self.ss_text = self.es_text = None + def check_extra_flush(self, b): + # Optionally flush previously accumulated runs of payload data + # according to user specified conditions. + if self.options['delim'] == 'none': + return + if not self.accu_bytes: + return + + # This implementation exlusively handles "text lines", but adding + # support for more variants here is straight forward. + # + # Search for the first data byte _after_ a user specified text + # line termination sequence was seen. The termination sequence's + # alphabet may be variable, and the sequence may span multiple + # data bytes. We accept either CR or LF, and combine the CR+LF + # sequence to strive for maximum length annotations for improved + # readability at different zoom levels. It's acceptable that this + # implementation would also combine multiple line terminations + # like LF+LF. + term_chars = (10, 13) + is_eol = b in term_chars + had_eol = self.accu_bytes[-1] in term_chars + if had_eol and not is_eol: + self.flush_bytes_text_accu() + def handle_ifc_change(self, ifc): # Track IFC line for parallel input. # Assertion of IFC de-selects all talkers and listeners. if ifc: self.last_talker = None self.last_listener = [] + self.flush_bytes_text_accu() def handle_eoi_change(self, eoi): # Track EOI line for parallel and serial input. @@ -446,6 +476,8 @@ class Decoder(srd.Decoder): # TODO Process data depending on peripheral type and channel? def handle_data_byte(self): + if not self.curr_atn: + self.check_extra_flush(self.curr_raw) b = self.curr_raw texts = _get_raw_text(b, self.curr_atn) self.emit_data_ann(self.ss_raw, self.es_raw, ANN_RAW_BYTE, texts) @@ -456,6 +488,13 @@ class Decoder(srd.Decoder): upd_iec = False, py_type = None py_peers = False + if self.options['atn_parity'] == 'yes': + par = 1 if b & 0x80 else 0 + b &= ~0x80 + ones = bin(b).count('1') + par + if ones % 2: + warn_texts = ['Command parity error', 'parity', 'PAR'] + self.emit_warn_ann(self.ss_raw, self.es_raw, warn_texts) is_cmd, is_unl, is_unt = _is_command(b) laddr = _is_listen_addr(b) taddr = _is_talk_addr(b)