forked from M-Labs/artiq
Update AD9834 coredevice driver
This commit is contained in:
parent
7669cfce3d
commit
7534a8fe04
@ -5,6 +5,8 @@ RTIO Driver for the Analog Devices AD9834 DDS via 3-wire SPI interface.
|
|||||||
# https://www.analog.com/media/en/technical-documentation/data-sheets/AD9834.pdf
|
# https://www.analog.com/media/en/technical-documentation/data-sheets/AD9834.pdf
|
||||||
# https://www.analog.com/media/en/technical-documentation/app-notes/an-1070.pdf
|
# https://www.analog.com/media/en/technical-documentation/app-notes/an-1070.pdf
|
||||||
|
|
||||||
|
from numpy import int32
|
||||||
|
|
||||||
from artiq.coredevice import spi2 as spi
|
from artiq.coredevice import spi2 as spi
|
||||||
from artiq.experiment import *
|
from artiq.experiment import *
|
||||||
from artiq.language.core import *
|
from artiq.language.core import *
|
||||||
@ -64,167 +66,21 @@ class AD9834:
|
|||||||
self.ctrl_reg = 0x0000 # Reset control register
|
self.ctrl_reg = 0x0000 # Reset control register
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self):
|
def write(self, data: TInt32):
|
||||||
"""
|
"""
|
||||||
Initialize the AD9834: configure the SPI bus and reset the DDS.
|
Write a 16-bit word to the AD9834.
|
||||||
|
|
||||||
This method performs the necessary setup for the AD9834 device, including:
|
This method sends a 16-bit data word to the AD9834 via the SPI bus. The input
|
||||||
- Configuring the SPI bus parameters (clock polarity, data width, and frequency).
|
data is left-shifted by 16 bits to ensure proper alignment for the SPI controller,
|
||||||
- Putting the AD9834 into a reset state to ensure proper initialization.
|
allowing for accurate processing of the command by the AD9834.
|
||||||
|
|
||||||
The SPI bus is configured to use 16 bits of data width with the clock frequency
|
This method is used internally by other methods to update the control registers
|
||||||
provided as a parameter when creating the AD9834 instance. After configuring
|
and frequency settings of the AD9834. It should not be called directly unless
|
||||||
the SPI bus, the method invokes :meth:`enable_reset()` to reset the AD9834.
|
low-level register manipulation is required.
|
||||||
This is an essential step to prepare the device for subsequent configuration
|
|
||||||
of frequency and phase.
|
|
||||||
|
|
||||||
This method should be called before any other operations are performed
|
:param data: The 16-bit word to be sent to the AD9834.
|
||||||
on the AD9834 to ensure that the device is in a known state.
|
|
||||||
"""
|
"""
|
||||||
self.bus.set_config(spi.SPI_CLK_POLARITY | spi.SPI_END, 16, self.spi_freq, 1)
|
self.bus.write(data << 16)
|
||||||
self.enable_reset()
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def set_frequency_reg(self, freq_reg, frequency: TFloat):
|
|
||||||
"""
|
|
||||||
Set the frequency for the specified frequency register.
|
|
||||||
|
|
||||||
This method calculates the frequency word based on the provided frequency in Hz
|
|
||||||
and writes it to the specified frequency register.
|
|
||||||
|
|
||||||
:param freq_reg: The frequency register to write to, must be one of
|
|
||||||
:const:`AD9834_FREQ_REG_0` or :const:`AD9834_FREQ_REG_1`.
|
|
||||||
:param frequency: The desired frequency in Hz, which will be converted to a
|
|
||||||
frequency word suitable for the AD9834.
|
|
||||||
|
|
||||||
The frequency word is calculated using the formula:
|
|
||||||
|
|
||||||
``freq_word = (frequency * (1 << 28)) / clk_freq``
|
|
||||||
|
|
||||||
The result is limited to the lower 28 bits for compatibility with the AD9834.
|
|
||||||
|
|
||||||
The method first sets the control register to enable the appropriate settings,
|
|
||||||
then sends the fourteen least significant bits LSBs and fourteen most significant
|
|
||||||
bits MSBs in two consecutive writes to the specified frequency register.
|
|
||||||
"""
|
|
||||||
if freq_reg not in FREQ_REGS:
|
|
||||||
raise ValueError("Invalid frequency register")
|
|
||||||
assert frequency <= 37.5 * MHz, "Frequency exceeds maximum value of 37.5 MHz"
|
|
||||||
freq_word = int((frequency * (1 << 28)) / self.clk_freq) & 0x0FFFFFFF
|
|
||||||
self.ctrl_reg |= AD9834_B28
|
|
||||||
self.write(self.ctrl_reg)
|
|
||||||
lsb = freq_word & 0x3FFF
|
|
||||||
msb = (freq_word >> 14) & 0x3FFF
|
|
||||||
self.write(freq_reg | lsb)
|
|
||||||
self.write(freq_reg | msb)
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def set_frequency_reg_msb(self, freq_reg, word: TInt32):
|
|
||||||
"""
|
|
||||||
Set the fourteen most significant bits MSBs of the specified frequency register.
|
|
||||||
|
|
||||||
This method updates the specified frequency register with the provided MSB value.
|
|
||||||
It configures the control register to indicate that the MSB is being set.
|
|
||||||
|
|
||||||
:param freq_reg: The frequency register to update, must be one of
|
|
||||||
:const:`AD9834_FREQ_REG_0` or :const:`AD9834_FREQ_REG_1`.
|
|
||||||
:param word: The value to be written to the fourteen MSBs of the frequency register.
|
|
||||||
|
|
||||||
The method first clears the appropriate control bits, sets :const:`AD9834_HLB` to
|
|
||||||
indicate that the MSB is being sent, and then writes the updated control register
|
|
||||||
followed by the MSB value to the specified frequency register.
|
|
||||||
"""
|
|
||||||
if freq_reg not in FREQ_REGS:
|
|
||||||
raise ValueError("Invalid frequency register")
|
|
||||||
self.ctrl_reg &= ~AD9834_B28
|
|
||||||
self.ctrl_reg |= AD9834_HLB
|
|
||||||
self.write(self.ctrl_reg)
|
|
||||||
self.write(freq_reg | (word & 0x3FFF))
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def set_frequency_reg_lsb(self, freq_reg, word: TInt32):
|
|
||||||
"""
|
|
||||||
Set the fourteen least significant bits LSBs of the specified frequency register.
|
|
||||||
|
|
||||||
This method updates the specified frequency register with the provided LSB value.
|
|
||||||
It configures the control register to indicate that the LSB is being set.
|
|
||||||
|
|
||||||
:param freq_reg: The frequency register to update, must be one of
|
|
||||||
:const:`AD9834_FREQ_REG_0` or :const:`AD9834_FREQ_REG_1`.
|
|
||||||
:param word: The value to be written to the fourteen LSBs of the frequency register.
|
|
||||||
|
|
||||||
The method first clears the appropriate control bits and writes the updated control
|
|
||||||
register followed by the LSB value to the specified frequency register.
|
|
||||||
"""
|
|
||||||
if freq_reg not in FREQ_REGS:
|
|
||||||
raise ValueError("Invalid frequency register")
|
|
||||||
self.ctrl_reg &= ~AD9834_B28
|
|
||||||
self.ctrl_reg &= ~AD9834_HLB
|
|
||||||
self.write(self.ctrl_reg)
|
|
||||||
self.write(freq_reg | (word & 0x3FFF))
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def select_frequency_reg(self, freq_reg):
|
|
||||||
"""
|
|
||||||
Select the active frequency register for the phase accumulator.
|
|
||||||
|
|
||||||
This method chooses between the two available frequency registers in the AD9834 to
|
|
||||||
control the frequency of the output waveform. The control register is updated
|
|
||||||
to reflect the selected frequency register.
|
|
||||||
|
|
||||||
:param freq_reg: The frequency register to select. Must be one of
|
|
||||||
:const:`AD9834_FREQ_REG_0` or :const:`AD9834_FREQ_REG_1`.
|
|
||||||
"""
|
|
||||||
if freq_reg not in FREQ_REGS:
|
|
||||||
raise ValueError("Invalid frequency register")
|
|
||||||
if freq_reg == FREQ_REGS[0]:
|
|
||||||
self.ctrl_reg &= ~AD9834_FSEL
|
|
||||||
else:
|
|
||||||
self.ctrl_reg |= AD9834_FSEL
|
|
||||||
|
|
||||||
self.ctrl_reg &= ~AD9834_PIN_SW
|
|
||||||
self.write(self.ctrl_reg)
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def set_phase_reg(self, phase_reg, phase: TInt32):
|
|
||||||
"""
|
|
||||||
Set the phase for the specified phase register.
|
|
||||||
|
|
||||||
This method updates the specified phase register with the provided phase value.
|
|
||||||
|
|
||||||
:param phase_reg: The phase register to update, must be one of
|
|
||||||
:const:`AD9834_PHASE_REG_0` or :const:`AD9834_PHASE_REG_1`.
|
|
||||||
:param phase: The value to be written to the phase register.
|
|
||||||
|
|
||||||
The method masks the phase value to ensure it fits within the 12-bit limit
|
|
||||||
and writes it to the specified phase register.
|
|
||||||
"""
|
|
||||||
if phase_reg not in PHASE_REGS:
|
|
||||||
raise ValueError("Invalid phase register")
|
|
||||||
phase_word = phase & 0x0FFF
|
|
||||||
self.write(phase_reg | phase_word)
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def select_phase_reg(self, phase_reg):
|
|
||||||
"""
|
|
||||||
Select the active phase register for the phase accumulator.
|
|
||||||
|
|
||||||
This method chooses between the two available phase registers in the AD9834 to
|
|
||||||
control the phase of the output waveform. The control register is updated
|
|
||||||
to reflect the selected phase register.
|
|
||||||
|
|
||||||
:param phase_reg: The phase register to select. Must be one of
|
|
||||||
:const:`AD9834_PHASE_REG_0` or :const:`AD9834_PHASE_REG_1`.
|
|
||||||
"""
|
|
||||||
if phase_reg not in PHASE_REGS:
|
|
||||||
raise ValueError("Invalid phase register")
|
|
||||||
if phase_reg == PHASE_REGS[0]:
|
|
||||||
self.ctrl_reg &= ~AD9834_PSEL
|
|
||||||
else:
|
|
||||||
self.ctrl_reg |= AD9834_PSEL
|
|
||||||
|
|
||||||
self.ctrl_reg &= ~AD9834_PIN_SW
|
|
||||||
self.write(self.ctrl_reg)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def enable_reset(self):
|
def enable_reset(self):
|
||||||
@ -255,6 +111,158 @@ class AD9834:
|
|||||||
self.ctrl_reg &= ~AD9834_RESET
|
self.ctrl_reg &= ~AD9834_RESET
|
||||||
self.write(self.ctrl_reg)
|
self.write(self.ctrl_reg)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def init(self):
|
||||||
|
"""
|
||||||
|
Initialize the AD9834: configure the SPI bus and reset the DDS.
|
||||||
|
|
||||||
|
This method performs the necessary setup for the AD9834 device, including:
|
||||||
|
- Configuring the SPI bus parameters (clock polarity, data width, and frequency).
|
||||||
|
- Putting the AD9834 into a reset state to ensure proper initialization.
|
||||||
|
|
||||||
|
The SPI bus is configured to use 16 bits of data width with the clock frequency
|
||||||
|
provided as a parameter when creating the AD9834 instance. After configuring
|
||||||
|
the SPI bus, the method invokes :meth:`enable_reset()` to reset the AD9834.
|
||||||
|
This is an essential step to prepare the device for subsequent configuration
|
||||||
|
of frequency and phase.
|
||||||
|
|
||||||
|
This method should be called before any other operations are performed
|
||||||
|
on the AD9834 to ensure that the device is in a known state.
|
||||||
|
"""
|
||||||
|
self.bus.set_config(spi.SPI_CLK_POLARITY | spi.SPI_END, 16, self.spi_freq, 1)
|
||||||
|
self.enable_reset()
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_frequency_reg_msb(self, freq_reg: TInt32, word: TInt32):
|
||||||
|
"""
|
||||||
|
Set the fourteen most significant bits MSBs of the specified frequency register.
|
||||||
|
|
||||||
|
This method updates the specified frequency register with the provided MSB value.
|
||||||
|
It configures the control register to indicate that the MSB is being set.
|
||||||
|
|
||||||
|
:param freq_reg: The frequency register to write to (0-1).
|
||||||
|
:param word: The value to be written to the fourteen MSBs of the frequency register.
|
||||||
|
|
||||||
|
The method first clears the appropriate control bits, sets :const:`AD9834_HLB` to
|
||||||
|
indicate that the MSB is being sent, and then writes the updated control register
|
||||||
|
followed by the MSB value to the specified frequency register.
|
||||||
|
"""
|
||||||
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
self.ctrl_reg &= ~AD9834_B28
|
||||||
|
self.ctrl_reg |= AD9834_HLB
|
||||||
|
self.write(self.ctrl_reg)
|
||||||
|
self.write(FREQ_REGS[freq_reg] | (word & 0x3FFF))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_frequency_reg_lsb(self, freq_reg: TInt32, word: TInt32):
|
||||||
|
"""
|
||||||
|
Set the fourteen least significant bits LSBs of the specified frequency register.
|
||||||
|
|
||||||
|
This method updates the specified frequency register with the provided LSB value.
|
||||||
|
It configures the control register to indicate that the LSB is being set.
|
||||||
|
|
||||||
|
:param freq_reg: The frequency register to write to (0-1).
|
||||||
|
:param word: The value to be written to the fourteen LSBs of the frequency register.
|
||||||
|
|
||||||
|
The method first clears the appropriate control bits and writes the updated control
|
||||||
|
register followed by the LSB value to the specified frequency register.
|
||||||
|
"""
|
||||||
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
self.ctrl_reg &= ~AD9834_B28
|
||||||
|
self.ctrl_reg &= ~AD9834_HLB
|
||||||
|
self.write(self.ctrl_reg)
|
||||||
|
self.write(FREQ_REGS[freq_reg] | (word & 0x3FFF))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_frequency_reg(self, freq_reg: TInt32, freq_word: TInt32):
|
||||||
|
"""
|
||||||
|
Set the frequency for the specified frequency register using a precomputed frequency word.
|
||||||
|
|
||||||
|
This writes to the 28-bit frequency register in one transfer.
|
||||||
|
|
||||||
|
:param freq_reg: The frequency register to write to (0-1).
|
||||||
|
:param freq_word: The precomputed frequency word.
|
||||||
|
"""
|
||||||
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
self.ctrl_reg |= AD9834_B28
|
||||||
|
self.write(self.ctrl_reg)
|
||||||
|
lsb = freq_word & 0x3FFF
|
||||||
|
msb = (freq_word >> 14) & 0x3FFF
|
||||||
|
self.write(FREQ_REGS[freq_reg] | lsb)
|
||||||
|
self.write(FREQ_REGS[freq_reg] | msb)
|
||||||
|
|
||||||
|
@portable(flags={"fast-math"})
|
||||||
|
def frequency_to_ftw(self, frequency: TFloat) -> TInt32:
|
||||||
|
"""Return the 28-bit frequency tuning word corresponding to the given
|
||||||
|
frequency.
|
||||||
|
"""
|
||||||
|
assert frequency <= 37.5 * MHz, "Frequency exceeds maximum value of 37.5 MHz"
|
||||||
|
return int((frequency * (1 << 28)) / self.clk_freq) & 0x0FFFFFFF
|
||||||
|
|
||||||
|
@portable(flags={"fast-math"})
|
||||||
|
def turns_to_pow(self, turns: TFloat) -> TInt32:
|
||||||
|
"""Return the 12-bit phase offset word corresponding to the given phase
|
||||||
|
in turns."""
|
||||||
|
assert 0.0 <= turns <= 1.0, "Turns exceeds range 0.0 - 1.0"
|
||||||
|
return int32(round(turns * 0x1000)) & int32(0x0FFF)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def select_frequency_reg(self, freq_reg: TInt32):
|
||||||
|
"""
|
||||||
|
Select the active frequency register for the phase accumulator.
|
||||||
|
|
||||||
|
This method chooses between the two available frequency registers in the AD9834 to
|
||||||
|
control the frequency of the output waveform. The control register is updated
|
||||||
|
to reflect the selected frequency register.
|
||||||
|
|
||||||
|
:param freq_reg: The frequency register to write to (0-1).
|
||||||
|
"""
|
||||||
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
if freq_reg:
|
||||||
|
self.ctrl_reg |= AD9834_FSEL
|
||||||
|
else:
|
||||||
|
self.ctrl_reg &= ~AD9834_FSEL
|
||||||
|
|
||||||
|
self.ctrl_reg &= ~AD9834_PIN_SW
|
||||||
|
self.write(self.ctrl_reg)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_phase_reg(self, phase_reg: TInt32, phase: TInt32):
|
||||||
|
"""
|
||||||
|
Set the phase for the specified phase register.
|
||||||
|
|
||||||
|
This method updates the specified phase register with the provided phase value.
|
||||||
|
|
||||||
|
:param phase_reg: The phase register to write to (0-1).
|
||||||
|
:param phase: The value to be written to the phase register.
|
||||||
|
|
||||||
|
The method masks the phase value to ensure it fits within the 12-bit limit
|
||||||
|
and writes it to the specified phase register.
|
||||||
|
"""
|
||||||
|
assert 0 <= phase_reg <= 1, "Invalid phase register index"
|
||||||
|
phase_word = phase & 0x0FFF
|
||||||
|
self.write(PHASE_REGS[phase_reg] | phase_word)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def select_phase_reg(self, phase_reg: TInt32):
|
||||||
|
"""
|
||||||
|
Select the active phase register for the phase accumulator.
|
||||||
|
|
||||||
|
This method chooses between the two available phase registers in the AD9834 to
|
||||||
|
control the phase of the output waveform. The control register is updated
|
||||||
|
to reflect the selected phase register.
|
||||||
|
|
||||||
|
:param phase_reg: The phase register to write to (0-1).
|
||||||
|
"""
|
||||||
|
assert 0 <= phase_reg <= 1, "Invalid phase register index"
|
||||||
|
if phase_reg:
|
||||||
|
self.ctrl_reg |= AD9834_PSEL
|
||||||
|
else:
|
||||||
|
self.ctrl_reg &= ~AD9834_PSEL
|
||||||
|
|
||||||
|
self.ctrl_reg &= ~AD9834_PIN_SW
|
||||||
|
self.write(self.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sleep(self, dac_pd: bool = False, clk_dis: bool = False):
|
def sleep(self, dac_pd: bool = False, clk_dis: bool = False):
|
||||||
"""
|
"""
|
||||||
@ -329,19 +337,13 @@ class AD9834:
|
|||||||
self.ctrl_reg &= ~AD9834_OPBITEN
|
self.ctrl_reg &= ~AD9834_OPBITEN
|
||||||
elif msb_2:
|
elif msb_2:
|
||||||
self.ctrl_reg |= AD9834_OPBITEN
|
self.ctrl_reg |= AD9834_OPBITEN
|
||||||
self.ctrl_reg &= ~AD9834_MODE
|
self.ctrl_reg &= ~(AD9834_MODE | AD9834_SIGN_PIB | AD9834_DIV2)
|
||||||
self.ctrl_reg &= ~AD9834_SIGN_PIB
|
|
||||||
self.ctrl_reg &= ~AD9834_DIV2
|
|
||||||
elif msb:
|
elif msb:
|
||||||
self.ctrl_reg |= AD9834_OPBITEN
|
self.ctrl_reg |= AD9834_OPBITEN | AD9834_DIV2
|
||||||
self.ctrl_reg &= ~AD9834_MODE
|
self.ctrl_reg &= ~(AD9834_MODE | AD9834_SIGN_PIB)
|
||||||
self.ctrl_reg &= ~AD9834_SIGN_PIB
|
|
||||||
self.ctrl_reg |= AD9834_DIV2
|
|
||||||
elif comp_out:
|
elif comp_out:
|
||||||
self.ctrl_reg |= AD9834_OPBITEN
|
self.ctrl_reg |= AD9834_OPBITEN | AD9834_SIGN_PIB | AD9834_DIV2
|
||||||
self.ctrl_reg &= ~AD9834_MODE
|
self.ctrl_reg &= ~AD9834_MODE
|
||||||
self.ctrl_reg |= AD9834_SIGN_PIB
|
|
||||||
self.ctrl_reg |= AD9834_DIV2
|
|
||||||
else:
|
else:
|
||||||
self.ctrl_reg &= ~AD9834_OPBITEN
|
self.ctrl_reg &= ~AD9834_OPBITEN
|
||||||
|
|
||||||
@ -380,18 +382,56 @@ class AD9834:
|
|||||||
self.write(self.ctrl_reg)
|
self.write(self.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write(self, data: TInt32):
|
def set_mu(
|
||||||
|
self,
|
||||||
|
freq_word: TInt32 = 0,
|
||||||
|
phase_word: TInt32 = 0,
|
||||||
|
freq_reg: TInt32 = 0,
|
||||||
|
phase_reg: TInt32 = 0,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Write a 16-bit word to the AD9834.
|
Set DDS frequency and phase in machine units.
|
||||||
|
|
||||||
This method sends a 16-bit data word to the AD9834 via the SPI bus. The input
|
This method updates the specified frequency and phase registers with the provided
|
||||||
data is left-shifted by 16 bits to ensure proper alignment for the SPI controller,
|
machine units, selects the corresponding registers, and enables the output.
|
||||||
allowing for accurate processing of the command by the AD9834.
|
|
||||||
|
|
||||||
This method is used internally by other methods to update the control registers
|
:param freq_word: Frequency tuning word (28-bit).
|
||||||
and frequency settings of the AD9834. It should not be called directly unless
|
:param phase_word: Phase tuning word (12-bit).
|
||||||
low-level register manipulation is required.
|
:param freq_reg: Frequency register to write to (0 or 1).
|
||||||
|
:param phase_reg: Phase register to write to (0 or 1).
|
||||||
:param data: The 16-bit word to be sent to the AD9834.
|
|
||||||
"""
|
"""
|
||||||
self.bus.write(data << 16)
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
assert 0 <= phase_reg <= 1, "Invalid phase register index"
|
||||||
|
|
||||||
|
self.set_frequency_reg_lsb(freq_reg, freq_word & 0x3FFF)
|
||||||
|
self.set_frequency_reg_msb(freq_reg, (freq_word >> 14) & 0x3FFF)
|
||||||
|
self.set_phase_reg(phase_reg, phase_word)
|
||||||
|
self.select_frequency_reg(freq_reg)
|
||||||
|
self.select_phase_reg(phase_reg)
|
||||||
|
self.output_enable()
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set(
|
||||||
|
self,
|
||||||
|
frequency: TFloat = 0.0,
|
||||||
|
phase: TFloat = 0.0,
|
||||||
|
freq_reg: TInt32 = 0,
|
||||||
|
phase_reg: TInt32 = 0,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Set DDS frequency in Hz and phase using fractional turns.
|
||||||
|
|
||||||
|
This method converts the specified frequency and phase to their corresponding
|
||||||
|
machine units, updates the selected registers, and enables the output.
|
||||||
|
|
||||||
|
:param frequency: Frequency in Hz.
|
||||||
|
:param phase: Phase in fractional turns (e.g., 0.5 for 180 degrees).
|
||||||
|
:param freq_reg: Frequency register to write to (0 or 1).
|
||||||
|
:param phase_reg: Phase register to write to (0 or 1).
|
||||||
|
"""
|
||||||
|
assert 0 <= freq_reg <= 1, "Invalid frequency register index"
|
||||||
|
assert 0 <= phase_reg <= 1, "Invalid phase register index"
|
||||||
|
|
||||||
|
freq_word = self.frequency_to_ftw(frequency)
|
||||||
|
phase_word = self.turns_to_pow(phase)
|
||||||
|
self.set_mu(freq_word, phase_word, freq_reg, phase_reg)
|
||||||
|
@ -11,8 +11,6 @@ from artiq.coredevice.ad9834 import (
|
|||||||
AD9834_SIGN_PIB,
|
AD9834_SIGN_PIB,
|
||||||
AD9834_SLEEP1,
|
AD9834_SLEEP1,
|
||||||
AD9834_SLEEP12,
|
AD9834_SLEEP12,
|
||||||
FREQ_REGS,
|
|
||||||
PHASE_REGS,
|
|
||||||
)
|
)
|
||||||
from artiq.experiment import *
|
from artiq.experiment import *
|
||||||
from artiq.language.units import MHz
|
from artiq.language.units import MHz
|
||||||
@ -34,165 +32,251 @@ class AD9834Exp(EnvExperiment):
|
|||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self):
|
def init(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.init()
|
self.dev.init()
|
||||||
self.set_dataset("spi_freq", self.dev.spi_freq)
|
self.set_dataset("spi_freq", self.dev.spi_freq)
|
||||||
self.set_dataset("clk_freq", self.dev.clk_freq)
|
self.set_dataset("clk_freq", self.dev.clk_freq)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_frequency_reg_fail1(self):
|
def frequency_to_ftw_fail(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
frequency = 10 * MHz
|
self.dev.init()
|
||||||
self.dev.set_frequency_reg(19, frequency)
|
self.dev.frequency_to_ftw(37.6 * MHz)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_frequency_reg_fail2(self):
|
def turns_to_phase_fail(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.set_frequency_reg(FREQ_REGS[0], 37.6 * MHz)
|
self.dev.init()
|
||||||
|
self.dev.turns_to_phase(1.1)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_frequency_reg_fail(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
self.dev.set_frequency_reg(19, self.dev.frequency_to_ftw(10 * MHz))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_frequency_reg(self):
|
def set_frequency_reg(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.init()
|
self.dev.init()
|
||||||
self.dev.set_frequency_reg(FREQ_REGS[1], 19 * MHz)
|
self.dev.set_frequency_reg(1, self.dev.frequency_to_ftw(19 * MHz))
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_frequency_reg_msb(self):
|
def set_frequency_reg_msb(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.init()
|
self.dev.init()
|
||||||
self.dev.ctrl_reg |= AD9834_B28
|
self.dev.ctrl_reg |= AD9834_B28
|
||||||
self.dev.set_frequency_reg_msb(FREQ_REGS[0], 0x1111)
|
self.dev.set_frequency_reg_msb(0, 0x1111)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_frequency_reg_lsb(self):
|
def set_frequency_reg_lsb(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.init()
|
self.dev.init()
|
||||||
self.dev.ctrl_reg |= AD9834_B28 | AD9834_HLB
|
self.dev.ctrl_reg |= AD9834_B28 | AD9834_HLB
|
||||||
self.dev.set_frequency_reg_lsb(FREQ_REGS[1], 0xFFFF)
|
self.dev.set_frequency_reg_lsb(1, 0xFFFF)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def select_frequency_reg_0(self):
|
def select_frequency_reg_0(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_FSEL | AD9834_PIN_SW
|
self.dev.init()
|
||||||
self.dev.select_frequency_reg(FREQ_REGS[0])
|
self.dev.select_frequency_reg(0)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg & ~(AD9834_FSEL | AD9834_PIN_SW))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def select_frequency_reg_1(self):
|
def select_frequency_reg_1(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_PIN_SW
|
self.dev.init()
|
||||||
self.dev.select_frequency_reg(FREQ_REGS[1])
|
self.dev.select_frequency_reg(1)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", (self.dev.ctrl_reg | AD9834_FSEL) & ~AD9834_PIN_SW)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_phase_reg_fail(self):
|
def set_phase_reg_fail(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
self.dev.set_phase_reg(19, 0x123)
|
self.dev.set_phase_reg(19, 0x123)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_phase_reg(self):
|
def set_phase_reg(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.init()
|
self.dev.init()
|
||||||
self.dev.set_phase_reg(PHASE_REGS[0], 0x123)
|
self.dev.set_phase_reg(0, 0x123)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def select_phase_reg_0(self):
|
def select_phase_reg_0(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_PSEL | AD9834_PIN_SW
|
self.dev.init()
|
||||||
self.dev.select_phase_reg(PHASE_REGS[0])
|
self.dev.select_phase_reg(0)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg & ~(AD9834_PSEL | AD9834_PIN_SW))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def select_phase_reg_1(self):
|
def select_phase_reg_1(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_PIN_SW
|
self.dev.init()
|
||||||
self.dev.select_phase_reg(PHASE_REGS[1])
|
self.dev.select_phase_reg(1)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", (self.dev.ctrl_reg | AD9834_PSEL) & ~AD9834_PIN_SW)
|
||||||
|
|
||||||
@kernel
|
|
||||||
def enable_reset(self):
|
|
||||||
self.core.break_realtime()
|
|
||||||
self.dev.enable_reset()
|
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
|
||||||
|
|
||||||
@kernel
|
|
||||||
def output_enable(self):
|
|
||||||
self.core.break_realtime()
|
|
||||||
self.dev.ctrl_reg |= AD9834_RESET
|
|
||||||
self.dev.output_enable()
|
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sleep_dac_powerdown(self):
|
def sleep_dac_powerdown(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
self.dev.sleep(dac_pd=True)
|
self.dev.sleep(dac_pd=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sleep_internal_clk_disable(self):
|
def sleep_internal_clk_disable(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
self.dev.sleep(clk_dis=True)
|
self.dev.sleep(clk_dis=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
self.dev.sleep(dac_pd=True, clk_dis=True)
|
self.dev.sleep(dac_pd=True, clk_dis=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def awake(self):
|
def awake(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_SLEEP1 | AD9834_SLEEP12
|
self.dev.init()
|
||||||
self.dev.sleep()
|
self.dev.awake()
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset(
|
||||||
|
"ctrl_reg", self.dev.ctrl_reg & ~(AD9834_SLEEP1 | AD9834_SLEEP12)
|
||||||
|
)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sign_bit_high_z(self):
|
def sign_bit_high_z(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_OPBITEN
|
self.dev.init()
|
||||||
self.dev.config_sign_bit_out()
|
self.dev.config_sign_bit_out()
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg & ~AD9834_OPBITEN)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sign_bit_msb_2(self):
|
def sign_bit_msb_2(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_MODE | AD9834_SIGN_PIB | AD9834_DIV2
|
self.dev.init()
|
||||||
self.dev.config_sign_bit_out(msb_2=True)
|
self.dev.config_sign_bit_out(msb_2=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset(
|
||||||
|
"ctrl_reg",
|
||||||
|
(self.dev.ctrl_reg | AD9834_OPBITEN)
|
||||||
|
& ~(AD9834_MODE | AD9834_SIGN_PIB | AD9834_DIV2),
|
||||||
|
)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sign_bit_msb(self):
|
def sign_bit_msb(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_MODE | AD9834_SIGN_PIB
|
self.dev.init()
|
||||||
self.dev.config_sign_bit_out(msb=True)
|
self.dev.config_sign_bit_out(msb=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset(
|
||||||
|
"ctrl_reg",
|
||||||
|
(self.dev.ctrl_reg | AD9834_MODE | AD9834_SIGN_PIB)
|
||||||
|
& ~(AD9834_MODE | AD9834_SIGN_PIB),
|
||||||
|
)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def sign_bit_comp_out(self):
|
def sign_bit_comp_out(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_MODE
|
self.dev.init()
|
||||||
self.dev.config_sign_bit_out(comp_out=True)
|
self.dev.config_sign_bit_out(comp_out=True)
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset(
|
||||||
|
"ctrl_reg",
|
||||||
|
(self.dev.ctrl_reg | AD9834_OPBITEN | AD9834_SIGN_PIB | AD9834_DIV2)
|
||||||
|
& ~AD9834_MODE,
|
||||||
|
)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def enable_triangular_waveform(self):
|
def enable_triangular_waveform(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_OPBITEN
|
self.dev.init()
|
||||||
self.dev.enable_triangular_waveform()
|
self.dev.enable_triangular_waveform()
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg | AD9834_MODE)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def disable_triangular_waveform(self):
|
def disable_triangular_waveform(self):
|
||||||
self.core.break_realtime()
|
self.core.reset()
|
||||||
self.dev.ctrl_reg |= AD9834_MODE
|
self.dev.init()
|
||||||
self.dev.disable_triangular_waveform()
|
self.dev.disable_triangular_waveform()
|
||||||
self.set_dataset("ctrl_reg", self.dev.ctrl_reg)
|
self.set_dataset("ctrl_reg", self.dev.ctrl_reg & ~AD9834_MODE)
|
||||||
|
|
||||||
|
## The following tests should be hooked up to an oscilloscope
|
||||||
|
## to monitor the waveforms
|
||||||
|
@kernel
|
||||||
|
def single_tone(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
self.dev.set_frequency_reg(0, self.dev.frequency_to_ftw(1 * MHz))
|
||||||
|
self.dev.select_frequency_reg(0)
|
||||||
|
self.dev.output_enable()
|
||||||
|
delay(5 * s)
|
||||||
|
self.dev.enable_reset()
|
||||||
|
self.core.wait_until_mu(now_mu())
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def toggle_frequency(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
self.dev.set_frequency_reg(0, self.dev.frequency_to_ftw(1 * MHz))
|
||||||
|
self.dev.set_frequency_reg(1, self.dev.frequency_to_ftw(2 * MHz))
|
||||||
|
self.dev.select_frequency_reg(0)
|
||||||
|
self.dev.output_enable()
|
||||||
|
|
||||||
|
for _ in range(6):
|
||||||
|
self.dev.select_frequency_reg(0)
|
||||||
|
delay(1 * s)
|
||||||
|
self.dev.select_frequency_reg(1)
|
||||||
|
delay(1 * s)
|
||||||
|
|
||||||
|
self.dev.enable_reset()
|
||||||
|
self.core.wait_until_mu(now_mu())
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def toggle_phase(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
self.dev.set_frequency_reg(0, self.dev.frequency_to_ftw(1 * MHz))
|
||||||
|
self.dev.select_frequency_reg(0)
|
||||||
|
self.dev.set_phase_reg(0, 0x0)
|
||||||
|
self.dev.set_phase_reg(1, 0x7FF)
|
||||||
|
self.dev.output_enable()
|
||||||
|
|
||||||
|
for _ in range(300000):
|
||||||
|
self.dev.select_phase_reg(0)
|
||||||
|
delay(10 * us)
|
||||||
|
self.dev.select_phase_reg(1)
|
||||||
|
delay(10 * us)
|
||||||
|
|
||||||
|
self.dev.enable_reset()
|
||||||
|
self.core.wait_until_mu(now_mu())
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set_mu(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
freq_word = self.dev.frequency_to_ftw(1 * MHz)
|
||||||
|
phase_word = self.dev.turns_to_phase(0.5)
|
||||||
|
self.dev.set_mu(freq_word, phase_word, 0, 1)
|
||||||
|
|
||||||
|
delay(5 * s)
|
||||||
|
|
||||||
|
self.dev.enable_reset()
|
||||||
|
self.core.wait_until_mu(now_mu())
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def set(self):
|
||||||
|
self.core.reset()
|
||||||
|
self.dev.init()
|
||||||
|
self.dev.set(2 * MHz, 0.5, 1, 0)
|
||||||
|
|
||||||
|
delay(5 * s)
|
||||||
|
|
||||||
|
self.dev.enable_reset()
|
||||||
|
self.core.wait_until_mu(now_mu())
|
||||||
|
|
||||||
|
|
||||||
class AD9834Test(ExperimentCase):
|
class AD9834Test(ExperimentCase):
|
||||||
@ -208,21 +292,27 @@ class AD9834Test(ExperimentCase):
|
|||||||
self.assertEqual(clk_freq, 75 * MHz)
|
self.assertEqual(clk_freq, 75 * MHz)
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
def test_set_frequency_reg_fail(self):
|
def test_frequency_to_ftw_fail(self):
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
self.execute(AD9834Exp, "set_frequency_reg_fail1")
|
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaises(AssertionError):
|
||||||
self.execute(AD9834Exp, "set_frequency_reg_fail2")
|
self.execute(AD9834Exp, "frequency_to_ftw_fail")
|
||||||
|
|
||||||
|
def test_turns_to_phase_fail(self):
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.execute(AD9834Exp, "turns_to_phase_fail")
|
||||||
|
|
||||||
|
def test_set_frequency_reg_fail(self):
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.execute(AD9834Exp, "set_frequency_reg_fail")
|
||||||
|
|
||||||
def test_set_frequency_reg(self):
|
def test_set_frequency_reg(self):
|
||||||
self.execute(AD9834Exp, "set_frequency_reg")
|
self.execute(AD9834Exp, "set_frequency_reg")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET | AD9834_B28)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_B28 | AD9834_RESET)
|
||||||
|
|
||||||
def test_set_frequency_reg_msb(self):
|
def test_set_frequency_reg_msb(self):
|
||||||
self.execute(AD9834Exp, "set_frequency_reg_msb")
|
self.execute(AD9834Exp, "set_frequency_reg_msb")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET | AD9834_HLB)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_HLB | AD9834_RESET)
|
||||||
|
|
||||||
def test_set_frequency_reg_lsb(self):
|
def test_set_frequency_reg_lsb(self):
|
||||||
self.execute(AD9834Exp, "set_frequency_reg_lsb")
|
self.execute(AD9834Exp, "set_frequency_reg_lsb")
|
||||||
@ -232,15 +322,15 @@ class AD9834Test(ExperimentCase):
|
|||||||
def test_select_frequency_reg_0(self):
|
def test_select_frequency_reg_0(self):
|
||||||
self.execute(AD9834Exp, "select_frequency_reg_0")
|
self.execute(AD9834Exp, "select_frequency_reg_0")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
def test_select_frequency_reg_1(self):
|
def test_select_frequency_reg_1(self):
|
||||||
self.execute(AD9834Exp, "select_frequency_reg_1")
|
self.execute(AD9834Exp, "select_frequency_reg_1")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_FSEL)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_FSEL | AD9834_RESET)
|
||||||
|
|
||||||
def test_set_phase_reg_fail(self):
|
def test_set_phase_reg_fail(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(AssertionError):
|
||||||
self.execute(AD9834Exp, "set_phase_reg_fail")
|
self.execute(AD9834Exp, "set_phase_reg_fail")
|
||||||
|
|
||||||
def test_set_phase_reg(self):
|
def test_set_phase_reg(self):
|
||||||
@ -251,71 +341,85 @@ class AD9834Test(ExperimentCase):
|
|||||||
def test_select_phase_reg_0(self):
|
def test_select_phase_reg_0(self):
|
||||||
self.execute(AD9834Exp, "select_phase_reg_0")
|
self.execute(AD9834Exp, "select_phase_reg_0")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
def test_select_phase_reg_1(self):
|
def test_select_phase_reg_1(self):
|
||||||
self.execute(AD9834Exp, "select_phase_reg_1")
|
self.execute(AD9834Exp, "select_phase_reg_1")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_PSEL)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_PSEL | AD9834_RESET)
|
||||||
|
|
||||||
def test_enable_reset(self):
|
|
||||||
self.execute(AD9834Exp, "enable_reset")
|
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
|
||||||
|
|
||||||
def test_output_enable(self):
|
|
||||||
self.execute(AD9834Exp, "output_enable")
|
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
|
||||||
|
|
||||||
def test_sleep_dac_powerdown(self):
|
def test_sleep_dac_powerdown(self):
|
||||||
self.execute(AD9834Exp, "sleep_dac_powerdown")
|
self.execute(AD9834Exp, "sleep_dac_powerdown")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_SLEEP12)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_SLEEP12 | AD9834_RESET)
|
||||||
|
|
||||||
def test_sleep_internal_clk_disable(self):
|
def test_sleep_internal_clk_disable(self):
|
||||||
self.execute(AD9834Exp, "sleep_internal_clk_disable")
|
self.execute(AD9834Exp, "sleep_internal_clk_disable")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_SLEEP1)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_SLEEP1 | AD9834_RESET)
|
||||||
|
|
||||||
def test_sleep(self):
|
def test_sleep(self):
|
||||||
self.execute(AD9834Exp, "sleep")
|
self.execute(AD9834Exp, "sleep")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_SLEEP1 | AD9834_SLEEP12)
|
self.assertEqual(
|
||||||
|
ctrl_reg, 0x0000 | AD9834_SLEEP1 | AD9834_SLEEP12 | AD9834_RESET
|
||||||
|
)
|
||||||
|
|
||||||
def test_awake(self):
|
def test_awake(self):
|
||||||
self.execute(AD9834Exp, "awake")
|
self.execute(AD9834Exp, "awake")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
def test_sign_bit_high_z(self):
|
def test_sign_bit_high_z(self):
|
||||||
self.execute(AD9834Exp, "sign_bit_high_z")
|
self.execute(AD9834Exp, "sign_bit_high_z")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
def test_sign_bit_msb_2(self):
|
def test_sign_bit_msb_2(self):
|
||||||
self.execute(AD9834Exp, "sign_bit_msb_2")
|
self.execute(AD9834Exp, "sign_bit_msb_2")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_OPBITEN)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_OPBITEN | AD9834_RESET)
|
||||||
|
|
||||||
def test_sign_bit_msb(self):
|
def test_sign_bit_msb(self):
|
||||||
self.execute(AD9834Exp, "sign_bit_msb")
|
self.execute(AD9834Exp, "sign_bit_msb")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_OPBITEN | AD9834_DIV2)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_OPBITEN | AD9834_DIV2 | AD9834_RESET)
|
||||||
|
|
||||||
def test_sign_bit_comp_out(self):
|
def test_sign_bit_comp_out(self):
|
||||||
self.execute(AD9834Exp, "sign_bit_comp_out")
|
self.execute(AD9834Exp, "sign_bit_comp_out")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
ctrl_reg, 0x0000 | AD9834_OPBITEN | AD9834_SIGN_PIB | AD9834_DIV2
|
ctrl_reg,
|
||||||
|
0x0000 | AD9834_OPBITEN | AD9834_SIGN_PIB | AD9834_DIV2 | AD9834_RESET,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_enble_triangular_waveform(self):
|
def test_enble_triangular_waveform(self):
|
||||||
self.execute(AD9834Exp, "enable_triangular_waveform")
|
self.execute(AD9834Exp, "enable_triangular_waveform")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000 | AD9834_MODE)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_MODE | AD9834_RESET)
|
||||||
|
|
||||||
def test_disble_triangular_waveform(self):
|
def test_disble_triangular_waveform(self):
|
||||||
self.execute(AD9834Exp, "disable_triangular_waveform")
|
self.execute(AD9834Exp, "disable_triangular_waveform")
|
||||||
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
ctrl_reg = self.dataset_mgr.get("ctrl_reg")
|
||||||
self.assertEqual(ctrl_reg, 0x0000)
|
self.assertEqual(ctrl_reg, 0x0000 | AD9834_RESET)
|
||||||
|
|
||||||
|
## Waveform Tests
|
||||||
|
def test_single_tone(self):
|
||||||
|
print("Running waveform test:", self._testMethodName)
|
||||||
|
self.execute(AD9834Exp, "single_tone")
|
||||||
|
|
||||||
|
def test_toggle_frequency(self):
|
||||||
|
print("Running waveform test:", self._testMethodName)
|
||||||
|
self.execute(AD9834Exp, "toggle_frequency")
|
||||||
|
|
||||||
|
def test_toggle_phase(self):
|
||||||
|
print("Running waveform test:", self._testMethodName)
|
||||||
|
self.execute(AD9834Exp, "toggle_phase")
|
||||||
|
|
||||||
|
def test_set_mu(self):
|
||||||
|
print("Running waveform test:", self._testMethodName)
|
||||||
|
self.execute(AD9834Exp, "set_mu")
|
||||||
|
|
||||||
|
def test_set(self):
|
||||||
|
print("Running waveform test:", self._testMethodName)
|
||||||
|
self.execute(AD9834Exp, "set")
|
||||||
|
Loading…
Reference in New Issue
Block a user