## ## This file is part of the libsigrokdecode project. ## ## Copyright (C) 2013-2016 Uwe Hermann ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## 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, see . ## import sigrokdecode as srd from common.srdhelper import bitpack class ChannelError(Exception): pass NUM_CHANNELS = 32 class Decoder(srd.Decoder): api_version = 3 id = 'i80' name = 'Intel 8080' longname = 'Intel 8080 like bus' desc = 'Parallel asynchronous 8/16 bit bus.' license = 'gplv2+' inputs = ['logic'] outputs = ['i80'] tags = ['Util'] channels = ( {'id': 'cs', 'name': 'CS', 'desc': 'Chip select line', 'idn':'dec_i80_chan_cs'}, {'id': 'cmd', 'name': 'CMD', 'desc': 'Command line', 'idn':'dec_i80_chan_cmd'}, {'id': 'rst', 'name': 'RST', 'desc': 'Reset line', 'idn':'dec_i80_chan_rst'}, {'id': 'hrdy', 'name': 'HRDY', 'desc': 'Ready line', 'idn':'dec_i80_chan_hrdy'}, {'id': 'd0', 'name': 'D0', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d0'}, {'id': 'd1', 'name': 'D1', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d1'}, {'id': 'd2', 'name': 'D2', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d2'}, {'id': 'd3', 'name': 'D3', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d3'}, {'id': 'd4', 'name': 'D4', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d4'}, {'id': 'd5', 'name': 'D5', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d5'}, {'id': 'd6', 'name': 'D6', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d6'}, {'id': 'd7', 'name': 'D7', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d7'}, ) optional_channels = ( {'id': 'd8', 'name': 'D8', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d8'}, {'id': 'd9', 'name': 'D9', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d9'}, {'id': 'd10', 'name': 'D10', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d10'}, {'id': 'd11', 'name': 'D11', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d11'}, {'id': 'd12', 'name': 'D12', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d12'}, {'id': 'd13', 'name': 'D13', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d13'}, {'id': 'd14', 'name': 'D14', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d14'}, {'id': 'd15', 'name': 'D15', 'desc': 'Serial data line', 'idn':'dec_i80_chan_d15'}, {'id': 'hwe', 'name': 'HWE', 'desc': 'Write enable line', 'idn':'dec_i80_chan_hwe'}, {'id': 'hre', 'name': 'HRE', 'desc': 'Read enable line', 'idn':'dec_i80_chan_hre'}, ) options = ( {'id': 'cs_polarity', 'desc': 'Chip select active state', 'default': 'low', 'values': ('low', 'high'), 'idn':'dec_i80_opt_cs_polarity'}, {'id': 'cmd_polarity', 'desc': 'Command active state', 'default': 'low', 'values': ('low', 'high'), 'idn':'dec_i80_opt_cmd_polarity'}, {'id': 'hwe_polarity', 'desc': 'Write enable active state', 'default': 'low', 'values': ('low', 'high'), 'idn':'dec_i80_opt_hwe_polarity'}, {'id': 'hre_polarity', 'desc': 'Read enable active state', 'default': 'low', 'values': ('low', 'high'), 'idn':'dec_i80_opt_hre_polarity'}, {'id': 'rst_polarity', 'desc': 'Reset polarity', 'default': 'low', 'values': ('low', 'high'), 'idn':'dec_i80_opt_rst_polarity'}, {'id': 'hrdy_polarity', 'desc': 'HRDY polarity', 'default': 'high', 'values': ('low', 'high'), 'idn':'dec_i80_opt_cs_polarity'}, {'id': 'endianness', 'desc': 'Data endianness', 'default': 'little', 'values': ('little', 'big'), 'idn':'dec_i80_opt_endianess'}, ) annotations = ( ('write_data', 'Write'), ('read_data', 'Read'), ('command', 'Command'), ('reset', 'Reset'), ('warnings', 'Warnings'), ) annotation_rows = ( ('data', 'Data', (0,1,2)), ('events', 'Events', (3,)), ('warnings', 'Warnings', (4,)), ) def __init__(self): self.reset() def reset(self): self.items = [] self.saved_item = None self.saved_word = None self.ss_word = self.es_word = None self.first = True self.have_clock = True self.prv_dex = 0 self.num_item_bits = None def start(self): self.out_python = self.register(srd.OUTPUT_PYTHON) self.out_ann = self.register(srd.OUTPUT_ANN) def putd(self, s, e, data): self.put(s, e, self.out_ann, data) def end(self): #the last annotation #self.put_py(self._data_begin, self.samplenum, ['ITEM', self._data]) #self.put_ann(self._data_begin, self.samplenum, [0, [self.format.format(self._data)]]) ... def decode(self): # Determine which (optional) channels have input data. Insist in # a non-empty input data set. Cope with sparse connection maps. # Store enough state to later "compress" sampled input data. bus_width_8_bit = all(not self.has_channel(chan) for chan in range(12, 20)) bus_width_16_bit = all(self.has_channel(chan) for chan in range(12, 20)) if not bus_width_8_bit and not bus_width_16_bit: raise ChannelError('Can\'t determine bus width. Define only 8 or 16 bits!') self.format = "@{{:0{}X}}".format(2 if bus_width_8_bit else 4) have_hwe = self.has_channel(20) hwe_active_low = self.options['hwe_polarity'] == 'low' have_hre = self.has_channel(21) hre_active_low = self.options['hre_polarity'] == 'low' if not have_hwe and not have_hre: raise ChannelError('Either hre or hwe must be set!') cs_active_low = self.options['cs_polarity'] == 'low' cmd_active_low = self.options['cmd_polarity'] == 'low' rst_active_low = self.options['rst_polarity'] == 'low' trigger_conds = [ {0: 'e'}, # CS {2: 'e'}, # RST {20: 'r' if hwe_active_low else 'f'}, # HWE {21: 'r' if hre_active_low else 'f'}, # HRE ] # Keep processing the input stream. Assume "always zero" for # not-connected input lines. is_first = True self._last_samplenum = 0 while True: (cs, cmd, rst, hrdy, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 ,d11 ,d12 ,d13 ,d14 ,d15, hwe, hre) = self.wait(trigger_conds) operation = (cs, cmd, hwe, hre, rst, hrdy) if bus_width_8_bit: data = bitpack([d0, d1, d2, d3, d4, d5, d6, d7]) elif bus_width_16_bit: data = bitpack([d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15]) if is_first: is_first = False self._last_operation = operation self._data_begin = 0 self._rst_begin = 0 self._data = data self._data_is_cmd = operation[1] self._data_dir = 1 self._last_samplenum = self.samplenum continue # check edge on hwe if have_hwe and ((not self._last_operation[2] and operation[2] and hwe_active_low) or (self._last_operation[2] and not operation[2] and not hwe_active_low)): self._data = data self._data_is_cmd = not operation[1] if cmd_active_low else operation[1] self._data_dir = 1 # check edge on hre elif have_hre and ((not self._last_operation[3] and operation[3] and hre_active_low) or (self._last_operation[3] and not operation[3] and not hre_active_low)): self._data = data self._data_is_cmd = not operation[1] if cmd_active_low else operation[1] self._data_dir = 0 # check cs switch if operation[0] != self._last_operation[0]: # cs on if cs_active_low != operation[0]: self._data_begin = self.samplenum #cs off elif self._data_is_cmd: self.putd(self._data_begin, self.samplenum, [2, [self.format.format(self._data)]]) else: self.putd(self._data_begin, self.samplenum, [0 if self._data_dir else 1, [self.format.format(self._data)]]) # check rst switch if operation[4] != self._last_operation[4]: if rst_active_low != operation[4]: self._rst_begin = self.samplenum else: self.putd(self._rst_begin, self.samplenum, [3, ['Reset']]) self._last_operation = operation self._last_samplenum = self.samplenum