|
| 1 | +AD917x Family no-OS Driver |
| 2 | +========================== |
| 3 | + |
| 4 | +Supported Devices |
| 5 | +----------------- |
| 6 | + |
| 7 | +- :adi:`AD9171` |
| 8 | +- :adi:`AD9172` |
| 9 | +- :adi:`AD9173` |
| 10 | +- :adi:`AD9174` |
| 11 | +- :adi:`AD9175` |
| 12 | +- :adi:`AD9176` |
| 13 | + |
| 14 | +Overview |
| 15 | +-------- |
| 16 | + |
| 17 | +The AD9172 is a high-performance, dual, 16-bit digital-to-analog |
| 18 | +converter (DAC) that supports DAC sample rates up to 12.6 GSPS, making |
| 19 | +it ideal for advanced wireless communications infrastructure and |
| 20 | +multiband base station radios. It supports multiband wireless |
| 21 | +applications and provides three bypassable, complex data input channels |
| 22 | +per RF DAC. Each channel is equipped with an independent numerical |
| 23 | +controlled oscillator (NCO) and a selectable interpolation filter, |
| 24 | +enabling flexible multiband frequency planning at a maximum complex |
| 25 | +input data rate of 1.54 GSPS per channel. The AD9172’s proprietary, low |
| 26 | +spurious design achieves excellent performance metrics, including a |
| 27 | +2-tone intermodulation distortion (IMD) of −83 dBc at 1.8 GHz and a |
| 28 | +spurious free dynamic range (SFDR) of <−80 dBc. Additionally, its |
| 29 | +flexible 8-lane, 15.4 Gbps JESD204B interface makes it a robust solution |
| 30 | +for high-bandwidth applications. |
| 31 | + |
| 32 | +Applications |
| 33 | +------------ |
| 34 | + |
| 35 | +- Wireless communications infrastructure |
| 36 | +- Multiband base station radios |
| 37 | +- Microwave/E-band backhaul systems |
| 38 | +- Instrumentation, automatic test equipment (ATE) |
| 39 | +- Radars and jammers |
| 40 | + |
| 41 | +Operation Modes |
| 42 | +---------------- |
| 43 | + |
| 44 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 45 | +| Mode Name | Description | Configuration | Typical Use | |
| 46 | +| | | Bits | | |
| 47 | ++=====================+===============================+===============================+===============================+ |
| 48 | +| JESD Mode | Configures the high-speed | AD917X_JESD_MODE_REG | Configuring the JESD | |
| 49 | +| | serial JESD interface, link | with AD917X_JESD_MODE(x) and | interface for serial data | |
| 50 | +| | selection and mode validation.| AD917X_LINK_MODE | transfer between the DAC | |
| 51 | +| | | | and processing elements. | |
| 52 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 53 | +| DDSM Mode | Sets up the Delta-Sigma | AD917X_DDSM_DATA-PATH | Enabling precise frequency | |
| 54 | +| | Digital Modulator datapath, | _CFG_REG using | conversion and digital | |
| 55 | +| | controlling modulation and | AD917X_DDSM_MODE(x), | dithering in applications | |
| 56 | +| | NCO features. | AD917X_DDSM_NCO_EN, | requiring signal modulation. | |
| 57 | +| | | AD917X_DDSM_MODULUS_EN, | | |
| 58 | +| | | AD917X_DDSM_SEL_SIDEBAND, | | |
| 59 | +| | | AD917X_DDSM_EN_SYNC_ALL | | |
| 60 | +| | | _CHNL_NCO_RESETS | | |
| 61 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 62 | +| DDSC Mode | Configures the alternate | AD917X_DDSC_DATA-PATH | Generating calibration test | |
| 63 | +| | digital synthesis engine, | _CFG_REG with | tones or steady frequency | |
| 64 | +| | test tone generation and | AD917X_DDSC_NCO_EN, | signals for system | |
| 65 | +| | modulation control. | AD917X_DDSC_MODULUS_EN, | verification and diagnostics. | |
| 66 | +| | | AD917X_DDSC_SEL_SIDEBAND, | | |
| 67 | +| | | AD917X_DDSC_TEST_TONE_EN | | |
| 68 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 69 | +| Integer NCO Mode | Operates using an integer | AD917X_DDSM_NCO_EN and | Used when the desired | |
| 70 | +| | frequency tuning word with | AD917X_DDSM_MODE(0); | carrier frequency is an | |
| 71 | +| | modulus disabled. The FTW is | AD917X_DDSC_NCO_EN without | integer division of the DAC | |
| 72 | +| | set directly without | AD917X_DDSC_MODULUS_EN | frequency. | |
| 73 | +| | fractional components. | | | |
| 74 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 75 | +| Modulus NCO Mode | Enables fractional frequency | AD917X_DDSM_MODULUS_EN and | Applied when fine frequency | |
| 76 | +| | tuning by configuring the FTW | AD917X_DDSC_MODULUS_EN, | adjustments are required and | |
| 77 | +| | with a non-zero accumulator | along with AD917X_DDSM | the frequency is not an | |
| 78 | +| | modulus and delta values. | _NCO_EN and AD917X_DDSC | integer division of the DAC | |
| 79 | +| | | _NCO_EN | frequency. | |
| 80 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 81 | +| JESD Single Link | Configures the JESD datapath | AD917X_JESD_MODE(jesd_mode) | Suitable for applications | |
| 82 | +| Mode | for operation with a single | with the AD917X_LINK_MODE | where lower data throughput | |
| 83 | +| | link, dual-link flag disabled.| bit cleared | and simplified lane mapping | |
| 84 | +| | | | are sufficient. | |
| 85 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 86 | +| JESD Dual Link Mode | Sets up the JESD datapath for | AD917X_JESD_MODE(jesd_mode) | Ideal for scenarios | |
| 87 | +| | dual-link operation, | combined with AD917X_ | requiring increased | |
| 88 | +| | increasing throughput by | LINK_MODE bit set | throughput by using multiple | |
| 89 | +| | activating the dual-link flag.| | JESD lanes concurrently. | |
| 90 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 91 | +| SYSREF_NONE | Disables SYSREF support. | SYSREF_NONE | Used when SYSREF | |
| 92 | +| | | | synchronization is not | |
| 93 | +| | | | required. | |
| 94 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 95 | +| SYSREF_ONESHOT | Activates one-shot SYSREF | SYSREF_ONESHOT | Ideal for single | |
| 96 | +| | mode to trigger a single | | synchronization events | |
| 97 | +| | synchronization event. | | during initialization or | |
| 98 | +| | | | calibration. | |
| 99 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 100 | +| SYSREF_CONT | Enables continuous SYSREF | SYSREF_CONT | Best for applications that | |
| 101 | +| | synchronization, providing | | need ongoing, periodic | |
| 102 | +| | periodic events. | | synchronization. | |
| 103 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 104 | +| SYSREF_MON | Sets the driver to SYSREF | SYSREF_MON | Useful when it is necessary | |
| 105 | +| | monitor mode, observing | | to monitor SYSREF signals | |
| 106 | +| | SYSREF signals without | | without actively | |
| 107 | +| | synchronizing. | | synchronizing. | |
| 108 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 109 | +| Mode 0 | DAC0 outputs I0 and DAC1 | AD9172_MODE_0 | Standard dual-channel | |
| 110 | +| | outputs I1. | | operation with independent | |
| 111 | +| | | | I/Q paths. | |
| 112 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 113 | +| Mode 1 | DAC0 outputs I0 + I1 and | AD9172_MODE_1 | Combined channel output for | |
| 114 | +| | DAC1 outputs Q0 + Q1. | | summed signal processing. | |
| 115 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 116 | +| Mode 2 | DAC0 outputs I0 and DAC1 | AD9172_MODE_2 | Direct mapping of separate | |
| 117 | +| | outputs Q0. | | I and Q signals. | |
| 118 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 119 | +| Mode 3 | DAC0 outputs I0 + I1 and | AD9172_MODE_3 | Used for single-channel | |
| 120 | +| | DAC1 outputs 0. | | operation when one DAC | |
| 121 | +| | | | output is disabled. | |
| 122 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 123 | +| Direct Mode | DAC0 carries I0 and DAC1 | AD9172_DDSM_MODE (0x0) | Standard dual-channel | |
| 124 | +| | carries I1. | | operation with independent | |
| 125 | +| | | | I and Q signals. | |
| 126 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 127 | +| Sum Mode | DAC0 carries the sum of I0 | AD9172_DDSM_MODE (0x1) | Suitable for applications | |
| 128 | +| | and I1, DAC1 carries Q0 + Q1. | | requiring combined outputs | |
| 129 | +| | | | for increased driving power. | |
| 130 | ++---------------------+-------------------------------+-------------------------------+-------------------------------+ |
| 131 | + |
| 132 | +Device Configuration |
| 133 | +-------------------- |
| 134 | + |
| 135 | +Initialization |
| 136 | +~~~~~~~~~~~~~~ |
| 137 | + |
| 138 | +The ``ad9172_init()`` function is responsible for setting up the AD9172 DAC |
| 139 | +by configuring the necessary communication interfaces such as SPI and GPIO, |
| 140 | +allocating memory for the device descriptor and state, and transferring the |
| 141 | +initialization parameters into the driver’s internal structures. This |
| 142 | +function initializes all essential registers to ensure the device is |
| 143 | +ready for operation and must be the first API invoked during the device |
| 144 | +lifecycle. |
| 145 | + |
| 146 | +JESD Interface Configuration |
| 147 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 148 | + |
| 149 | +The ``ad917x_jesd_set_scrambler_enable()`` function enables or |
| 150 | +disables the descrambler for the JESD interface and adjusts the |
| 151 | +scrambler settings by taking in the device handle and the appropriate |
| 152 | +control parameter. The function must be called after successful |
| 153 | +initialization to properly configure the high-speed JESD data transfer |
| 154 | +path. |
| 155 | + |
| 156 | +Resource Removal |
| 157 | +~~~~~~~~~~~~~~~~ |
| 158 | + |
| 159 | +``ad9172_remove()`` function is designed to gracefully de-allocate resources that |
| 160 | +were previously allocated during device initialization and |
| 161 | +configuration. It handles the removal of SPI and GPIO descriptors and |
| 162 | +frees any memory associated with device state or descriptor structures, |
| 163 | +ensuring that system resources are reclaimed without causing leaks. |
| 164 | + |
| 165 | +Driver Initialization Example |
| 166 | +----------------------------- |
| 167 | + |
| 168 | +.. code-block:: C |
| 169 | +
|
| 170 | + #include <stdio.h> |
| 171 | + #include <stdlib.h> |
| 172 | + #include "ad9172.h" |
| 173 | + #include "no_os_gpio.h" |
| 174 | + #include "no_os_spi.h" |
| 175 | + #include "no_os_delay.h" |
| 176 | + #include <stdint.h> |
| 177 | + #include <errno.h> |
| 178 | + #include <string.h> |
| 179 | + #include <inttypes.h> |
| 180 | + #include "no_os_alloc.h" |
| 181 | + #include "api_error.h" |
| 182 | +
|
| 183 | + struct xil_spi_init_param xil_spi_param = { |
| 184 | + .type = SPI_PS, |
| 185 | + .flags = 0 |
| 186 | + }; |
| 187 | +
|
| 188 | + ad9172_init_param default_init_param = { |
| 189 | + .spi_init = { |
| 190 | + .device_id = XPAR_PSU_SPI_0_DEVICE_ID, |
| 191 | + .max_speed_hz = 1000000, |
| 192 | + .mode = NO_OS_SPI_MODE_0, |
| 193 | + .chip_select = SPI_AD9172_CS, |
| 194 | + .platform_ops = &xil_spi_ops, |
| 195 | + .extra = &xil_spi_param |
| 196 | + }, |
| 197 | + .gpio_txen0 = { |
| 198 | + .number = 76, |
| 199 | + .platform_ops = &xil_gpio_ops, |
| 200 | + .extra = &xilinx_gpio_init_param |
| 201 | + }, |
| 202 | + .gpio_txen1 = { |
| 203 | + .number = 77, |
| 204 | + .platform_ops = &xil_gpio_ops, |
| 205 | + .extra = &xilinx_gpio_init_param |
| 206 | + }, |
| 207 | + .gpio_reset = { |
| 208 | + .number = 54, |
| 209 | + .platform_ops = &xil_gpio_ops, |
| 210 | + .extra = &xilinx_gpio_init_param |
| 211 | + }, |
| 212 | + .dac_rate_khz = 11796480, |
| 213 | + .dac_clkin_Hz = 368640000, |
| 214 | + .jesd_link_mode = 4, |
| 215 | + .jesd_subclass = 1, |
| 216 | + .dac_interpolation = 8, |
| 217 | + .channel_interpolation = 4, |
| 218 | + .clock_output_config = 4, |
| 219 | + .syncoutb_type = SIGNAL_LVDS, |
| 220 | + .sysref_coupling = COUPLING_AC, |
| 221 | + .dac_freq_hz = 368640000, |
| 222 | + .dev_xfer = client_spi_xfer, |
| 223 | + .delay_us = client_delay_us, |
| 224 | + .tx_en_pin_ctrl = client_tx_en_pin_ctrl, |
| 225 | + .reset_pin_ctrl = client_reset_pin_ctrl, |
| 226 | + .hw_open = client_hw_open, |
| 227 | + .hw_close = client_hw_close |
| 228 | + }; |
| 229 | +
|
| 230 | + ad9172_dev *device; |
| 231 | + int ret; |
| 232 | +
|
| 233 | + ret = ad9172_init(&device, &default_init_param); |
| 234 | + if (ret) { |
| 235 | + printf("AD9172 initialization failed: %s\n", adi_api_get_error_string(ret)); |
| 236 | + goto error; |
| 237 | + } |
| 238 | + printf("AD9172 successfully initialized\n"); |
| 239 | +
|
| 240 | + uint8_t revision[3] = {0, 0, 0}; |
| 241 | + adi_chip_id_t dac_chip_id; |
| 242 | +
|
| 243 | + ret = ad917x_get_chip_id(device, &dac_chip_id); |
| 244 | + if (ret) { |
| 245 | + printf("Failed to get chip ID: %s\n", adi_api_get_error_string(ret)); |
| 246 | + goto error; |
| 247 | + } |
| 248 | +
|
| 249 | + ret = ad917x_get_revision(device, &revision[0], &revision[1], &revision[2]); |
| 250 | + if (ret) { |
| 251 | + printf("Failed to get revision: %s\n", adi_api_get_error_string(ret)); |
| 252 | + goto error; |
| 253 | + } |
| 254 | +
|
| 255 | + printf("*********************************************\n"); |
| 256 | + printf("AD917x DAC Chip ID: %d\n", dac_chip_id.chip_type); |
| 257 | + printf("AD917x DAC Product ID: %d\n", dac_chip_id.prod_id); |
| 258 | + printf("AD917x DAC Product Grade: %d\n", dac_chip_id.prod_grade); |
| 259 | + printf("AD917x DAC Product Revision: %d\n", dac_chip_id.dev_revision); |
| 260 | + printf("AD917x Revision: %d.%d.%d\n", revision[0], revision[1], revision[2]); |
| 261 | + printf("*********************************************\n"); |
| 262 | +
|
| 263 | + goto finish; |
| 264 | +
|
| 265 | + error: |
| 266 | + printf("Error occurred during AD9172 initialization: %s\n", adi_api_get_error_string(ret)); |
| 267 | +
|
| 268 | + finish: |
| 269 | + ; |
0 commit comments