pdq: documentation

This commit is contained in:
Robert Jördens 2017-05-02 18:55:02 +02:00
parent 1a1edb13bf
commit fed24309b8
1 changed files with 73 additions and 3 deletions

View File

@ -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