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
702f8ce4
Commit
702f8ce4
authored
4 years ago
by
Timothy Pearson
Browse files
Options
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
)
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