qmi.instruments.wieserlabs.flexdds
Instrument driver for the Wieserlabs FlexDDS-NG Dual signal source.
Classes
|
Register names and addresses of the DCP. |
|
Register names and addresses of the AD9910 DDS. |
|
FlexDDS commands can be specified to apply to one or both of the output channels. |
|
PLL status of the Wieserlabs FlexDDS. |
|
Instrument driver for the Wieserlabs FlexDDS-NG Dual signal source. |
- class qmi.instruments.wieserlabs.flexdds.OutputChannel(value)
FlexDDS commands can be specified to apply to one or both of the output channels.
- conjugate()
Returns self, the complex conjugate of any int.
- bit_length()
Number of bits necessary to represent self in binary.
>>> bin(37) '0b100101' >>> (37).bit_length() 6
- bit_count()
Number of ones in the binary representation of the absolute value of self.
Also known as the population count.
>>> bin(13) '0b1101' >>> (13).bit_count() 3
- to_bytes(length=1, byteorder='big', *, signed=False)
Return an array of bytes representing an integer.
- length
Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
- classmethod from_bytes(bytes, byteorder='big', *, signed=False)
Return the integer represented by the given array of bytes.
- bytes
Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Indicates whether two’s complement is used to represent the integer.
- as_integer_ratio()
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
- real
the real part of a complex number
- imag
the imaginary part of a complex number
- numerator
the numerator of a rational number in lowest terms
- denominator
the denominator of a rational number in lowest terms
- class qmi.instruments.wieserlabs.flexdds.DdsRegister(value)
Register names and addresses of the AD9910 DDS.
- conjugate()
Returns self, the complex conjugate of any int.
- bit_length()
Number of bits necessary to represent self in binary.
>>> bin(37) '0b100101' >>> (37).bit_length() 6
- bit_count()
Number of ones in the binary representation of the absolute value of self.
Also known as the population count.
>>> bin(13) '0b1101' >>> (13).bit_count() 3
- to_bytes(length=1, byteorder='big', *, signed=False)
Return an array of bytes representing an integer.
- length
Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
- classmethod from_bytes(bytes, byteorder='big', *, signed=False)
Return the integer represented by the given array of bytes.
- bytes
Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Indicates whether two’s complement is used to represent the integer.
- as_integer_ratio()
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
- real
the real part of a complex number
- imag
the imaginary part of a complex number
- numerator
the numerator of a rational number in lowest terms
- denominator
the denominator of a rational number in lowest terms
- class qmi.instruments.wieserlabs.flexdds.DcpRegister(value)
Register names and addresses of the DCP.
- conjugate()
Returns self, the complex conjugate of any int.
- bit_length()
Number of bits necessary to represent self in binary.
>>> bin(37) '0b100101' >>> (37).bit_length() 6
- bit_count()
Number of ones in the binary representation of the absolute value of self.
Also known as the population count.
>>> bin(13) '0b1101' >>> (13).bit_count() 3
- to_bytes(length=1, byteorder='big', *, signed=False)
Return an array of bytes representing an integer.
- length
Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
- classmethod from_bytes(bytes, byteorder='big', *, signed=False)
Return the integer represented by the given array of bytes.
- bytes
Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.
- byteorder
The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.
- signed
Indicates whether two’s complement is used to represent the integer.
- as_integer_ratio()
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
- real
the real part of a complex number
- imag
the imaginary part of a complex number
- numerator
the numerator of a rational number in lowest terms
- denominator
the denominator of a rational number in lowest terms
- class qmi.instruments.wieserlabs.flexdds.PllStatus(pll1_lock: bool, pll2_lock: bool, holdover: bool, clkin0_lost: bool, clkin1_lost: bool)
PLL status of the Wieserlabs FlexDDS.
- pll1_lock: bool
Alias for field number 0
- pll2_lock: bool
Alias for field number 1
- holdover: bool
Alias for field number 2
- clkin0_lost: bool
Alias for field number 3
- clkin1_lost: bool
Alias for field number 4
- count(value, /)
Return number of occurrences of value.
- index(value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
- class qmi.instruments.wieserlabs.flexdds.Wieserlabs_FlexDDS_NG_Dual(context: QMI_Context, name: str, transport: str)
Instrument driver for the Wieserlabs FlexDDS-NG Dual signal source.
The instrument is based on two AD9910 direct digital synthesizer (DDS) chips, one for each output channel. The instrument also contains one DDS Command Processor (DCP) for each channel. The DCP can be used to program the DDS and to enable analog modulation modes.
This driver provides a simple, limited, high-level interface to the instrument through the methods set_single_tone(), set_amplitude_modulation() and set_frequency_modulation(). These methods support only a subset of the features of the instrument.
This driver also provides a low-level interface to the instrument through the the dcp_XXX() methods. These methods support more functionality (however waiting, triggering and digital I/O are still not supported). Detailed understanding of the FlexDDS user manual and the AD9910 datasheet are needed to use the low-level interface.
- open() None
Connect to the instrument hardware.
When this method returns, the instrument must be ready for interaction via calls to instrument-specific methods.
Subclasses can extend this method to implement instrument-specific initialization. If they do, they should call
super().open()as a last statement.
- close() None
Close the connection to the instrument hardware and release associated resources.
When this method returns, the instrument must not be used again unless it is first re-opened by calling the open() method.
Subclasses can extend this method if they have specific resources to close. If they do, they should call
super().close()as a last statement.
- get_version() str
Read the instrument version string.
- get_pll_status() PllStatus
Read the PLL status.
This is an undocumented command. The meaning of the result is not fully understood, however it seems that the attribute pll1_lock shows whether the 10 MHz external reference is detected.
- dds_reset(channel: OutputChannel) None
Reset both the DDS and the DCP for the specified channel(s).
Resetting will disable the output channel and reset all DDS registers to their default settings. It will also stop the DCP and discard any pending DCP instructions.
This command takes effect immediately.
- dcp_start(channel: OutputChannel) None
Start the DCP for the specified channel(s).
When started, the DCP will begin executing instructions from the DCP FIFO. The DCP will continue to run until it is explicitly disabled (via dcp_stop()) or until it is reset (via dds_reset()).
Starting the DCP will also flush pending instructions from the input queue to the DCP FIFO.
This command takes effect immediately.
- dcp_stop(channel: OutputChannel) None
Stop the DCP for the specified channel(s).
This command takes effect immediately.
- dcp_spi_write(channel: OutputChannel, register: DdsRegister, value: int, wait_spi: bool = True, flush: bool = False) None
Send an SPI write instruction to the DCP.
Instructs the DCP to write to the specified register of the AD9910 DDS.
This instruction will be queued and only takes effect when it has been flushed to the DCP, and the DCP is running, and the DCP has completed all previous instructions.
- Parameters:
channel – Select one or both output channels.
register – Destination DDS register.
value – Value to write to the DDS register.
wait_spi – True to make the DCP wait until the SPI write is finished. False to continue with the next DCP instruction while the SPI write is pending.
flush – True to flush DCP instructions to the DCP FIFO.
- dcp_register_write(channel: OutputChannel, register: DcpRegister, value: int, flush: bool = False) None
Send a register write instruction to the DCP.
Instructs the DCP to write to the specified DCP register.
This instruction will be queued and only takes effect when it has been flushed to the DCP, and the DCP is running, and the DCP has completed all previous instructions.
- Parameters:
channel – Select one or both output channels.
register – Destination DCP register.
value – Value to write to the DCP register.
flush – True to flush DCP instructions to the DCP FIFO.
- dcp_update(channel: OutputChannel, flush: bool = False) None
Send an update instruction to the DCP.
Instructs the DCP to pulse the IO_UPDATE signal to the AD9910 DDS. A pulse on the IO_UPDATE signal will cause any new values in DDS registers to take effect.
It is important that all SPI write instructions have completed before sending the IO_UPDATE pulse. This can be ensured by setting wait_spi=True on the last call to dcp_spi_write().
This instruction will be queued and only takes effect when it has been flushed to the DCP, and the DCP is running, and the DCP has completed all previous instructions.
- Parameters:
channel – Select one or both output channels.
flush – True to flush DCP instructions to the DCP FIFO.
- set_single_tone(channel: OutputChannel, frequency: float, amplitude: float, phase: float) None
Configure the specified channel to produce a single tone.
The frequency will be rounded to the closest integer multiple of the internal frequency resolution (see Wieserlabs_FlexDDS_NG_Dual.FREQUENCY_RESOLUTION).
The amplitude is a linear voltage scale factor, expressed as a fraction of the maximum output amplitude: +10 dBm (2 Vpp).
This function assumes that the FlexDDS is in a “normal” configuration. When in doubt, call dds_reset() before calling this function.
- Parameters:
channel – Select one or both output channels.
frequency – Tone frequency in Hz (range 300 kHz … 400 MHz).
amplitude – Amplitude scale factor (range 0.0 … 1.0).
phase – Phase offset as fraction of the full sine wave period (range 0.0 … 1.0).
- set_amplitude_modulation(channel: OutputChannel, frequency: float, base_ampl: float, phase: float, mod_input: int, mod_offset: float, mod_scale: float) None
Configure the specified channel for a single tone with analog amplitude modulation.
The base_ampl parameter sets the nominal amplitude scale factor, expressed as a fraction of the maximum output amplitude: +10 dBm (2 Vpp). This nominal amplitude applies when the modulation level is zero.
The effective amplitude scale factor can be calculated as follows:
A = base_ampl + mod_scale * (M + mod_offset)
- where M is the signal level of the analog modulation input in Volt (range -0.5 … +0.5);
A is the effective amplitude scale factor as a fraction of the maximum output level (2 Vpp).
The effective amplitude scale factor A will be clipped to the range 0.0 … 1.0.
For example, the following call will configure output channel 0 for 10 MHz output with amplitude modulation to span the amplitude range from 0 Vpp (at analog input level -0.5 Volt) to 2 Vpp (at analog input level +0.5 Volt):
instr.set_amplitude_modulation(channel=OutputChannel.OUT0, frequency=10.0e6, base_amplitude=0.5, phase=0, mod_input=0, mod_offset=0, mod_scale=1.0)
This function assumes that the FlexDDS is in a “normal” configuration. When in doubt, call dds_reset() before calling this function.
- Parameters:
channel – Select one or both output channels.
frequency – Tone frequency in Hz (range 300 kHz … 400 MHz).
base_ampl – Base amplitude scale factor (range -2.0 … 2.0).
phase – Phase offset as fraction of the full sine wave period (range 0.0 … 1.0).
mod_input – Analog input channel for amplitude modulation (0 or 1).
mod_offset – Offset to add to the analog input signal in Volt (range -0.5 … +0.5).
mod_scale – Scale factor from analog input signal to RF output amplitude, where 1.0 means that the full range of the analog input corresponds to the full range of the output amplitude (range -30.0 … +30.0).
- set_frequency_modulation(channel: OutputChannel, base_freq: float, amplitude: float, phase: float, mod_input: int, mod_offset: float, mod_scale: float) None
Configure the specified channel for a single tone with analog frequency modulation.
The base_freq parameter sets the nominal output frequency in Hz. This nominal frequency applies when the modulation level is zero.
The effective frequency can be calculated as follows:
F = base_freq + mod_scale * (M + mod_offset)
- where M is the signal level of the analog modulation input in Volt (range -0.5 … +0.5);
F is the effective frequency in Hz.
For example, the following call configures output channel 0 for a base output frequency of 10 MHz with a 1 MHz modulation range, such that analog input -0.5 V results in 9.5 MHz and analog input +0.5 V results in 10.5 MHz:
instr.set_frequency_modulation(channel=OutputChannel.OUT0, base_freq=10.0e6, amplitude=0.5, phase=0, mod_input=0, mod_offset=0, mod_scale=1.0e6)
This function assumes that the FlexDDS is in a “normal” configuration. When in doubt, call dds_reset() before calling this function.
- Parameters:
channel – Select one or both output channels.
base_freq – Base frequency in Hz (range 300 kHz … 400 MHz).
amplitude – Amplitude scale factor (range 0.0 … 1.0).
phase – Phase offset as fraction of the full sine wave period (range 0.0 … 1.0).
mod_input – Analog input channel for amplitude modulation (0 or 1).
mod_offset – Offset to add to the analog input signal in Volt (range -0.5 … +0.5).
mod_scale – Frequency shift in Hz corresponding to the peak-to-peak range of the analog input (range -500 MHz … +500 MHz). This can also be interpreted as a scale factor from analog input to frequency in Hz/Volt.
- set_digital_modulation(channel: OutputChannel, frequency: float, amplitude: float, phase: float, mod_input: int, mod_invert: bool) None
Configure the specified channel to produce a single tone with digital on/off modulation.
The frequency will be rounded to the closest integer multiple of the internal frequency resolution (see Wieserlabs_FlexDDS_NG_Dual.FREQUENCY_RESOLUTION).
The amplitude is a linear voltage scale factor, expressed as a fraction of the maximum output amplitude: +10 dBm (2 Vpp).
This function assumes that the FlexDDS is in a “normal” configuration. When in doubt, call dds_reset() before calling this function.
- Parameters:
channel – Select one or both output channels.
frequency – Tone frequency in Hz (range 300 kHz … 400 MHz).
amplitude – Amplitude scale factor (range 0.0 … 1.0).
phase – Phase offset as fraction of the full sine wave period (range 0.0 … 1.0).
mod_input – Digital input channel for on/off modulation (0 = BNC port A, 1 = BNC port B, 2 = BNC port C).
mod_invert – True to invert the modulation signal (high TTL signal on BNC input disables the RF output); False to use the non-inverted modulation signal (high TTL signal on BNC enables the RF output).
- set_phase_modulation(channel: OutputChannel, frequency: float, amplitude: float, mod_input: int, mod_offset: float, mod_scale: float) None
Configure the specified channel for a single tone with analog phase modulation.
The effective phase can be calculated as follows:
P = mod_scale * (M + mod_offset)
- where M is the signal level of the analog modulation input in Volt (range -0.5 … +0.5);
P is the effective phase as fraction of the full sine wave period (range 0.0 … 1.0).
The effective phase P will be clipped to the range 0.0 … 1.0. It is thus not possible to shift the phase through multiple periods of the sine wave.
This function assumes that the FlexDDS is in a “normal” configuration. When in doubt, call dds_reset() before calling this function.
- Parameters:
channel – Select one or both output channels.
frequency – Tone frequency in Hz (range 300 kHz … 400 MHz).
amplitude – Amplitude scale factor (range 0.0 … 1.0).
mod_input – Analog input channel for amplitude modulation (0 or 1).
mod_offset – Offset to add to the analog input signal in Volt (range -0.5 … +0.5).
mod_scale – Scale factor from analog input signal to RF phase, where 1.0 means that the full range of the analog input corresponds to one full sine wave period (range -30.0 … +30.0).
- force_unlock() None
Forcefully unlock the remote object.
This unlocks the object, regardless of who owns the lock. This allows you to unlock an object if the locking proxy has been destroyed without unlocking.
Use this with care.
Do not override this stub method in subclasses. It has already been implemented in QMI_RpcProxy.
- classmethod get_category() str | None
Return the optional name of the category this object belongs to.
A category name is a free-form string that has no special significance. Its purpose is to distinguish between groups of RPC objects that fulfill similar roles.
- get_name() str
Return the name of this object.
- Returns:
name attribute.
- get_signals() list[SignalDescription]
Return a list of signals that can be published by this object.
- Returns:
List consisting of qmi_signals attributes.
- is_locked() bool
Query if the remote object is locked.
Do not override this stub method in subclasses. It has already been implemented in QMI_RpcProxy.
- is_open() bool
Return True if the instrument is open (ready for interaction).
- lock(timeout: float = 0.0, lock_token: str | None = None) bool
Lock the remote object. If timeout is given, try every 0.1s within the given timeout value. The remote object can be locked with an optional custom lock token by giving a string into lock_token keyword argument.
If successful, this proxy is the only proxy that can invoke RPC methods on the remote object; other proxies will receive an “object is locked” response. The return value indicates if the lock was granted; a denied lock means the object was already locked by another proxy.
Do not override this stub method in subclasses. It has already been implemented in QMI_RpcProxy.
- release_rpc_object() None
Give a warning if the instrument is removed while still open.
- unlock(lock_token: str | None = None) bool
Unlock the remote object.
Without optional parameters, this is only allowed by the proxy that initially locked the object. By giving the lock token as an input parameter, the specific object locked by this token can be unlocked. The return value indicates if the unlocking was successful.
Do not override this stub method in subclasses. It has already been implemented in QMI_RpcProxy.