# Sinara 4410/4412 DDS Urukul (AD9910/AD9912)

* [Datasheet](https://m-labs.hk/docs/sinara-datasheets/4410-4412.pdf)
* [Wiki](https://github.com/sinara-hw/Urukul/wiki)
* [Firmware](https://github.com/quartiq/urukul)

## JSON

```json
{
    "type": "urukul",
    "dds": "<variant>", // ad9910/ad9912
    "ports": [<port num>, <port num>], // second port is optional
    "clk_sel": <clock num>,
    "synchronization": true/false, // for AD9910 only
    "refclk": <freq>, // for external clock signal
    "pll_en": <0 or 1, default 1> // PLL bypass, to allow higher external clocker frequencies (1e9 for example)
}
```

## Setup

Check if [SUServo](./suservo.md) is enabled/disabled respective to customer needs. Connect to the clocker source.

### Synchronization

Phase synchronization enables phase control from Kasli/Kasli-SoC with an absolute phase reference, i.e. you can use the phase control API in the coredevice driver.
Without synchronization the phase between Urukuls will not drift, but it can change across reboots, and the phase control API cannot be used.
Synchronization requires Kasli and Urukul to be clocked from the same oscillator with <<1ns noise, otherwise the synchronization may fail, and that's
why this feature is disabled by default.
There is no intrinsic impact on Urukul output phase noise and the synchronization process is quick and reliable when done correctly.

### One-EEM mode

Users may choose to use only one EEM port, if they want more cards to be in their crate. However following features
will become unavailable:
 * SU-Servo
 * Low-latency RF switch control
 * Synchronization

RF switches are still available but the commands need to go over the SPI bus so it's higher-latency and lower-resolution.

### Urukul 4412

Urukul 4412 has higher frequency resolution (47 bit against 32 at Urukul 4410), however lacks such features:
 * SU-Servo
 * Synchronization

## Testing

After running `artiq_sinara_test`:

```text
*** Testing Urukul DDSes.
urukul0_cpld: initializing CPLD...
urukul0_cpld: testing attenuator digital control...
urukul0_cpld: done
Calibrating inter-device synchronization...
urukul0_ch0	no EEPROM synchronization
urukul0_ch1	no EEPROM synchronization
urukul0_ch2	no EEPROM synchronization
urukul0_ch3	no EEPROM synchronization
...done
All urukul channels active.
Check each channel amplitude (~1.6Vpp/8dbm at 50ohm) and frequency.
Frequencies:
urukul0_ch0	10MHz
urukul0_ch1	11MHz
urukul0_ch2	12MHz
urukul0_ch3	13MHz
Press ENTER when done.

Testing RF switch control. Check LEDs at urukul RF ports.
Press ENTER when done.
```

1. Setup oscilloscope's impedance at 50 ohm
2. Touch each connector with oscilloscope, setup time- and voltage- scale and trigger, so that you can see sine waves
3. Measure frequencies and amplitudes on each connector, check with `artiq_sinara_test`'s respective values
4. When done, proceed with `artiq_sinara_test` and check LEDs are lighting up one after another


## Common problems

### Urukul AD9912 product id mismatch or missing LEDs

```pycon
ValueError: Urukul AD9912 product id mismatch
```

Some Urukuls may fail with this error during testing, usually meaning that the Urukul has not been flashed with the 
firmware, especially if the ID is `65535` (you will need to edit the code to check this). 

Another common symptom of no firmware is that no LEDs are lit up, besides Power Good - whereas if the firmware has been flashed, the RF channels will be lit red.

You can flash the firmware yourself with a JTAG adapter:

1. Download the latest binary release from [quartiq/urukul](https://github.com/quartiq/urukul) and extract the `urukul.jed` file.
2. Connect the Urukul with the JTAG adapter to the PC and connect its EEM0 to any available Kasli/Kasli-SoC (**do not hot-plug**), then power on the Kasli/Kasli-SoC.
3. Run `nix-shell -p xc3sprog`.
4. Run `xc3sprog -c jtaghs2 urukul.jed -m /opt/Xilinx/Vivado/<available version>/data/xicom/cable_data/digilent/lnx64/xbr/`.
5. If the last command outputs Verify: Success, then your Urukul is ready. It can also output the message 
   ```shell
   *** buffer overflow detected ***: terminated
   Aborted (core dumped)
   ```
   , which is okay if `Verify: Success` was also emitted.

### no valid window/delay

```pycon
ValueError: no valid window/delay
```

Check with the customer to see if synchronization is necessary, and disable it if it is not. 
In any case, simply restart the test.

### Noise instead of signal

It may be due to misconfiguration of SUServo. Check that both firmware and pins enable/disable the SUServo mode.

### Improper frequency

This can happen due to lack/bad clock source connection. Check that clock source is connected respective to the customer needs,
and if it is connected to the [Clocker](clocker.md), check that clocker receives clock signal properly.

### Urukul proto_rev mismatch

```pycon
ValueError: Urukul proto_rev mismatch
```

Check the ports are connected respectively to the JSON description.

### PLL lock timeout

```pycon
ValueError: PLL lock timeout
```

This can happen due to lack/bad clock source connection. Check that clock source is connected respective to the customer needs,
and if it is connected to the [Clocker](clocker.md), check that clocker receives clock signal properly and `EXT`/`INT` pin 
matches real clocker source.

### Urukul AD9910 AUX_DAC mismatch

```pycon
ValueError: Urukul AD9910 AUX_DAC mismatch
```

Ensure it is the AD9910 and not the AD9912. Also check SUServo pins are set up respective to the JSON description.

### Jagged signal with 1GHz external clock on AD9910

By default, on AD9910 external clock signal is divided by 4, while it should be not divided at all with PLL disabled.
Change the ``clk_div`` parameter to the CPLD in the device_db file:

```python
device_db["urukulX_cpld"] = {
    "type": "local",
    "module": "artiq.coredevice.urukul",
    "class": "CPLD",
    "arguments": {
        "spi_device": "spi_urukul0",
        "sync_device": None,
        "io_update_device": "ttl_urukul0_io_update",
        "refclk": 1000000000.0,
        "clk_sel": 1,
        "clk_div" : 1 # <--- add this line
    }
}
```