mirror of https://github.com/m-labs/artiq.git
pdq: documentation
This commit is contained in:
parent
1a1edb13bf
commit
fed24309b8
|
@ -11,6 +11,16 @@ _PDQ_SPI_CONFIG = (
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
def _PDQ_CMD(board, is_mem, adr, we):
|
def _PDQ_CMD(board, is_mem, adr, we):
|
||||||
|
"""Pack PDQ command fields into command byte.
|
||||||
|
|
||||||
|
:param board: Board address, 0 to 15, with ``15 = 0xf`` denoting broadcast
|
||||||
|
to all boards connected.
|
||||||
|
:param is_mem: If ``1``, ``adr`` denote the address of the memory to access
|
||||||
|
(0 to 2). Otherwise ``adr`` denotes the register to access.
|
||||||
|
:param adr: Address of the register or memory to access.
|
||||||
|
(``_PDQ_ADR_CONFIG``, ``_PDQ_ADR_FRAME``, ``_PDQ_ADR_CRC``).
|
||||||
|
:param we: If ``1`` then write, otherwise read.
|
||||||
|
"""
|
||||||
return (adr << 0) | (is_mem << 2) | (board << 3) | (we << 7)
|
return (adr << 0) | (is_mem << 2) | (board << 3) | (we << 7)
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,11 +30,22 @@ _PDQ_ADR_FRAME = 2
|
||||||
|
|
||||||
|
|
||||||
class PDQ:
|
class PDQ:
|
||||||
"""
|
"""PDQ smart arbitrary waveform generator stack.
|
||||||
|
|
||||||
|
Provides access to a stack of PDQ boards connected via SPI using PDQ
|
||||||
|
gateware version 3 or later.
|
||||||
|
|
||||||
|
The SPI bus is wired with ``CS_N`` from the core device connected to
|
||||||
|
``F2 IN`` on the master PDQ, ``CLK`` connected to ``F3 IN``, ``MOSI``
|
||||||
|
connected to ``F4 IN`` and ``MISO`` (optionally) connected to ``F5 OUT``.
|
||||||
|
``F1 TTL Input Trigger`` remains as waveform trigger input.
|
||||||
|
Due to hardware constraints, there can only be one board connected to the
|
||||||
|
core device's MISO line and therefore there can only be SPI readback
|
||||||
|
from one board at any time.
|
||||||
|
|
||||||
:param spi_device: Name of the SPI bus this device is on.
|
:param spi_device: Name of the SPI bus this device is on.
|
||||||
:param chip_select: Value to drive on the chip select lines
|
:param chip_select: Value to drive on the chip select lines of the SPI bus
|
||||||
during transactions.
|
during transactions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
kernel_invariants = {"core", "chip_select", "bus"}
|
kernel_invariants = {"core", "chip_select", "bus"}
|
||||||
|
@ -54,11 +75,26 @@ class PDQ:
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_reg(self, adr, data, board):
|
def write_reg(self, adr, data, board):
|
||||||
|
"""Set a PDQ register.
|
||||||
|
|
||||||
|
:param adr: Address of the register (``_PDQ_ADR_CONFIG``,
|
||||||
|
``_PDQ_ADR_FRAME``, ``_PDQ_ADR_CRC``).
|
||||||
|
:param data: Register data (8 bit).
|
||||||
|
:param board: Board to access, ``0xf`` to write to all boards.
|
||||||
|
"""
|
||||||
self.bus.write((_PDQ_CMD(board, 0, adr, 1) << 24) | (data << 16))
|
self.bus.write((_PDQ_CMD(board, 0, adr, 1) << 24) | (data << 16))
|
||||||
delay_mu(self.bus.ref_period_mu) # get to 20ns min cs high
|
delay_mu(self.bus.ref_period_mu) # get to 20ns min cs high
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_reg(self, adr, board):
|
def read_reg(self, adr, board):
|
||||||
|
"""Get a PDQ register.
|
||||||
|
|
||||||
|
:param adr: Address of the register (``_PDQ_ADR_CONFIG``,
|
||||||
|
``_PDQ_ADR_FRAME``, ``_PDQ_ADR_CRC``).
|
||||||
|
:param board: Board to access, ``0xf`` to write to all boards.
|
||||||
|
|
||||||
|
:return: Register data (8 bit).
|
||||||
|
"""
|
||||||
self.bus.set_xfer(self.chip_select, 16, 8)
|
self.bus.set_xfer(self.chip_select, 16, 8)
|
||||||
self.bus.write(_PDQ_CMD(board, 0, adr, 0) << 24)
|
self.bus.write(_PDQ_CMD(board, 0, adr, 0) << 24)
|
||||||
delay_mu(self.bus.ref_period_mu) # get to 20ns min cs high
|
delay_mu(self.bus.ref_period_mu) # get to 20ns min cs high
|
||||||
|
@ -69,32 +105,58 @@ class PDQ:
|
||||||
@kernel
|
@kernel
|
||||||
def write_config(self, reset=0, clk2x=0, enable=1,
|
def write_config(self, reset=0, clk2x=0, enable=1,
|
||||||
trigger=0, aux_miso=0, aux_dac=0b111, board=0xf):
|
trigger=0, aux_miso=0, aux_dac=0b111, board=0xf):
|
||||||
|
"""Set configuration register.
|
||||||
|
|
||||||
|
:param reset: Reset board (auto-clear).
|
||||||
|
:param clk2x: Enable clock double (100 MHz).
|
||||||
|
:param enable: Enable the reading and execution of waveform data from
|
||||||
|
memory.
|
||||||
|
:param trigger: Software trigger, logical OR with ``F1 TTL Input
|
||||||
|
Trigger``.
|
||||||
|
:param aux_miso: Use ``F5 OUT`` for ``MISO``. If ``0``, use the
|
||||||
|
masked logical OR of the DAC channels.
|
||||||
|
:param aux_dac: DAC channel mask to for AUX (``F5 OUT``) output.
|
||||||
|
:param board: Boards to address, ``0xf`` to write to all boards.
|
||||||
|
"""
|
||||||
config = ((reset << 0) | (clk2x << 1) | (enable << 2) |
|
config = ((reset << 0) | (clk2x << 1) | (enable << 2) |
|
||||||
(trigger << 3) | (aux_miso << 4) | (aux_dac << 5))
|
(trigger << 3) | (aux_miso << 4) | (aux_dac << 5))
|
||||||
self.write_reg(_PDQ_ADR_CONFIG, config, board)
|
self.write_reg(_PDQ_ADR_CONFIG, config, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_config(self, board=0xf):
|
def read_config(self, board=0xf):
|
||||||
|
"""Read configuration register."""
|
||||||
return self.read_reg(_PDQ_ADR_CONFIG, board)
|
return self.read_reg(_PDQ_ADR_CONFIG, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_crc(self, crc, board=0xf):
|
def write_crc(self, crc, board=0xf):
|
||||||
|
"""Write checksum register."""
|
||||||
self.write_reg(_PDQ_ADR_CRC, crc, board)
|
self.write_reg(_PDQ_ADR_CRC, crc, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_crc(self, board=0xf):
|
def read_crc(self, board=0xf):
|
||||||
|
"""Read checksum register."""
|
||||||
return self.read_reg(_PDQ_ADR_CRC, board)
|
return self.read_reg(_PDQ_ADR_CRC, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_frame(self, frame, board=0xf):
|
def write_frame(self, frame, board=0xf):
|
||||||
|
"""Write frame selection register."""
|
||||||
self.write_reg(_PDQ_ADR_FRAME, frame, board)
|
self.write_reg(_PDQ_ADR_FRAME, frame, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_frame(self, board=0xf):
|
def read_frame(self, board=0xf):
|
||||||
|
"""Read frame selection register."""
|
||||||
return self.read_reg(_PDQ_ADR_FRAME, board)
|
return self.read_reg(_PDQ_ADR_FRAME, board)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_mem(self, mem, adr, data, board=0xf): # FIXME: m-labs/artiq#714
|
def write_mem(self, mem, adr, data, board=0xf): # FIXME: m-labs/artiq#714
|
||||||
|
"""Write to DAC channel waveform data memory.
|
||||||
|
|
||||||
|
:param mem: DAC channel memory to access (0 to 2).
|
||||||
|
:param adr: Start address.
|
||||||
|
:param data: Memory data. List of 16 bit integers.
|
||||||
|
:param board: Board to access (0-15) with ``0xf = 15`` being broadcast
|
||||||
|
to all boards.
|
||||||
|
"""
|
||||||
self.bus.set_xfer(self.chip_select, 24, 0)
|
self.bus.set_xfer(self.chip_select, 24, 0)
|
||||||
self.bus.write((_PDQ_CMD(board, 1, mem, 1) << 24) |
|
self.bus.write((_PDQ_CMD(board, 1, mem, 1) << 24) |
|
||||||
((adr & 0x00ff) << 16) | (adr & 0xff00))
|
((adr & 0x00ff) << 16) | (adr & 0xff00))
|
||||||
|
@ -108,6 +170,14 @@ class PDQ:
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_mem(self, mem, adr, data, board=0xf, buffer=8):
|
def read_mem(self, mem, adr, data, board=0xf, buffer=8):
|
||||||
|
"""Read from DAC channel waveform data memory.
|
||||||
|
|
||||||
|
:param mem: DAC channel memory to access (0 to 2).
|
||||||
|
:param adr: Start address.
|
||||||
|
:param data: Memory data. List of 16 bit integers.
|
||||||
|
:param board: Board to access (0-15) with ``0xf = 15`` being broadcast
|
||||||
|
to all boards.
|
||||||
|
"""
|
||||||
n = len(data)
|
n = len(data)
|
||||||
if not n:
|
if not n:
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue