Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Raptor Engineering Public Development
dsview
Commits
b018742e
Unverified
Commit
b018742e
authored
5 years ago
by
DreamSourceLab
Committed by
GitHub
5 years ago
Browse files
Options
Download
Plain Diff
Merge pull request #262 from abougouffa/master
Fix #258, and add new decoders
parents
c5c12248
ce11f856
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1500 additions
and
0 deletions
+1500
-0
DSView/CMakeLists.txt
DSView/CMakeLists.txt
+2
-0
libsigrokdecode4DSL/decoders/cc1101/__init__.py
libsigrokdecode4DSL/decoders/cc1101/__init__.py
+28
-0
libsigrokdecode4DSL/decoders/cc1101/lists.py
libsigrokdecode4DSL/decoders/cc1101/lists.py
+115
-0
libsigrokdecode4DSL/decoders/cc1101/pd.py
libsigrokdecode4DSL/decoders/cc1101/pd.py
+293
-0
libsigrokdecode4DSL/decoders/ds2408/__init__.py
libsigrokdecode4DSL/decoders/ds2408/__init__.py
+25
-0
libsigrokdecode4DSL/decoders/ds2408/pd.py
libsigrokdecode4DSL/decoders/ds2408/pd.py
+129
-0
libsigrokdecode4DSL/decoders/enc28j60/__init__.py
libsigrokdecode4DSL/decoders/enc28j60/__init__.py
+32
-0
libsigrokdecode4DSL/decoders/enc28j60/lists.py
libsigrokdecode4DSL/decoders/enc28j60/lists.py
+161
-0
libsigrokdecode4DSL/decoders/enc28j60/pd.py
libsigrokdecode4DSL/decoders/enc28j60/pd.py
+294
-0
libsigrokdecode4DSL/decoders/pca9571/__init__.py
libsigrokdecode4DSL/decoders/pca9571/__init__.py
+25
-0
libsigrokdecode4DSL/decoders/pca9571/pd.py
libsigrokdecode4DSL/decoders/pca9571/pd.py
+102
-0
libsigrokdecode4DSL/decoders/seven_segment/__init__.py
libsigrokdecode4DSL/decoders/seven_segment/__init__.py
+24
-0
libsigrokdecode4DSL/decoders/seven_segment/pd.py
libsigrokdecode4DSL/decoders/seven_segment/pd.py
+134
-0
libsigrokdecode4DSL/decoders/x2444m/__init__.py
libsigrokdecode4DSL/decoders/x2444m/__init__.py
+25
-0
libsigrokdecode4DSL/decoders/x2444m/pd.py
libsigrokdecode4DSL/decoders/x2444m/pd.py
+111
-0
No files found.
DSView/CMakeLists.txt
View file @
b018742e
...
...
@@ -92,6 +92,7 @@ endif()
find_package
(
Threads
)
find_package
(
PythonLibs 3 EXACT
)
find_package
(
Boost 1.42 COMPONENTS filesystem system thread REQUIRED
)
find_package
(
libusb-1.0 REQUIRED
)
find_package
(
libzip REQUIRED
)
...
...
@@ -390,6 +391,7 @@ else()
list
(
APPEND DSVIEW_LINK_LIBS
${
PKGDEPS_LIBRARIES
}
)
endif
()
list
(
APPEND DSVIEW_LINK_LIBS
${
PYTHON_LIBRARIES
}
)
add_executable
(
${
PROJECT_NAME
}
${
DSView_SOURCES
}
...
...
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/cc1101/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Marco Geisler <m-sigrok@mageis.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
'''
This decoder stacks on top of the 'spi' PD and decodes the protocol spoken
by the Texas Instruments low-power sub-1GHz RF transceiver chips.
Details:
http://www.ti.com/lit/ds/symlink/cc1101.pdf
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/cc1101/lists.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Marco Geisler <m-sigrok@mageis.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
regs
=
{
# addr: 'name'
0x00
:
'IOCFG2'
,
0x01
:
'IOCFG1'
,
0x02
:
'IOCFG0'
,
0x03
:
'FIFOTHR'
,
0x04
:
'SYNC1'
,
0x05
:
'SYNC0'
,
0x06
:
'PKTLEN'
,
0x07
:
'PKTCTRL1'
,
0x08
:
'PKTCTRL0'
,
0x09
:
'ADDR'
,
0x0A
:
'CHANNR'
,
0x0B
:
'FSCTRL1'
,
0x0C
:
'FSCTRL0'
,
0x0D
:
'FREQ2'
,
0x0E
:
'FREQ1'
,
0x0F
:
'FREQ0'
,
0x10
:
'MDMCFG4'
,
0x11
:
'MDMCFG3'
,
0x12
:
'MDMCFG2'
,
0x13
:
'MDMCFG1'
,
0x14
:
'MDMCFG0'
,
0x15
:
'DEVIATN'
,
0x16
:
'MCSM2'
,
0x17
:
'MCSM1'
,
0x18
:
'MCSM0'
,
0x19
:
'FOCCFG'
,
0x1A
:
'BSCFG'
,
0x1B
:
'AGCTRL2'
,
0x1C
:
'AGCTRL1'
,
0x1D
:
'AGCTRL0'
,
0x1E
:
'WOREVT1'
,
0x1F
:
'WOREVT0'
,
0x20
:
'WORCTRL'
,
0x21
:
'FREND1'
,
0x22
:
'FREND0'
,
0x23
:
'FSCAL3'
,
0x24
:
'FSCAL2'
,
0x25
:
'FSCAL1'
,
0x26
:
'FSCAL0'
,
0x27
:
'RCCTRL1'
,
0x28
:
'RCCTRL0'
,
0x29
:
'FSTEST'
,
0x2A
:
'PTEST'
,
0x2B
:
'AGCTEST'
,
0x2C
:
'TEST2'
,
0x2D
:
'TEST1'
,
0x2E
:
'TEST0'
,
0x30
:
'PARTNUM'
,
0x31
:
'VERSION'
,
0x32
:
'FREQEST'
,
0x33
:
'LQI'
,
0x34
:
'RSSI'
,
0x35
:
'MARCSTATE'
,
0x36
:
'WORTIME1'
,
0x37
:
'WORTIME0'
,
0x38
:
'PKTSTATUS'
,
0x39
:
'VCO_VC_DAC'
,
0x3A
:
'TXBYTES'
,
0x3B
:
'RXBYTES'
,
0x3C
:
'RCCTRL1_STATUS'
,
0x3D
:
'RCCTRL0_STATUS'
,
0x3E
:
'PATABLE'
,
0x3F
:
'FIFO'
}
strobes
=
{
# addr: 'name'
0x30
:
'SRES'
,
0x31
:
'SFSTXON'
,
0x32
:
'SXOFF'
,
0x33
:
'SCAL'
,
0x34
:
'SRX'
,
0x35
:
'STX'
,
0x36
:
'SIDLE'
,
0x37
:
''
,
0x38
:
'SWOR'
,
0x39
:
'SPWD'
,
0x3A
:
'SFRX'
,
0x3B
:
'SFTX'
,
0x3C
:
'SWORRST'
,
0x3D
:
'SNOP'
}
status_reg_states
=
{
# value: 'state name'
0b000
:
'IDLE'
,
0b001
:
'RX'
,
0b010
:
'TX'
,
0b011
:
'FSTXON'
,
0b100
:
'CALIBRATE'
,
0b101
:
'SETTLING'
,
0b110
:
'RXFIFO_OVERFLOW'
,
0b111
:
'TXFIFO_OVERFLOW'
}
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/cc1101/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Marco Geisler <m-sigrok@mageis.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
import
sigrokdecode
as
srd
from
collections
import
namedtuple
from
.lists
import
*
ANN_STROBE
,
ANN_SINGLE_READ
,
ANN_SINGLE_WRITE
,
ANN_BURST_READ
,
\
ANN_BURST_WRITE
,
ANN_STATUS_READ
,
ANN_STATUS
,
ANN_WARN
=
range
(
8
)
Pos
=
namedtuple
(
'Pos'
,
[
'ss'
,
'es'
])
Data
=
namedtuple
(
'Data'
,
[
'mosi'
,
'miso'
])
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'cc1101'
name
=
'CC1101'
longname
=
'Texas Instruments CC1101'
desc
=
'Low-power sub-1GHz RF transceiver chip.'
license
=
'gplv2+'
inputs
=
[
'spi'
]
outputs
=
[]
tags
=
[
'IC'
,
'Wireless/RF'
]
annotations
=
(
(
'strobe'
,
'Command strobe'
),
(
'single_read'
,
'Single register read'
),
(
'single_write'
,
'Single register write'
),
(
'burst_read'
,
'Burst register read'
),
(
'burst_write'
,
'Burst register write'
),
(
'status'
,
'Status register'
),
(
'warning'
,
'Warning'
),
)
annotation_rows
=
(
(
'cmd'
,
'Commands'
,
(
ANN_STROBE
,)),
(
'data'
,
'Data'
,
(
ANN_SINGLE_READ
,
ANN_SINGLE_WRITE
,
ANN_BURST_READ
,
ANN_BURST_WRITE
,
ANN_STATUS_READ
)),
(
'status'
,
'Status register'
,
(
ANN_STATUS
,)),
(
'warnings'
,
'Warnings'
,
(
ANN_WARN
,)),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
self
.
next
()
self
.
requirements_met
=
True
self
.
cs_was_released
=
False
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
warn
(
self
,
pos
,
msg
):
'''Put a warning message 'msg' at 'pos'.'''
self
.
put
(
pos
.
ss
,
pos
.
es
,
self
.
out_ann
,
[
ANN_WARN
,
[
msg
]])
def
putp
(
self
,
pos
,
ann
,
msg
):
'''Put an annotation message 'msg' at 'pos'.'''
self
.
put
(
pos
.
ss
,
pos
.
es
,
self
.
out_ann
,
[
ann
,
[
msg
]])
def
putp2
(
self
,
pos
,
ann
,
msg1
,
msg2
):
'''Put an annotation message 'msg' at 'pos'.'''
self
.
put
(
pos
.
ss
,
pos
.
es
,
self
.
out_ann
,
[
ann
,
[
msg1
,
msg2
]])
def
next
(
self
):
'''Resets the decoder after a complete command was decoded.'''
# 'True' for the first byte after CS# went low.
self
.
first
=
True
# The current command, and the minimum and maximum number
# of data bytes to follow.
self
.
cmd
=
None
self
.
min
=
0
self
.
max
=
0
# Used to collect the bytes after the command byte
# (and the start/end sample number).
self
.
mb
=
[]
self
.
ss_mb
=
-
1
self
.
es_mb
=
-
1
def
mosi_bytes
(
self
):
'''Returns the collected MOSI bytes of a multi byte command.'''
return
[
b
.
mosi
for
b
in
self
.
mb
]
def
miso_bytes
(
self
):
'''Returns the collected MISO bytes of a multi byte command.'''
return
[
b
.
miso
for
b
in
self
.
mb
]
def
decode_command
(
self
,
pos
,
b
):
'''Decodes the command byte 'b' at position 'pos' and prepares
the decoding of the following data bytes.'''
c
=
self
.
parse_command
(
b
)
if
c
is
None
:
self
.
warn
(
pos
,
'unknown command'
)
return
self
.
cmd
,
self
.
dat
,
self
.
min
,
self
.
max
=
c
if
self
.
cmd
==
'Strobe'
:
self
.
putp
(
pos
,
ANN_STROBE
,
self
.
format_command
())
else
:
# Don't output anything now, the command is merged with
# the data bytes following it.
self
.
ss_mb
=
pos
.
ss
def
format_command
(
self
):
'''Returns the label for the current command.'''
if
self
.
cmd
in
(
'Read'
,
'Burst read'
,
'Write'
,
'Burst write'
,
'Status read'
):
return
self
.
cmd
if
self
.
cmd
==
'Strobe'
:
reg
=
strobes
.
get
(
self
.
dat
,
'unknown strobe'
)
return
'{} {}'
.
format
(
self
.
cmd
,
reg
)
else
:
return
'TODO Cmd {}'
.
format
(
self
.
cmd
)
def
parse_command
(
self
,
b
):
'''Parses the command byte.
Returns a tuple consisting of:
- the name of the command
- additional data needed to dissect the following bytes
- minimum number of following bytes
- maximum number of following bytes (None for infinite)
'''
addr
=
b
&
0x3F
if
(
addr
<
0x30
)
or
(
addr
==
0x3E
)
or
(
addr
==
0x3F
):
if
(
b
&
0xC0
)
==
0x00
:
return
(
'Write'
,
addr
,
1
,
1
)
if
(
b
&
0xC0
)
==
0x40
:
return
(
'Burst write'
,
addr
,
1
,
99999
)
if
(
b
&
0xC0
)
==
0x80
:
return
(
'Read'
,
addr
,
1
,
1
)
if
(
b
&
0xC0
)
==
0xC0
:
return
(
'Burst read'
,
addr
,
1
,
99999
)
else
:
self
.
warn
(
pos
,
'unknown address/command combination'
)
else
:
if
(
b
&
0x40
)
==
0x00
:
return
(
'Strobe'
,
addr
,
0
,
0
)
if
(
b
&
0xC0
)
==
0xC0
:
return
(
'Status read'
,
addr
,
1
,
99999
)
else
:
self
.
warn
(
pos
,
'unknown address/command combination'
)
def
decode_reg
(
self
,
pos
,
ann
,
regid
,
data
):
'''Decodes a register.
pos -- start and end sample numbers of the register
ann -- the annotation number that is used to output the register.
regid -- may be either an integer used as a key for the 'regs'
dictionary, or a string directly containing a register name.'
data -- the register content.
'''
if
type
(
regid
)
==
int
:
# Get the name of the register.
if
regid
not
in
regs
:
self
.
warn
(
pos
,
'unknown register'
)
return
name
=
'{} ({:02X})'
.
format
(
regs
[
regid
],
regid
)
else
:
name
=
regid
if
regid
==
'STATUS'
and
ann
==
ANN_STATUS
:
label
=
'Status'
self
.
decode_status_reg
(
pos
,
ann
,
data
,
label
)
else
:
if
self
.
cmd
in
(
'Write'
,
'Read'
,
'Status read'
,
'Burst read'
,
'Burst write'
):
label
=
'{}: {}'
.
format
(
self
.
format_command
(),
name
)
else
:
label
=
'Reg ({}) {}'
.
format
(
self
.
cmd
,
name
)
self
.
decode_mb_data
(
pos
,
ann
,
data
,
label
)
def
decode_status_reg
(
self
,
pos
,
ann
,
data
,
label
):
'''Decodes the data bytes 'data' of a status register at position
'pos'. The decoded data is prefixed with 'label'.'''
status
=
data
[
0
]
# bit 7 --> CHIP_RDYn
if
status
&
0b10000000
==
0b10000000
:
longtext_chiprdy
=
'CHIP_RDYn is high! '
else
:
longtext_chiprdy
=
''
# bits 6:4 --> STATE
state
=
(
status
&
0x70
)
>>
4
longtext_state
=
'STATE is {}, '
.
format
(
status_reg_states
[
state
])
# bits 3:0 --> FIFO_BYTES_AVAILABLE
fifo_bytes
=
status
&
0x0F
if
self
.
cmd
in
(
'Single read'
,
'Status read'
,
'Burst read'
):
longtext_fifo
=
'{} bytes available in RX FIFO'
.
format
(
fifo_bytes
)
else
:
longtext_fifo
=
'{} bytes free in TX FIFO'
.
format
(
fifo_bytes
)
text
=
'{} = {:02X}'
.
format
(
label
,
status
)
longtext
=
''
.
join
([
text
,
'; '
,
longtext_chiprdy
,
longtext_state
,
longtext_fifo
])
self
.
putp2
(
pos
,
ann
,
longtext
,
text
)
def
decode_mb_data
(
self
,
pos
,
ann
,
data
,
label
):
'''Decodes the data bytes 'data' of a multibyte command at position
'pos'. The decoded data is prefixed with 'label'.'''
def
escape
(
b
):
return
'{:02X}'
.
format
(
b
)
data
=
' '
.
join
([
escape
(
b
)
for
b
in
data
])
text
=
'{} = {}'
.
format
(
label
,
data
)
self
.
putp
(
pos
,
ann
,
text
)
def
finish_command
(
self
,
pos
):
'''Decodes the remaining data bytes at position 'pos'.'''
if
self
.
cmd
==
'Write'
:
self
.
decode_reg
(
pos
,
ANN_SINGLE_WRITE
,
self
.
dat
,
self
.
mosi_bytes
())
elif
self
.
cmd
==
'Burst write'
:
self
.
decode_reg
(
pos
,
ANN_BURST_WRITE
,
self
.
dat
,
self
.
mosi_bytes
())
elif
self
.
cmd
==
'Read'
:
self
.
decode_reg
(
pos
,
ANN_SINGLE_READ
,
self
.
dat
,
self
.
miso_bytes
())
elif
self
.
cmd
==
'Burst read'
:
self
.
decode_reg
(
pos
,
ANN_BURST_READ
,
self
.
dat
,
self
.
miso_bytes
())
elif
self
.
cmd
==
'Strobe'
:
self
.
decode_reg
(
pos
,
ANN_STROBE
,
self
.
dat
,
self
.
mosi_bytes
())
elif
self
.
cmd
==
'Status read'
:
self
.
decode_reg
(
pos
,
ANN_STATUS_READ
,
self
.
dat
,
self
.
miso_bytes
())
else
:
self
.
warn
(
pos
,
'unhandled command'
)
def
decode
(
self
,
ss
,
es
,
data
):
if
not
self
.
requirements_met
:
return
ptype
,
data1
,
data2
=
data
if
ptype
==
'CS-CHANGE'
:
if
data1
is
None
:
if
data2
is
None
:
self
.
requirements_met
=
False
raise
ChannelError
(
'CS# pin required.'
)
elif
data2
==
1
:
self
.
cs_was_released
=
True
if
data1
==
0
and
data2
==
1
:
# Rising edge, the complete command is transmitted, process
# the bytes that were sent after the command byte.
if
self
.
cmd
:
# Check if we got the minimum number of data bytes
# after the command byte.
if
len
(
self
.
mb
)
<
self
.
min
:
self
.
warn
((
ss
,
ss
),
'missing data bytes'
)
elif
self
.
mb
:
self
.
finish_command
(
Pos
(
self
.
ss_mb
,
self
.
es_mb
))
self
.
next
()
self
.
cs_was_released
=
True
elif
ptype
==
'DATA'
and
self
.
cs_was_released
:
mosi
,
miso
=
data1
,
data2
pos
=
Pos
(
ss
,
es
)
if
miso
is
None
or
mosi
is
None
:
self
.
requirements_met
=
False
raise
ChannelError
(
'Both MISO and MOSI pins required.'
)
if
self
.
first
:
self
.
first
=
False
# First MOSI byte is always the command.
self
.
decode_command
(
pos
,
mosi
)
# First MISO byte is always the status register.
self
.
decode_reg
(
pos
,
ANN_STATUS
,
'STATUS'
,
[
miso
])
else
:
if
not
self
.
cmd
or
len
(
self
.
mb
)
>=
self
.
max
:
self
.
warn
(
pos
,
'excess byte'
)
else
:
# Collect the bytes after the command byte.
if
self
.
ss_mb
==
-
1
:
self
.
ss_mb
=
ss
self
.
es_mb
=
es
self
.
mb
.
append
(
Data
(
mosi
,
miso
))
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/ds2408/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
'''
This decoder stacks on top of the 'onewire_network' PD and decodes the
Maxim DS2408 1-Wire 8-channel addressable switch protocol.
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/ds2408/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Mariusz Bialonczyk <manio@skyboo.net>
##
## 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 <http://www.gnu.org/licenses/>.
##
import
sigrokdecode
as
srd
# Dictionary of FUNCTION commands and their names.
command
=
{
0xf0
:
'Read PIO Registers'
,
0xf5
:
'Channel Access Read'
,
0x5a
:
'Channel Access Write'
,
0xcc
:
'Write Conditional Search Register'
,
0xc3
:
'Reset Activity Latches'
,
0x3c
:
'Disable Test Mode'
,
}
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'ds2408'
name
=
'DS2408'
longname
=
'Maxim DS2408'
desc
=
'1-Wire 8-channel addressable switch.'
license
=
'gplv2+'
inputs
=
[
'onewire_network'
]
outputs
=
[]
tags
=
[
'Embedded/industrial'
,
'IC'
]
annotations
=
(
(
'text'
,
'Human-readable text'
),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
# Bytes for function command.
self
.
bytes
=
[]
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
putx
(
self
,
data
):
self
.
put
(
self
.
ss
,
self
.
es
,
self
.
out_ann
,
data
)
def
decode
(
self
,
ss
,
es
,
data
):
code
,
val
=
data
if
code
==
'RESET/PRESENCE'
:
self
.
ss
,
self
.
es
=
ss
,
es
self
.
putx
([
0
,
[
'Reset/presence: %s'
%
(
'true'
if
val
else
'false'
)]])
self
.
bytes
=
[]
elif
code
==
'ROM'
:
self
.
ss
,
self
.
es
=
ss
,
es
family_code
=
val
&
0xff
self
.
putx
([
0
,
[
'ROM: 0x%016x (family code 0x%02x)'
%
(
val
,
family_code
)]])
self
.
bytes
=
[]
elif
code
==
'DATA'
:
self
.
bytes
.
append
(
val
)
if
1
==
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
if
val
not
in
command
:
self
.
putx
([
0
,
[
'Unrecognized command: 0x%02x'
%
val
]])
else
:
self
.
putx
([
0
,
[
'%s (0x%02x)'
%
(
command
[
val
],
val
)]])
elif
0xf0
==
self
.
bytes
[
0
]:
# Read PIO Registers
if
2
==
len
(
self
.
bytes
):
self
.
ss
=
ss
elif
3
==
len
(
self
.
bytes
):
self
.
es
=
es
self
.
putx
([
0
,
[
'Target address: 0x%04x'
%
((
self
.
bytes
[
2
]
<<
8
)
+
self
.
bytes
[
1
])]])
elif
3
<
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
self
.
putx
([
0
,
[
'Data: 0x%02x'
%
self
.
bytes
[
-
1
]]])
elif
0xf5
==
self
.
bytes
[
0
]:
# Channel Access Read
if
2
==
len
(
self
.
bytes
):
self
.
ss
=
ss
elif
2
<
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
self
.
putx
([
0
,
[
'PIO sample: 0x%02x'
%
self
.
bytes
[
-
1
]]])
elif
0x5a
==
self
.
bytes
[
0
]:
# Channel Access Write
if
2
==
len
(
self
.
bytes
):
self
.
ss
=
ss
elif
3
==
len
(
self
.
bytes
):
self
.
es
=
es
if
(
self
.
bytes
[
-
1
]
==
(
self
.
bytes
[
-
2
]
^
0xff
)):
self
.
putx
([
0
,
[
'Data: 0x%02x (bit-inversion correct: 0x%02x)'
%
(
self
.
bytes
[
-
2
],
self
.
bytes
[
-
1
])]])
else
:
self
.
putx
([
0
,
[
'Data error: second byte (0x%02x) is not bit-inverse of first (0x%02x)'
%
(
self
.
bytes
[
-
1
],
self
.
bytes
[
-
2
])]])
elif
3
<
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
if
0xaa
==
self
.
bytes
[
-
1
]:
self
.
putx
([
0
,
[
'Success'
]])
elif
0xff
==
self
.
bytes
[
-
1
]:
self
.
putx
([
0
,
[
'Fail New State'
]])
elif
0xcc
==
self
.
bytes
[
0
]:
# Write Conditional Search Register
if
2
==
len
(
self
.
bytes
):
self
.
ss
=
ss
elif
3
==
len
(
self
.
bytes
):
self
.
es
=
es
self
.
putx
([
0
,
[
'Target address: 0x%04x'
%
((
self
.
bytes
[
2
]
<<
8
)
+
self
.
bytes
[
1
])]])
elif
3
<
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
self
.
putx
([
0
,
[
'Data: 0x%02x'
%
self
.
bytes
[
-
1
]]])
elif
0xc3
==
self
.
bytes
[
0
]:
# Reset Activity Latches
if
2
==
len
(
self
.
bytes
):
self
.
ss
=
ss
elif
2
<
len
(
self
.
bytes
):
self
.
ss
,
self
.
es
=
ss
,
es
if
0xaa
==
self
.
bytes
[
-
1
]:
self
.
putx
([
0
,
[
'Success'
]])
else
:
self
.
putx
([
0
,
[
'Invalid byte'
]])
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/enc28j60/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Jiahao Li <reg@ljh.me>
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all
## copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
'''
This decoder stacks on top of the 'spi' PD and decodes the protocol spoken
by the Microchip ENC28J60 Ethernet chip.
Details:
http://ww1.microchip.com/downloads/en/DeviceDoc/39662e.pdf
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/enc28j60/lists.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Jiahao Li <reg@ljh.me>
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all
## copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
REGS
=
[
[
'ERDPTL'
,
'ERDPTH'
,
'EWRPTL'
,
'EWRPTH'
,
'ETXSTL'
,
'ETXSTH'
,
'ETXNDL'
,
'ETXNDH'
,
'ERXSTL'
,
'ERXSTH'
,
'ERXNDL'
,
'ERXNDH'
,
'ERXRDPTL'
,
'ERXRDPTH'
,
'ERXWRPTL'
,
'ERXWRPTH'
,
'EDMASTL'
,
'EDMASTH'
,
'EDMANDL'
,
'EDMANDH'
,
'EDMADSTL'
,
'EDMADSTH'
,
'EDMACSL'
,
'EDMACSH'
,
'—'
,
'—'
,
'Reserved'
,
'EIE'
,
'EIR'
,
'ESTAT'
,
'ECON2'
,
'ECON1'
,
],
[
'EHT0'
,
'EHT1'
,
'EHT2'
,
'EHT3'
,
'EHT4'
,
'EHT5'
,
'EHT6'
,
'EHT7'
,
'EPMM0'
,
'EPMM1'
,
'EPMM2'
,
'EPMM3'
,
'EPMM4'
,
'EPMM5'
,
'EPMM6'
,
'EPMM7'
,
'EPMCSL'
,
'EPMCSH'
,
'—'
,
'—'
,
'EPMOL'
,
'EPMOH'
,
'Reserved'
,
'Reserved'
,
'ERXFCON'
,
'EPKTCNT'
,
'Reserved'
,
'EIE'
,
'EIR'
,
'ESTAT'
,
'ECON2'
,
'ECON1'
,
],
[
'MACON1'
,
'Reserved'
,
'MACON3'
,
'MACON4'
,
'MABBIPG'
,
'—'
,
'MAIPGL'
,
'MAIPGH'
,
'MACLCON1'
,
'MACLCON2'
,
'MAMXFLL'
,
'MAMXFLH'
,
'Reserved'
,
'Reserved'
,
'Reserved'
,
'—'
,
'Reserved'
,
'Reserved'
,
'MICMD'
,
'—'
,
'MIREGADR'
,
'Reserved'
,
'MIWRL'
,
'MIWRH'
,
'MIRDL'
,
'MIRDH'
,
'Reserved'
,
'EIE'
,
'EIR'
,
'ESTAT'
,
'ECON2'
,
'ECON1'
,
],
[
'MAADR5'
,
'MAADR6'
,
'MAADR3'
,
'MAADR4'
,
'MAADR1'
,
'MAADR2'
,
'EBSTSD'
,
'EBSTCON'
,
'EBSTCSL'
,
'EBSTCSH'
,
'MISTAT'
,
'—'
,
'—'
,
'—'
,
'—'
,
'—'
,
'—'
,
'—'
,
'EREVID'
,
'—'
,
'—'
,
'ECOCON'
,
'Reserved'
,
'EFLOCON'
,
'EPAUSL'
,
'EPAUSH'
,
'Reserved'
,
'EIE'
,
'EIR'
,
'ESTAT'
,
'ECON2'
,
'ECON1'
,
],
]
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/enc28j60/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Jiahao Li <reg@ljh.me>
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all
## copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
import
sigrokdecode
as
srd
from
.lists
import
*
OPCODE_MASK
=
0b11100000
REG_ADDR_MASK
=
0b00011111
OPCODE_HANDLERS
=
{
0b00000000
:
'_process_rcr'
,
0b00100000
:
'_process_rbm'
,
0b01000000
:
'_process_wcr'
,
0b01100000
:
'_process_wbm'
,
0b10000000
:
'_process_bfs'
,
0b10100000
:
'_process_bfc'
,
0b11100000
:
'_process_src'
,
}
(
ANN_RCR
,
ANN_RBM
,
ANN_WCR
,
ANN_WBM
,
ANN_BFS
,
ANN_BFC
,
ANN_SRC
,
ANN_DATA
,
ANN_REG_ADDR
,
ANN_WARNING
)
=
range
(
10
)
REG_ADDR_ECON1
=
0x1F
BIT_ECON1_BSEL0
=
0b00000001
BIT_ECON1_BSEL1
=
0b00000010
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'enc28j60'
name
=
'ENC28J60'
longname
=
'Microchip ENC28J60'
desc
=
'Microchip ENC28J60 10Base-T Ethernet controller protocol.'
license
=
'mit'
inputs
=
[
'spi'
]
outputs
=
[]
tags
=
[
'Embedded/industrial'
,
'Networking'
]
annotations
=
(
(
'rcr'
,
'Read Control Register'
),
(
'rbm'
,
'Read Buffer Memory'
),
(
'wcr'
,
'Write Control Register'
),
(
'wbm'
,
'Write Buffer Memory'
),
(
'bfs'
,
'Bit Field Set'
),
(
'bfc'
,
'Bit Field Clear'
),
(
'src'
,
'System Reset Command'
),
(
'data'
,
'Data'
),
(
'reg-addr'
,
'Register Address'
),
(
'warning'
,
'Warning'
),
)
annotation_rows
=
(
(
'commands'
,
'Commands'
,
(
ANN_RCR
,
ANN_RBM
,
ANN_WCR
,
ANN_WBM
,
ANN_BFS
,
ANN_BFC
,
ANN_SRC
)),
(
'fields'
,
'Fields'
,
(
ANN_DATA
,
ANN_REG_ADDR
)),
(
'warnings'
,
'Warnings'
,
(
ANN_WARNING
,)),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
self
.
mosi
=
[]
self
.
miso
=
[]
self
.
ranges
=
[]
self
.
cmd_ss
=
None
self
.
cmd_es
=
None
self
.
range_ss
=
None
self
.
range_es
=
None
self
.
active
=
False
self
.
bsel0
=
None
self
.
bsel1
=
None
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
putc
(
self
,
data
):
self
.
put
(
self
.
cmd_ss
,
self
.
cmd_es
,
self
.
out_ann
,
data
)
def
putr
(
self
,
data
):
self
.
put
(
self
.
range_ss
,
self
.
range_es
,
self
.
out_ann
,
data
)
def
_process_command
(
self
):
if
len
(
self
.
mosi
)
==
0
:
self
.
active
=
False
return
header
=
self
.
mosi
[
0
]
opcode
=
header
&
OPCODE_MASK
if
opcode
not
in
OPCODE_HANDLERS
:
self
.
_put_command_warning
(
"Unknown opcode."
)
self
.
active
=
False
return
getattr
(
self
,
OPCODE_HANDLERS
[
opcode
])()
self
.
active
=
False
def
_get_register_name
(
self
,
reg_addr
):
if
(
self
.
bsel0
is
None
)
or
(
self
.
bsel1
is
None
):
# We don't know the bank we're in yet.
return
None
else
:
bank
=
(
self
.
bsel1
<<
1
)
+
self
.
bsel0
return
REGS
[
bank
][
reg_addr
]
def
_put_register_header
(
self
):
reg_addr
=
self
.
mosi
[
0
]
&
REG_ADDR_MASK
reg_name
=
self
.
_get_register_name
(
reg_addr
)
self
.
range_ss
,
self
.
range_es
=
self
.
cmd_ss
,
self
.
ranges
[
1
][
0
]
if
reg_name
is
None
:
# We don't know the bank we're in yet.
self
.
putr
([
ANN_REG_ADDR
,
[
'Reg Bank ? Addr 0x{0:02X}'
.
format
(
reg_addr
),
'?:{0:02X}'
.
format
(
reg_addr
)]])
self
.
putr
([
ANN_WARNING
,
[
'Warning: Register bank not known yet.'
,
'Warning'
]])
else
:
self
.
putr
([
ANN_REG_ADDR
,
[
'Reg {0}'
.
format
(
reg_name
),
'{0}'
.
format
(
reg_name
)]])
if
(
reg_name
==
'-'
)
or
(
reg_name
==
'Reserved'
):
self
.
putr
([
ANN_WARNING
,
[
'Warning: Invalid register accessed.'
,
'Warning'
]])
def
_put_data_byte
(
self
,
data
,
byte_index
,
binary
=
False
):
self
.
range_ss
=
self
.
ranges
[
byte_index
][
0
]
if
byte_index
==
len
(
self
.
mosi
)
-
1
:
self
.
range_es
=
self
.
cmd_es
else
:
self
.
range_es
=
self
.
ranges
[
byte_index
+
1
][
0
]
if
binary
:
self
.
putr
([
ANN_DATA
,
[
'Data 0b{0:08b}'
.
format
(
data
),
'{0:08b}'
.
format
(
data
)]])
else
:
self
.
putr
([
ANN_DATA
,
[
'Data 0x{0:02X}'
.
format
(
data
),
'{0:02X}'
.
format
(
data
)]])
def
_put_command_warning
(
self
,
reason
):
self
.
putc
([
ANN_WARNING
,
[
'Warning: {0}'
.
format
(
reason
),
'Warning'
]])
def
_process_rcr
(
self
):
self
.
putc
([
ANN_RCR
,
[
'Read Control Register'
,
'RCR'
]])
if
(
len
(
self
.
mosi
)
!=
2
)
and
(
len
(
self
.
mosi
)
!=
3
):
self
.
_put_command_warning
(
'Invalid command length.'
)
return
self
.
_put_register_header
()
reg_name
=
self
.
_get_register_name
(
self
.
mosi
[
0
]
&
REG_ADDR_MASK
)
if
reg_name
is
None
:
# We can't tell if we're accessing MAC/MII registers or not
# Let's trust the user in this case.
pass
else
:
if
(
reg_name
[
0
]
==
'M'
)
and
(
len
(
self
.
mosi
)
!=
3
):
self
.
_put_command_warning
(
'Attempting to read a MAC/MII '
+
'register without using the dummy byte.'
)
return
if
(
reg_name
[
0
]
!=
'M'
)
and
(
len
(
self
.
mosi
)
!=
2
):
self
.
_put_command_warning
(
'Attempting to read a non-MAC/MII '
+
'register using the dummy byte.'
)
return
if
len
(
self
.
mosi
)
==
2
:
self
.
_put_data_byte
(
self
.
miso
[
1
],
1
)
else
:
self
.
range_ss
,
self
.
range_es
=
self
.
ranges
[
1
][
0
],
self
.
ranges
[
2
][
0
]
self
.
putr
([
ANN_DATA
,
[
'Dummy Byte'
,
'Dummy'
]])
self
.
_put_data_byte
(
self
.
miso
[
2
],
2
)
def
_process_rbm
(
self
):
if
self
.
mosi
[
0
]
!=
0b00111010
:
self
.
_put_command_warning
(
'Invalid header byte.'
)
return
self
.
putc
([
ANN_RBM
,
[
'Read Buffer Memory: Length {0}'
.
format
(
len
(
self
.
mosi
)
-
1
),
'RBM'
]])
for
i
in
range
(
1
,
len
(
self
.
miso
)):
self
.
_put_data_byte
(
self
.
miso
[
i
],
i
)
def
_process_wcr
(
self
):
self
.
putc
([
ANN_WCR
,
[
'Write Control Register'
,
'WCR'
]])
if
len
(
self
.
mosi
)
!=
2
:
self
.
_put_command_warning
(
'Invalid command length.'
)
return
self
.
_put_register_header
()
self
.
_put_data_byte
(
self
.
mosi
[
1
],
1
)
if
self
.
mosi
[
0
]
&
REG_ADDR_MASK
==
REG_ADDR_ECON1
:
self
.
bsel0
=
(
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL0
)
>>
0
self
.
bsel1
=
(
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL1
)
>>
1
def
_process_wbm
(
self
):
if
self
.
mosi
[
0
]
!=
0b01111010
:
self
.
_put_command_warning
(
'Invalid header byte.'
)
return
self
.
putc
([
ANN_WBM
,
[
'Write Buffer Memory: Length {0}'
.
format
(
len
(
self
.
mosi
)
-
1
),
'WBM'
]])
for
i
in
range
(
1
,
len
(
self
.
mosi
)):
self
.
_put_data_byte
(
self
.
mosi
[
i
],
i
)
def
_process_bfc
(
self
):
self
.
putc
([
ANN_BFC
,
[
'Bit Field Clear'
,
'BFC'
]])
if
len
(
self
.
mosi
)
!=
2
:
self
.
_put_command_warning
(
'Invalid command length.'
)
return
self
.
_put_register_header
()
self
.
_put_data_byte
(
self
.
mosi
[
1
],
1
,
True
)
if
self
.
mosi
[
0
]
&
REG_ADDR_MASK
==
REG_ADDR_ECON1
:
if
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL0
:
self
.
bsel0
=
0
if
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL1
:
self
.
bsel1
=
0
def
_process_bfs
(
self
):
self
.
putc
([
ANN_BFS
,
[
'Bit Field Set'
,
'BFS'
]])
if
len
(
self
.
mosi
)
!=
2
:
self
.
_put_command_warning
(
'Invalid command length.'
)
return
self
.
_put_register_header
()
self
.
_put_data_byte
(
self
.
mosi
[
1
],
1
,
True
)
if
self
.
mosi
[
0
]
&
REG_ADDR_MASK
==
REG_ADDR_ECON1
:
if
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL0
:
self
.
bsel0
=
1
if
self
.
mosi
[
1
]
&
BIT_ECON1_BSEL1
:
self
.
bsel1
=
1
def
_process_src
(
self
):
self
.
putc
([
ANN_SRC
,
[
'System Reset Command'
,
'SRC'
]])
if
len
(
self
.
mosi
)
!=
1
:
self
.
_put_command_warning
(
'Invalid command length.'
)
return
self
.
bsel0
=
0
self
.
bsel1
=
0
def
decode
(
self
,
ss
,
es
,
data
):
ptype
,
data1
,
data2
=
data
if
ptype
==
'CS-CHANGE'
:
new_cs
=
data2
if
new_cs
==
0
:
self
.
active
=
True
self
.
cmd_ss
=
ss
self
.
mosi
=
[]
self
.
miso
=
[]
self
.
ranges
=
[]
elif
new_cs
==
1
:
if
self
.
active
:
self
.
cmd_es
=
es
self
.
_process_command
()
elif
ptype
==
'DATA'
:
mosi
,
miso
=
data1
,
data2
self
.
mosi
.
append
(
mosi
)
self
.
miso
.
append
(
miso
)
self
.
ranges
.
append
((
ss
,
es
))
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/pca9571/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Mickael Bosch <mickael.bosch@linux.com>
##
## 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 <http://www.gnu.org/licenses/>.
##
'''
This decoder stacks on top of the 'i2c' PD and decodes the NXP Semiconductors
PCA9571 8-bit I²C output expander protocol.
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/pca9571/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Mickael Bosch <mickael.bosch@linux.com>
##
## 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 <http://www.gnu.org/licenses/>.
##
import
sigrokdecode
as
srd
NUM_OUTPUT_CHANNELS
=
8
# TODO: Other I²C functions: general call / reset address, device ID address.
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'pca9571'
name
=
'PCA9571'
longname
=
'NXP PCA9571'
desc
=
'NXP PCA9571 8-bit I²C output expander.'
license
=
'gplv2+'
inputs
=
[
'i2c'
]
outputs
=
[]
tags
=
[
'Embedded/industrial'
,
'IC'
]
annotations
=
(
(
'register'
,
'Register type'
),
(
'value'
,
'Register value'
),
(
'warning'
,
'Warning messages'
),
)
annotation_rows
=
(
(
'regs'
,
'Registers'
,
(
0
,
1
)),
(
'warnings'
,
'Warnings'
,
(
2
,)),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
self
.
state
=
'IDLE'
self
.
last_write
=
0xFF
# Chip port default state is high.
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
putx
(
self
,
data
):
self
.
put
(
self
.
ss
,
self
.
es
,
self
.
out_ann
,
data
)
def
handle_io
(
self
,
b
):
if
self
.
state
==
'READ DATA'
:
operation
=
[
'Outputs read'
,
'R'
]
if
b
!=
self
.
last_write
:
self
.
putx
([
2
,
[
'Warning: read value and last write value '
'(%02X) are different'
%
self
.
last_write
]])
else
:
operation
=
[
'Outputs set'
,
'W'
]
self
.
last_write
=
b
self
.
putx
([
1
,
[
operation
[
0
]
+
': %02X'
%
b
,
operation
[
1
]
+
': %02X'
%
b
]])
def
check_correct_chip
(
self
,
addr
):
if
addr
!=
0x25
:
self
.
putx
([
2
,
[
'Warning: I²C slave 0x%02X not a PCA9571 '
'compatible chip.'
%
addr
]])
return
False
return
True
def
decode
(
self
,
ss
,
es
,
data
):
cmd
,
databyte
=
data
self
.
ss
,
self
.
es
=
ss
,
es
# State machine.
if
cmd
in
(
'ACK'
,
'BITS'
):
# Discard 'ACK' and 'BITS'.
pass
elif
cmd
in
(
'START'
,
'START REPEAT'
):
# Start a communication.
self
.
state
=
'GET SLAVE ADDR'
elif
cmd
in
(
'NACK'
,
'STOP'
):
# Reset the state machine.
self
.
state
=
'IDLE'
elif
cmd
in
(
'ADDRESS READ'
,
'ADDRESS WRITE'
):
if
((
self
.
state
==
'GET SLAVE ADDR'
)
and
self
.
check_correct_chip
(
databyte
)):
if
cmd
==
'ADDRESS READ'
:
self
.
state
=
'READ DATA'
else
:
self
.
state
=
'WRITE DATA'
else
:
self
.
state
=
'IDLE'
elif
cmd
in
(
'DATA READ'
,
'DATA WRITE'
):
if
self
.
state
in
(
'READ DATA'
,
'WRITE DATA'
):
self
.
handle_io
(
databyte
)
else
:
self
.
state
=
'IDLE'
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/seven_segment/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Benedikt Otto <benedikt_o@web.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
'''
This decoder decodes the output of a 7-segment display.
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/seven_segment/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2019 Benedikt Otto <benedikt_o@web.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
import
sigrokdecode
as
srd
class
ChannelError
(
Exception
):
pass
digits
=
{
(
0
,
0
,
0
,
0
,
0
,
0
,
0
):
' '
,
(
1
,
1
,
1
,
1
,
1
,
1
,
0
):
'0'
,
(
0
,
1
,
1
,
0
,
0
,
0
,
0
):
'1'
,
(
1
,
1
,
0
,
1
,
1
,
0
,
1
):
'2'
,
(
1
,
1
,
1
,
1
,
0
,
0
,
1
):
'3'
,
(
0
,
1
,
1
,
0
,
0
,
1
,
1
):
'4'
,
(
1
,
0
,
1
,
1
,
0
,
1
,
1
):
'5'
,
(
1
,
0
,
1
,
1
,
1
,
1
,
1
):
'6'
,
(
1
,
1
,
1
,
0
,
0
,
0
,
0
):
'7'
,
(
1
,
1
,
1
,
1
,
1
,
1
,
1
):
'8'
,
(
1
,
1
,
1
,
1
,
0
,
1
,
1
):
'9'
,
(
1
,
1
,
1
,
0
,
1
,
1
,
1
):
'A'
,
(
0
,
0
,
1
,
1
,
1
,
1
,
1
):
'B'
,
(
1
,
0
,
0
,
1
,
1
,
1
,
0
):
'C'
,
(
0
,
1
,
1
,
1
,
1
,
0
,
1
):
'D'
,
(
1
,
0
,
0
,
1
,
1
,
1
,
1
):
'E'
,
(
1
,
0
,
0
,
0
,
1
,
1
,
1
):
'F'
,
}
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'seven_segment'
name
=
'7-segment'
longname
=
'7-segment display'
desc
=
'7-segment display protocol.'
license
=
'gplv2+'
inputs
=
[
'logic'
]
outputs
=
[]
tags
=
[
'Display'
]
channels
=
(
{
'id'
:
'a'
,
'name'
:
'A'
,
'desc'
:
'Segment A'
},
{
'id'
:
'b'
,
'name'
:
'B'
,
'desc'
:
'Segment B'
},
{
'id'
:
'c'
,
'name'
:
'C'
,
'desc'
:
'Segment C'
},
{
'id'
:
'd'
,
'name'
:
'D'
,
'desc'
:
'Segment D'
},
{
'id'
:
'e'
,
'name'
:
'E'
,
'desc'
:
'Segment E'
},
{
'id'
:
'f'
,
'name'
:
'F'
,
'desc'
:
'Segment F'
},
{
'id'
:
'g'
,
'name'
:
'G'
,
'desc'
:
'Segment G'
},
)
optional_channels
=
(
{
'id'
:
'dp'
,
'name'
:
'DP'
,
'desc'
:
'Decimal point'
},
)
options
=
(
{
'id'
:
'polarity'
,
'desc'
:
'Expected polarity'
,
'default'
:
'common-cathode'
,
'values'
:
(
'common-cathode'
,
'common-anode'
)},
)
annotations
=
(
(
'decoded-digit'
,
'Decoded digit'
),
)
annotation_rows
=
(
(
'decoded-digits'
,
'Decoded digits'
,
(
0
,)),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
pass
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
putb
(
self
,
ss_block
,
es_block
,
data
):
self
.
put
(
ss_block
,
es_block
,
self
.
out_ann
,
data
)
def
pins_to_hex
(
self
,
pins
):
return
digits
.
get
(
pins
,
None
)
def
decode
(
self
):
oldpins
=
self
.
wait
()
# Check if at least the 7 signals are present.
if
False
in
[
p
in
(
0
,
1
)
for
p
in
oldpins
[:
7
]]:
raise
ChannelError
(
'7 or 8 pins have to be present.'
)
lastpos
=
self
.
samplenum
self
.
have_dp
=
self
.
has_channel
(
7
)
conditions
=
[{
0
:
'e'
},
{
1
:
'e'
},
{
2
:
'e'
},
{
3
:
'e'
},
{
4
:
'e'
},
{
5
:
'e'
},
{
6
:
'e'
}]
if
self
.
have_dp
:
conditions
.
append
({
7
:
'e'
})
while
True
:
# Wait for any change.
pins
=
self
.
wait
(
conditions
)
if
self
.
options
[
'polarity'
]
==
'common-anode'
:
# Invert all data lines if a common anode display is used.
if
self
.
have_dp
:
oldpins
=
tuple
((
1
-
state
for
state
in
oldpins
))
else
:
oldpins
=
tuple
((
1
-
state
for
state
in
oldpins
[:
7
]))
# Convert to character string.
digit
=
self
.
pins_to_hex
(
oldpins
[:
7
])
if
digit
is
not
None
:
dp
=
oldpins
[
7
]
# Check if decimal point is present and active.
if
self
.
have_dp
and
dp
==
1
:
digit
+=
'.'
self
.
putb
(
lastpos
,
self
.
samplenum
,
[
0
,
[
digit
]])
lastpos
=
self
.
samplenum
oldpins
=
pins
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/x2444m/__init__.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2018 Stefan Petersen <spe@ciellt.se>
##
## 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 <http://www.gnu.org/licenses/>.
##
'''
This decoder stacks on top of the 'spi' PD and decodes the Xicor X2444M/P
nonvolatile static RAM protocol.
'''
from
.pd
import
Decoder
This diff is collapsed.
Click to expand it.
libsigrokdecode4DSL/decoders/x2444m/pd.py
0 → 100644
View file @
b018742e
##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2018 Stefan Petersen <spe@ciellt.se>
##
## 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 <http://www.gnu.org/licenses/>.
##
import
re
import
sigrokdecode
as
srd
registers
=
{
0x80
:
[
'WRDS'
,
0
,
lambda
_
:
''
],
0x81
:
[
'STO'
,
1
,
lambda
_
:
''
],
0x82
:
[
'SLEEP'
,
2
,
lambda
_
:
''
],
0x83
:
[
'WRITE'
,
3
,
lambda
v
:
'0x%x'
%
v
],
0x84
:
[
'WREN'
,
4
,
lambda
_
:
''
],
0x85
:
[
'RCL'
,
5
,
lambda
_
:
''
],
0x86
:
[
'READ'
,
6
,
lambda
v
:
'0x%x'
%
v
],
0x87
:
[
'READ'
,
7
,
lambda
v
:
'0x%x'
%
v
],
}
class
Decoder
(
srd
.
Decoder
):
api_version
=
3
id
=
'x2444m'
name
=
'X2444M/P'
longname
=
'Xicor X2444M/P'
desc
=
'Xicor X2444M/P nonvolatile static RAM protocol.'
license
=
'gplv2+'
inputs
=
[
'spi'
]
outputs
=
[]
tags
=
[
'IC'
,
'Memory'
]
annotations
=
(
(
'wrds'
,
'Write disable'
),
(
'sto'
,
'Store RAM data in EEPROM'
),
(
'sleep'
,
'Enter sleep mode'
),
(
'write'
,
'Write data into RAM'
),
(
'wren'
,
'Write enable'
),
(
'rcl'
,
'Recall EEPROM data into RAM'
),
(
'read'
,
'Data read from RAM'
),
(
'read'
,
'Data read from RAM'
),
)
def
__init__
(
self
):
self
.
reset
()
def
reset
(
self
):
self
.
cs_start
=
0
self
.
cs_asserted
=
False
self
.
cmd_digit
=
0
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
def
putreadwrite
(
self
,
ss
,
es
,
reg
,
idx
,
addr
,
value
):
self
.
put
(
ss
,
es
,
self
.
out_ann
,
[
idx
,
[
'%s: %s => 0x%4.4x'
%
(
reg
,
addr
,
value
),
'%s: %s => 0x%4.4x'
%
(
reg
[
0
],
addr
,
value
),
reg
[
0
]]])
def
putcmd
(
self
,
ss
,
es
,
reg
,
idx
):
self
.
put
(
ss
,
es
,
self
.
out_ann
,
[
idx
,
[
reg
,
reg
[
0
]]])
def
decode
(
self
,
ss
,
es
,
data
):
ptype
,
mosi
,
miso
=
data
if
ptype
==
'DATA'
:
if
not
self
.
cs_asserted
:
return
if
self
.
cmd_digit
==
0
:
self
.
addr
=
mosi
self
.
addr_start
=
ss
elif
self
.
cmd_digit
>
0
:
self
.
read_value
=
(
self
.
read_value
<<
8
)
+
miso
self
.
write_value
=
(
self
.
write_value
<<
8
)
+
mosi
self
.
cmd_digit
+=
1
elif
ptype
==
'CS-CHANGE'
:
self
.
cs_asserted
=
(
miso
==
1
)
# When not asserted, CS has just changed from asserted to deasserted.
if
not
self
.
cs_asserted
:
# Only one digit, simple command. Else read/write.
if
self
.
cmd_digit
==
1
:
name
,
idx
,
decoder
=
registers
[
self
.
addr
&
0x87
]
self
.
putcmd
(
self
.
addr_start
,
es
,
name
,
idx
)
elif
self
.
cmd_digit
>
1
:
name
,
idx
,
decoder
=
registers
[
self
.
addr
&
0x87
]
if
name
==
'READ'
:
value
=
self
.
read_value
elif
name
==
'WRITE'
:
value
=
self
.
write_value
else
:
value
=
0
self
.
putreadwrite
(
self
.
addr_start
,
es
,
name
,
idx
,
decoder
((
self
.
addr
>>
3
)
&
0x0f
),
value
)
if
self
.
cs_asserted
:
self
.
cs_start
=
ss
self
.
cmd_digit
=
0
self
.
read_value
=
0
self
.
write_value
=
0
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment