2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2018 Max Weller
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
21 import sigrokdecode as srd
22 from common.srdhelper import SrdIntEnum
24 Pin = SrdIntEnum.from_str('Pin', 'CLK DATA CE')
26 ann_cmdbit, ann_databit, ann_cmd, ann_data, ann_warning = range(5)
28 class Decoder(srd.Decoder):
32 longname = 'Siemens SDA 2506-5'
33 desc = 'Serial nonvolatile 1-Kbit EEPROM.'
37 tags = ['IC', 'Memory']
39 {'id': 'clk', 'name': 'CLK', 'desc': 'Clock'},
40 {'id': 'd', 'name': 'DATA', 'desc': 'Data'},
41 {'id': 'ce', 'name': 'CE#', 'desc': 'Chip-enable'},
44 ('cmdbit', 'Command bit'),
45 ('databit', 'Data bit'),
47 ('databyte', 'Data byte'),
48 ('warning', 'Warning'),
51 ('bits', 'Bits', (ann_cmdbit, ann_databit)),
52 ('data', 'Data', (ann_data,)),
53 ('commands', 'Commands', (ann_cmd,)),
54 ('warnings', 'Warnings', (ann_warning,)),
58 self.samplerate = None
65 def metadata(self, key, value):
66 if key == srd.SRD_CONF_SAMPLERATE:
67 self.samplerate = value
70 self.out_ann = self.register(srd.OUTPUT_ANN)
72 def putbit(self, ss, es, typ, value):
73 self.put(ss, es, self.out_ann, [typ, ['%s' % (value)]])
75 def putdata(self, ss, es):
78 value = (value << 1) | self.databits[i]
79 self.put(ss, es, self.out_ann, [ann_data, ['%02X' % (value)]])
81 def decode_bits(self, offset, width):
83 for i in range(width):
84 out = (out << 1) | self.cmdbits[offset + i][0]
85 return (out, self.cmdbits[offset + width - 1][1], self.cmdbits[offset][2])
87 def decode_field(self, name, offset, width):
88 val, ss, es = self.decode_bits(offset, width)
89 self.put(ss, es, self.out_ann, [ann_data, ['%s: %02X' % (name, val)]])
94 # Wait for CLK edge or CE# edge.
95 clk, d, ce = self.wait([{Pin.CLK: 'e'}, {Pin.CE: 'e'}])
97 if self.matched[0] and ce == 1 and clk == 1:
98 # Rising clk edge and command mode.
99 bitstart = self.samplenum
101 self.cmdbits = [(d, bitstart, self.samplenum)] + self.cmdbits
102 if len(self.cmdbits) > 24:
103 self.cmdbits = self.cmdbits[0:24]
104 self.putbit(bitstart, self.samplenum, ann_cmdbit, d)
105 elif self.matched[0] and ce == 0 and clk == 0:
106 # Falling clk edge and data mode.
107 bitstart = self.samplenum
108 clk, d, ce = self.wait([{'skip': int(2.5 * (1e6 / self.samplerate))}, {0: 'r'}, {2: 'e'}]) # Wait 25 us for data ready.
109 if self.matched == (True, False, False):
110 self.wait([{0: 'r'}, {2: 'e'}])
111 if len(self.databits) == 0:
112 self.datastart = bitstart
113 self.databits = [d] + self.databits
114 self.putbit(bitstart, self.samplenum, ann_databit, d)
115 if len(self.databits) == 8:
116 self.putdata(self.datastart, self.samplenum)
118 elif self.matched[1] and ce == 0:
121 self.decode_field('addr', 1, 7)
122 self.decode_field('CB', 0, 1)
123 if self.cmdbits[0][0] == 0:
124 # Beginning read command.
125 self.decode_field('read', 1, 7)
126 self.put(self.cmdbits[7][1], self.samplenum,
127 self.out_ann, [ann_cmd, ['read' ]])
129 # Beginning write command.
130 self.decode_field('data', 8, 8)
131 addr, ss, es = self.decode_bits(1, 7)
132 data, ss, es = self.decode_bits(8, 8)
133 cmdstart = self.samplenum
135 self.put(cmdstart, self.samplenum, self.out_ann,
136 [ann_cmd, ['Write to %02X: %02X' % (addr, data)]])
138 # Beginning erase command.
139 val, ss, es = self.decode_bits(1, 7)
140 cmdstart = self.samplenum
142 self.put(cmdstart, self.samplenum, self.out_ann,
143 [ann_cmd, ['Erase: %02X' % (val)]])
145 except Exception as ex: