# Core drivers reference¶

These drivers are for the core device and the peripherals closely integrated into it, which do not use the controller mechanism.

## artiq.coredevice.core module¶

class artiq.coredevice.core.Core(dmgr, ref_period, external_clock=False, ref_multiplier=8, comm_device='comm')[source]

Core device driver.

Parameters: ref_period – period of the reference clock for the RTIO subsystem. On platforms that use clock multiplication and SERDES-based PHYs, this is the period after multiplication. For example, with a RTIO core clocked at 125MHz and a SERDES multiplication factor of 8, the reference period is 1ns. The time machine unit is equal to this period. external_clock – whether the core device should switch to its external RTIO clock input instead of using its internal oscillator. ref_multiplier – ratio between the RTIO fine timestamp frequency and the RTIO coarse timestamp frequency (e.g. SERDES multiplication factor). comm_device – name of the device used for communications.
break_realtime()[source]

Set the time cursor after the current value of the hardware RTIO counter plus a margin of 125000 machine units.

If the time cursor is already after that position, this function does nothing.

reset()[source]

Clear RTIO FIFOs, release RTIO PHY reset, and set the time cursor at the current value of the hardware RTIO counter plus a margin of 125000 machine units.

## artiq.coredevice.ttl module¶

class artiq.coredevice.ttl.TTLClockGen(dmgr, channel, core_device='core')[source]

RTIO TTL clock generator driver.

This should be used with TTL channels that have a clock generator built into the gateware (not compatible with regular TTL channels).

The time cursor is not modified by any function in this class.

Parameters: channel – channel number
frequency_to_ftw(frequency)[source]

Returns the frequency tuning word corresponding to the given frequency.

ftw_to_frequency(ftw)[source]

Returns the frequency corresponding to the given frequency tuning word.

set(frequency)[source]

Like set_mu, but using Hz.

set_mu(frequency)[source]

Set the frequency of the clock, in machine units, at the current position of the time cursor.

This also sets the phase, as the time of the first generated rising edge corresponds to the time of the call.

The clock generator contains a 24-bit phase accumulator operating on the RTIO clock. At each RTIO clock tick, the frequency tuning word is added to the phase accumulator. The most significant bit of the phase accumulator is connected to the TTL line. Setting the frequency tuning word has the additional effect of setting the phase accumulator to 0x800000.

Due to the way the clock generator operates, frequency tuning words that are not powers of two cause jitter of one RTIO clock cycle at the output.

stop()[source]

Stop the toggling of the clock and set the output level to 0.

sync()[source]

Busy-wait until all programmed frequency switches and stops have been effected.

class artiq.coredevice.ttl.TTLInOut(dmgr, channel, core_device='core')[source]

RTIO TTL input/output driver.

In output mode, provides functions to set the logic level on the signal.

In input mode, provides functions to analyze the incoming signal, with real-time gating to prevent overflows.

RTIO TTLs supports zero-length transition suppression. For example, if two pulses are emitted back-to-back with no delay between them, they will be merged into a single pulse with a duration equal to the sum of the durations of the original pulses.

This should be used with bidirectional channels.

Note that the channel is in input mode by default. If you need to drive a signal, you must call output. If the channel is in output mode most of the time in your setup, it is a good idea to call output in the startup kernel.

Parameters: channel – channel number
count()[source]

Poll the RTIO input during all the previously programmed gate openings, and returns the number of registered events.

This function does not interact with the time cursor.

gate_both(duration)[source]

Register both rising and falling edge events for the specified duration (in seconds).

The time cursor is advanced by the specified duration.

gate_both_mu(duration)[source]

Register both rising and falling edge events for the specified duration (in machine units).

The time cursor is advanced by the specified duration.

gate_falling(duration)[source]

Register falling edge events for the specified duration (in seconds).

The time cursor is advanced by the specified duration.

gate_falling_mu(duration)[source]

Register falling edge events for the specified duration (in machine units).

The time cursor is advanced by the specified duration.

gate_rising(duration)[source]

Register rising edge events for the specified duration (in seconds).

The time cursor is advanced by the specified duration.

gate_rising_mu(duration)[source]

Register rising edge events for the specified duration (in machine units).

The time cursor is advanced by the specified duration.

input()[source]

Set the direction to input at the current position of the time cursor.

There must be a delay of at least one RTIO clock cycle before any other command can be issued.

off()[source]

Set the output to a logic low state at the current position of the time cursor.

The channel must be in output mode.

The time cursor is not modified by this function.

on()[source]

Set the output to a logic high state at the current position of the time cursor.

The channel must be in output mode.

The time cursor is not modified by this function.

output()[source]

Set the direction to output at the current position of the time cursor.

There must be a delay of at least one RTIO clock cycle before any other command can be issued.

pulse(duration)[source]

Pulses the output high for the specified duration (in seconds).

The time cursor is advanced by the specified duration.

pulse_mu(duration)[source]

Pulses the output high for the specified duration (in machine units).

The time cursor is advanced by the specified duration.

sync()[source]

Busy-wait until all programmed level switches have been effected.

timestamp_mu()[source]

Poll the RTIO input and returns an event timestamp (in machine units), according to the gating.

If the gate is permanently closed, returns a negative value.

This function does not interact with the time cursor.

class artiq.coredevice.ttl.TTLOut(dmgr, channel, core_device='core')[source]

RTIO TTL output driver.

This should be used with output-only channels.

Parameters: channel – channel number
off()[source]

Set the output to a logic low state at the current position of the time cursor.

The time cursor is not modified by this function.

on()[source]

Sets the output to a logic high state at the current position of the time cursor.

The time cursor is not modified by this function.

pulse(duration)[source]

Pulse the output high for the specified duration (in seconds).

The time cursor is advanced by the specified duration.

pulse_mu(duration)[source]

Pulse the output high for the specified duration (in machine units).

The time cursor is advanced by the specified duration.

sync()[source]

Busy-wait until all programmed level switches have been effected.

## artiq.coredevice.dds module¶

class artiq.coredevice.dds._DDSGeneric(dmgr, bus_channel, channel, core_dds_device='core_dds')[source]

Core device Direct Digital Synthesis (DDS) channel driver.

Controls one DDS channel managed directly by the core device’s runtime.

This class should not be used directly, instead, use the chip-specific drivers such as AD9858 and AD9914.

The time cursor is not modified by any function in this class.

Parameters: bus – name of the DDS bus device that this DDS is connected to. channel – channel number of the DDS device to control.
amplitude_to_asf(amplitude)[source]

Returns amplitude scale factor corresponding to given amplitude.

asf_to_amplitude(asf)[source]

Returns the amplitude corresponding to the given amplitude scale factor.

frequency_to_ftw(frequency)[source]

Returns the frequency tuning word corresponding to the given frequency.

ftw_to_frequency(ftw)[source]

Returns the frequency corresponding to the given frequency tuning word.

init()[source]

Resets and initializes the DDS channel.

This needs to be done for each DDS channel before it can be used, and it is recommended to use the startup kernel for this.

This function cannot be used in a batch; the correct way of initializing multiple DDS channels is to call this function sequentially with a delay between the calls. 2ms provides a good timing margin.

pow_to_turns(pow)[source]

Returns the phase in turns corresponding to the given phase offset word.

set(frequency, phase=0.0, phase_mode=-1, amplitude=1.0)[source]

Like set_mu, but uses Hz and turns.

set_mu(frequency, phase=0, phase_mode=-1, amplitude=4095)[source]

Sets the DDS channel to the specified frequency and phase.

This uses machine units (FTW and POW). The frequency tuning word width is 32, whereas the phase offset word width depends on the type of DDS chip and can be retrieved via the pow_width attribute. The amplitude width is 12.

The “frequency update” pulse is sent to the DDS with a fixed latency with respect to the current position of the time cursor.

Parameters: frequency – frequency to generate. phase – adds an offset, in turns, to the phase. phase_mode – if specified, overrides the default phase mode set by set_phase_mode for this call.
set_phase_mode(phase_mode)[source]

Sets the phase mode of the DDS channel. Supported phase modes are:

• PHASE_MODE_CONTINUOUS: the phase accumulator is unchanged when switching frequencies. The DDS phase is the sum of the phase accumulator and the phase offset. The only discrete jumps in the DDS output phase come from changes to the phase offset.
• PHASE_MODE_ABSOLUTE: the phase accumulator is reset when switching frequencies. Thus, the phase of the DDS at the time of the frequency change is equal to the phase offset.
• PHASE_MODE_TRACKING: when switching frequencies, the phase accumulator is set to the value it would have if the DDS had been running at the specified frequency since the start of the experiment.
turns_to_pow(turns)[source]

Returns the phase offset word corresponding to the given phase in turns.

class artiq.coredevice.dds.AD9858(dmgr, bus_channel, channel, core_dds_device='core_dds')[source]

Driver for AD9858 DDS chips. See _DDSGeneric for a description of the functionality.

class artiq.coredevice.dds.AD9914(dmgr, bus_channel, channel, core_dds_device='core_dds')[source]

Driver for AD9914 DDS chips. See _DDSGeneric for a description of the functionality.

init_sync(sync_delay=0)[source]

Resets and initializes the DDS channel as well as configures the AD9914 DDS for synchronisation. The synchronisation procedure follows the steps outlined in the AN-1254 application note.

This needs to be done for each DDS channel before it can be used, and it is recommended to use the startup kernel for this.

This function cannot be used in a batch; the correct way of initializing multiple DDS channels is to call this function sequentially with a delay between the calls. 10ms provides a good timing margin.

Parameters: sync_delay – integer from 0 to 0x3f that sets the value of SYNC_OUT (bits 3-5) and SYNC_IN (bits 0-2) delay ADJ bits.
class artiq.coredevice.dds.CoreDDS(dmgr, sysclk, core_device='core')[source]

Core device Direct Digital Synthesis (DDS) driver.

Parameters: sysclk – DDS system frequency. The DDS system clock must be a phase-locked multiple of the RTIO clock.
dds_batch_enter()[source]

Starts a DDS command batch. All DDS commands are buffered after this call, until batch_exit is called.

The time of execution of the DDS commands is the time cursor position when the batch is entered.

dds_batch_exit()[source]

Ends a DDS command batch. All buffered DDS commands are issued on the bus.

## artiq.coredevice.spi module¶

class artiq.coredevice.spi.SPIMaster(dmgr, channel, core_device='core')[source]

Core device Serial Peripheral Interface (SPI) bus master. Owns one SPI bus.

Transfer Sequence:

Notes:

• In order to chain a transfer onto an in-flight transfer without deasserting cs in between, the second write() needs to happen strictly later than 2*ref_period_mu (two coarse RTIO cycles) but strictly earlier than xfer_period_mu + write_period_mu after the first. Note that write() already applies a delay of xfer_period_mu + write_period_mu.
• A full transfer takes write_period_mu + xfer_period_mu.
• Chained transfers can happen every xfer_period_mu.
• Read data is available every xfer_period_mu starting a bit after xfer_period_mu (depending on clk_phase).
• As a consequence, in order to chain transfers together, new data must be written before the pending transfer’s read data becomes available.
Parameters: channel – RTIO channel number of the SPI bus to control.
input_async()[source]

Retrieves data read asynchronously from the data register.

input_async() must match a preeeding read_async().

read_async()[source]

Trigger an asynchronous read from the data register.

For bit alignment and bit ordering see set_config().

Reads always finish in two cycles.

Every data register read triggered by a read_async() must be matched by a input_async() to retrieve the data.

This method advances the timeline by the duration of the RTIO-to-Wishbone bus transaction (three RTIO clock cycles).

read_sync()[source]

Read the data register synchronously.

This is a shortcut for read_async() followed by input_async().

set_config(flags=0, write_freq=20000000.0, read_freq=20000000.0)[source]

Set the configuration register.

• If config.cs_polarity == 0 (cs active low, the default), “cs_n all deasserted” means “all cs_n bits high”.
• cs_n is not mandatory in the pads supplied to the gateware core. Framing and chip selection can also be handled independently through other means, e.g. TTLOut.
• If there is a miso wire in the pads supplied in the gateware, input and output may be two signals (“4-wire SPI”), otherwise mosi must be used for both output and input (“3-wire SPI”) and config.half_duplex must to be set when reading data is desired or when the slave drives the mosi signal at any point.
• The first bit output on mosi is always the MSB/LSB (depending on config.lsb_first) of the data register, independent of xfer.write_length. The last bit input from miso always ends up in the LSB/MSB (respectively) of the data register, independent of xfer.read_length.
• Writes to the config register take effect immediately.

Configuration flags:

• SPI_OFFLINE: all pins high-z (reset=1)
• SPI_ACTIVE: transfer in progress (read-only)
• SPI_PENDING: transfer pending in intermediate buffer (read-only)
• SPI_CS_POLARITY: active level of cs_n (reset=0)
• SPI_CLK_POLARITY: idle level of clk (reset=0)
• SPI_CLK_PHASE: first edge after cs assertion to sample data on (reset=0). In Motorola/Freescale SPI language (SPI_CLK_POLARITY, SPI_CLK_PHASE) == (CPOL, CPHA):
• (0, 0): idle low, output on falling, input on rising
• (0, 1): idle low, output on rising, input on falling
• (1, 0): idle high, output on rising, input on falling
• (1, 1): idle high, output on falling, input on rising
• SPI_LSB_FIRST: LSB is the first bit on the wire (reset=0)
• SPI_HALF_DUPLEX: 3-wire SPI, in/out on mosi (reset=0)

This method advances the timeline by the duration of the RTIO-to-Wishbone bus transaction (three RTIO clock cycles).

Parameters: flags – A bit map of SPI_* flags. write_freq – Desired SPI clock frequency during write bits. read_freq – Desired SPI clock frequency during read bits.
set_config_mu(flags=0, write_div=6, read_div=6)[source]

Set the config register (in SPI bus machine units).

Parameters: write_div – Counter load value to divide the RTIO clock by to generate the SPI write clk. (minimum=2, reset=2) f_rtio_clk/f_spi_write == write_div. If write_div is odd, the setup phase of the SPI clock is biased to longer lengths by one RTIO clock cycle. read_div – Ditto for the read clock.
set_xfer(chip_select=0, write_length=0, read_length=0)[source]

Set the xfer register.

• Every transfer consists of a write of write_length bits immediately followed by a read of read_length bits.
• cs_n is asserted at the beginning and deasserted at the end of the transfer if there is no other transfer pending.
• cs_n handling is agnostic to whether it is one-hot or decoded somewhere downstream. If it is decoded, “cs_n all deasserted” should be handled accordingly (no slave selected). If it is one-hot, asserting multiple slaves should only be attempted if miso is either not connected between slaves, or open collector, or correctly multiplexed externally.
• For 4-wire SPI only the sum of read_length and write_length matters. The behavior is the same (except for clock speeds) no matter how the total transfer length is divided between the two. For 3-wire SPI, the direction of mosi is switched from output to input after write_length bits.
• Data output on mosi in 4-wire SPI during the read cycles is what is found in the data register at the time. Data in the data register outside the least/most (depending on config.lsb_first) significant read_length bits is what is seen on miso (or mosi if config.half_duplex) during the write cycles.
• Writes to xfer are synchronized to the start of the next (possibly chained) transfer.

This method advances the timeline by the duration of the RTIO-to-Wishbone bus transaction (three RTIO clock cycles).

Parameters: chip_select – Bit mask of chip selects to assert. Or number of the chip select to assert if cs is decoded downstream. (reset=0) write_length – Number of bits to write during the next transfer. (reset=0) read_length – Number of bits to read during the next transfer. (reset=0)
write(data=0)[source]

Write data to data register.

• The data register and the shift register are 32 bits wide. If there are no writes to the register, miso data reappears on mosi after 32 cycles.
• A wishbone data register write is acknowledged when the transfer has been written to the intermediate buffer. It will be started when there are no other transactions being executed, either beginning a new SPI transfer of chained to an in-flight transfer.
• Writes take three ref_period cycles unless another chained transfer is pending and the transfer being executed is not complete.
• The SPI data register is double-buffered: Once a transfer has started, new write data can be written, queuing a new transfer. Transfers submitted this way are chained and executed without deasserting cs in between. Once a transfer completes, the previous transfer’s read data is available in the data register.
• For bit alignment and bit ordering see set_config().

This method advances the timeline by the duration of the SPI transfer. If a transfer is to be chained, the timeline needs to be rewound.

## artiq.coredevice.ad5360 module¶

class artiq.coredevice.ad5360.AD5360(dmgr, spi_device, ldac_device=None, chip_select=1)[source]

Support for the Analog devices AD53[67][0123] multi-channel Digital to Analog Converters

Parameters: spi_device – Name of the SPI bus this device is on. ldac_device – Name of the TTL device that LDAC is connected to (optional). Needs to be explicitly initialized to high. chip_select – Value to drive on the chip select lines during transactions.
load()[source]

Pulse the LDAC line.

This method advances the timeline by two RTIO clock periods (16 ns).

read_channel_sync(channel=0, op=0)[source]

This method advances the timeline by the duration of write() plus three RTIO-to-Wishbone transactions.

Parameters: channel – Channel number to read from. op – Operation to perform, one of _AD5360_READ_X1A, _AD5360_READ_X1B, _AD5360_READ_OFFSET, _AD5360_READ_GAIN (default: _AD5360_READ_X1A). The 16 bit register value.
set(values, op=12582912)[source]

Write to several channels and pulse LDAC to update the channels.

This method does not advance the timeline. Write events are scheduled in the past. The DACs will synchronously start changing their output levels now.

Parameters: values – List of 16 bit values to write to the channels. op – Operation to perform, one of _AD5360_CMD_DATA, _AD5360_CMD_OFFSET, _AD5360_CMD_GAIN (default: _AD5360_CMD_DATA).
setup_bus(write_div=4, read_div=7)[source]

Configure the SPI bus and the SPI transaction parameters for this device. This method has to be called before any other method if the bus has been used to access a different device in the meantime.

This method advances the timeline by the duration of two RTIO-to-Wishbone bus transactions.

write(data)[source]

Write 24 bits of data.

This method advances the timeline by the duration of the SPI transfer and the required CS high time.

write_channel(channel=0, value=0, op=12582912)[source]

Write to a channel register.

This method advances the timeline by the duration of write().

Parameters: channel – Channel number to write to. value – 16 bit value to write to the register. op – Operation to perform, one of _AD5360_CMD_DATA, _AD5360_CMD_OFFSET, _AD5360_CMD_GAIN (default: _AD5360_CMD_DATA).
write_offsets(value=8191)[source]

Write the OFS0 and OFS1 offset DACs.

This method advances the timeline by twice the duration of write().

Parameters: value – Value to set both offset registers to.

## artiq.coredevice.i2c module¶

class artiq.coredevice.i2c.PCA9548(dmgr, busno=0, address=232, core_device='core')[source]

Driver for the PCA9548 I2C bus switch.

On the KC705, this chip is used for selecting the I2C buses on the two FMC connectors. HPC=1, LPC=2.

set(channel)[source]

Select one channel.

Selecting multiple channels at the same time is not supported by this driver.

Parameters: channel – channel number (0-7)
class artiq.coredevice.i2c.TCA6424A(dmgr, busno=0, address=68, core_device='core')[source]

Driver for the TCA6424A I2C I/O expander.

On the NIST QC2 hardware, this chip is used for switching the directions of TTL buffers.

set(outputs)[source]

Drive all pins of the chip to the levels given by the specified 24-bit word.

On the QC2 hardware, the LSB of the word determines the direction of TTL0 (on a given FMC card) and the MSB that of TTL23.

A bit set to 1 means the TTL is an output.

## artiq.coredevice.cache module¶

class artiq.coredevice.cache.CoreCache(dmgr, core_device='core')[source]

Core device cache access

get(key)[source]

Extract a value from the core device cache. After a value is extracted, it cannot be replaced with another value using put() until all kernel functions finish executing; attempting to replace it will result in a artiq.coredevice.exceptions.CacheError.

If the cache does not contain any value associated with key, an empty list is returned.

The value is not copied, so mutating it will change what’s stored in the cache.

Parameters: key (str) – cache key a list of 32-bit integers
put(key, value)[source]

Put a value into the core device cache. The value will persist until reboot.

To remove a value from the cache, call put() with an empty list.

Parameters: key (str) – cache key value (list) – a list of 32-bit integers

## artiq.coredevice.exceptions module¶

exception artiq.coredevice.exceptions.CacheError[source]

Raised when putting a value into a cache row would violate memory safety.

exception artiq.coredevice.exceptions.ClockFailure[source]

Raised when RTIO PLL has lost lock.

class artiq.coredevice.exceptions.CoreException(name, message, params, traceback)[source]

Information about an exception raised or passed through the core device.

exception artiq.coredevice.exceptions.DDSError[source]

Raised when attempting to start a DDS batch while already in a batch, when too many commands are batched, and when DDS channel settings are incorrect.

exception artiq.coredevice.exceptions.I2CError[source]

Raised with a I2C transaction fails.

exception artiq.coredevice.exceptions.InternalError[source]

Raised when the runtime encounters an internal error condition.

exception artiq.coredevice.exceptions.RTIOBusy[source]

Raised when at least one output event could not be executed because the given channel was already busy executing a previous event.

This exception is raised late: after the error condition occurred. More specifically it is raised on submitting an event on the same channel after the execution of the faulty event was attempted.

exception artiq.coredevice.exceptions.RTIOCollision[source]

Raised when an event is submitted on a given channel with the same coarse timestamp as the previous one but with a different fine timestamp.

Coarse timestamps correspond to the RTIO system clock (typically around 125MHz) whereas fine timestamps correspond to the RTIO SERDES clock (typically around 1GHz).

The offending event is discarded and the RTIO core keeps operating.

exception artiq.coredevice.exceptions.RTIOOverflow[source]

Raised when at least one event could not be registered into the RTIO input FIFO because it was full (CPU not reading fast enough).

This does not interrupt operations further than cancelling the current read attempt and discarding some events. Reading can be reattempted after the exception is caught, and events will be partially retrieved.

exception artiq.coredevice.exceptions.RTIOSequenceError[source]

Raised when an event is submitted on a given channel with a timestamp not larger than the previous one.

The offending event is discarded and the RTIO core keeps operating.

exception artiq.coredevice.exceptions.RTIOUnderflow[source]

Raised when the CPU fails to submit a RTIO event early enough (with respect to the event’s timestamp).

The offending event is discarded and the RTIO core keeps operating.

exception artiq.coredevice.exceptions.WatchdogExpired`[source]

Raised when a watchdog expires.