Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dsview
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Raptor Engineering Public Development
dsview
Commits
702f8ce4
Commit
702f8ce4
authored
Jun 18, 2020
by
Timothy Pearson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add basic QSPI support to SPI protocol decoder
parent
1de76d1e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
76 additions
and
16 deletions
+76
-16
libsigrokdecode4DSL/decoders/0-spi/pd.py
libsigrokdecode4DSL/decoders/0-spi/pd.py
+76
-16
No files found.
libsigrokdecode4DSL/decoders/0-spi/pd.py
View file @
702f8ce4
...
...
@@ -4,6 +4,7 @@
## Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
## Copyright (C) 2012-2014 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2019 DreamSourceLab <support@dreamsourcelab.com>
## Copyright (C) 2020 Raptor Engineering, LLC <support@raptorengineering.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
...
...
@@ -88,8 +89,10 @@ class Decoder(srd.Decoder):
{
'id'
:
'clk'
,
'type'
:
0
,
'name'
:
'CLK'
,
'desc'
:
'Clock'
},
)
optional_channels
=
(
{
'id'
:
'miso'
,
'type'
:
107
,
'name'
:
'MISO'
,
'desc'
:
'Master in, slave out'
},
{
'id'
:
'mosi'
,
'type'
:
109
,
'name'
:
'MOSI'
,
'desc'
:
'Master out, slave in'
},
{
'id'
:
'dq3'
,
'type'
:
-
1
,
'name'
:
'DQ3'
,
'desc'
:
'DQ3'
},
{
'id'
:
'dq2'
,
'type'
:
-
1
,
'name'
:
'DQ2'
,
'desc'
:
'DQ2'
},
{
'id'
:
'miso'
,
'type'
:
107
,
'name'
:
'MISO'
,
'desc'
:
'Master in, slave out / DQ1'
},
{
'id'
:
'mosi'
,
'type'
:
109
,
'name'
:
'MOSI'
,
'desc'
:
'Master out, slave in / DQ0'
},
{
'id'
:
'cs'
,
'type'
:
-
1
,
'name'
:
'CS#'
,
'desc'
:
'Chip-select'
},
)
options
=
(
...
...
@@ -106,10 +109,14 @@ class Decoder(srd.Decoder):
annotations
=
(
(
'106'
,
'miso-data'
,
'MISO data'
),
(
'108'
,
'mosi-data'
,
'MOSI data'
),
(
'110'
,
'qspi-data'
,
'QSPI data'
),
(
'112'
,
'qspi-byte'
,
'QSPI byte'
),
)
annotation_rows
=
(
(
'miso-data'
,
'MISO data'
,
(
0
,)),
(
'mosi-data'
,
'MOSI data'
,
(
1
,)),
(
'qspi-data'
,
'QSPI data'
,
(
2
,)),
(
'qspi-byte'
,
'QSPI byte'
,
(
3
,)),
)
def
__init__
(
self
):
...
...
@@ -118,14 +125,18 @@ class Decoder(srd.Decoder):
def
reset
(
self
):
self
.
samplerate
=
None
self
.
bitcount
=
0
self
.
misodata
=
self
.
mosidata
=
0
self
.
nibblecount
=
0
self
.
bytecount_cs_qspi
=
0
self
.
qspidata
=
self
.
misodata
=
self
.
mosidata
=
0
self
.
misobits
=
[]
self
.
mosibits
=
[]
self
.
qspibits
=
[]
self
.
ss_block
=
-
1
self
.
qspi_ss_block
=
-
1
self
.
samplenum
=
-
1
self
.
ss_transfer
=
-
1
self
.
cs_was_deasserted
=
False
self
.
have_cs
=
self
.
have_miso
=
self
.
have_mosi
=
None
self
.
have_cs
=
self
.
have_
qspi
=
self
.
have_
miso
=
self
.
have_mosi
=
None
def
start
(
self
):
self
.
out_ann
=
self
.
register
(
srd
.
OUTPUT_ANN
)
...
...
@@ -154,24 +165,46 @@ class Decoder(srd.Decoder):
if
self
.
have_mosi
:
self
.
put
(
ss
,
es
,
self
.
out_ann
,
[
1
,
[
'%02X'
%
self
.
mosidata
]])
def
putqspidata
(
self
):
if
self
.
have_qspi
:
ss
,
es
=
self
.
qspibits
[
-
1
][
1
],
self
.
qspibits
[
0
][
2
]
# Dataword annotations.
if
self
.
have_qspi
:
self
.
put
(
ss
,
es
,
self
.
out_ann
,
[
2
,
[
'%02X'
%
self
.
qspidata
]])
self
.
put
(
ss
,
es
,
self
.
out_ann
,
[
3
,
[
'%d'
%
self
.
bytecount_cs_qspi
]])
self
.
bytecount_cs_qspi
+=
1
def
reset_decoder_state
(
self
):
self
.
misodata
=
0
if
self
.
have_miso
else
None
self
.
mosidata
=
0
if
self
.
have_mosi
else
None
self
.
qspidata
=
0
if
self
.
have_qspi
else
None
self
.
misobits
=
[]
if
self
.
have_miso
else
None
self
.
mosibits
=
[]
if
self
.
have_mosi
else
None
self
.
qspibits
=
[]
if
self
.
have_qspi
else
None
self
.
bitcount
=
0
self
.
nibblecount
=
0
def
reset_qspi_decoder_state
(
self
):
self
.
qspidata
=
0
if
self
.
have_qspi
else
None
self
.
qspibits
=
[]
if
self
.
have_qspi
else
None
self
.
nibblecount
=
0
def
cs_asserted
(
self
,
cs
):
active_low
=
(
self
.
options
[
'cs_polarity'
]
==
'active-low'
)
return
(
cs
==
0
)
if
active_low
else
(
cs
==
1
)
def
handle_bit
(
self
,
miso
,
mosi
,
clk
,
cs
):
def
handle_bit
(
self
,
dq3
,
dq2
,
miso
,
mosi
,
clk
,
cs
):
# If this is the first bit of a dataword, save its sample number.
if
self
.
bitcount
==
0
:
self
.
nibblecount
=
0
;
self
.
ss_block
=
self
.
samplenum
self
.
cs_was_deasserted
=
\
not
self
.
cs_asserted
(
cs
)
if
self
.
have_cs
else
False
if
self
.
nibblecount
==
0
:
self
.
qspi_ss_block
=
self
.
samplenum
ws
=
self
.
options
[
'wordsize'
]
bo
=
self
.
options
[
'bitorder'
]
...
...
@@ -189,6 +222,15 @@ class Decoder(srd.Decoder):
else
:
self
.
mosidata
|=
mosi
<<
self
.
bitcount
if
self
.
have_qspi
:
nibble
=
0
nibble
|=
dq3
<<
3
nibble
|=
dq2
<<
2
nibble
|=
miso
<<
1
nibble
|=
mosi
<<
0
self
.
qspidata
=
self
.
qspidata
<<
4
self
.
qspidata
|=
nibble
# Guesstimate the endsample for this bit (can be overridden below).
es
=
self
.
samplenum
if
self
.
bitcount
>
0
:
...
...
@@ -202,27 +244,44 @@ class Decoder(srd.Decoder):
if
self
.
have_mosi
:
self
.
mosibits
.
insert
(
0
,
[
mosi
,
self
.
samplenum
,
es
])
# Guesstimate the endsample for this word (can be overridden below).
es
=
self
.
samplenum
if
self
.
nibblecount
>
0
:
if
self
.
have_qspi
:
es
+=
self
.
samplenum
-
self
.
qspibits
[
0
][
1
]
if
self
.
have_qspi
:
self
.
qspibits
.
insert
(
0
,
[
dq3
,
self
.
samplenum
,
es
])
if
self
.
bitcount
>
0
and
self
.
have_miso
:
self
.
misobits
[
1
][
2
]
=
self
.
samplenum
if
self
.
bitcount
>
0
and
self
.
have_mosi
:
self
.
mosibits
[
1
][
2
]
=
self
.
samplenum
if
self
.
nibblecount
>
0
and
self
.
have_qspi
:
self
.
qspibits
[
1
][
2
]
=
self
.
samplenum
self
.
bitcount
+=
1
self
.
nibblecount
+=
1
if
self
.
nibblecount
>
1
:
self
.
putqspidata
()
self
.
reset_qspi_decoder_state
()
# Continue to receive if not enough bits were received, yet.
if
self
.
bitcount
!=
ws
:
return
self
.
putdata
()
self
.
reset_decoder_state
()
def
find_clk_edge
(
self
,
miso
,
mosi
,
clk
,
cs
,
first
):
def
find_clk_edge
(
self
,
dq3
,
dq2
,
miso
,
mosi
,
clk
,
cs
,
first
):
if
self
.
have_cs
and
(
first
or
(
self
.
matched
&
(
0b1
<<
self
.
have_cs
))):
# Send all CS# pin value changes.
oldcs
=
None
if
first
else
1
-
cs
# Reset decoder state when CS# changes (and the CS# pin is used).
self
.
bytecount_cs_qspi
=
0
self
.
reset_decoder_state
()
# We only care about samples if CS# is asserted.
...
...
@@ -234,7 +293,7 @@ class Decoder(srd.Decoder):
return
# Found the correct clock edge, now get the SPI bit(s).
self
.
handle_bit
(
miso
,
mosi
,
clk
,
cs
)
self
.
handle_bit
(
dq3
,
dq2
,
miso
,
mosi
,
clk
,
cs
)
def
decode
(
self
):
# The CLK input is mandatory. Other signals are (individually)
...
...
@@ -242,11 +301,12 @@ class Decoder(srd.Decoder):
# Tell stacked decoders when we don't have a CS# signal.
if
not
self
.
has_channel
(
0
):
raise
ChannelError
(
'CLK pin required.'
)
self
.
have_miso
=
self
.
has_channel
(
1
)
self
.
have_mosi
=
self
.
has_channel
(
2
)
self
.
have_qspi
=
self
.
has_channel
(
1
)
and
self
.
has_channel
(
2
)
self
.
have_miso
=
self
.
has_channel
(
3
)
self
.
have_mosi
=
self
.
has_channel
(
4
)
if
not
self
.
have_miso
and
not
self
.
have_mosi
:
raise
ChannelError
(
'Either MISO or MOSI (or both) pins required.'
)
self
.
have_cs
=
self
.
has_channel
(
3
)
self
.
have_cs
=
self
.
has_channel
(
5
)
# We want all CLK changes. We want all CS changes if CS is used.
# Map 'have_cs' from boolean to an integer index. This simplifies
...
...
@@ -260,15 +320,15 @@ class Decoder(srd.Decoder):
if
self
.
have_cs
:
self
.
have_cs
=
len
(
wait_cond
)
wait_cond
.
append
({
3
:
'e'
})
wait_cond
.
append
({
5
:
'e'
})
# "Pixel compatibility" with the v2 implementation. Grab and
# process the very first sample before checking for edges. The
# previous implementation did this by seeding old values with
# None, which led to an immediate "change" in comparison.
(
clk
,
miso
,
mosi
,
cs
)
=
self
.
wait
({})
self
.
find_clk_edge
(
miso
,
mosi
,
clk
,
cs
,
True
)
(
clk
,
dq3
,
dq2
,
miso
,
mosi
,
cs
)
=
self
.
wait
({})
self
.
find_clk_edge
(
dq3
,
dq2
,
miso
,
mosi
,
clk
,
cs
,
True
)
while
True
:
(
clk
,
miso
,
mosi
,
cs
)
=
self
.
wait
(
wait_cond
)
self
.
find_clk_edge
(
miso
,
mosi
,
clk
,
cs
,
False
)
(
clk
,
dq3
,
dq2
,
miso
,
mosi
,
cs
)
=
self
.
wait
(
wait_cond
)
self
.
find_clk_edge
(
dq3
,
dq2
,
miso
,
mosi
,
clk
,
cs
,
False
)
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