SPI Bus
The SPI bus interface allows you to decode traffic sent over the SPI MOSI and MISO lines. In order to decode the traffic, a number of parameters need to be set based on your knowledge how the SPI bus should be operating.
Creating an SPI Bus
To create an SPI bus, a sck (clock) net, mosi (data) net, miso (data) net, and cs (chip select, optional) net need to be instantiated.
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.enable()
~ lager bus spi --source-sck SPI.SCK --source-mosi SPI.MOSI --source-miso SPI.MISO --source-cs SPI.CS --dut 1
Data Width
The data width of a SPI packet can vary. This allows you to set the assumed data width for data transmissions.
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_data_width(8)
~ lager bus spi --data-width 8 --dut 1
Polarity
This sets whether the MOSI, MISO, and CS lines are active HIGH or LOW.
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_signal_polarity(mosi=1,miso=1,cs=1) #1 is active High
~ lager bus spi --pol-mosi pos --pol-miso pos --pol-cs pos --dut 1
Clock Phase
This sets the assumed phase of the clock, whether it samples data on the rising edge or falling edge.
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_sck_phase_rising_edge()
~ lager bus spi --pha-sck rising --dut 1
Endianness
This sets the assumed endiannes of the SPI Bus signals. Typically this will be MSB (most significant bit).
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_endianness_msb()
~ lager bus spi --endianness msb --dut 1
Capture Mode
Capture more determines if data should be captured based on a timeout after a SPI transmission starts or based on the CS Line going active and then inactive.
Timeout
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_capture_mode_timeout(.0001)
~ lager bus spi --capture timeout --timeout .0001 --dut 1
CS
spi.set_capture_mode_cs(.0001)
~ lager bus spi --capture cs --dut 1
Signal Threshold
This sets the assumed voltage threshold a rising or falling SPI signal should pass through.
from lager import Net, NetType, SPI
mosi = Net.get('SPI.MOSI',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
miso = Net.get('SPI.MISO',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
sck = Net.get('SPI.SCK',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
cs = Net.get('SPI.CS',
type=NetType.Logic,
setup_function=setup_nets,
teardown_function=teardown_nets)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi = SPI(sck=sck,mosi=mosi,miso=miso,cs=cs)
spi.set_signal_threshold(mosi=1.5,miso=1.5,sck=1.5,cs=1.5)
~ lager bus spi --level-sck 1.5 --level-mosi 1.5 --level-miso 1.5 --level-cs 1.5 --dut 1