|
| 1 | +AD9081 no-OS Driver |
| 2 | +=================== |
| 3 | + |
| 4 | +Overview |
| 5 | +-------- |
| 6 | + |
| 7 | +The AD9081 is a mixed-signal front-end (MxFE) device |
| 8 | +designed for high-speed signal processing applications. It features four |
| 9 | +16-bit, 12 GSPS DAC cores and four 12-bit, 4 GSPS ADC cores, offering |
| 10 | +flexible digital signal processing with interpolation and decimation |
| 11 | +options. The device supports JESD204B/C high-speed serial interfaces |
| 12 | +with up to 16 lanes and data rates up to 24.75 Gbps, facilitating |
| 13 | +seamless integration with digital systems. It includes advanced |
| 14 | +synchronization mechanisms such as SYSREF management and supports |
| 15 | +digital upconversion and downconversion, making it suitable for wireless |
| 16 | +communications, broadband systems, and phased array radars. Implemented |
| 17 | +in C, the AD9081 driver’s API allows for device initialization, |
| 18 | +configuration, and control, featuring JESD204 link management, clock |
| 19 | +configuration, and NCO synchronization along with error handling and |
| 20 | +logging functions. |
| 21 | + |
| 22 | +Supported Devices |
| 23 | +----------------- |
| 24 | + |
| 25 | +- :adi:`AD9081` |
| 26 | + |
| 27 | +Applications |
| 28 | +------------ |
| 29 | + |
| 30 | +- Wireless communications infrastructure |
| 31 | +- Microwave point to point, E-band, and 5G mmWave |
| 32 | +- Broadband communications systems |
| 33 | +- DOCSIS 3.1 and 4.0 CMTS |
| 34 | +- Phased array radar and electronic warfare |
| 35 | +- Electronic test and measurement systems |
| 36 | + |
| 37 | +Operation Modes |
| 38 | +--------------- |
| 39 | + |
| 40 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 41 | +| Mode Name | Description | Configuration Bits | Typical Use | |
| 42 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 43 | +| adi_ad9081_test_mode_e | ADC test modes: Midscale, | AD9081_TMODE_* values | ADC signal pattern testing | |
| 44 | +| | Full-Scale, RAMP, PN seq. | | | |
| 45 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 46 | +| adi_ad9081_dac_mod_mux | DAC signal mux modes. | AD9081_DAC_MUX_MODE_* | DAC output routing | |
| 47 | +| _mode_e | | values | | |
| 48 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 49 | +| adi_ad9081_adc_nco_mode_e | ADC NCO: Variable/Zero IF | AD9081_ADC_NCO_* values | ADC NCO configuration | |
| 50 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 51 | +| adi_ad9081_adc_adc_to | ADC to DDC crossbar | AD9081_ADC_*_MODE values | Real/complex ADC config | |
| 52 | +| _cddc_xbar_e | settings. | | | |
| 53 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 54 | +| adi_ad9081_adc_pfir_i | PFIR I-mode filter config | AD9081_ADC_PFIR_I_MODE_* | ADC input filtering | |
| 55 | +| _mode_e | | values | | |
| 56 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 57 | +| adi_ad9081_adc_pfir_q | PFIR Q-mode filter config | AD9081_ADC_PFIR_Q_MODE_* | Q-channel filtering | |
| 58 | +| _mode_e | | values | | |
| 59 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 60 | +| adi_ad9081_adc_bypass | ADC bypass modes. | AD9081_ADC_*_MODE values | Data path/diagnostics | |
| 61 | +| _mode_e | | | | |
| 62 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 63 | +| adi_ad9081_jesd_rx_prbs | JESD RX PRBS test modes. | AD9081_JESD_RX_PRBS_TEST | RX data integrity test | |
| 64 | +| _test_mode_e | | _MODE_* values | | |
| 65 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 66 | +| adi_ad9081_jesd_tx_test | JESD TX test modes. | AD9081_JESD_TX_TEST_MODE_* | TX signal validation | |
| 67 | +| _mode_e | | values | | |
| 68 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 69 | +| adi_ad9081_deser_mode_e | JESD deserializer modes. | AD9081_*_RATE modes | Set deserialization rate | |
| 70 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 71 | +| adi_ad9081_cal_mode_e | JESD calibration modes. | AD9081_CAL_MODE_* values | JESD calibration | |
| 72 | ++----------------------------+---------------------------+-----------------------------+-------------------------------+ |
| 73 | + |
| 74 | +Device Configuration |
| 75 | +--------------------- |
| 76 | + |
| 77 | +Initialization Functions |
| 78 | +~~~~~~~~~~~~~~~~~~~~~~~~ |
| 79 | + |
| 80 | +The initialization functions in the AD9081 driver focus on setting up |
| 81 | +essential hardware components such as clocks, JESD204 links, and data |
| 82 | +converters. The ``app_clock_init`` function initializes application |
| 83 | +clocks by configuring SPI and GPIO parameters. The ``app_jesd_init`` |
| 84 | +function sets up the JESD204 transmitter and receiver interfaces and |
| 85 | +ADXCVR transceivers. The ``main`` function orchestrates the overall |
| 86 | +setup process, ensuring all components are correctly configured for |
| 87 | +high-speed data transactions and synchronization. |
| 88 | + |
| 89 | +Configuration Functions |
| 90 | +~~~~~~~~~~~~~~~~~~~~~~~ |
| 91 | + |
| 92 | +Configuration functions in the AD9081 system specify parameters for |
| 93 | +devices and interfaces. For instance, ``app_jesd_init`` configures clock |
| 94 | +rates and JESD204 subclass settings crucial for data alignment and |
| 95 | +synchronization. These configurations customize the operation of the |
| 96 | +AD9081 to meet specific application needs by defining frequencies and |
| 97 | +JESD link parameters. |
| 98 | + |
| 99 | +Synchronization Functions |
| 100 | +~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 101 | + |
| 102 | +Synchronization functions ensure coherent high-speed data transfer and |
| 103 | +signal processing on the AD9081 device. This includes managing |
| 104 | +SYSREF signals to align JESD204 data streams, maintaining timing |
| 105 | +accuracy between converters and interfaces. Functions leverage devices |
| 106 | +like the HMC7044 clock generator for clock distribution and jitter |
| 107 | +cleaning, which is critical for processes requiring coherent signal |
| 108 | +phases. |
| 109 | + |
| 110 | +Data Handling Functions |
| 111 | +~~~~~~~~~~~~~~~~~~~~~~~ |
| 112 | + |
| 113 | +Data handling functions manage data flow through ADC and DAC interfaces |
| 114 | +and DMA operations. The ``main`` function initializes ADC and DAC cores, |
| 115 | +ensuring efficient digital-to-analog and analog-to-digital conversions. |
| 116 | +Buffers like ``dac_buffer`` and ``adc_buffer`` store samples for |
| 117 | +processing or transmission, while DMA controllers move data to and from |
| 118 | +memory. These functions support high-speed signal processing |
| 119 | +applications by efficiently handling high-rate data streams. |
| 120 | + |
| 121 | +GPIO Configuration |
| 122 | +~~~~~~~~~~~~~~~~~~ |
| 123 | + |
| 124 | +To configure GPIO pins on the AD9081, utilize the no-OS codebase driver |
| 125 | +API functions. Use macros like ``AD9081_PERI_SEL_GPIO`` to define GPIO |
| 126 | +pins and functions. Functions like |
| 127 | +``adi_ad9081_dac_gpio_as_sync1_out_set`` configure synchronization |
| 128 | +outputs, and ``adi_ad9081_device_nco_sync_gpio_set`` adjusts GPIO states |
| 129 | +for NCO synchronization. Configuration parameters are available within |
| 130 | +structures like ``ad9081_init_param``, and GPIO descriptors are outlined |
| 131 | +in ``ad9081_phy``. |
| 132 | + |
| 133 | +Driver Initialization Example |
| 134 | +----------------------------- |
| 135 | + |
| 136 | +.. code-block:: C |
| 137 | +
|
| 138 | + #include <stdio.h> |
| 139 | + #include <inttypes.h> |
| 140 | + #include "no_os_gpio.h" |
| 141 | + #include "no_os_spi.h" |
| 142 | + #include "ad9081.h" |
| 143 | + #include "app_clock.h" |
| 144 | + #include "app_jesd.h" |
| 145 | +
|
| 146 | + int int_main(void) { |
| 147 | + // Declare variables for SPI, GPIO initialization |
| 148 | + struct xil_gpio_init_param xil_gpio_param = { |
| 149 | + #ifdef PLATFORM_MB |
| 150 | + .type = GPIO_PL, |
| 151 | + #else |
| 152 | + .type = GPIO_PS, |
| 153 | + #endif |
| 154 | + .device_id = XPAR_AXI_GPIO_DEVICE_ID |
| 155 | + }; |
| 156 | +
|
| 157 | + struct no_os_gpio_init_param gpio_phy_resetb = { |
| 158 | + .number = 55, |
| 159 | + .platform_ops = &xil_gpio_ops, |
| 160 | + .extra = &xil_gpio_param |
| 161 | + }; |
| 162 | +
|
| 163 | + struct xil_spi_init_param xil_spi_param = { |
| 164 | + #ifdef PLATFORM_MB |
| 165 | + .type = SPI_PL, |
| 166 | + #else |
| 167 | + .type = SPI_PS, |
| 168 | + #endif |
| 169 | + }; |
| 170 | +
|
| 171 | + struct no_os_spi_init_param phy_spi_init_param = { |
| 172 | + .device_id = XPAR_AXI_SPI_DEVICE_ID, |
| 173 | + .max_speed_hz = 1000000, |
| 174 | + .mode = NO_OS_SPI_MODE_0, |
| 175 | + .chip_select = 0, |
| 176 | + .platform_ops = &xil_spi_ops, |
| 177 | + .extra = &xil_spi_param |
| 178 | + }; |
| 179 | +
|
| 180 | + // Define the AD9081 initialization parameters |
| 181 | + struct ad9081_init_param phy_param = { |
| 182 | + .gpio_reset = &gpio_phy_resetb, |
| 183 | + .spi_init = &phy_spi_init_param, |
| 184 | + .dev_clk = &app_clk[0], |
| 185 | + .jesd_tx_clk = &jesd_clk[1], |
| 186 | + .jesd_rx_clk = &jesd_clk[0], |
| 187 | + .sysref_coupling_ac_en = 0, |
| 188 | + .sysref_cmos_input_enable = 0, |
| 189 | + .config_sync_0a_cmos_enable = 0, |
| 190 | + .multidevice_instance_count = 1, |
| 191 | + .jesd_sync_pins_01_swap_enable = false, |
| 192 | + .lmfc_delay_dac_clk_cycles = 0, |
| 193 | + .nco_sync_ms_extra_lmfc_num = 0, |
| 194 | + .nco_sync_direct_sysref_mode_enable = 0, |
| 195 | + .sysref_average_cnt_exp = 7, |
| 196 | + .continuous_sysref_mode_disable = 0, |
| 197 | + .tx_disable = false, |
| 198 | + .rx_disable = false, |
| 199 | + .dac_frequency_hz = AD9081_DAC_FREQUENCY, |
| 200 | + .tx_main_interpolation = AD9081_TX_MAIN_INTERPOLATION, |
| 201 | + .tx_main_nco_frequency_shift_hz = AD9081_TX_MAIN_NCO_SHIFT, |
| 202 | + .tx_dac_channel_crossbar_select = AD9081_TX_DAC_CHAN_CROSSBAR, |
| 203 | + .tx_channel_interpolation = AD9081_TX_CHAN_INTERPOLATION, |
| 204 | + .tx_channel_nco_frequency_shift_hz = AD9081_TX_CHAN_NCO_SHIFT, |
| 205 | + .tx_channel_gain = AD9081_TX_CHAN_GAIN, |
| 206 | + .jrx_link_tx[0] = &jrx_link_tx, |
| 207 | + .jrx_link_tx[1] = NULL, |
| 208 | + .adc_frequency_hz = AD9081_ADC_FREQUENCY, |
| 209 | + .nyquist_zone = AD9081_ADC_NYQUIST_ZONE, |
| 210 | + .rx_main_nco_frequency_shift_hz = AD9081_RX_MAIN_NCO_SHIFT, |
| 211 | + .rx_main_decimation = AD9081_RX_MAIN_DECIMATION, |
| 212 | + .rx_main_complex_to_real_enable = {0, 0, 0, 0}, |
| 213 | + .rx_main_enable = AD9081_RX_MAIN_ENABLE, |
| 214 | + .rx_channel_nco_frequency_shift_hz = AD9081_RX_CHAN_NCO_SHIFT, |
| 215 | + .rx_channel_decimation = AD9081_RX_CHAN_DECIMATION, |
| 216 | + .rx_channel_complex_to_real_enable = {0, 0, 0, 0, 0, 0, 0, 0}, |
| 217 | + .rx_channel_enable = AD9081_RX_CHAN_ENABLE, |
| 218 | + .jtx_link_rx[0] = &jtx_link_rx, |
| 219 | + .jtx_link_rx[1] = NULL, |
| 220 | + }; |
| 221 | +
|
| 222 | + // Placeholder for function execution output, success expected (0) |
| 223 | + int status = 0; |
| 224 | +
|
| 225 | + // Initialize clocks |
| 226 | + status = app_clock_init(app_clk); |
| 227 | + if (status < 0) { |
| 228 | + printf("Clock initialization failed\n"); |
| 229 | + return -1; |
| 230 | + } |
| 231 | +
|
| 232 | + // Initialize JESD interfaces |
| 233 | + status = app_jesd_init(jesd_clk, 0, 0, 0, 0, 0); |
| 234 | + if (status < 0) { |
| 235 | + printf("JESD initialization failed\n"); |
| 236 | + return -1; |
| 237 | + } |
| 238 | +
|
| 239 | + // Initialize AD9081 device with provided parameters |
| 240 | + status = ad9081_setup(&phy_param); |
| 241 | + if (status < 0) { |
| 242 | + printf("AD9081 initialization failed\n"); |
| 243 | + return -1; |
| 244 | + } |
| 245 | +
|
| 246 | + printf("AD9081 initialization successful\n"); |
| 247 | +
|
| 248 | + // Implement further operational setup here... |
| 249 | +
|
| 250 | + return 0; |
| 251 | + } |
0 commit comments