artiq/artiq/gateware/suservo/dds_ser.py
Robert Jordens 307cd07b9d suservo: lots of gateware/ runtime changes
tested/validated:

* servo enable/disable
* dds interface, timing, io_update, mask_nu
* channel control (en_out, en_iir, profile)
* profile configuration (coefficients, delays, offsets, channel)
* adc timings and waveforms measured
* asf state readback
* adc readback

individual changes below:

suservo: correct rtio readback

suservo: example, device_db [wip]

suservo: change rtio channel layout

suservo: mem ports in rio domain

suservo: sck clocked from rio_phy

suservo: cleanup, straighten out timing

suservo: dds cs polarity

suservo: simplify pipeline

suservo: drop unused eem names

suservo: decouple adc SR from IIR

suservo: expand coredevice layer

suservo: start the correct stage

suservo: actually load ctrl

suservo: refactor/tweak adc timing

suservo: implement cpld and dds init
2018-04-27 13:50:26 +02:00

44 lines
1.3 KiB
Python

import logging
from migen import *
from . import spi
logger = logging.getLogger(__name__)
DDSParams = spi.SPIParams
class DDS(spi.SPISimple):
"""Multi-DDS SPI interface.
* Supports SPI DDS chips like the AD9910.
* Shifts data out to multiple DDS in parallel with a shared CLK and shared
CS_N line.
* Supports a single hardcoded command.
* Configuration and setup must be done over a different channel.
* Asserts IO_UPDATE for one clock cycle immediately after the SPI transfer.
"""
def __init__(self, pads, params):
super().__init__(pads, params)
self.profile = [Signal(32 + 16 + 16, reset_less=True)
for i in range(params.channels)]
cmd = Signal(8, reset=0x0e) # write to single tone profile 0
assert params.width == len(cmd) + len(self.profile[0])
self.sync += [
If(self.start,
[d.eq(Cat(p, cmd))
for d, p in zip(self.data, self.profile)]
)
]
# this assumes that the cycle time (1/125 MHz = 8 ns) is >1 SYNC_CLK
# cycle (1/250 MHz = 4ns)
done_old = Signal()
self.sync += done_old.eq(self.done)
self.comb += pads.io_update.eq(self.done & ~done_old)