##
import sigrokdecode as srd
+from collections import namedtuple
'''
OUTPUT_PYTHON format:
Packet:
-[{'ss': bit start sample number,
- 'se': bit end sample number,
+[namedtuple('ss': bit start sample number,
+ 'es': bit end sample number,
'si': SI bit,
'so': SO bit,
- }, ...]
+ ), ...]
-Since address and word size are variable, a list of all bits in each packet
+Since address and word size are variable, a list of all bits in each packet
need to be output. Since Microwire is a synchronous protocol with separate
input and output lines (SI and SO) they are provided together, but because
Microwire is half-duplex only the SI or SO bits will be considered at once.
and end sample number of each bit (pair of SI/SO bit) are provided.
'''
+PyPacket = namedtuple('PyPacket', 'ss es si so')
+Packet = namedtuple('Packet', 'samplenum matched cs sk si so')
+
class Decoder(srd.Decoder):
api_version = 3
id = 'microwire'
license = 'gplv2+'
inputs = ['logic']
outputs = ['microwire']
+ tags = ['Embedded/industrial']
channels = (
{'id': 'cs', 'name': 'CS', 'desc': 'Chip select'},
{'id': 'sk', 'name': 'SK', 'desc': 'Clock'},
{'id': 'so', 'name': 'SO', 'desc': 'Slave out'},
)
annotations = (
+ ('start-bit', 'Start bit'),
('si-bit', 'SI bit'),
('so-bit', 'SO bit'),
- ('status-check', 'Status check'),
+ ('status-check-ready', 'Status check ready'),
+ ('status-check-busy', 'Status check busy'),
('warning', 'Warning'),
)
annotation_rows = (
- ('si-bits', 'SI bits', (0,)),
- ('so-bits', 'SO bits', (1,)),
- ('status', 'Status', (2,)),
- ('warnings', 'Warnings', (3,)),
+ ('si-bits', 'SI bits', (0, 1)),
+ ('so-bits', 'SO bits', (2,)),
+ ('status', 'Status', (3, 4)),
+ ('warnings', 'Warnings', (5,)),
)
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ pass
+
def start(self):
self.out_python = self.register(srd.OUTPUT_PYTHON)
self.out_ann = self.register(srd.OUTPUT_ANN)
cs, sk, si, so = self.wait({0: 'r'})
if sk:
self.put(self.samplenum, self.samplenum, self.out_ann,
- [3, ['Clock should be low on start',
+ [5, ['Clock should be low on start',
'Clock high on start', 'Clock high', 'SK high']])
sk = 0 # Enforce correct state for correct clock handling.
# Because we don't know if this is bit communication or a
packet = []
while cs:
# Save change.
- packet.append({'samplenum': self.samplenum,
- 'matched': self.matched,
- 'cs': cs, 'sk': sk, 'si': si, 'so': so})
- if sk == 0:
- cs, sk, si, so = self.wait([{0: 'l'}, {1: 'r'}, {3: 'e'}])
- else:
- cs, sk, si, so = self.wait([{0: 'l'}, {1: 'f'}, {3: 'e'}])
+ packet.append(Packet(self.samplenum, self.matched, cs, sk, si, so))
+ edge = 'r' if sk == 0 else 'f'
+ cs, sk, si, so = self.wait([{0: 'l'}, {1: edge}, {3: 'e'}])
# Save last change.
- packet.append({'samplenum': self.samplenum,
- 'matched': self.matched,
- 'cs': cs, 'sk': sk, 'si': si, 'so': so})
+ packet.append(Packet(self.samplenum, self.matched, cs, sk, si, so))
# Figure out if this is a status check.
# Either there is no clock or no start bit (on first rising edge).
status_check = True
for change in packet:
# Get first clock rising edge.
- if len(change['matched']) > 1 and change['matched'][1] \
- and change['sk']:
- if change['si']:
+ if len(change.matched) > 1 and change.matched[1] and change.sk:
+ if change.si:
status_check = False
break
# The SO signal might be noisy in the beginning because it starts
# in high impedance.
if status_check:
- start_samplenum = packet[0]['samplenum']
- bit_so = packet[0]['so']
+ start_samplenum = packet[0].samplenum
+ bit_so = packet[0].so
# Check for SO edges.
for change in packet:
- if len(change['matched']) > 2 and change['matched'][2]:
- if bit_so == 0 and change['so']:
+ if len(change.matched) > 2 and change.matched[2]:
+ if bit_so == 0 and change.so:
# Rising edge Busy -> Ready.
- self.put(start_samplenum, change['samplenum'],
- self.out_ann, [2, ['Busy', 'B']])
- start_samplenum = change['samplenum']
- bit_so = change['so']
+ self.put(start_samplenum, change.samplenum,
+ self.out_ann, [4, ['Busy', 'B']])
+ start_samplenum = change.samplenum
+ bit_so = change.so
# Put last state.
if bit_so == 0:
- self.put(start_samplenum, packet[-1]['samplenum'],
- self.out_ann, [2, ['Busy', 'B']])
+ self.put(start_samplenum, packet[-1].samplenum,
+ self.out_ann, [4, ['Busy', 'B']])
else:
- self.put(start_samplenum, packet[-1]['samplenum'],
- self.out_ann, [2, ['Ready', 'R']])
+ self.put(start_samplenum, packet[-1].samplenum,
+ self.out_ann, [3, ['Ready', 'R']])
else:
# Bit communication.
# Since the slave samples SI on clock rising edge we do the
bit_si = 0 # SI value at rising clock edge.
bit_so = 0 # SO value at falling clock edge.
start_bit = True # Start bit incoming (first bit).
- python_output = [] # Python output data.
+ pydata = [] # Python output data.
for change in packet:
- if len(change['matched']) > 1 and change['matched'][1]:
+ if len(change.matched) > 1 and change.matched[1]:
# Clock edge.
- if change['sk']: # Rising clock edge.
+ if change.sk: # Rising clock edge.
if bit_start > 0: # Bit completed.
if start_bit:
if bit_si == 0: # Start bit missing.
- self.put(bit_start, change['samplenum'],
+ self.put(bit_start, change.samplenum,
self.out_ann,
- [3, ['Start bit not high',
+ [5, ['Start bit not high',
'Start bit low']])
else:
- self.put(bit_start, change['samplenum'],
+ self.put(bit_start, change.samplenum,
self.out_ann,
[0, ['Start bit', 'S']])
start_bit = False
else:
- self.put(bit_start, change['samplenum'],
+ self.put(bit_start, change.samplenum,
self.out_ann,
- [0, ['SI bit: %d' % bit_si,
+ [1, ['SI bit: %d' % bit_si,
'SI: %d' % bit_si,
'%d' % bit_si]])
- self.put(bit_start, change['samplenum'],
+ self.put(bit_start, change.samplenum,
self.out_ann,
- [1, ['SO bit: %d' % bit_so,
+ [2, ['SO bit: %d' % bit_so,
'SO: %d' % bit_so,
'%d' % bit_so]])
- python_output.append({'ss': bit_start,
- 'se': change['samplenum'],
- 'si': bit_si, 'so': bit_so})
- bit_start = change['samplenum']
- bit_si = change['si']
+ pydata.append(PyPacket(bit_start,
+ change.samplenum, bit_si, bit_so))
+ bit_start = change.samplenum
+ bit_si = change.si
else: # Falling clock edge.
- bit_so = change['so']
- elif change['matched'][0] and \
- change['cs'] == 0 and change['sk'] == 0:
+ bit_so = change.so
+ elif change.matched[0] and \
+ change.cs == 0 and change.sk == 0:
# End of packet.
- self.put(bit_start, change['samplenum'], self.out_ann,
- [0, ['SI bit: %d' % bit_si,
+ self.put(bit_start, change.samplenum, self.out_ann,
+ [1, ['SI bit: %d' % bit_si,
'SI: %d' % bit_si, '%d' % bit_si]])
- self.put(bit_start, change['samplenum'], self.out_ann,
- [1, ['SO bit: %d' % bit_so,
+ self.put(bit_start, change.samplenum, self.out_ann,
+ [2, ['SO bit: %d' % bit_so,
'SO: %d' % bit_so, '%d' % bit_so]])
- python_output.append({'ss': bit_start,
- 'se': change['samplenum'],
- 'si': bit_si, 'so': bit_so})
- self.put(packet[0]['samplenum'],
- packet[len(packet) - 1]['samplenum'],
- self.out_python, python_output)
+ pydata.append(PyPacket(bit_start, change.samplenum,
+ bit_si, bit_so))
+ self.put(packet[0].samplenum, packet[len(packet) - 1].samplenum,
+ self.out_python, pydata)