diff --git a/docs/solutions/reference-designs/eval-ad9081/2to24ghz-mxfe-rf-front-end.rst b/docs/solutions/reference-designs/eval-ad9081/2to24ghz-mxfe-rf-front-end.rst new file mode 100644 index 00000000000..df66fd2d112 --- /dev/null +++ b/docs/solutions/reference-designs/eval-ad9081/2to24ghz-mxfe-rf-front-end.rst @@ -0,0 +1,231 @@ +2-24GHz RF Rx & Tx Front End for MxFE +===================================== + +The 2-24GHz RF Front End is a complete RF receiver and transmitter front end +designed to meet the specifications of typical wideband instrumentation and +electronic warfare (EW) systems. The latest generation of high performance +RF/microwave and mixed signal components available from ADI are used to reduce +system SWaP (size, weight, and power) and architectural complexity. + +The full system block diagram is shown below, consisting of four functional +blocks- the receiver front end, transmitter front end, digitizer, and LO +generation. + +|image1| + +Specifications +-------------- + +The receiver and transmitter specifications, shown in the table below, are +fairly typical of many wideband instrumentation and EW systems in operation +today. The signal chain is capable of 1GHz instantaneous bandwidth (IBW) in both +receive and transmit modes across the full 2-24GHz operating range. + +These specs may not be "one-size-fits-all" for every potential use case, but the +signal chain architecture and component selection is extremely flexible, +allowing for modifications of the individual pieces to meet specific performance +or functionality targets. Everything from the digitizer sample rates to the +individual RF components and signal chain filtering can be adjusted to +facilitate changes in frequency planning or system-level functionality. + +|image2| + +Support +------- + +For support on this reference design, please contact us through our technical support portal at the follow link: :adi:`en/support/technical-support.html` + +Resources +========= + +- :ez:`2 to 24GHz Wideband Transceiver Reference Design Webinar ` +- `Digitizer Overview `_ + +- `Receiver Front End Overview & Theory Of Operation `_ + + - `Rx Input Stage & Modes Of Operation `_ + - `Downconversion Stage & Frequency Plan `_ + - `Spurious Analysis `_ + - `IF Stage `_ + - `Timing & Control `_ + - `Rx Performance Simulations `_ + +- `Transmitter Front End Overview & Theory Of Operation `_ + + - `IF Input Stage `_ + - `Frequency Conversion Stage & Frequency Plan `_ + - `RF Output Stage `_ + - `Timing & Control `_ + - `Tx Performance Simulations `_ + +- `LO Generation Options `_ + + - `Fixed LO Source `_ + - `Tunable LO Source `_ + +- `Size Estimate `_ +- `Power Architecture `_ +- `Hardware `_ +- `Software Resources `_ + +Bill of Materials +================= + +The full Bill of Materials (BOM) is provided for planning purposes. The list +below does not include passive devices typically used for filtering power +supplies, control lines, loop filters, etc... This is provided for planning +purposes only. + ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Circuit | Part Number | QTY | Manufacturer | Notes | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Rx | :adi:`ADRF5020` | 4 | Analog Devices Inc. | Path Selection | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADL9005` | 3 | Analog Devices Inc. | LNA, RF Amps | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADMV8818` | 2 | Analog Devices Inc. | Tunable Filtering | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADRF5740` | 1 | Analog Devices Inc. | RF DSA | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8412` | 2 | Analog Devices Inc. | LF/IF Amp | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC773a` | 1 | Analog Devices Inc. | LB mix | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `L254XF3S `_ | 1 | Knowles | HB Image Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `HFCN-9700+ `_ | 1 | Mini-Circuits | LB IF Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8191LC4` | 1 | Analog Devices Inc. | Primary Mix | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `QCS-592+ `_ | 1 | Mini-Circuits | 90 Degree Hybrid | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADRF5730` | 1 | Analog Devices Inc. | IF DSA | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8413` | 1 | Analog Devices Inc. | IF Amp | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `HFCN-3100+ `_ | 1 | Mini-Circuits | Anti-Aliasing Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `LFCW-5000+ `_ | 1 | Mini-Circuits | Anti-Aliasing Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Rx Power Supply | :adi:`maxm17632` | 1 | Analog Devices Inc. | 12v -> 5.5v Regulator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP150-3.3` | 1 | Analog Devices Inc. | 3.3v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP5600` | 1 | Analog Devices Inc. | -2.5v CP/LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP7183-3.3` | 1 | Analog Devices Inc. | -3.3v CP/LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADM7171` | 1 | Analog Devices Inc. | 5v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP150-2.5` | 1 | Analog Devices Inc. | 2.5v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Tx | :adi:`HMC994APM5E` | 1 | Analog Devices Inc. | 0.5W Wideband PA | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADMV8818` | 1 | Analog Devices Inc. | Tunable Filtering | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADL9006` | 2 | Analog Devices Inc. | RF Amps | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADRF5020` | 2 | Analog Devices Inc. | Path Selection | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC882A` | 1 | Analog Devices Inc. | LB Tunable LPF | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8412` | 2 | Analog Devices Inc. | LB and IF Amps | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC652` | 2 | Analog Devices Inc. | Fixed Attenuators | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC773A` | 1 | Analog Devices Inc. | LB Mix | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `HFCN-9700+ `_ | 1 | Mini-Circuits | LB IF Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `LFCV-1452+ `_ | 1 | Mini-Circuits | LB IF Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `L254XF3S `_ | 1 | Knowles | HB Image Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8191LC4` | 1 | Analog Devices Inc. | Primary Mix | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `QCS-592+ `_ | 1 | Mini-Circuits | 90 Degree Hybrid | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `LFCG-4800+ `_ | 2 | Mini-Circuits | DAC Image Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADRF5730` | 1 | Analog Devices Inc. | IF DSA | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Tx Power Supply | :adi:`MAXM17632` | 1 | Analog Devices Inc. | 12v -> 5.5v Regulator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP150-3.3` | 1 | Analog Devices Inc. | 3.3v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP7183-3.3` | 1 | Analog Devices Inc. | -3.3v CP/LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADM7171` | 1 | Analog Devices Inc. | 5v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP5600` | 1 | Analog Devices Inc. | -2.5v CP/LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP150-2.5` | 1 | Analog Devices Inc. | 2.5v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`LT3081` | 1 | Analog Devices Inc. | 10v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Fixed LO | :adi:`ADF41513` | 1 | Analog Devices Inc. | PLL Chip | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADA4625` | 1 | Analog Devices Inc. | OP-AMP | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC8362` | 1 | Analog Devices Inc. | VCO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `BFCQ-1892+ `_ | 1 | Mini-Circuits | Harmonic Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC654LP2E` | 1 | Analog Devices Inc. | Attenuator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADL8105` | 1 | Analog Devices Inc. | Mixer Driver Amp | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Tunable LO | :adi:`ADF4371` | 1 | Analog Devices Inc. | PLL/VCO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADMV8416` | 1 | Analog Devices Inc. | Tunable Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADMV8432` | 1 | Analog Devices Inc. | Tunable Filter | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC656LP2E` | 1 | Analog Devices Inc. | Attenuator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC652LP2E` | 2 | Analog Devices Inc. | Attenuator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADRF5024` | 1 | Analog Devices Inc. | Path Selection | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC7950` | 2 | Analog Devices Inc. | Driver Amp | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC654LP2E` | 1 | Analog Devices Inc. | Attenuator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`HMC383` | 1 | Analog Devices Inc. | Mixer LO Driver Amp | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Digitizer | :adi:`AD9082` | 1 | Analog Devices Inc. | ADCs/DACs | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | `BALH-0009SMG `_ | 4 | Marki Microwave | Baluns - assuming 2 ADCs/ 2 DACs used | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADF4377` | 1 | Analog Devices Inc. | Clock for AD9082 | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| Digitizer Power Supply | :adi:`LTM8051` | 1 | Analog Devices Inc. | Multi-ch Regulator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`LT3045` | 3 | Analog Devices Inc. | 3.3v/5v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP7158-2` | 2 | Analog Devices Inc. | 2v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`LT8625S` | 1 | Analog Devices Inc. | 1v Regulator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`LT8627S` | 1 | Analog Devices Inc. | 1.3v Regulator | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ +| | :adi:`ADP1765-1` | 2 | Analog Devices Inc. | 1v LDO | ++------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+-----+---------------------+---------------------------------------+ + +| + +.. admonition:: Download + :class: download + + To request the Bill of Materials, please send a request `here `_ and include the following info: + + + - Name + - Job Title + - Company Name + - Company Location + - Application/Use Case + + +.. |image1| image:: https://wiki.analog.com/_media/resources/eval/developer-kits/2to24blockdiagram.png +.. |image2| image:: https://wiki.analog.com/_media/resources/eval/developer-kits/full_spec_table_r1p01.png diff --git a/docs/solutions/reference-designs/eval-ad9081/ad9081.rst b/docs/solutions/reference-designs/eval-ad9081/ad9081.rst new file mode 100644 index 00000000000..a4767a170a5 --- /dev/null +++ b/docs/solutions/reference-designs/eval-ad9081/ad9081.rst @@ -0,0 +1,2535 @@ +AD9081 MxFE Linux Driver +======================== + +Supported Devices +----------------- + +- :adi:`AD9081` +- :adi:`AD9082` +- :adi:`AD9988` +- :adi:`AD9986` +- :adi:`AD9177` +- :adi:`AD9207` +- :adi:`AD9209` + +Supported Boards +---------------- + +- :adi:`AD9081-FMCA-EBZ` +- :adi:`AD9082-FMCA-EBZ` +- :adi:`AD9988-FMCB-EBZ` +- :adi:`AD9986-FMCB-EBZ` +- :adi:`Quad-MxFE` + +User Guides +~~~~~~~~~~~ + +- `AD9081/AD9082 Prototyping Platform User Guide `_ +- `Quad-MxFE Prototyping Platform User Guide `_ + +Supported HDL Cores +------------------- + +- `AD9081-FMCA-EBZ (Single MxFE) HDL Reference Design `_ + +Description +----------- + +The mixed signal front end (MxFE®) is a high integration devicewith a 16-bit, 12 +GSPS maximum sample rate radio frequency (RF) digital-to-analog converter (DAC) +core and a 12-bit, 4 GSPS rate RF analog-to-digital converter (ADC) core. The +AD9081 features a 16-lane, 24.75 Gbps JESD204C or 15.5 Gbps JESD204B data +transceiver port, an on-chip clock multiplier, and digital signal processing +capability targeted at single-and dual-band direct-to-RF radio applications. + +The AD9081 supports four transmitter channels and four receiver channels with a +4D4A configuration. The receiver ADC channels can be shared with observation +channels in time division duplex(TDD) operating mode. The AD9081 directly +addresses the emerging base station applications with high integration and +common platform requirements. The device has flexible inter-polation/decimation +configurations that enable direct-to-RF multiband radio applications. AD9081 +supports a complex transmit input data rate up to 6 GSPS and a receive output +data rate in single-channel mode up to 4 GSPS. The maximum radio band spacing +supported in multichannel modes is 1.2 GHz. AD9081 features a bypassable +interpolator and decimator for achieving ultra wideband capability with low +latency loop back and frequency hopping modes targeted at phase array radar +system and electronic warfare jammer applications. + +For more information about the AD9081 or AD9082, contact Analog Devices, Inc., at: `mxfesupport@analog.com `_. + +Source Code +=========== + +Status +------ + ++---------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| Source | Mainlined? | ++===============================================================================================================+===========================================================================================================+ +| :git-linux:`drivers/iio/adc/ad9081.c` | `No `_ | ++---------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------+ + +Files +----- + ++------------+---------------------------------------------------------------------------------------------------------------+ +| Function | File | ++============+===============================================================================================================+ +| driver | :git-linux:`drivers/iio/adc/ad9081.c` | ++------------+---------------------------------------------------------------------------------------------------------------+ +| API driver | :git-linux:`drivers/iio/adc/ad9081` | ++------------+---------------------------------------------------------------------------------------------------------------+ + +Example device trees +~~~~~~~~~~~~~~~~~~~~ + ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+===========================================================================================================================================================+ +| dtsi | `adi-ad9081-fmc-ebz.dtsi `_ | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `socfpga_arria10_socdk_ad9081.dts `_ | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `socfpga_arria10_socdk_ad9081_np12.dts `_ | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `zynq-zc706-adv7511-ad9081-np12.dts `_ | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `zynq-zc706-adv7511-ad9081.dts `_ | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+======================================================================================================================================================================================================+ +| dtsi | `adi-ad9081-fmc-ebz.dtsi `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_10_rxmode_11.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_10_rxmode_11_lr_24_75Gbps.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_23_rxmode_25.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_23_rxmode_25_lr_24_75Gbps.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_23_rxmode_25_vcxo100.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_204c_txmode_24_rxmode_26_lr_24_75Gbps.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9081_m8_l4.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| dts | `vcu118_ad9082_204c_txmode_18_rxmode_19_lr_24_75Gbps.dts `_ | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Interrelated Device Drivers +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `JESD204 (FSM) Interface Linux Kernel Framework `_ +- `JESD204 Interface Framework `_ + +Transport Layer Receive AXI-ADC driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+===============================================================================================================================================+ +| driver | :git-linux:`drivers/iio/adc/cf_axi_adc_core.c` | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| driver | :git-linux:`drivers/iio/adc/cf_axi_adc_ring_stream.c` | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| include | :git-linux:`drivers/iio/adc/cf_axi_adc.h` | ++----------+-----------------------------------------------------------------------------------------------------------------------------------------------+ + +**Documentation:** `AXI ADC HDL Linux Driver `_ + +Transport Layer Transmit AXI-DAC / DDS driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++----------+-----------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+===================================================================================================================================+ +| driver | :git-linux:`drivers/iio/frequency/cf_axi_dds.c` | ++----------+-----------------------------------------------------------------------------------------------------------------------------------+ +| include | :git-linux:`drivers/iio/frequency/cf_axi_adc.h ` | ++----------+-----------------------------------------------------------------------------------------------------------------------------------+ + +**Documentation:** `AXI DAC HDL Linux Driver `_ + +Link Layer AXI JESD204B HDL driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++----------+---------------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+=======================================================================================================================================+ +| driver | :git-linux:`drivers/iio/jesd204/axi_jesd204_rx.c` | ++----------+---------------------------------------------------------------------------------------------------------------------------------------+ +| driver | :git-linux:`drivers/iio/jesd204/axi_jesd204_tx.c` | ++----------+---------------------------------------------------------------------------------------------------------------------------------------+ + +**Documentation:** + +- `JESD204B/C Transmit Linux Driver `_ +- `JESD204B/C Receive Linux Driver `_ + +PHY Layer AXI JESD204B GT (Gigabit Tranceiver) HDL driver (XILINX/ALTERA-INTEL) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++----------+-------------------------------------------------------------------------------------------------------------------------------+ +| Function | File | ++==========+===============================================================================================================================+ +| driver | :git-linux:`drivers/iio/jesd204/axi_adxcvr.c` | ++----------+-------------------------------------------------------------------------------------------------------------------------------+ + +**Documentation:** + +- `JESD204B/C AXI_ADXCVR Highspeed Transceivers Linux Driver `_ + +Enabling Linux driver support +============================= + +Configure kernel with "make menuconfig" (alternatively use "make xconfig" or +"make qconfig") + +.. hint:: + + The ADRV9009 driver depends on CONFIG_SPI + +Adding Linux driver support +=========================== + +Configure kernel with "make menuconfig" (alternatively use "make xconfig" or +"make qconfig") + +:: + + Linux Kernel Configuration + Device Drivers ---> + <*> JESD204 High-Speed Serial Interface Framework + <*> Industrial I/O support ---> + --- Industrial I/O support + - *- Enable ring buffer support within IIO + - *- Industrial I/O lock free software ring + - *- Enable triggered sampling support + + Analog to digital converters + [--snip--] + + - *- Analog Devices High-Speed AXI ADC driver core + <*> Analog Devices AD9081 and similar Mixed Signal Front End (MxFE) + < > Analog Devices AD9208 and similar high speed ADCs + < > Analog Devices AD9361, AD9364 RF Agile Transceiver driver + < > Analog Devices AD9371 RF Transceiver driver + < > Analog Devices ADRV9009/ADRV9008 RF Transceiver driver + < > Analog Devices AD6676 Wideband IF Receiver driver + < > Analog Devices AD9467, AD9680, etc. high speed ADCs + + [--snip--] + + Frequency Synthesizers DDS/PLL ---> + Direct Digital Synthesis ---> + <*> Analog Devices CoreFPGA AXI DDS driver + Clock Generator/Distribution ---> + < > Analog Devices AD9508 Clock Fanout Buffer + < > Analog Devices AD9523 Low Jitter Clock Generator + < > Analog Devices AD9528 Low Jitter Clock Generator + < > Analog Devices AD9548 Network Clock Generator/Synchronizer + < > Analog Devices AD9517 12-Output Clock Generator + <*> Analog Devices HMC7044, HMC7043 Clock Jitter Attenuator with JESD204B + < > Analog Devices LTC6952 Clock Ultralow Jitter with JESD204B/C + + <*> JESD204 High-Speed Serial Interface Support ---> + --- JESD204 High-Speed Serial Interface Support + < > Altera Arria10 JESD204 PHY Support + <*> Analog Devices AXI ADXCVR PHY Support + < > Generic AXI JESD204B configuration driver + <*> Analog Devices AXI JESD204B TX Support + <*> Analog Devices AXI JESD204B RX Support + +Device tree customization +========================= + +The AD9081 Linux IIO device driver is configured and customized using device tree, a simple tree structure of nodes and properties. Properties are key-value pairs, and node may contain both properties and child nodes. The top device node of the AD9081/82 contains common and device specific attributes. Under the top node, there are two child-nodes (``adi,tx-dacs`` and ``adi,rx-adcs``). In case of DAC or ADC only operation, both nodes are required and must contain at least the ``adi,dac-frequency-hz`` and respectively the ``adi,adc-frequency-hz`` property. However omitting the child nodes will disable this ADC/DAC data path. + +.. code:: none + + &spi { + trx0_ad9081: ad9081@0 { + + // Device common properties + + adi,tx-dacs { + // Tx/DAC properties and child-nodes + + }; + + adi,rx-adcs { + // Rx/ADC properties and child-nodes + }; + }; + }; + +Each of these child nodes handle certain aspects of either the digital-to-analog +converter core side or the analog-to-digital converter side of the Mixed Signal +Frontend (MxFE®) These child-nodes again contain ADC or DAC side common +attributes. Such as the ADC/DAC frequency. But also, three child-nodes to +customize the main data paths, the channelizers and the serial JESD204 +interfaces. + +.. code:: c + + adi,rx-adcs { + + adi,main-data-paths { + + }; + + adi,channelizer-paths { + + }; + + adi,jesd-links { + + }; + }; + +- The ``adi,main-data-paths`` node iterates the used ADCs or DACs together with its default/dedicated CDDCs and CDUCs. Each of these nodes have in return again properties to configure the default NCO frequencies, modes, decimation, etc. (A list of supported properties/attributes can be found below.) +- The second mandatory node is the ``adi,channelizer-paths`` node. The utilized channelizers FDDCs and FDUCs are described in here, which are always related to the main data paths. Therefore, the main data path child-nodes contain a property (``adi,crossbar-select``) of a device node containing a phandle to the FDUC or FDDC that it is attached to. +- The last mandatory child-node is the ``adi,jesd-links`` node. This node contains up to two (single/dual link) child-nodes, one for each link. + +.. code:: none + + adi,main-data-paths { + + ad9081_dac0: dac@0 { + + }; + ad9081_dac1: dac@1 { + + }; + ad9081_dac2: dac@2 { + + }; + ad9081_dac3: dac@3 { + + }; + }; + + adi,channelizer-paths { + + ad9081_tx_fddc_chan0: channel@0 { + + }; + ad9081_tx_fddc_chan1: channel@1 { + + }; + }; + + adi,jesd-links { + + ad9081_tx_jesd_l0: link@0 { + + }; + }; + +AD9081 Mixed-Signal Front End (MxFE) Device Tree Bindings +========================================================= + +Overview +-------- + +The AD9081 is a high-performance, single-chip, mixed-signal front end (MxFE) +integrating: + +- **Four 16-bit, 12 GSPS RF DAC cores** +- **Four 12-bit, 4 GSPS RF ADC cores** + +Compatible Devices +------------------ + +The following devices are supported by this driver: + +- ``adi,ad9081`` - AD9081 MxFE +- ``adi,ad9082`` - AD9082 MxFE +- ``adi,ad9988`` - AD9988 MxFE +- ``adi,ad9986`` - AD9986 MxFE +- ``adi,ad9177`` - AD9177 Quad DAC +- ``adi,ad9207`` - AD9207 Dual ADC +- ``adi,ad9209`` - AD9209 Quad ADC + +Required Properties +------------------- + +=============== ======= ================================================ +Property Type Description +=============== ======= ================================================ +``compatible`` string One of the supported device strings listed above +``reg`` integer SPI chip select number +``clocks`` phandle Reference to device clock +``clock-names`` string Must be "dev_clk" +=============== ======= ================================================ + +Optional Properties +------------------- + +Basic Configuration +~~~~~~~~~~~~~~~~~~~ + +===================== ========= ============ =========================== +Property Type Range/Values Description +===================== ========= ============ =========================== +``spi-max-frequency`` integer ≤ 25000000 Maximum SPI frequency in Hz +``reset-gpios`` phandle - GPIO for hardware reset +``interrupts`` interrupt - Device interrupt line +===================== ========= ============ =========================== + +Standalone and Multi-Device Setup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++-------------------------------------------+---------+--------------------------------------------------------+ +| Property | Type | Description | ++===========================================+=========+========================================================+ +| ``adi,standalone-enable`` | boolean | Enable standalone mode for the device | ++-------------------------------------------+---------+--------------------------------------------------------+ +| ``adi,multidevice-instance-count`` | u32 | Number of devices in multidevice synchronization setup | ++-------------------------------------------+---------+--------------------------------------------------------+ +| ``adi,dual-link-use-separate-tpl-enable`` | boolean | Enable separate TPL for dual-link mode | ++-------------------------------------------+---------+--------------------------------------------------------+ + +JESD Synchronization +~~~~~~~~~~~~~~~~~~~~ + ++---------------------------------------+---------+---------------------------------------+ +| Property | Type | Description | ++=======================================+=========+=======================================+ +| ``adi,jesd-sync-pins-01-swap-enable`` | boolean | Swap JESD sync pins 0 and 1 | ++---------------------------------------+---------+---------------------------------------+ +| ``adi,jesd-sync-pin-0a-cmos-enable`` | boolean | Enable CMOS mode for JESD sync pin 0A | ++---------------------------------------+---------+---------------------------------------+ +| ``adi,lmfc-delay-dac-clk-cycles`` | u32 | LMFC delay in DAC clock cycles | ++---------------------------------------+---------+---------------------------------------+ + +NCO Synchronization +~~~~~~~~~~~~~~~~~~~ + ++--------------------------------------------+---------+-------+-----------------------------------------------------+ +| Property | Type | Range | Description | ++============================================+=========+=======+=====================================================+ +| ``adi,nco-sync-ms-extra-lmfc-num`` | u32 | - | Extra LMFC cycles for NCO sync in master-slave mode | ++--------------------------------------------+---------+-------+-----------------------------------------------------+ +| ``adi,nco-sync-direct-sysref-mode-enable`` | boolean | - | Enable direct SYSREF mode for NCO synchronization | ++--------------------------------------------+---------+-------+-----------------------------------------------------+ + +SYSREF Configuration +~~~~~~~~~~~~~~~~~~~~ + ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| Property | Type | Range | Description | ++===========================================+=========+=======+=========================================================+ +| ``adi,sysref-average-cnt-exp`` | u32 | 0-15 | SYSREF averaging count exponent (2 | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| ``adi,sysref-ac-coupling-enable`` | boolean | - | Enable AC coupling for SYSREF | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| ``adi,sysref-cmos-input-enable`` | boolean | - | Enable CMOS input mode for SYSREF | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| ``adi,sysref-single-end-pos-termination`` | u32 | 0-3 | Termination resistance for positive single-ended SYSREF | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| ``adi,sysref-single-end-neg-termination`` | u32 | 0-3 | Termination resistance for negative single-ended SYSREF | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ +| ``adi,continuous-sysref-mode-disable`` | boolean | - | Disable continuous SYSREF mode | ++-------------------------------------------+---------+-------+---------------------------------------------------------+ + +Loopback and GPIO +~~~~~~~~~~~~~~~~~ + ++----------------------------------------------+------+-------+-------------------------------------------------+ +| Property | Type | Range | Description | ++==============================================+======+=======+=================================================+ +| ``adi,direct-loopback-mode-dac-adc-mapping`` | u32 | 0-255 | Mapping for direct loopback between DAC and ADC | ++----------------------------------------------+------+-------+-------------------------------------------------+ +| ``adi,master-slave-sync-gpio-num`` | u32 | 0-15 | GPIO number for master-slave synchronization | ++----------------------------------------------+------+-------+-------------------------------------------------+ + +TX DAC Configuration (adi,tx-dacs) +---------------------------------- + +The TX DAC configuration is specified in a sub-node with the following +structure: + +DAC Global Properties +~~~~~~~~~~~~~~~~~~~~~ + ++----------------------------------+---------+---------------------------------------------------+ +| Property | Type | Description | ++==================================+=========+===================================================+ +| ``adi,dac-frequency-hz`` | u64 | DAC operating frequency in Hz (use ``/bits/ 64``) | ++----------------------------------+---------+---------------------------------------------------+ +| ``adi,ffh-hopf-via-gpio-enable`` | boolean | Enable FFH HOPF via GPIO | ++----------------------------------+---------+---------------------------------------------------+ + +PA Protection Global Settings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++-----------------------------------------+-----------+------------------------------------------------------------------+ +| Property | Type | Description | ++=========================================+===========+==================================================================+ +| ``adi,pa-protection-gpio-as-pa-enable`` | boolean | Configure GPIO pins 0-3 as PA enable outputs | ++-----------------------------------------+-----------+------------------------------------------------------------------+ +| ``adi,pa-protection-rotation-mode`` | u32 (0-3) | Rotation mode configuration (see header file for bitmask values) | ++-----------------------------------------+-----------+------------------------------------------------------------------+ + +Main Data Paths (adi,main-data-paths) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Contains configuration for up to 4 DACs (dac@0 through dac@3). + +Global Main Path Properties +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++-----------------------+------+----------------+------------------------------------------+ +| Property | Type | Values | Description | ++=======================+======+================+==========================================+ +| ``adi,interpolation`` | u32 | 1,2,3,4,6,8,12 | Interpolation factor for main data paths | ++-----------------------+------+----------------+------------------------------------------+ + +Per-DAC Properties (dac@N) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++---------------------------------------------+---------+--------------+---------------------------------------+ +| Property | Type | Range/Values | Description | ++=============================================+=========+==============+=======================================+ +| ``reg`` | u32 | 0-3 | DAC channel index | ++---------------------------------------------+---------+--------------+---------------------------------------+ +| ``adi,nco-frequency-shift-hz`` | u64 | - | NCO frequency shift in Hz | ++---------------------------------------------+---------+--------------+---------------------------------------+ +| ``adi,full-scale-current-ua`` | u32 | 7750-40320 | Full-scale current in microamperes | ++---------------------------------------------+---------+--------------+---------------------------------------+ +| ``adi,maindp-dac-1x-non1x-crossbar-select`` | u32 | 0-3 | Crossbar selection for 1x/non-1x mode | ++---------------------------------------------+---------+--------------+---------------------------------------+ +| ``adi,crossbar-select`` | phandle | - | Reference to channelizer path | ++---------------------------------------------+---------+--------------+---------------------------------------+ + +PA Protection Per-DAC Properties +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Soft-Off/On Control +""""""""""""""""""" + ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ +| Property | Type | Range | Description | ++================================================+=========+=========+===============================================================+ +| ``adi,pa-protection-soft-off-enable`` | boolean | - | Enable soft-off gain control | ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ +| ``adi,pa-protection-soft-off-new-gain-enable`` | boolean | - | Enable new soft-off gain block | ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ +| ``adi,pa-protection-soft-off-ramp-rate`` | u32 | 0-15 | Soft-off gain ramp rate (32 steps over 2^(code+8) DAC clocks) | ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ +| ``adi,pa-protection-soft-off-triggers`` | u32 | bitmask | Soft-off triggers (see header file) | ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ +| ``adi,pa-protection-soft-on-triggers`` | u32 | bitmask | Soft-on triggers (see header file) | ++------------------------------------------------+---------+---------+---------------------------------------------------------------+ + +Power Averaging +""""""""""""""" + ++-------------------------------------------+---------+---------+------------------------------------------+ +| Property | Type | Range | Description | ++===========================================+=========+=========+==========================================+ +| ``adi,pa-protection-long-avg-enable`` | boolean | - | Enable long averaging power calculation | ++-------------------------------------------+---------+---------+------------------------------------------+ +| ``adi,pa-protection-long-avg-time`` | u32 | 0-255 | Time for long averaging | ++-------------------------------------------+---------+---------+------------------------------------------+ +| ``adi,pa-protection-long-avg-threshold`` | u32 | 0-65535 | Long average power threshold (I² + Q²) | ++-------------------------------------------+---------+---------+------------------------------------------+ +| ``adi,pa-protection-short-avg-enable`` | boolean | - | Enable short averaging power calculation | ++-------------------------------------------+---------+---------+------------------------------------------+ +| ``adi,pa-protection-short-avg-time`` | u32 | 0-255 | Time for short averaging | ++-------------------------------------------+---------+---------+------------------------------------------+ +| ``adi,pa-protection-short-avg-threshold`` | u32 | 0-65535 | Short average power threshold (I² + Q²) | ++-------------------------------------------+---------+---------+------------------------------------------+ + +Digital Step Attenuator (DSA) +""""""""""""""""""""""""""""" + ++-----------------------------------+---------+--------+---------------------------------------------------+ +| Property | Type | Range | Description | ++===================================+=========+========+===================================================+ +| ``adi,pa-protection-dsa-enable`` | boolean | - | Enable DSA for this DAC | ++-----------------------------------+---------+--------+---------------------------------------------------+ +| ``adi,pa-protection-dsa-code`` | u32 | 0-235 | DSA attenuation code (0=no attenuation, 235=47dB) | ++-----------------------------------+---------+--------+---------------------------------------------------+ +| ``adi,pa-protection-dsa-cutover`` | u32 | 0-255 | DSA cutover threshold | ++-----------------------------------+---------+--------+---------------------------------------------------+ +| ``adi,pa-protection-dsa-boost`` | u32 | 0-15 | DSA boost setting above 26mA baseline | ++-----------------------------------+---------+--------+---------------------------------------------------+ +| ``adi,pa-protection-dsa-gain`` | u32 | 0-4095 | 12-bit DSA digital gain value | ++-----------------------------------+---------+--------+---------------------------------------------------+ + +Channelizer Paths (adi,channelizer-paths) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Contains configuration for up to 8 channels (channel@0 through channel@7). + +Global Channelizer Properties +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++-----------------------+------+-------------+--------------------------------------------+ +| Property | Type | Values | Description | ++=======================+======+=============+============================================+ +| ``adi,interpolation`` | u32 | 1,2,3,4,6,8 | Interpolation factor for channelizer paths | ++-----------------------+------+-------------+--------------------------------------------+ + +Per-Channel Properties (channel@N) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +============================== ==== ======= ========================= +Property Type Range Description +============================== ==== ======= ========================= +``reg`` u32 0-7 Channelizer index +``adi,nco-frequency-shift-hz`` u64 - NCO frequency shift in Hz +``adi,nco-phase-offset`` u32 0-65535 NCO phase offset +``adi,gain`` u32 0-4095 Channel gain (12-bit) +============================== ==== ======= ========================= + +JESD Links (adi,jesd-links) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Contains configuration for up to 2 JESD links (link@0 and link@1). + +Per-Link Properties (link@N) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++------------------------------+----------+--------------+---------------------------------------+ +| Property | Type | Range/Values | Description | ++==============================+==========+==============+=======================================+ +| ``reg`` | u32 | 0-1 | JESD204 link index | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,logical-lane-mapping`` | u8-array | 1-8 lanes | Logical lane mapping | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,link-mode`` | u32 | - | JESD quick configuration mode | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,subclass`` | u32 | 0,1,2 | JESD subclass | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,version`` | u32 | 0,1,2 | JESD version (0=204A, 1=204B, 2=204C) | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,dual-link`` | u32 | 0,1 | Dual link mode | ++------------------------------+----------+--------------+---------------------------------------+ +| ``adi,tpl-phase-adjust`` | u32 | - | TPL phase adjustment value | ++------------------------------+----------+--------------+---------------------------------------+ + +JESD204 Parameters +^^^^^^^^^^^^^^^^^^ + +Standard JESD204 parameters with both ``adi,`` and ``jesd204-`` prefixes supported: + ++-----------+-------------------------------------+-------+---------------------------------+ +| Parameter | Property | Range | Description | ++===========+=====================================+=======+=================================+ +| M | ``converters-per-device`` | 1-16 | Number of converters | ++-----------+-------------------------------------+-------+---------------------------------+ +| F | ``octets-per-frame`` | 1-256 | Octets per frame | ++-----------+-------------------------------------+-------+---------------------------------+ +| K | ``frames-per-multiframe`` | 1-32 | Frames per multiframe | ++-----------+-------------------------------------+-------+---------------------------------+ +| N | ``converter-resolution`` | 1-32 | Converter resolution bits | ++-----------+-------------------------------------+-------+---------------------------------+ +| N' | ``bits-per-sample`` | 1-32 | Bits per sample | ++-----------+-------------------------------------+-------+---------------------------------+ +| CS | ``control-bits-per-sample`` | 0-3 | Control bits per sample | ++-----------+-------------------------------------+-------+---------------------------------+ +| L | ``lanes-per-device`` | 1-8 | Lanes per device | ++-----------+-------------------------------------+-------+---------------------------------+ +| S | ``samples-per-converter-per-frame`` | 1-32 | Samples per converter per frame | ++-----------+-------------------------------------+-------+---------------------------------+ +| HD | ``high-density`` | 0,1 | High density mode | ++-----------+-------------------------------------+-------+---------------------------------+ +| DID | ``device-id`` | 0-255 | Device ID | ++-----------+-------------------------------------+-------+---------------------------------+ + +RX ADC Configuration (adi,rx-adcs) +---------------------------------- + +The RX ADC configuration follows a similar structure to TX DACs. + +ADC Global Properties +~~~~~~~~~~~~~~~~~~~~~ + ++--------------------------+------+--------+-------------------------------------------------+ +| Property | Type | Values | Description | ++==========================+======+========+=================================================+ +| ``adi,adc-frequency-hz`` | u64 | - | ADC operating frequency in Hz | ++--------------------------+------+--------+-------------------------------------------------+ +| ``adi,nyquist-zone`` | u32 | 0,1 | Global Nyquist zone (0=odd, 1=even), default: 0 | ++--------------------------+------+--------+-------------------------------------------------+ + +Main Data Paths (adi,main-data-paths) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Contains configuration for up to 4 ADCs (adc@0 through adc@3). + +Per-ADC Properties (adc@N) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++--------------------------------+---------------+----------------+---------------------------------------+ +| Property | Type | Range/Values | Description | ++================================+===============+================+=======================================+ +| ``reg`` | u32 | 0-3 | ADC channel index | ++--------------------------------+---------------+----------------+---------------------------------------+ +| ``adi,decimation`` | u32 | 1,2,3,4,6,8,12 | Decimation factor | ++--------------------------------+---------------+----------------+---------------------------------------+ +| ``adi,nco-frequency-shift-hz`` | i64 | - | NCO frequency shift (can be negative) | ++--------------------------------+---------------+----------------+---------------------------------------+ +| ``adi,nco-mixer-mode`` | u32 | 0-3 | NCO mixer mode (see below) | ++--------------------------------+---------------+----------------+---------------------------------------+ +| ``adi,nyquist-zone`` | u32 | 0,1 | Per-ADC Nyquist zone override | ++--------------------------------+---------------+----------------+---------------------------------------+ +| ``adi,crossbar-select`` | phandle-array | - | References to channelizer paths | ++--------------------------------+---------------+----------------+---------------------------------------+ + +**NCO Mixer Modes:** + +- 0: Variable IF Mode (AD9081_ADC_NCO_VIF) +- 1: Zero IF Mode (AD9081_ADC_NCO_ZIF) +- 2: Fs/4 Hz IF Mode (AD9081_ADC_NCO_FS_4_IF) +- 3: Test Mode (AD9081_ADC_NCO_TEST) + +Channelizer Paths (adi,channelizer-paths) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Contains configuration for up to 8 channels (channel@0 through channel@7). + +Per-Channel Properties (channel@N) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++--------------------------------+------+-------------+-----------------------------------+ +| Property | Type | Range | Description | ++================================+======+=============+===================================+ +| ``reg`` | u32 | 0-7 | Channelizer index | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,decimation`` | u32 | 1,2,3,4,6,8 | Decimation factor | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,gain`` | u32 | 0-4095 | Channel gain (12-bit) | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,nco-frequency-shift-hz`` | i64 | - | NCO frequency shift | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,nco-phase-offset`` | u32 | 0-65535 | NCO phase offset | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,6db-gain-enable`` | u32 | 0,1 | Enable 6dB gain | ++--------------------------------+------+-------------+-----------------------------------+ +| ``adi,complex-to-real-enable`` | u32 | 0,1 | Enable complex-to-real conversion | ++--------------------------------+------+-------------+-----------------------------------+ + +JESD Links (adi,jesd-links) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +RX JESD links follow the same structure as TX links with additional: + ++--------------------------+---------------+--------------------------------------------------+ +| Property | Type | Description | ++==========================+===============+==================================================+ +| ``adi,converter-select`` | phandle-array | References to converters with FDDC_I/Q selection | ++--------------------------+---------------+--------------------------------------------------+ + +Header File Constants +--------------------- + +Include the header file for PA protection trigger constants: + +.. code:: c + + #include + +PA Protection Rotation Mode Flags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``AD9081_PA_ROTATION_JESD_AUTO`` - Enable JESD auto off/on during rotation +- ``AD9081_PA_ROTATION_DATAPATH_AUTO`` - Enable datapath auto soft off/on during rotation + +PA Protection Soft-Off Triggers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``AD9081_PA_SOFT_OFF_SPI`` - Trigger via SPI command +- ``AD9081_PA_SOFT_OFF_TXEN`` - Trigger via TXEN pin +- ``AD9081_PA_SOFT_OFF_JESD_ERR`` - Trigger on JESD error +- Additional triggers available in header file + +PA Protection Soft-On Triggers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``AD9081_PA_SOFT_ON_SPI`` - Trigger via SPI command +- ``AD9081_PA_SOFT_ON_TXEN`` - Trigger via TXEN pin +- Additional triggers available in header file + +NCO Mixer Modes (ADC) +~~~~~~~~~~~~~~~~~~~~~ + +- ``AD9081_ADC_NCO_VIF`` - Variable IF Mode +- ``AD9081_ADC_NCO_ZIF`` - Zero IF Mode +- ``AD9081_ADC_NCO_FS_4_IF`` - Fs/4 Hz IF Mode +- ``AD9081_ADC_NCO_TEST`` - Test Mode + +Notes +----- + +- **64-bit Values**: Properties exceeding 4GHz require ``/bits/ 64`` prefix +- **Negative Frequencies**: NCO frequency shifts can be negative (use parentheses in DTS) +- **PA Protection**: When using PA protection features, ensure all required properties for enabled features are specified +- **Phandle References**: Use for linking DACs to channelizers and ADCs to channelizers + +Device Tree Example +------------------- + +.. code:: dts + + #include + #include + + &spi { + trx0_ad9081: ad9081@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "adi,ad9081"; + reg = <0>; + spi-max-frequency = <5000000>; + + /* Clocks */ + clocks = <&hmc7044 2>; + clock-names = "dev_clk"; + + clock-output-names = "rx_sampl_clk", "tx_sampl_clk"; + #clock-cells = <1>; + + jesd204-device; + #jesd204-cells = <2>; + jesd204-top-device = <0>; /* This is the TOP device */ + jesd204-link-ids = ; + + jesd204-inputs = + <&axi_ad9081_core_rx 0 FRAMER_LINK0_RX>, + <&axi_ad9081_core_tx 0 DEFRAMER_LINK0_TX>; + + adi,tx-dacs { + #size-cells = <0>; + #address-cells = <1>; + + adi,dac-frequency-hz = /bits/ 64 <6200000000>; + + adi,main-data-paths { + #address-cells = <1>; + #size-cells = <0>; + + adi,interpolation = <2>; + + ad9081_dac0: dac@0 { + reg = <0>; + adi,crossbar-select = <&ad9081_tx_fddc_chan0>; + adi,nco-frequency-shift-hz = /bits/ 64 <100000000>; /* 100 MHz */ + }; + ad9081_dac1: dac@1 { + reg = <1>; + adi,crossbar-select = <&ad9081_tx_fddc_chan1>; + adi,nco-frequency-shift-hz = /bits/ 64 <200000000>; /* 200 MHz */ + }; + ad9081_dac2: dac@2 { + reg = <2>; + adi,crossbar-select = <&ad9081_tx_fddc_chan0>, <&ad9081_tx_fddc_chan1>; /* All 4 channels @ dac2 */ + adi,nco-frequency-shift-hz = /bits/ 64 <300000000>; /* 300 MHz */ + }; + ad9081_dac3: dac@3 { + reg = <3>; + adi,crossbar-select = <&ad9081_tx_fddc_chan0>, <&ad9081_tx_fddc_chan1>; /* All 4 channels @ dac2 */ + adi,nco-frequency-shift-hz = /bits/ 64 <400000000>; /* 400 MHz */ + }; + }; + + adi,channelizer-paths { + #address-cells = <1>; + #size-cells = <0>; + adi,interpolation = <2>; + + ad9081_tx_fddc_chan0: channel@0 { + reg = <0>; + adi,gain = <0>; + adi,nco-frequency-shift-hz = /bits/ 64 <50000000>; + + }; + ad9081_tx_fddc_chan1: channel@1 { + reg = <1>; + adi,gain = <0>; + adi,nco-frequency-shift-hz = /bits/ 64 <100000000>; + + }; + }; + + adi,jesd-links { + #size-cells = <0>; + #address-cells = <1>; + + ad9081_tx_jesd_l0: link@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + adi,converter-select = <&ad9081_tx_fddc_chan0 0>, <&ad9081_tx_fddc_chan0 1>, /* FIXME not supported */ + <&ad9081_tx_fddc_chan1 0>, <&ad9081_tx_fddc_chan1 1>; + adi,logical-lane-mapping = /bits/ 8 <0 1 2 3 4 5 6 7>; + + adi,link-mode = <17>; /* JESD Quick Configuration Mode */ + adi,subclass = <1>; /* JESD SUBCLASS 0,1,2 */ + adi,version = <1>; /* JESD VERSION 0=204A,1=204B,2=204C */ + adi,dual-link = <0>; /* JESD Dual Link Mode */ + + adi,converters-per-device = <4>; /* JESD M */ + adi,octets-per-frame = <1>; /* JESD F */ + + adi,frames-per-multiframe = <32>; /* JESD K */ + adi,converter-resolution = <16>; /* JESD N */ + adi,bits-per-sample = <16>; /* JESD NP' */ + adi,control-bits-per-sample = <0>; /* JESD CS */ + adi,lanes-per-device = <8>; /* JESD L */ + adi,samples-per-converter-per-frame = <1>; /* JESD S */ + adi,high-density = <0>; /* JESD HD */ + }; + }; + }; + + adi,rx-adcs { + #size-cells = <0>; + #address-cells = <1>; + + adi,adc-frequency-hz = /bits/ 64 <3100000000>; + + adi,main-data-paths { + #address-cells = <1>; + #size-cells = <0>; + + ad9081_adc0: adc@0 { + reg = <0>; + adi,decimation = <2>; + adi,nco-frequency-shift-hz = /bits/ 64 <70000000>; + //adi,crossbar-select = <&ad9081_rx_fddc_chan0>, <&ad9081_rx_fddc_chan2>; /* Static for now */ + }; + ad9081_adc1: adc@1 { + reg = <1>; + adi,decimation = <2>; + adi,nco-frequency-shift-hz = /bits/ 64 <150000000>; + //adi,crossbar-select = <&ad9081_rx_fddc_chan1>, <&ad9081_rx_fddc_chan3>; /* Static for now */ + }; + }; + + adi,channelizer-paths { + #address-cells = <1>; + #size-cells = <0>; + + ad9081_rx_fddc_chan0: channel@0 { + reg = <0>; + adi,decimation = <1>; + adi,gain = <0>; + adi,nco-frequency-shift-hz = /bits/ 64 <30000000>; + + }; + ad9081_rx_fddc_chan1: channel@1 { + reg = <1>; + adi,decimation = <1>; + adi,gain = <0>; + adi,nco-frequency-shift-hz = /bits/ 64 <60000000>; + + }; + }; + + adi,jesd-links { + #size-cells = <0>; + #address-cells = <1>; + + ad9081_rx_jesd_l0: link@0 { + reg = <0>; + adi,converter-select = <&ad9081_rx_fddc_chan0 0>, <&ad9081_rx_fddc_chan0 1>, + <&ad9081_rx_fddc_chan1 0>, <&ad9081_rx_fddc_chan1 1>; + adi,logical-lane-mapping = /bits/ 8 <0 1 2 3 4 5 6 7>; + + adi,link-mode = <18>; /* JESD Quick Configuration Mode */ + adi,subclass = <1>; /* JESD SUBCLASS 0,1,2 */ + adi,version = <1>; /* JESD VERSION 0=204A,1=204B,2=204C */ + adi,dual-link = <0>; /* JESD Dual Link Mode */ + + adi,converters-per-device = <4>; /* JESD M */ + adi,octets-per-frame = <1>; /* JESD F */ + + adi,frames-per-multiframe = <32>; /* JESD K */ + adi,converter-resolution = <16>; /* JESD N */ + adi,bits-per-sample = <16>; /* JESD NP' */ + adi,control-bits-per-sample = <0>; /* JESD CS */ + adi,lanes-per-device = <8>; /* JESD L */ + adi,samples-per-converter-per-frame = <1>; /* JESD S */ + adi,high-density = <0>; /* JESD HD */ + }; + }; + }; + }; + }; + +General IIO and driver conventions +================================== + +Controlling the MxFE is done via the IIO sysfs interface. For convenience users can use `libiio `_ and its various programming langue bindings. The MxFE IIO device under /sys/bus/iio/devices/iio:deviceX features a set of channels and device attributes, which are explained here. Some basic, but important concepts are explained in the bullet list below: + +- Channels prefixed with ``in_voltageX`` apply to Receive (RX) ADC data paths. +- Channels prefixed with ``out_voltageX`` apply to Transmit (TX) DAC data paths. +- Each channel has a complex modifier ``in_voltageX_i`` and ``in_voltageX_q`` or ``out_voltageX_i`` and ``out_voltageX_q``. Controlling a channel attribute for the ``i`` modified channel will simultaneously control the ``q`` modified channel and vice versa. So, writing/reading only needs to happen once, since they are mirrored. The complex IQ modifiers are only important for the data buffers, sine I & Q are individual data components. +- IIO channels ``[in|out]_voltageX``\ apply to the channelizer data paths (Fine DDC/DUC). + + - Each IIO channel has some ``[in|out]_voltageX_[i|q]_channel_[attributes]`` + - In case the channelizer data paths (Fine DDC/DUC) are bypassed + (decimation=1 or interpolation=1), the X still applies to a data path. + + - On the RX side: The **adi,converter-select** property is used to connect **adi,channelizer-paths**, where the **reg = ** property value defines the X in the IIO channel name. + - On the TX side: The **adi,maindp-dac-1x-non1x-crossbar-select = ** property within adi,main-data-paths dac@Y takes the data path number (DC_DP_X) as argument (x). So setting it to 0 on the DAC node for DAC1 will instruct the XBAR to route the very first data path to the CDUC1 which by default routes to DAC1. In case this property is not present, the default mapping CDUC0->DAC0, CDUC1->DAC1, … will be used. + +- Each channelizer data path (FDDC, FDUC) connects at least to one Coarse DDC/DUC (CDDC/CDUC), which maps then to one or more ADCs/DACs depending on configuration. These are called main data paths and are controlled via the ``[in|out]_voltageX_[i|q]_main_[attributes]`` attributes. + + - Be aware, since multiple channels can map to the same main data path (CDDC/CDUC), changing a main attribute of one channel will also update same attribute of any other channel that maps to the same main data path (CDDC/CDUC). + - The crossbar mapping between Fine and Coarse Digital Up/Down Converters, + ADCs/DACs is defined in the device tree. + +- Device attributes (without ``in_voltageX``\ or ``out_voltageX`` prefix) apply to the entire device. + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root:/> cd /sys/bus/iio/devices/ + root:/sys/bus/iio/devices> ls + iio:device0 iio:device3 iio:device2 + + root:/sys/bus/iio/devices> cd iio:device2 + + root@analog:/sys/bus/iio/devices/iio:device2# ls -al + total 0 + drwxr-xr-x 5 root root 0 Mar 28 12:44 . + drwxr-xr-x 5 root root 0 Mar 28 12:44 .. + -rw-r--r-- 1 root root 4096 Mar 28 12:44 adc_clk_powerdown + drwxr-xr-x 2 root root 0 Mar 28 12:44 buffer + -r--r--r-- 1 root root 4096 Mar 28 12:44 dev + --w------- 1 root root 4096 Mar 28 12:44 filter_fir_config + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_temp0_input + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_temp0_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_i_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage0_q_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_i_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage1_q_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_i_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage2_q_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_i_nyquist_zone + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_channel_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_channel_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_channel_nco_phase + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_6db_digital_gain_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_ffh_trig_hop_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage3_q_nyquist_zone + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_adc_frequency + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_main_ffh_mode_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_main_nco_frequency_available + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_nyquist_zone_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_sampling_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_test_mode + -r--r--r-- 1 root root 4096 Mar 28 12:44 in_voltage_test_mode_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 jesd204_fsm_ctrl + -r--r--r-- 1 root root 4096 Mar 28 12:44 jesd204_fsm_error + -r--r--r-- 1 root root 4096 Mar 28 12:44 jesd204_fsm_paused + --w------- 1 root root 4096 Mar 28 12:44 jesd204_fsm_resume + -r--r--r-- 1 root root 4096 Mar 28 12:44 jesd204_fsm_state + -rw-r--r-- 1 root root 4096 Mar 28 12:44 loopback_mode + -r--r--r-- 1 root root 4096 Mar 28 12:44 loopback_mode_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 multichip_sync + -r--r--r-- 1 root root 4096 Mar 28 12:44 name + lrwxrwxrwx 1 root root 0 Mar 28 12:44 of_node -> ../../../../../firmware/devicetree/base/fpga-axi@0/axi-ad9081-rx-hpc@84a10000 + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_i_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage0_q_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_i_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage1_q_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_i_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage2_q_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_i_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_channel_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_channel_nco_gain_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_channel_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_channel_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_channel_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_label + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_ffh_mode + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_ffh_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_ffh_index + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_ffh_select + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_phase + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_test_tone_en + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage3_q_main_nco_test_tone_scale + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_channel_nco_frequency_available + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_dac_frequency + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_main_ffh_gpio_mode_en + -r--r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_main_ffh_mode_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_main_nco_frequency_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 out_voltage_sampling_frequency + drwxr-xr-x 2 root root 0 Mar 28 12:44 power + -rw-r--r-- 1 root root 4096 Mar 28 12:44 powerdown + drwxr-xr-x 2 root root 0 Mar 28 12:44 scan_elements + lrwxrwxrwx 1 root root 0 Mar 28 12:44 subsystem -> ../../../../../bus/iio + -rw-r--r-- 1 root root 4096 Mar 28 12:44 sync_start_enable + -r--r--r-- 1 root root 4096 Mar 28 12:44 sync_start_enable_available + -rw-r--r-- 1 root root 4096 Mar 28 12:44 uevent + + +Show device name +---------------- + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat name + axi-ad9081-rx-hpc + + +ADC Rate +-------- + +**What:** ``in_voltage_adc_frequency`` + +Read only attribute which returns the RX ADC rate Hz. + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat in_voltage_adc_frequency + 4000000000 + + +RX Sample Rate +-------------- + +**What:** ``in_voltage_sampling_frequency`` + +Read only attribute which returns the RX digital IQ base-band rate in Hz. This +must not be confused with the ADC rate, which is (MAIN_decimation \* +CHANNEL_decimation) time higher. MAIN_decimation, CHANNEL_decimation are defined +in the device tree. + +in_voltage_sampling_frequency = in_voltage_adc_frequency / (MAIN_decimation \* +CHANNEL_decimation) + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat in_voltage_sampling_frequency + 250000000 + + +DAC Rate +-------- + +**What:** ``out_voltage_dac_frequency`` + +Read only attribute which returns the TX DAC rate Hz. + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat out_voltage_dac_frequency + 12000000000 + + +TX Sample Rate +-------------- + +**What:** ``out_voltage_sampling_frequency`` + +Read only attribute which returns the TX digital IQ base-band rate in Hz. This +must not be confused with the DAC rate, which is (MAIN_interpolation \* +CHANNEL_interpolation) time higher. MAIN_interpolation, CHANNEL_interpolation +are defined in the device tree. + +out_voltage_sampling_frequency = fDAC / (MAIN_interpolation \* +CHANNEL_interpolation) + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat out_voltage_sampling_frequency + 250000000 + + +ADC Nyquist Zone Control +------------------------ + +**What:** ``in_voltageX_nyquist_zone`` **What:** ``in_voltage_nyquist_zone_available`` + +Calibration is used to reduce residual spurious artifacts that are common among +interleaving ADC architectures because of sub ADC timing, gain, and offsets +mismatches. The ADCs are initially factory calibrated, and background +calibration is also employed to further improve and maintain the performance +across device operating conditions. + +One background calibration algorithm employed adjusts the interleaving timing +mismatches and depends on the knowledge of the Nyquist zone being odd or even, +which depends on the ADC input frequency (fIN), and sample rate (fADC), as +defined in the following equation: + +Nyquist Zone = ROUNDDOWN × (fIN/(fADC/2)) + 1 (Please see: Calibration and +Specifying Nyquist Zone in UG-1578) + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-drivers/iio-mxfe/ad908x_nyquist_zones.png + :align: center + :width: 400 + +The current Nyquist Zone can be queried and controlled via the ``in_voltage_nyquist_zone`` attribute. + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:device2> cat in_voltage_nyquist_zone_available + odd even + root:/sys/bus/iio/devices/iio:device2> echo even > cat in_voltage0_i_nyquist_zone + root:/sys/bus/iio/devices/iio:device2> cat cat in_voltage0_i_nyquist_zone + even + + +NCO Frequency Control +--------------------- + +Main Data Path +~~~~~~~~~~~~~~ + +**What:** ``[in|out]_voltageX_[i|q]_main_nco_frequency`` + +Sets the main data path (CDDC/CDUC) NCO frequency (fCARRIER) in Hz + +**out_voltageX_i_main_nco_frequency Range is:** −fDAC/2 ≤ fCARRIER < +fDAC/2 **in_voltageX_i_main_nco_frequency Range is:** −fADC/2 ≤ fCARRIER < +fADC/2 + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 1000000000 > out_voltage0_i_main_nco_frequency + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_main_nco_frequency + 1000000000 + + root@analog:/sys/bus/iio/devices/iio:device2# echo 300000000 > in_voltage0_i_main_nco_frequency + root@analog:/sys/bus/iio/devices/iio:device2# cat in_voltage0_i_main_nco_frequency + 300000000 + + +Channel Data Path +~~~~~~~~~~~~~~~~~ + +**What:** ``[in|out]_voltageX_[i|q]_channel_nco_frequency`` + +Sets the channel data path (FDDC/FDUC) NCO frequency (fCARRIER) in Hz + +**out_voltageX_i_channel_nco_frequency Range is:** −(fDAC/MAIN_interpolation)/2 ≤ fCARRIER < +(fDAC/MAIN_interpolation)/2 **in_voltageX_i_channel_nco_frequency Range is:** −(fADC/MAIN_decimation)/2 ≤ fCARRIER < +(fADC/MAIN_decimation)/2 + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 1000000000 > out_voltage0_i_channel_nco_frequency + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_channel_nco_frequency + 1000000000 + + root@analog:/sys/bus/iio/devices/iio:device2# echo 300000000 > out_voltage0_i_channel_nco_frequency + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_channel_nco_frequency + 300000000 + + +NCO Phase Control +----------------- + +Main Data Path +~~~~~~~~~~~~~~ + +**What:** ``[in|out]_voltageX_[i|q]_main_nco_phase`` + +Sets the main data path (CDDC/CDUC) NCO phase offset in milli degrees + +**Range is**: −180° ≤ Degrees Offset ≤ +180° (Values are in milli degrees.) + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 66000 > out_voltage0_i_main_nco_phase + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_main_nco_phase + 66000 + + root@analog:/sys/bus/iio/devices/iio:device2# echo -42000 > in_voltage0_i_main_nco_phase + root@analog:/sys/bus/iio/devices/iio:device2# cat in_voltage0_i_main_nco_phase + -42000 + + +Channel Data Path +~~~~~~~~~~~~~~~~~ + +**What:** ``[in|out]_voltageX_[i|q]_channel_nco_phase`` + +Sets the channel data path (FDDC/FDUC) NCO phase offset in milli degrees + +**Range is**: −180° ≤ Degrees Offset ≤ +180° (Values are in milli degrees.) + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 13123 > out_voltage0_i_channel_nco_phase + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_channel_nco_phase + 13123 + + root@analog:/sys/bus/iio/devices/iio:device2# echo 13123 > out_voltage0_i_channel_nco_phase + root@analog:/sys/bus/iio/devices/iio:device2# cat out_voltage0_i_channel_nco_phase + 13123 + + +TX NCO Channel Digital Gain +--------------------------- + +**What:** ``out_voltageX_[i|q]_channel_nco_gain_scale`` + +The input data into each channelizer stage can be rescaled prior to additional processing. This feature is useful in multiband applications to prevent digital clipping when the outputs of two or more channelizer stages are summed in the main datapath to produce a multiband band signal. The gain/scale is set via ``out_voltageX_[i|q]_channel_nco_gain_scale`` attribute. + +**Range is**: 0 ≤ Gain ≤ 1.999 (−∞ dB < dBGain ≤ +6.018 dB) + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 0.707 > out_voltage0_i_channel_nco_gain_scale + + +TX NCO Test Tone Modes +---------------------- + +**What:** ``out_voltageX_[i|q]_[channel|main]_nco_test_tone_en`` **What:** ``out_voltageX_[i|q]_[channel|main]_nco_test_tone_scale`` + +The Test Tone Mode can be enabled using the ``out_voltageX_[i|q]_[channel|main]_nco_test_tone_en`` attributes in order to provide a complex, single-tone output. The tone is generated using a programmable internal dc amplitude level that is injected into the complex modulator input to generate an unmodulated single tone. The dc amplitude level is controlled by the ``out_voltageX_[i|q]_[channel|main]_nco_test_tone_scale`` attributes which corresponds to a full-scale tone. + +**Range is**: 0 ≤ Scale ≤ 0.9999. + +Please see also `NCO Frequency Control `_ section. + +The ``out_voltageX_[i|q]_channel_nco_test_tone_en`` mode is most useful for applications that require multiple single-tone signals of varying frequency and amplitude, while applications that only require a single tone can use the same feature available on the main datapath NCOs. ``out_voltageX_[i|q]_main_nco_test_tone_en`` + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 0.25 > out_voltage0_i_channel_nco_test_tone_scale + root@analog:/sys/bus/iio/devices/iio:device2# echo 1 > out_voltage0_i_channel_nco_test_tone_en + + +Fast Frequency Hopping Control +------------------------------ + +The complex NCOs used in both the transmit and receive datapaths support FFH +mode. In the transmit datapath, each main datapath NCO consists of a bank of 31 +NCOs. In the receive main and channelizer datapaths, each NCO consists of a bank +of 16 NCOs. The transmit and receive hop sequence can be independently +controlled via GPIOx pins or the SPI register (IIO sysfs attributes). +Asynchronous trigger hop mode is an additional mode only supported on the +receive path. + +Transmit Main Path FFH NCO Mode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**What:** ``out_voltageX_[i|q]_main_nco_ffh_frequency`` **What:** ``out_voltageX_[i|q]_main_nco_ffh_index`` **What:** ``out_voltageX_[i|q]_main_nco_ffh_select`` **What:** ``out_voltageX_[i|q]_main_ffh_mode`` **What:** ``out_voltage_main_ffh_gpio_mode_en`` + +The FFH NCO associated with each main datapath is implemented with 31 additional 32-bit NCOs. Each NCO can be configured with a unique frequency tuning word FTWx where x is a value between 0 and 30. These FTWs can be preloaded into the hopping frequency register bank using the ``out_voltageX_[i|q]_main_nco_ffh_index`` and ``out_voltageX_[i|q]_main_nco_ffh_frequency`` attributes. + +The user first addresses hopping frequency register bank by setting its index using ``out_voltageX_[i|q]_main_nco_ffh_index``, followed by setting the frequency using ``out_voltageX_[i|q]_main_nco_ffh_frequency``. The user repeats these steps until all required FTWs are programmed. Once this is done, the pre-configured FTW can be called via the channels ``out_voltageX_[i|q]_main_nco_ffh_select`` attribute, which accepts values between 0..30. Alternatively GPIO based hopping can be enabled using the ``out_voltage_main_ffh_gpio_mode_en`` attribute. The hop transition mode of NCOs can be controlled using the ``out_voltageX_[i|q]_main_ffh_mode`` attribute. Allowed options are phase_continuous, phase_incontinuous, and phase_coherent. + +Receive Main Path FFH NCO Mode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**What:** ``in_voltageX_[i|q]_main_nco_frequency`` **What:** ``in_voltageX_[i|q]_main_nco_phase`` **What:** ``in_voltageX_[i|q]_main_nco_ffh_index`` **What:** ``in_voltageX_[i|q]_main_nco_ffh_select`` **What:** ``in_voltageX_[i|q]_main_ffh_mode`` **What:** ``in_voltageX_[i|q]_main_ffh_trig_hop_en`` **What:** ``in_voltageX_[i|q]_main_ffh_gpio_mode_en`` + +Each main data path (CDDC) NCO contains 16 channel registers sets, that can be programmed with unique Frequency (PIW) and Phase (POW) settings. The user sets the channel index using ``in_voltageX_[i|q]_main_nco_ffh_index``, followed by setting the frequency and phase using ``in_voltageX_[i|q]_main_nco_frequency`` and ``in_voltageX_[i|q]_main_nco_phase``. The index attribute accepts values between 0 and 15. The user repeats these steps until all required FTWs are programmed. Once this is done, the pre-configured NCO can be selected via the channels ``in_voltageX_[i|q]_main_nco_ffh_select`` select attribute, which also accepts values between 0..15. Alternatively, GPIO based hopping can be configured using the ``in_voltageX_[i|q]_main_ffh_mode`` attribute. The ``in_voltageX_[i|q]_main_ffh_mode`` attribute options are instantaneous_update, synchronous_update_by_transfer_bit and synchronous_update_by_gpio. Using ``in_voltageX_[i|q]_main_ffh_gpio_mode_en`` the GPIO controlled mode is enabled, the mode switches between the mode set in the devicetree using ``adi,nco-channel-select-mode`` and software/SPI control using ``in_voltageX_[i|q]_main_nco_ffh_select``. + +Programmable FIR Filter +----------------------- + +What: ``filter_fir_config`` + +Both the AD9081 and AD9082 provide a hardware FIR filter that can be programmed +with up to 192 taps, and runs at the full converter rate of 4 or 6 GS/s +respectively. Typical usecases of this filter include, but are not limited to: + +- Equalization of analog impairments +- Channel-to-channel crosstalk correction +- Equalization with crosstalk correction +- Quadrature error correction + +The full capabilities and supported operational modes are described on page 138 and onwards of the :adi:`AD9081/AD9082 User Guide (Rev. PrC) ` + +Filter configurations can be written as follows: + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# cat /root/pfilt.cfg > filter_fir_config + + +Configuration File Format +~~~~~~~~~~~~~~~~~~~~~~~~~ + +A filter configuration file is an ASCII textfile with LF line-endings, and +supports the following directives: + +- All lines starting with a ``#`` symbol are skipped / treated as comments. Note, the ``#`` has to be the **first** character of a line. +- Filter mode + + - The filter mode determines the filter architecture, for more information about these see the user guide. + - Syntax: ``mode: ``, where supported values of ``I_MODE`` and ``Q_MODE`` are: ``disabled``, ``real_n4``, ``real_n2``, ``matrix``, ``complex_full``, ``complex_half``, ``real_n``. + +- Filter gain + + - The digital gain can be used to compensate coefficient gain/losses + - Syntax: ``gain: ``, where the filter gain values ``S[abcd]`` must be ``-12``, ``-6``, ``0``, ``6`` or ``12`` (Unit is dB). + + - Note: All values are required, even if only one is actually used! + +- Destination + + - The destination directive controls which ADC pair and page these values are applied to. Pages can be used to store multiple sets of coefficients and rapidly switch between them using gpios. + - Syntax: ``dest: `` + + - ``ADC_PAIR`` must be either ``adc_pair_0``, ``adc_pair_1`` or ``adc_pair_all`` + - ``PAGES`` must be either ``page_0``, ``page_1``, ``page_2``, ``page_3`` or ``page_all`` + +- Delay + + - This setting is used for filter delay compensation in half complex mode and quadrature error correction / image rejection respectively. + - Syntax: ``delay: `` + + - ``HALF_COMPLEX_DELAY``: Integer in [0, 255] (Unit is samples) + - ``IMAGE_CANCEL_DELAY``: Integer in [0, 127] (Unit is samples) + +- Filter coefficients + + - Lines containing filter coefficients are not prefixed, and should either contain two or four 16-bit integers in decimal notation, where four values are required when ``I_MODE == matrix``. + +The parser can be found here: `ad9081_parse_fir `_ + +Examples +^^^^^^^^ + +The iio-oscilloscope project provides some samples which can be used as a +reference: + +- :git-iio-oscilloscope:`filters/ad9081/ad9081_pfir_OFF.cfg` +- :git-iio-oscilloscope:`filters/ad9081/ad9081_pfir_DualReal.cfg` +- :git-iio-oscilloscope:`filters/ad9081/ad9081_pfir_SingleInphase.cfg` +- :git-iio-oscilloscope:`filters/ad9081/ad9081_pfir_Matrix.cfg` +- :git-iio-oscilloscope:`filters/ad9081/ad9081_pfir_FullComplex.cfg` + +Loopback Modes +-------------- + +The AD9081/AD9082 supports two methods to loopback the samples from the receive +(ADC) path to the transmit (DAC) path. + +JESD Loopback RX->TX +~~~~~~~~~~~~~~~~~~~~ + +**What:** ``loopback_mode`` + +The **indirect loopback** path loops the ADC outputs through the receive and transmit datapaths to take advantage of the signal processing capability. The data loopback occurs between the lane FIFO blocks of the JESD204B/C transmitter and JESD204B/C receiver. For this mode to function correctly the JESD configuration between RX and TX must be identical and only use a single link.The physical to logical lane mapping for both links must also match. + +The **direct loopback** path loops the ADC output data directly back into a specified DAC without any signal processing, which provides the shortest path latency but no ability to delay or modify the received signal before re-transmitting through the DAC cores. For this mode to function correctly the ADC and DAC rates must match. + ++-------+--------------------------------------------------------------------------------------+ +| Mode | Function | ++=======+======================================================================================+ +| ``0`` | Looback mode is disabled | ++-------+--------------------------------------------------------------------------------------+ +| ``1`` | Indirect Loopback enabled | ++-------+--------------------------------------------------------------------------------------+ +| ``2`` | Direct Loopback enabled | ++-------+--------------------------------------------------------------------------------------+ +| ``3`` | Direct Loopback enabled with control of ADC data overflow before looping back to DAC | ++-------+--------------------------------------------------------------------------------------+ + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# echo 1 > loopback_mode + + +On-Die Temperature Reading +-------------------------- + +**What:** ``in_temp0_input`` + +The device contains a Temperature Monitoring Unit (TMU) that functions as a digital thermometer. The TMU is comprised of four sensors placed at different chip locations. The on-die temperature value is measured and digitized through an ADC. At any given time, the temperature in signed milli-degrees Celsius, from the sensor with the **highest** temperature can be read from the ``in_temp0_input`` attribute. + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/bus/iio/devices/iio:device2# cat in_temp0_input + 86120 + + +Low level debug functions via debugfs +===================================== + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# ls -al + total 0 + drwxr-xr-x 2 root root 0 Jan 1 1970 . + drwxr-xr-x 5 root root 0 Jan 1 1970 .. + -rw-r--r-- 1 root root 0 Jan 1 1970 bist_prbs_error_counters_jrx + -rw-r--r-- 1 root root 0 Jan 1 1970 bist_prbs_select_jrx + -rw-r--r-- 1 root root 0 Jan 1 1970 bist_prbs_select_jtx + -rw-r--r-- 1 root root 0 Jan 1 1970 bist_spo_set_jrx + -rw-r--r-- 1 root root 0 Jan 1 1970 bist_spo_sweep_jrx + -rw------- 1 root root 0 Jan 1 1970 dac-full-scale-current-ua + -rw-r--r-- 1 root root 0 Feb 6 18:18 direct_reg_access + -rw-r--r-- 1 root root 0 Jan 1 1970 pseudorandom_err_check + -r--r--r-- 1 root root 0 Jan 1 1970 status + +JESD Link Status +---------------- + +Reading ``status`` returns a status string. + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# cat status + **JESD TX (JRX) Link1 0xF lanes in DATA + JESD TX (JRX) Link1 TPL Phase Difference Read 0, Set 3 + JESD RX (JTX) Link1 in DATA, SYNC deasserted, PLL locked, PHASE established, MODE valid** + root@analog:/sys/kernel/debug/iio/iio:device2# + + +dac-full-scale-current-ua +------------------------- + +Writing ``dac-full-scale-current-ua`` controls the DAC full scale current in uA. Recommended range is 7000...40000 (7mA - 40mA) + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# echo 40000 > dac-full-scale-current-ua + root@analog:/sys/kernel/debug/iio/iio:device2# + + +bist_prbs_select_jrx +-------------------- + +Writing ``bist_prbs_select_jrx`` selects the `PRBS `_ type. (accepted values depend on the GT architecture). Reading returns the selected type. + +.. tip:: + + When testing this feature make sure `axi_adxcvr-tx prbs_select `_ is configured with a matching PRBS. + +===== ============ +Value Comment +===== ============ +0 PRBS_DISABLE +7 PRBS7 +9 PRBS9 +15 PRBS15 +31 PRBS31 +===== ============ + +:: + + + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# echo 15 1 > bist_prbs_select_jrx + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_prbs_select_jrx + 15 + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_prbs_error_counters_jrx + 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 + + +bist_prbs_error_counters_jrx +---------------------------- + +Reading ``bist_prbs_error_counters_jrx`` returns the PRBS error counters for all lanes. + ++-----------------+-----------------+-----------------+-----+-----------------+-----------------+-----------------+-----------------+-----+-----------------+ +| Link0 | | | | | [: Link1] | | | | | ++=================+=================+=================+=====+=================+=================+=================+=================+=====+=================+ +| Lane_0 | Lane_1 | Lane_2 | ... | Lane_L-1 | : Lane_0 | Lane_1 | Lane_2 | ... | Lane_L-1 | ++-----------------+-----------------+-----------------+-----+-----------------+-----------------+-----------------+-----------------+-----+-----------------+ +| / | / | / | ... | / | / | / | / | ... | / | ++-----------------+-----------------+-----------------+-----+-----------------+-----------------+-----------------+-----------------+-----+-----------------+ + +Format is: / + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_prbs_error_counters_jrx + 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 + + +bist_prbs_select_jtx +-------------------- + +Writing ``bist_prbs_select_jtx`` selects the `PRBS `_ type. (accepted values depend on the GT architecture). Reading returns the selected type. + +===== ============ +Value Comment +===== ============ +0 PRBS_DISABLE +7 PRBS7 +15 PRBS15 +31 PRBS31 +===== ============ + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# echo 31 > bist_prbs_select_jtx + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_prbs_select_jtx + 31 + + +bist_spo_sweep_jrx +------------------ + +Writing following 3 values to ``bist_spo_sweep_jrx`` performs a horizontal sweep of the “static phase offset” (SPO) codes and checking for PRBS errors as described in the JESD204B/C Receiver PHY PRBS Testing section of the User Guide. Reading ``bist_spo_sweep_jrx`` returns the good left and right SPO value. + +.. tip:: + + When testing this feature make sure `axi_adxcvr-tx prbs_select `_ is configured with a matching PRBS. + +===== ============ +Value PRBS type +===== ============ +0 PRBS_DISABLE +7 PRBS7 +9 PRBS9 +15 PRBS15 +31 PRBS31 +===== ============ + + + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# echo 0 15 1 > bist_spo_sweep_jrx + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_spo_sweep_jrx + l:18 r:20 + + +bist_spo_set_jrx +---------------- + +Writing ``bist_spo_set_jrx`` sets the SPO offset. Range depends on the deserializer mode. Reading returns the written value. This feature can be used to implement 2D eye scan externally. + +================= =========== ========= +Deserializer mode Lane rate SPO Range +================= =========== ========= +HALF_RATE 8...16 Gbps +/- 32 +QUART_RATE > 16 Gbps +/- 16 +================= =========== ========= + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device2# echo 2 > bist_spo_set_jrx + root@analog:/sys/kernel/debug/iio/iio:device2# cat bist_spo_set_jrx + 2 + + +bist_2d_eyescan_jrx +------------------- + +The device has built in comparator circuits that enables the ability to +reproduce an eye diagram estimate at the output of the CTLE circuit inside the +JESD204B/C receiver core. + +Writing ``bist_2d_eyescan_jrx`` selects the physical lane (0..7). In HALF_RATE mode two additional arguments are requires. (PRBS type and duration) Reading returns either error (-22) in case the Lane is not mapped, or CSV for SPO offset, good upper and lower voltages in mV. + ++-------------------+-------------+-----------+------------------------------------------------------------------+ +| Deserializer mode | Lane rate | SPO Range | bist_2d_eyescan_jrx arguments | ++===================+=============+===========+==================================================================+ +| HALF_RATE | 8...16 Gbps | +/- 32 | | ++-------------------+-------------+-----------+------------------------------------------------------------------+ +| QUART_RATE | > 16 Gbps | +/- 16 | | ++-------------------+-------------+-----------+------------------------------------------------------------------+ + +.. tip:: + + When using HALF_RATE mode make sure `axi_adxcvr-tx prbs_select `_ is configured with a matching PRBS. + +===== ============ +Value PRBS type +===== ============ +0 PRBS_DISABLE +7 PRBS7 +9 PRBS9 +15 PRBS15 +31 PRBS31 +===== ============ + +**Example:** + +.. container:: box bggreen + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:~# echo 7 > /sys/bus/platform/devices/84b60000.axi-adxcvr-tx/prbs_select + root@analog:~# iio_attr -D axi-ad9081-rx-hpc bist_2d_eyescan_jrx "1 7 10" + # lane 1 spo_steps 64 rate 10000000 + -1,204,-204 + -2,204,-204 + -3,204,-208 + -4,204,-204 + -5,204,-204 + -6,204,-204 + -7,200,-200 + -8,200,-200 + -9,196,-196 + -10,196,-192 + -11,188,-184 + -12,180,-180 + -13,172,-176 + -14,160,-164 + -15,152,-148 + [-snip-] + + +Example Eye Diagram Created from Half Rate Eye Scan Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Example from: `pyadi-iio `_ + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-drivers/iio-mxfe/screenshot_from_2024-01-19_14-15-55.png + :align: center + :width: 400 + +Low level register access via debugfs (direct_reg_access) +========================================================= + +This page contains a few lose documentation snippets used in various spots. + +IIO device files +================ + +Each and every IIO device, typically a hardware chip, has a device folder under +/sys/bus/iio/devices/iio:deviceX. Where X is the IIO index of the device. Under +every of these directory folders reside a set of files, depending on the +characteristics and features of the hardware device in question. These files are +consistently generalized and documented in the IIO ABI documentation. In order +to determine which IIO deviceX corresponds to which hardware device, the user +can read the name file /sys/bus/iio/devices/iio:deviceX/name. In case the +sequence in which the iio device drivers are loaded/registered is constant, the +numbering is constant and may be known in advance. + +IIO devices with trigger consumer interface +=========================================== + +If deviceX supports triggered sampling, it’s a so called trigger consumer and +there will be an additional folder /sys/bus/iio/device/iio:deviceX/trigger. In +this folder there is a file called current_trigger, allowing controlling and +viewing the current trigger source connected to deviceX. Available trigger +sources can be identified by reading the name file +/sys/bus/iio/devices/triggerY/name. The same trigger source can connect to +multiple devices, so a single trigger may initialize data capture or reading +from a number of sensors, converters, etc. + +.. hint:: + + Trigger Consumers: + + | Currently triggers are only used for the filling of software ring buffers and as such any device supporting INDIO_RING_TRIGGERED has the consumer interface automatically created. + +**Description:** Read name of triggerY + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/triggerY/> cat name + irqtrig56 + + +**Description:** Make irqtrig56 (trigger using system IRQ56, likely a GPIO IRQ), to current trigger of deviceX + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:deviceX/trigger> echo irqtrig56 > current_trigger + + +**Description:** Read current trigger source of deviceX + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + :: + + root:/sys/bus/iio/devices/iio:deviceX/trigger> cat current_trigger + irqtrig56 + + +Standalone trigger drivers +========================== + ++----------------------------------------------------------------------+-------------------------------------------------------------------------------+ +| name | description | ++======================================================================+===============================================================================+ +| iio-trig-gpio | Provides support for using GPIO pins as IIO triggers. | ++----------------------------------------------------------------------+-------------------------------------------------------------------------------+ +| iio-trig-rtc | Provides support for using periodic capable real time clocks as IIO triggers. | ++----------------------------------------------------------------------+-------------------------------------------------------------------------------+ +| `iio-trig-sysfs `_ | Provides support for using SYSFS entry as IIO triggers. | ++----------------------------------------------------------------------+-------------------------------------------------------------------------------+ +| `iio-trig-bfin-timer `_ | Provides support for using a Blackfin timer as IIO triggers. | ++----------------------------------------------------------------------+-------------------------------------------------------------------------------+ + +Buffer management +================= + +The Industrial I/O subsystem provides support for various ring buffer based data +acquisition methods. Apart from device specific hardware buffer support, the +user can chose between two different software ring buffer implementations. One +is the IIO lock free software ring, and the other is based on Linux kfifo. +Devices with buffer support feature an additional sub-folder in the +/sys/bus/iio/devices/deviceX/ folder hierarchy. Called deviceX:bufferY, where Y +defaults to 0, for devices with a single buffer. + +Every buffer implementation features a set of files: + +| **length** +| Get/set the number of sample sets that may be held by the buffer. + +| **enable** +| Enables/disables the buffer. This file should be written last, after length and selection of scan elements. + +| **watermark** +| A single positive integer specifying the maximum number of scan elements to wait for. Poll will block until the watermark is reached. Blocking read will wait until the minimum between the requested read amount or the low water mark is available. Non-blocking read will retrieve the available samples from the buffer even if there are less samples then watermark level. This allows the application to block on poll with a timeout and read the available samples after the timeout expires and thus have a maximum delay guarantee. + +| **data_available** +| A read-only value indicating the bytes of data available in the buffer. In the case of an output buffer, this indicates the amount of empty space available to write data to. In the case of an input buffer, this indicates the amount of data available for reading. + +| **length_align_bytes** +| Using the high-speed interface. DMA buffers may have an alignment requirement for the buffer length. Newer versions of the kernel will report the alignment requirements associated with a device through the \`length_align_bytes\` property. + +| **scan_elements** +| The scan_elements directory contains interfaces for elements that will be captured for a single triggered sample set in the buffer. + +Typical ADC scan elements +========================= + +| **in_voltageX_en / in_voltageX-voltageY_en / timestamp_en:** +| Scan element control for triggered data capture. Writing 1 will enable the scan element, writing 0 will disable it + +| **in_voltageX_type / in_voltageX-voltageY_type / timestamp_type:** +| Description of the scan element data storage within the buffer and therefore in the form in which it is read from user-space. Form is [s|u]bits/storage-bits. s or u specifies if signed (2's complement) or unsigned. bits is the number of bits of data and storage-bits is the space (after padding) that it occupies in the buffer. Note that some devices will have additional information in the unused bits so to get a clean value, the bits value must be used to mask the buffer output value appropriately. The storage-bits value also specifies the data alignment. So u12/16 will be a unsigned 12 bit integer stored in a 16 bit location aligned to a 16 bit boundary. For other storage combinations this attribute will be extended appropriately. + +| **in_voltageX_index / in_voltageX-voltageY_index / timestamp_index:** +| A single positive integer specifying the position of this scan element in the buffer. Note these are not dependent on what is enabled and may not be contiguous. Thus for user-space to establish the full layout these must be used in conjunction with all \_en attributes to establish which channels are present, and the relevant \_type attributes to establish the data storage format. + +Event Management +================ + +The Industrial I/O subsystem provides support for passing hardware generated +events up to userspace. + +In IIO events are not used for passing normal readings from the sensing devices +to userspace, but rather for out of band information. Normal data reaches +userspace through a low overhead character device - typically via either +software or hardware buffer. The stream format is pseudo fixed, so is described +and controlled via sysfs rather than adding headers to the data describing what +is in it. + +Pretty much all IIO events correspond to thresholds on some value derived from +one or more raw readings from the sensor. They are provided by the underlying +hardware. + +**Examples include:** + +- Straight crossing a voltage threshold +- Moving average crosses a threshold +- Motion detectors (lots of ways of doing this). +- Thresholds on sum squared or rms values. +- Rate of change thresholds. +- Lots more variants... + +Events have timestamps. + +**The Interface:** + +- Single user at a time. + +- Simple chrdev per device (aggregation across devices doesn't really make + sense for IIO as you tend to really care which sensor caused the event rather + than just that it happened.) + +**The format is:** + +.. code:: none + + /** + * struct iio_event_data - The actual event being pushed to userspace + * @id: event identifier + * @timestamp: best estimate of time of event occurrence (often from + * the interrupt handler) + */ + struct iio_event_data { + u64 id; + s64 timestamp; + }; + +Typical event attributes +======================== + +| **/sys/bus/iio/devices/iio:deviceX/events** +| Configuration of which hardware generated events are passed up to user-space. + +- **Threshold Events:** + +| **Z[\_name]_thresh[\_rising|falling]_en** +| Event generated when channel passes a threshold in the specified (\_rising|_falling) direction. If the direction is not specified, then either the device will report an event which ever direction a single threshold value is called in (e.g. [Z][\_name]\__thresh_value) or [Z][\_name]\__thresh_rising_value and [Z][\_name]\__thresh_falling_value may take different values, but the device can only enable both thresholds or neither. Note the driver will assume the last p events requested are to be enabled where p is however many it supports (which may vary depending on the exact set requested. So if you want to be sure you have set what you think you have, check the contents of these attributes after everything is configured. Drivers may have to buffer any parameters so that they are consistent when a given event type is enabled a future point (and not those for whatever event was previously enabled). + +| **Z[\_name]_thresh[\_rising|falling]_value** +| Specifies the value of threshold that the device is comparing against for the events enabled by Z[\_name]_thresh[\_rising|falling]_en. If separate attributes exist for the two directions, but direction is not specified for this attribute, then a single threshold value applies to both directions. The raw or input element of the name indicates whether the value is in raw device units or in processed units (as \_raw and \_input do on sysfs direct channel read attributes). + +- **Rate of Change Events:** + +| **[Z][\_name]_roc[\_rising|falling]_en** +| Event generated when channel passes a threshold on the rate of change (1st differential) in the specified (\_rising|_falling) direction. If the direction is not specified, then either the device will report an event which ever direction a single threshold value is called in (e.g. [Z][\_name]\__roc_value) or [Z][\_name]\__roc_rising_value and [Z][\_name]\__roc_falling_value may take different values, but the device can only enable both rate of change thresholds or neither. Note the driver will assume the last p events requested are to be enabled where p is however many it supports (which may vary depending on the exact set requested. So if you want to be sure you have set what you think you have, check the contents of these attributes after everything is configured. Drivers may have to buffer any parameters so that they are consistent when a given event type is enabled a future point (and not those for whatever event was previously enabled). + +| **[Z][\_name]_roc[\_rising|falling]_value** +| Specifies the value of rate of change threshold that the device is comparing against for the events enabled by [Z][\_name]_roc[\_rising|falling]_en. If separate attributes exist for the two directions, but direction is not specified for this attribute, then a single threshold value applies to both directions. The raw or input element of the name indicates whether the value is in raw device units or in processed units (as \_raw and \_input do on sysfs direct channel read attributes). + +- **Magnitude Events:** + +| **Z[\_name]_mag[\_rising|falling]_en** +| Similar to in_accel_x_thresh[\_rising|_falling]_en, but here the magnitude of the channel is compared to the threshold, not its signed value. + +| **Z[\_name]_mag[\_rising|falling]_value** +| The value to which the magnitude of the channel is compared. If number or direction is not specified, applies to all channels of this type. + +- **Temporal Conditions:** + +| **[Z][\_name][\_thresh|_roc][\_rising|falling]_period** +| Period of time (in seconds) for which the condition must be met before an event is generated. If direction is not specified then this period applies to both directions. + +Low level register access via debugfs (direct_reg_access) +========================================================= + +Some IIO drivers feature an optional debug facility, allowing users to read or +write registers directly. Special care needs to be taken when using this +feature, since you can modify registers on the back of the driver. + +.. tip:: + + To simplify direct register access you may want to use the libiio `iio_reg `_ command line utility. + +Accessing debugfs requires root privileges. + +In order to identify if the IIO device in question feature this option you first +need to identify the IIO device number. + +Therefore read the name attribute of each IIO device + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:~# grep "" /sys/bus/iio/devices/iio\:device*/name + /sys/bus/iio/devices/iio:device0/name:ad7291 + /sys/bus/iio/devices/iio:device1/name:ad9361-phy + /sys/bus/iio/devices/iio:device2/name:xadc + /sys/bus/iio/devices/iio:device3/name:adf4351-udc-rx-pmod + /sys/bus/iio/devices/iio:device4/name:adf4351-udc-tx-pmod + /sys/bus/iio/devices/iio:device5/name:cf-ad9361-dds-core-lpc + /sys/bus/iio/devices/iio:device6/name:cf-ad9361-lpc + root@analog:~# + + +Change directory to **/sys/kernel/debug**/iio/ iio:deviceX and check if the direct_reg_access file exists. + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:~# cd /sys/kernel/debug/iio/iio\:device1 + root@analog:/sys/kernel/debug/iio/iio:device1# ls direct_reg_access + direct_reg_access + + +**Reading** + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device1# echo 0x7 > direct_reg_access + root@analog:/sys/kernel/debug/iio/iio:device1# cat direct_reg_access + 0x40 + + +**Writing** + +Write ADDRESS VALUE + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device1# echo 0x7 0x50 > direct_reg_access + root@analog:/sys/kernel/debug/iio/iio:device1# cat direct_reg_access + 0x50 + + +**Accessing HDL CORE registers** + +| Special ADI device driver convention for devices that have both: +| \* a SPI/I2C control interface + +- and some sort of HDL Core with registers (AXI) + +In this case when accessing the HDL Core Registers always set BIT31. + +The register map for typical ADI HDL cores can be found here: `Register Map `_ + +.. container:: box bggreen + + + .. note:: + + This specifies any shell prompt running on the target + + + + +.. code-block:: none + + root@analog:/sys/kernel/debug/iio/iio:device6# echo 0x80000000 > direct_reg_access + root@analog:/sys/kernel/debug/iio/iio:device6# cat direct_reg_access + 0x80062 + + +IIO pointers +============ + +- IIO mailing list: linux-iio@vger.kernel.org +- `IIO Linux Kernel Documentation sysfs-bus-iio-\* `_ +- `IIO Documentation `_ +- `IIO test and visualization application `_ +- `libiio - IIO system library `_ +- `libiio - Internals `_ +- `Pointers and good books `_ +- `IIO High Speed `_ +- `Software Defined Radio using the IIO framework `_ +- + +|libiio introduction| + +*Need Help?* + +- :ez:`Analog Devices Linux Device Drivers Help Forum ` +- `Ask a Question `_ + +.. |libiio introduction| image:: https://wiki.analog.com/_media/software/linux/docs/iio/youtube>p_vntewue24 + +Special Access Modes +-------------------- + +2. Page Mask Register Access +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Condition:** ``reg & 0x40000000 == 0`` and ``reg & 0x3F000000 != 0`` This mode allows setting a page mask register before performing the actual register access. This is useful for accessing paged/banked registers where a page selection register must be configured first. + +**Register Parameter Encoding:** + +:: + + Bit 31-30 | Bit 29-24 | Bit 23-16 | Bit 15-14 | Bit 13-0 + ---------|--------------------|--------------------|----------|------------------ + unused | Page Mask Register | Page Mask Value | unused | Register Address + (0) | (0x3F) | (0xFF) | | (0x3FFF) + ++--------------------+---------+------------+---------------------------------------------------+ +| Field | Bits | Mask | Description | ++====================+=========+============+===================================================+ +| Page Mask Register | [29:24] | ``0x3F`` | 6-bit address of the page/mask selection register | ++--------------------+---------+------------+---------------------------------------------------+ +| Page Mask Value | [23:16] | ``0xFF`` | 8-bit value to write to the page mask register | ++--------------------+---------+------------+---------------------------------------------------+ +| Register Address | [13:0] | ``0x3FFF`` | 14-bit target register address | ++--------------------+---------+------------+---------------------------------------------------+ + +The function first writes the page mask value to the page mask register, then +performs the read/write on the target register. + +**Usage Examples:** + +:: + + # Set page mask register 0x1B to value 0x01, then read register 0x301 + # reg = (0x1B << 24) | (0x01 << 16) | 0x301 = 0x1B010301 + + root:/sys/kernel/debug/iio/iio:deviceX> echo 0x1B010301 > direct_reg_access + root:/sys/kernel/debug/iio/iio:deviceX> cat direct_reg_access + + # Set page mask register 0x1B to value 0x02, then write 0x55 to register 0x301 + # reg = (0x1B << 24) | (0x02 << 16) | 0x301 = 0x1B020301 + + root:/sys/kernel/debug/iio/iio:deviceX> echo 0x1B020301 0x55 > direct_reg_access + +3. CBUS JRX (SerDes/CTLE) Register Access +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Condition:** ``reg & 0x40000000 != 0`` (bit 30 set) This mode provides access to the JESD204 receiver (JRX) CBUS registers, which include the SerDes lane configuration and CTLE (Continuous Time Linear Equalizer) settings. + +**Register Parameter Encoding:** + +:: + + Bit 31 | Bit 30 | Bit 29-16 | Bit 15-8 | Bit 7-0 + -------|-----------|-----------|-------------|------------------ + unused | Mode Flag | unused | Lane Mask | Register Address + | (1) | | (0xFF) | (0xFF) + ++------------------+--------+----------------+-------------------------------------------------------------------------------------------+ +| Field | Bits | Mask | Description | ++==================+========+================+===========================================================================================+ +| Mode Flag | [30] | ``0x40000000`` | Must be set to 1 to enable CBUS access | ++------------------+--------+----------------+-------------------------------------------------------------------------------------------+ +| Lane Mask | [15:8] | ``0xFF`` | 8-bit lane mask using ``1 << lane`` encoding (lane 0 = 0x01, lane 1 =0x02, lane 7 = 0x80) | ++------------------+--------+----------------+-------------------------------------------------------------------------------------------+ +| Register Address | [7:0] | ``0xFF`` | 8-bit CBUS register address | ++------------------+--------+----------------+-------------------------------------------------------------------------------------------+ + +**Lane Mask Encoding:** + +==== ========== +Lane Mask Value +==== ========== +0 0x01 +1 0x02 +2 0x04 +3 0x08 +4 0x10 +5 0x20 +6 0x40 +7 0x80 +==== ========== + +**Usage Examples:** + +:: + + # Read CBUS register 0xFD on lane 0 + # reg = 0x40000000 | (0x01 << 8) | 0xFD = 0x400001FD + root:/sys/kernel/debug/iio/iio:deviceX> echo 0x400001FD > direct_reg_access + root:/sys/kernel/debug/iio/iio:deviceX> cat direct_reg_access + + # Read CBUS register 0xFD on lane 3 + # reg = 0x40000000 | (0x08 << 8) | 0xFD = 0x400008FD + + root:/sys/kernel/debug/iio/iio:deviceX> echo 0x400008FD > direct_reg_access + root:/sys/kernel/debug/iio/iio:deviceX> cat direct_reg_access + + # Write 0x0F to CBUS register 0x20 on lane 5 + # reg = 0x40000000 | (0x20 << 8) | 0x20 = 0x40002020 + + root:/sys/kernel/debug/iio/iio:deviceX> echo 0x40002020 0x0F > direct_reg_access + +Summary Table +------------- + +============ ====== ============ ===================================== +Mode Bit 30 Bits [29:24] Access Type +============ ====== ============ ===================================== +Standard SPI 0 0x00 Direct register read/write +Page Mask 0 0x01-0x3F Paged register access with mask setup +CBUS JRX 1 (unused) SerDes/CTLE lane register access +============ ====== ============ ===================================== diff --git a/docs/solutions/reference-designs/eval-ad9081/ad9081_plugin.rst b/docs/solutions/reference-designs/eval-ad9081/ad9081_plugin.rst new file mode 100644 index 00000000000..1df7a354082 --- /dev/null +++ b/docs/solutions/reference-designs/eval-ad9081/ad9081_plugin.rst @@ -0,0 +1,129 @@ +AD9081 Plugin Description +========================= + +The AD9081 plugin works with the `IIO Oscilloscope `_. You always use the latest version if possible. Changing any field will immediately write changes which have been made to the AD9081 settings to the hardware, and then read it back to make sure the setting is valid. If you want to set something that the GUI changes to a different number, that either means that GUI is rounding (sorry), or the hardware (either the AD9081 or the FPGA fabric) does not support that mode/precision. + +If you want to go play with ``/sys/bus/iio/devices/....`` and manipulate the devices behind the back of the GUI, it's still possible to see the settings by clicking the ``Reload Settings`` button at the bottom of the GUI. + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/ad9081_osc_plugin.png + :align: right + :width: 400 + +The AD9081 view is divided in three sections: + +- **Receive Chain** +- **Transmit Chain** +- **FPGA Settings** + +-------------- + +Receive Chain +------------- + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/ad9081_osc_plugin_rx.png + :align: right + :width: 300 + +- **ADC Rate(MHz):** Displays the ADC Sample Rate. `Read More `_ +- **ADC Nyquist Zone Control:** Selects the Nyquist Zone. `Read More `_ +- **RX Main NCO Frequency Control:** Controls the Main NCO. Frequency `Read More `_ +- **RX Main NCO Phase Control:** Controls the Main NCO Phase. `Read More `_ +- **RX Channel NCO Frequency Control:** Controls the Channel NCO Frequency. `Read More `_ +- **RX Channel NCO Phase Control:** Controls the Channel NCO Phase. `Read More `_ + +-------------- + +Transmit Chain +-------------- + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/ad9081_osc_plugin_tx.png + :align: right + :width: 300 + +- **DAC Rate(MHz):** Displays the DAC Sample Rate. `Read More `_ +- **TX Main NCO Frequency Control:** Controls the Main NCO Frequency.\ `Read More `_ +- **TX Main NCO Phase Control:** Controls the Main NCO Phase. `Read More `_ +- **TX Channel NCO Frequency Control:** Controls the Channel. NCO Frequency `Read More `_ +- **TX Channel NCO Phase Control:** Controls the Channel NCO Phase. `Read More `_ +- **TX NCO Channel Digital Gain:** Controls the Channel NCO digital gain. `Read More `_ +- **TX NCO Test Tone Modes:** Controls the Test Tone generation. `Read More `_ + +-------------- + +FPGA Settings +------------- + +Transmit/DDS +~~~~~~~~~~~~ + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/ad9081_osc_plugin_fpga.png + :align: center + :width: 600 + +The plugin provides several options on how the transmitted data is generated. + +It is possible to either use the built-in two tone **Direct Digital Synthesizer (DDS)** to transmit a bi-tonal signal on channels I and Q of the DAC. Or it is possible to use the **Direct Memory Access (DMA) facility** to transmit custom data that you have stored in a file. + +This can be achieved by selecting one of the following options listed by the **DDS Mode**: + +One CW Tone +~~~~~~~~~~~ + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/one_cw_tone.png + :align: right + +In **One CW Tone** mode one continuous wave (CW) tone will be outputted. The plugin displays the controls to set the Frequency, Amplitude and Phase for just one tone and makes sure that the amplitude of the other tone is set to 0. The resulting signal will be outputted on the Channel I of the DAC and the exact same signal but with a difference in phase of 90 degrees will be outputted on the Channel Q of the DAC. + +Two CW Tone +~~~~~~~~~~~ + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/two_cw_tones.png + :align: right + +In **Two CW Tone** mode two continuous wave (CW) tones will be outputted. The plugin displays the controls to set the frequencies F1 and F2, amplitudes A1 and A2, phases P1 and P2 for the two tones. The resulting signal will be outputted on the Channel I of the DAC and the exact same signal but with a difference in phase of 90 degrees will be outputted on the Channel Q of the DAC. + +Independent I/Q Control +~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/iq_independent.png + :align: right + +In **Independent I/Q Control** the plugin displays the controls to set the frequencies, amplitudes and phases for the two tones that will be outputted on channel I and additionally it allows for the two tones that will be outputted on channel Q of the DAC to be configured independently. + +.. note:: + + Note: The bi-tonal signal (T) is defined as the sum of two tones: T(t) = A1 + \* sin(2 \* p \* F1 \* t + P1) + A2 \* sin(2 \* p \* F2 \* t + P2), where + A-amplitude, F-frequency, P-phase of a tone. + +DAC Buffer Output +~~~~~~~~~~~~~~~~~ + +|image1| The file selector under the **File Selection** section is used to locate and choose the desired data file. Under the **DAC Channels** section the enabled channels will be used to transmit the data stored in the file. To finalize the process, a click on the **Load** button is required. + +**Restrictions:** + +- There are two types of files than can be loaded: **.txt** or **.mat**. The IIO-Oscilloscope comes with several :git-iio-oscilloscope:`data files ` that can be used. If you want to create your own data files please take a look at the `Basic IQ Data Files `_ documentation first. +- Due to hardware limitation only specific combinations of enabled channels are + possible. You can enable a total of 1, 2, 4, etc. channels. If 1 channel is + enabled then it can be any of them. If two channels are enabled then channels + 0, 1 or channels 2, 3 can be enabled and so on. + +Disable +~~~~~~~ + +In this mode both DDS and DMA are disabled causing the DAC channels to stop +transmitting any data. + +.. note:: + + Upon pressing Reload Settings button the values will be reloaded with the + corresponding driver values. Useful in scenarios where the diver values get + changed outside this plugin and a refresh on plugin's values is needed. + +.. hint:: + + Some plugin values will be rounded to the nearest value supported by the + hardware. + +.. |image1| image:: https://wiki.analog.com/_media/resources/tools-software/linux-software/dac_output_buffer_panel.png diff --git a/docs/solutions/reference-designs/eval-ad9081/ad9082.rst b/docs/solutions/reference-designs/eval-ad9081/ad9082.rst new file mode 100644 index 00000000000..582f003cddc --- /dev/null +++ b/docs/solutions/reference-designs/eval-ad9081/ad9082.rst @@ -0,0 +1,581 @@ +EVALUATING THE AD9082, AD9081, AD9986, AD9988 Mixed-Signal Front-End (MxFE™) RF Transceiver (Evaluation board quick start guide) +================================================================================================================================ + +Preface +======= + +This user guide describes additional modes and features available in the :adi:`AD9082 Evaluation Board ` , :adi:`AD9081 Evaluation Board `, :adi:`AD9986 Evaluation Board ` and :adi:`AD9988 Evaluation Board `. This guide explains the hardware and software setup needed to setup the AD9082, AD9081, AD9986 or AD9988 in the specified mode. The guide explains how a user can use the supplied hardware (AD9081-FMCA-EBZ, AD9082-FMCA-EBZ, AD9988-FMCB-EBZ or AD9986-FMCB-EBZ with ADS9-V2EBZ) and software (ACE) to setup the RF transceiver device in a mode that is not explained in the :adi:`Evaluation Board User Guide `. + +Required Documents +================== + +- Product Datasheet + + - :adi:`AD9081 ` + + - :adi:`AD9988 ` + - :adi:`AD9082 ` + - :adi:`AD9986 ` + - :adi:`AD9177 ` + - :adi:`AD9207 ` + - :adi:`AD9209 ` + +- :adi:`UG-1578, Device User Guide ` +- :adi:`UG-1829, Evaluation Board User Guide ` + +MxFE Evaluation Board Hardware Summary +====================================== + +The table below shows the various evaluation boards and their details. + ++-----------------+--------------------------+------------------------------------+----------------------------+-----------------------+-------------------------------------------+ +| **EVB Part #** | **Devices Supported** | **Power Delivery** | **Analog Front End Balun** | **Clock Input Balun** | **On-Board Crystal Oscillator Frequency** | ++=================+==========================+====================================+============================+=======================+===========================================+ +| AD9081-FMCA-EBZ | AD9081 / AD9209 / AD9177 | via FMC connector: uModule and LDO | BALH-0009SMG | SMP + BAL-0416 | 100MHz | ++-----------------+--------------------------+------------------------------------+----------------------------+-----------------------+-------------------------------------------+ +| AD9082-FMCA-EBZ | AD9082 / AD9207 / AD9177 | via FMC connector: uModule and LDO | BALH-0009SMG | SMP + BAL-0416 | 100MHz | ++-----------------+--------------------------+------------------------------------+----------------------------+-----------------------+-------------------------------------------+ +| AD9988-FMCB-EBZ | AD9988 | External 12V using ADP5056 and LDO | TCM1-83X / LDB184G6 | SMA + NCR2-123+ | 122.88MHz | ++-----------------+--------------------------+------------------------------------+----------------------------+-----------------------+-------------------------------------------+ +| AD9986-FMCB-EBZ | AD9986 | External 12V using ADP5056 and LDO | TCM1-83X / LDB184G6 | SMA + NCR2-123+ | 122.88MHz | ++-----------------+--------------------------+------------------------------------+----------------------------+-----------------------+-------------------------------------------+ + +Installation of the Heat Sink with Integrated Fan +================================================= + +A heat sink with integrated fan is shipped with the evaluation board for active +cooling of the IC device. Note the power consumption of the IC device is +dependent on its operation mode with some configurations consuming up to 13 W +where the IC die temperature can approach or exceed its maximum specified +operating range of 120 °C. For this reason, it is recommended that this heat +sink shown in Figure 1 is installed before the evaluation process begins. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/fansink1.png + :alt: Heat Sink with Fan + :align: center + +The installation steps are as follows: + +- Remove blue frame clip that is attached to assembly by lifting metal tab free from this frame clip (using small tweezer or metal pick). This frame clip is not essential for attachment of the heat sink to the IC device (while noting that the FMCB-EBZ variant does not accept this frame clip due to passive components within its keep out region). +- Remove the thin plastic tape to expose the adhesive surface + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/fansink2.png + :alt: Removing the plastic tape + :align: center + +- Carefully position and center the heat sink on top of the IC package such that it also remains clear of the RF baluns. +- Once positioned correctly, press down on the heat sinks top side for 10 seconds to secure it to the IC package. +- Connect the power supply cable + +The fan should start spinning once power is applied to the evaluation board. In +the unlikely event that it does not spin, it has been found that the two screws +used to secure the fan to the heatsink are too tight such that the fan blades +cannot spin freely. Loosening the screws using a standard Phillips screwdriver +often releases the fan blade allowing it to spin freely. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/fansink3.png + :alt: FanSink™ assembled on the Evaluation Board + :align: center + +Additional information on this product called fanSink™ from Advanced Thermal +Solutions can be found on the vendor’s website. + +Setting up MxFE™ in a Narrowband mode +===================================== + +The following instructions allow the user to setup the MxFE chip in a single +band 250MSPS I/Q data rate setup with direct RF sampling. The device is setup as +shown below: + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/narrowband_setup_for_wiki.png + :alt: Setup block diagram of AD9081 + :align: center + +The evaluation board is setup to use the on-board HMC7044 and on-chip PLL to +provide the DAC and ADC clocks. The HMC7044 also provides the clocks for the +FPGA to setup the SERDES link correctly. Refer to the Evaluation board user +guide (UG-1829) for more information on the hardware setup. + +Configuring the device in ACE +----------------------------- + +Open ACE and open the AD9081 plugin. |ACE Start page| Double click on the AD9081 block to open the chip view |Open the Chip View| Configure the device Chip View's Quick Configuration section as shown in the figures below. The steps are numbered in sequence. |image1|\ |image2| |image3|\ + +|image4| + +Hit Apply + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/7_apply.png + +Allow a few seconds for ACE and the ADS9v2 hardware to setup the AD9081. When +the chip is configured correctly, the chip view will show a status readout as +shown below. + +|Chip Status readouts| + +Obtaining an FFT from the ADC +----------------------------- + +Click on "Proceed to Analysis" button to capture an FFT from the ADC. A no input FFT is shown below. |FFT output with no input signal| Clicking on the "Update JESD Status" button in the chip view will output the FPGA's JESD204B link status. It will also readout the MxFE chip's junction temperature by polling the on-chip TMU + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/10_chip_view_after_fftanalysis_view.png + :alt: FPGA JESD204 status and MxFE junction temperature readout + +Connect a signal generator to any of the ADC inputs. Set the frequency to a +3.207GHz CW tone. The NCO is tuned to 3.2GHz. Set the amplitude to 5dBm for +example. This will need to be adjusted based on cable and other RF losses. In +the figure below, the signal generator output was set to 9.9dBm to get to +~-1.2dBFS fundamental power. + +|Single Tone FFT with a CW tone at 3.207GHz| + +Setting up DPG Lite to generate a tone out of the DAC +----------------------------------------------------- + +Open DPGDownloader Lite. Select a Single Tone waveform. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/12_dpgl_setup1.png + :alt: Selecting a Single Tone in DPG Lite + :width: 200 + +Configure the DPG Lite GUI as shown below. The steps necessary for the setup are enumerated. |DPG Lite Setup for Single Tone| After enabling the DAC output by pressing the "Play" button in DPG Lite, use a SMA cable to connect DAC0 output to ADC3 input on the AD9081-FMCA-EBZ. Capture an FFT in ACE. |DAC0 to ADC3 External Loopback| Below is a screenshot of the ADC FFT with simultaneous capture of all four channels. ADC1 is sampling the signal generator output. ADC3 is sampling the DAC0 output. + +|image5| + +Setting up MxFE™ in a Wideband mode +=================================== + +The following instructions allow the user to setup the MxFE chip in a single +band 1000MSPS I/Q data rate setup with direct RF sampling. The majority of the +instructions are similar to the Narrowband use case. The device is setup as +shown below: + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/wideband_setup_for_wiki.png + :alt: Setup block diagram of AD9081 + :align: center + +Configuring the device in ACE +----------------------------- + +Only showing the Quick configuration section with the appropriate inputs to +setup the AD9081 in wideband mode. + +|image6|\ |image7| + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/3_clock_config2.png + +Hit Apply + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/7_apply.png + +Allow a few seconds for ACE and the ADS9v2 hardware to setup the AD9081. + +Setting up DPG Lite to generate a tone out of the DAC +----------------------------------------------------- + +Setup DPG Lite for single tone as shown below. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/4_dpgl_setup.png + :alt: Selecting a Single Tone in DPG Lite + +Obtaining an FFT from the ADC +----------------------------- + +Connect a signal generator to any of the ADC inputs. Set the frequency to a +3.207GHz CW tone. + +Click on "Proceed to Analysis" button to capture an FFT from the ADC. + +|FFT output| + +Setting up AD9081/AD9988 in a 4T4R Dual-Band setup +================================================== + +The AD9081/AD9988 and AD9082/AD9986 have flexible digital signal processing +(DSP) that allows it to act as a 4T4R (4 transmit and 4 receive) transceiver for +multiband radios. Below is an example showing the AD9081/AD9988 in a multiband +setup, where the device processes LTE bands 1 and 4. The band details are shown +below + ++----------+-----------------+--------------+------------------+--------------------+ +| **Band** | **Duplex Mode** | **f\ (MHz)** | **Uplink (MHz)** | **Downlink (MHz)** | ++==========+=================+==============+==================+====================+ +| 1 | FDD | 2100 | 1920 - 1980 | 2110 - 2170 | ++----------+-----------------+--------------+------------------+--------------------+ +| 4 | FDD | 1700 | 1710 - 1785 | 1805 - 1880 | ++----------+-----------------+--------------+------------------+--------------------+ + +For optimal performance of the AD9081/AD9988 in a direct RF conversion mode, it is essential to have a good frequency plan. In this example, a DAC sample rate (*f*\ :sub:`DAC`) of 4.9152GHz and an ADC sample rate (*f*\ :sub:`ADC`) of 2.4576GHz. The frequency plan of the receive path (ADC) is shown below. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/multiband_frequency_plan.png + :alt: Receive (ADC) frequency plan with Bands 1 and 4 + :width: 400 + +To support the dual band operation, the AD9081/AD9988 will need to be configured +as shown below. Please note that the AD9081-FMCA-EBZ and AD9988-FMCB-EBZ have +different standard crystal oscillators. The AD9988-FMCA-EBZ has an on-board +122.88MHz crystal, and therefore can be configured using ACE, on-board HMC7044, +and on-chip PLL. For the example below, the AD9081-FMCA-EBZ was modified to use +a direct external clock, bypassing the HMC7044 and on-chip PLL. Refer to the +Evaluation Board User Guide (UG-1829) for more details. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/mxfe_setup_for_multiband.png + :alt: AD9081 / AD9988 Multiband setup details + +ACE setup details for dual-band transceiver operation +----------------------------------------------------- + +Follow the steps below to configure AD9081/AD9988 in the ACE GUI. The Quick configuration setup summary is shown in the screenshots below. Please note that in this example, a direct external clock was used. Please refer to :adi:`UG-1829 ` for details on how to run the evaluation board using an external clock source. + +|image8|\ |image9| |image10|\ |image11| + +Below is an FFT of the ADC sampling a 1.7325GHZ CW tone + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/1p7325ghz.png + :alt: ADC sampled output of 1.7325GHz CW tone + +and the ADC sampling a 1.95GHZ CW tone + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/1p95ghz.png + :alt: ADC sampled output of 1.95GHz CW tone + +Setting up transmitter in DPG Lite dual-band operation +------------------------------------------------------ + +Below is the spectrum of the DAC output two tones representing the center +frequencies of the two bands. + +|DAC outputs showing the center frequencies of the two bands| + +A Note on ADC performance +========================= + +The AD9081/AD9988/AD9082/AD9986 are highly integrated direct RF transceivers. Hence, the performance of the ADC may vary based on the device setup. For example, if the AD9082-FMCA-EBZ was setup to run in a transceiver mode (with DACs ON), and receive only mode (ADC only), there will be a noticeable difference in the ADC's noise performance. See below: |2.7GHz -1dBFS tone with AD9082 configured as a transceiver|\ + +|2.7GHz -1dBFS tone with AD9082 configured in Rx only mode| + +AD9081/82 Programmable Filter (PFILT) +===================================== + +This section of the user guide talks about how to run the MATLAB code for the +BPF compensation filter design and use the coefficients generated from it to +load the PFILT on AD9082-FMCA-EBZ board using ACE plug-in. The same technique +can be applied to the other evaluation boards listed above, as well. In this +document we are considering that you have a working set up of the +AD9082-FMCA-EBZ with following instructions from UG-1829 as listed under the +Documents needed section. Please refer to UG-1829 for hardware needed, how to +load ACE software and the required plug-in for using the AD9082-FMCA-EBZ. + +**Where to start PFILT design – to equalize the response using the PFILT. How to download the MATLAB model for PFILT?** For documentation on the MATLAB support refer to this Wiki page: `Hsx Toolbox `_ Please download the entire toolbox with the link off the main README: :git-HighSpeedConverterToolbox:`README.md` Then all the helper functions are on path. You can download the toolbox directly within MATLAB through Addon Explorer or grab the source from GitHub. This is documented here: https://wiki.analog.com/resources/tools-software/hsx-toolbox. This MATLAB support is provided through ADI’s High Speed Converter Toolbox. Click on this link below on GitHub `HighSpeedConverterToolbox `_ and use the green button code as shown below to download the Compensation Filter folder under hsx_examples/mxfe_sim/ + +|HighSpeedConverterToolBox under GitHub| Figure 2: HighSpeedConverterToolBox under GitHub + +Under the Compensation Filter Folder you should see the following: + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure3.png + :alt: Compensation Filter Folder view under HighSpeedConverterToolBox + :align: center + +:: + + Figure 3: Compensation Filter Folder view under HighSpeedConverterToolBox + +This document uses the MxFEADCCompensationFilterDesign_BPF.m MATLAB code. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure4.png + :alt: BPF MATLAB code view under MATLAB + :align: center + +:: + + Figure 4: BPF MATLAB code view under MATLAB + +You can either use the Run on the Editor Tab.Or Run individual sections on the +Editor Tab. + +The MATLAB code uses the input response of the ADC in the file +“MXFE_ADC_Response” When you run the MATLAB code for the BPF you will get this +output response below, which we are interested in. We define the Pass Band and +the 2 Stop Bands for this ADC response. We then generate the target response +similar to the red trace in the figure. This is the filter that is generated. It +is the one in red which is the magnitude compensation filter. The composite +response is the one in yellow. This is for 192 tap BPF filter per channel. + +|BPF Compensation Filter Response| Figure 5: BPF Compensation Filter Response + +This is the output response that we try to replicate on the bench measurements +using the AD9082-FMCB-EBZ. The MATLAB code also generated this figure below +which defines the target response for the 2 Stop bands and Pass bands. + +|Target Responses for the BPF Compensation Filter design| Figure 6: Target Responses for the BPF Compensation Filter design + +When you type on the command window, “xt”, you will get the coefficient values +as shown below: It generates coefficients to load into PFIR on MxFE using the HW + AD9082-FMCB-EBZ. The coefficient format generated in MATLAB is in decimal +format. + +It needs to be converted to 2’s complement and then to Hex Format prior to +loading it to the PFILT on AD9082-FMC-EBZ hardware using ACE plug-in + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure7.png + :alt: Coefficient values in Decimal format generated from the MATLAB code for the BPF + :align: center + +:: + + Figure 7: Coefficient values in Decimal format generated from the MATLAB code for the BPF + +The coefficient /taps are generated from MATLAB. These are in decimal format. +Prior to loading into ACE, these need to be converted to 2’s complement first +and then to Hex format. Example of how the coefficient file looks like after +converting into Hex. It is a text file and below is an excerpt from a +coefficient file for a bandpass, 192 tap filter. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure8.png + :alt: Excerpt from a Coefficient file for PFILT loading + :align: center + +:: + + Figure 8: Excerpt from a Coefficient file for PFILT loading + +In this document we are considering that you have a working set up of the +AD9082-FMCB-EBZ with following instructions from UG-1829 as listed under the +Documents needed section. Once you have a working set up of the AD9082-FMCB-EBZ, +please use the last ADC Full Bandwidth condition shown under Table 2 of Page 11 +of the UG-1829. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure9.png + :align: center + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure9r.png + :alt: Board View of selected Full Bandwidth ADC Use Case + :align: center + +:: + + Figure 9: Board View of selected Full Bandwidth ADC Use Case + +You can check the FFT response of the signal without PFILT: + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure10.png + :alt: FFT of the signal @0.5GHz to ADC input, without PFILT + :align: center + +:: + + Figure 10: FFT of the signal @0.5GHz to ADC input, without PFILT + +**How to load the generated coefficients by MATLAB code in the ACE Tool?** 1.Design Band pass filter in MATLAB PFILT tool to equalize the ADC input: For a 192 tap single real mode PFILT: Use the following settings under Quick Configuration tool in Chip view for AD9082 board. You get to the chip view by click on the highlighted box in green in the figure below + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure11.png + :alt: AD9082 Board view under ACE Plug-in + :align: center + +:: + + Figure 11: AD9082 Board view under ACE Plug-in + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure12.png + :alt: AD9082 Chip view under ACE Plug-in + :align: center + +:: + + Figure 12: AD9082 Chip view under ACE Plug-in + +**Configuring the Programmable Filter in ACE: 1.Click the programmable filter block in chip as highlighted in the picture below.** + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure13.png + :alt: Programmable Filter Configuration Pop-up Window + :align: center + +:: + + Figure 13: Programmable Filter Configuration Pop-up Window + +2.The settings shown in the Programmable filter configuration shows for AD9082 +TxFE. As, TxFE only has two ADCs. If it AD9081, under PFILT Quad mode selection +we need to choose PFilter Quad mode. We have selected Real N Tap Filter for +PFILT I mode and PFILT Q Mode is disabled. + +3.Depending on whether, PFilter I Mode or PFilter Q Mode is selected, then the +PFILTER Coefficient Load select should be Real I Load or Real Q load. + +4.Under Analysis window, Channel 0 is I data, Channel 1 is Q data. + +5.Under select the PFilter coefficient file, load the coefficient file. The +coefficients needs to be in Hex Format when we upload them in ACE. So we convert +the coefficients generated from MATLAB from Decimal  2’s complement Hex Format +before loading into ACE. + +6.Once the coefficient file is loaded, click the Configure Filter Block under +the chip view. Please note that it takes several seconds to complete loading the +coefficients into the PFILT block. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure14.png + :alt: Configure PFilter + :align: center + +:: + + Figure 14: Configure PFilter + +7.Now proceed to Analysis by click at the “Proceed to Analysis” button at the +bottom of the chip view page. + +8.Below is the FFT plot at sampling frequency of 3Gsps and input to the ADC is +0.5GHz. + +Showing Channel 0 which I Mode. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure15.png + :alt: FFT plot at sampling frequency of 3Gsps + :align: center + +:: + + Figure 15: FFT plot at sampling frequency of 3Gsps + +This FFT plot correlates to the MATLAB compensation filter response shown in +Figure 5. + +If you select the Channel 1 which is Q channel and as Q mode is disabled for the +selected 192 tap single real PFilter configuration. So no signal seen on the FFT +plot below. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure16.png + :alt: FFT plot Channel 1 which is Q channel with Q mode Disabled under PFILT Configuration Tool + :align: center + +:: + + Figure 16: FFT plot Channel 1 which is Q channel with Q mode Disabled under PFILT Configuration Tool + +9.Under the configuration window for PFILT, if you select the PFILT Q mode and +disable the PFILT I mode. Then the FFT plot for Channel 1 will be showing the +signal transmission as below: + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure17.png + :alt: FFT plot Channel 1 which is Q channel with Q mode Enabled under PFILT Configuration Tool. + :align: center + +:: + + Figure 17: FFT plot Channel 1 which is Q channel with Q mode Enabled under PFILT Configuration Tool. + +Troubleshooting Tips +==================== + +\*\* Evaluation Board is not Functioning Properly \*\* + +- Ensure that the evaluation board is properly seated in the FMC connector +- After ACE has programmed the FPGA, power is provided to the evaluation board. + Ensure that the LEDs that denote power is ok, are all lit. See image below. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/ceboard_power_rail_led.jpg + :alt: LEDs denoting power to the various rails on the evaluation board + :width: 200 + +- Ensure that the eRPC server has made a successful connection to the + evaluation board. If the Chip Info reads back a successful UID, this means + that the connection is successful. Otherwise, the UID will read 0x0 (see + Figure 11). If this is the case, power cycle the board, and restart all + software. + +\*\* ACE is slow to capture data and setup the board \*\* + +- Ensure that the USB connection between ADS9-v2EBZ board and the PC is done through a USB3.0 cable. +- Connect the cable to a USB3.0 supported port on the PC +- Restart all software and hardware + +\*\* Unable to capture data after device is setup \*\* + +In some instances, the user may be unable to capture data from the FPGA. This is +characterized by no capture via ACE, or a “configure channel failed” error in +ACE. In either case, only four of the six LEDs on the FPGA board will be lit +(see figure below). + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/ads9v2_unsuccessful_capture.jpg + :alt: LED status on ADS9-v2EBZ following an unsuccessful data capture + :width: 200 + +If this happens, and the setup is using an external direct clock to the chip, +ensure that the instrumentation is setup as explained in the evaluation board +user guide UG-1829. Ensure the correct clock and refclock frequencies are set. +Check the connections to the board to make sure they are snug. If the problem +persists, open DPG Lite and download a tone. After this step, a successful data +capture will show all the LEDs lit. See figure below. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/ads9v2_successful_capture.jpg + :alt: LED status on ADS9-v2EBZ following a successful data capture + :width: 200 + +\*\* HMC7044 Configuration Error \*\* + +When operating with the on-board clocking and on-chip PLL mode, the user can get +a “HMC7044 Configuration Error” in the ACE setup. + +.. image:: https://wiki.analog.com/_media/resources/eval/mxfe/hmc7044_config_error.png + :alt: HMC7044 Configuration Error (REFCLK value cannot be supported using a 100MHz Crystal Oscillator) + :width: 200 + +If this happens, ensure the correct modes are selected to setup the chip. Please +note that not all modes that are listed in the UG-1578, device user guide, are +supported by the evaluation board hardware using the on-board HMC7044 clock and +on-chip PLL. This is because the HMC7044 derives the reference from a 100MHz +crystal oscillator if using the FMCA version, or 122.88MHz crystal oscillator if +using the FMCB version of the evaluation board. + +If this use case is required, the best approach is to switch to using the direct +external clock. This bypasses the HMC7044 setup and the user is not limited to +the setup options provided only by the combination of on-board crystal +oscillator and the HMC7044 setup. + +\*\* ACE Does Not Auto-Detect the Hardware \*\* + +After powering up the ADS9-V2EBZ FPGA board and starting ACE, the hardware will +be auto-detected and the plugin icon should appear in the GUI as shown at the +top of the "Configuring the device in ACE" section. In the unusual case that the +hardware is not detected and the plugin icon does not appear, try a different +USB3 cable before going to the trouble of reinstalling the plugin, or +reinstalling the whole ACE package. + +Automating ACE with MATLAB +========================== + +User Guide: `ad9xxx_matlab_user_guide.pdf `_ + +Code: `ad9xxx_matlab_code.zip `_ + +.. |ACE Start page| image:: https://wiki.analog.com/_media/resources/eval/mxfe/1_start.png +.. |Open the Chip View| image:: https://wiki.analog.com/_media/resources/eval/mxfe/2_board_view.png +.. |image1| image:: https://wiki.analog.com/_media/resources/eval/mxfe/3_chip_setup1.png +.. |image2| image:: https://wiki.analog.com/_media/resources/eval/mxfe/4_chip_setup2.png +.. |image3| image:: https://wiki.analog.com/_media/resources/eval/mxfe/5_chip_setup3.png +.. |image4| image:: https://wiki.analog.com/_media/resources/eval/mxfe/6_chip_setup4.png +.. |Chip Status readouts| image:: https://wiki.analog.com/_media/resources/eval/mxfe/8_chip_view_after_apply.png +.. |FFT output with no input signal| image:: https://wiki.analog.com/_media/resources/eval/mxfe/9_analysis_view.png +.. |Single Tone FFT with a CW tone at 3.207GHz| image:: https://wiki.analog.com/_media/resources/eval/mxfe/11_st_fft_onchippll_3p207ghz_9p9dbm.png +.. |DPG Lite Setup for Single Tone| image:: https://wiki.analog.com/_media/resources/eval/mxfe/13_dpgl_setup2.png +.. |DAC0 to ADC3 External Loopback| image:: https://wiki.analog.com/_media/resources/eval/mxfe/14_st_fft_3p201ghz_dac0_loop_adc3_0dbfs.png +.. |image5| image:: https://wiki.analog.com/_media/resources/eval/mxfe/15_two_channel_outputs.png +.. |image6| image:: https://wiki.analog.com/_media/resources/eval/mxfe/1_jesd204_setup.png +.. |image7| image:: https://wiki.analog.com/_media/resources/eval/mxfe/2_clock_config1.png +.. |FFT output| image:: https://wiki.analog.com/_media/resources/eval/mxfe/5_fft_output.png +.. |image8| image:: https://wiki.analog.com/_media/resources/eval/mxfe/11.png + :width: 200 +.. |image9| image:: https://wiki.analog.com/_media/resources/eval/mxfe/21.png + :width: 200 +.. |image10| image:: https://wiki.analog.com/_media/resources/eval/mxfe/31.png + :width: 200 +.. |image11| image:: https://wiki.analog.com/_media/resources/eval/mxfe/41.png + :width: 200 +.. |DAC outputs showing the center frequencies of the two bands| image:: https://wiki.analog.com/_media/resources/eval/mxfe/dac_output_dualband.png +.. |2.7GHz -1dBFS tone with AD9082 configured as a transceiver| image:: https://wiki.analog.com/_media/resources/eval/mxfe/ad9082_2p7ghz_adconlyfft.png + :width: 600 +.. |2.7GHz -1dBFS tone with AD9082 configured in Rx only mode| image:: https://wiki.analog.com/_media/resources/eval/mxfe/ad9082_2p7ghz_trxmodefft.png + :width: 600 +.. |HighSpeedConverterToolBox under GitHub| image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure2.png +.. |BPF Compensation Filter Response| image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure5.png +.. |Target Responses for the BPF Compensation Filter design| image:: https://wiki.analog.com/_media/resources/eval/mxfe/figure6.png diff --git a/docs/solutions/reference-designs/eval-ad9081/index.rst b/docs/solutions/reference-designs/eval-ad9081/index.rst index 3bbe7cae614..46703a0ac7d 100644 --- a/docs/solutions/reference-designs/eval-ad9081/index.rst +++ b/docs/solutions/reference-designs/eval-ad9081/index.rst @@ -71,9 +71,13 @@ While :adi:`EVAL-AD9082` looks like this, with 2x ADCs and 4x DACs: .. toctree:: :hidden: - user-guide + 2to24ghz-mxfe-rf-front-end + ad9081 + ad9081_plugin + ad9082 prerequisites quickstart/index + user-guide Recommendations ------------------------------------------------------------------------------- diff --git a/scripts/fix-rst-errors b/scripts/fix-rst-errors new file mode 100755 index 00000000000..619abb7f059 --- /dev/null +++ b/scripts/fix-rst-errors @@ -0,0 +1,713 @@ +#!/usr/bin/env python3 +""" +Fix RST build errors across landing page branches. + +Handles: malformed grid tables, unexpected indentation, undefined substitutions, +anonymous hyperlink mismatch, title overline/underline mismatch, duplicate +substitution definitions, bullet list blank lines, bogus toctree paths. +""" + +import re +import subprocess +import sys +from pathlib import Path + + +def git(*args, check=True): + r = subprocess.run(["git", *args], capture_output=True, text=True, check=False) + if r.returncode != 0 and check: + print(f" git error: {r.stderr.strip()}") + return r + + +def fix_simple_tables(content: str) -> str: + """Fix simple RST tables where column widths don't match data.""" + lines = content.split('\n') + result = [] + i = 0 + while i < len(lines): + # Detect simple table: line of ===== ===== (no + signs) + m = re.match(r'^(\s*)(=+(?:\s+=+)+)\s*$', lines[i]) + if m: + indent = m.group(1) + # Collect the whole simple table + table_start = i + table_lines = [lines[i]] + j = i + 1 + while j < len(lines): + if re.match(r'^\s*=+(?:\s+=+)*\s*$', lines[j]): + table_lines.append(lines[j]) + if len([l for l in table_lines if re.match(r'^\s*=+', l)]) >= 3: + j += 1 + break + j += 1 + elif lines[j].strip() == '' and j + 1 < len(lines) and re.match(r'^\s*=+', lines[j + 1]): + table_lines.append(lines[j]) + j += 1 + elif lines[j].strip(): + table_lines.append(lines[j]) + j += 1 + else: + break + + # Parse columns from separator + sep_line = table_lines[0].lstrip() + col_widths = [len(c) for c in sep_line.split()] + + # Calculate max width needed from data rows + for tl in table_lines: + if re.match(r'^\s*=+', tl): + continue + stripped = tl[len(indent):] + # Split data into columns based on current col positions + pos = 0 + for c in range(len(col_widths)): + if c < len(col_widths) - 1: + # Find content end (next column start based on separators) + sep_pos = sum(col_widths[:c+1]) + c + 1 # +1 for space + cell = stripped[pos:sep_pos].rstrip() + col_widths[c] = max(col_widths[c], len(cell)) + pos = sep_pos + else: + cell = stripped[pos:].strip() + col_widths[c] = max(col_widths[c], len(cell)) + + # Rebuild table + new_sep = indent + ' '.join('=' * w for w in col_widths) + for tl in table_lines: + if re.match(r'^\s*=+', tl): + result.append(new_sep) + else: + result.append(tl) + i = j + else: + result.append(lines[i]) + i += 1 + return '\n'.join(result) + + +def fix_grid_tables(content: str) -> str: + """Rebuild all grid tables so separator widths match data row widths.""" + lines = content.split('\n') + result = [] + i = 0 + while i < len(lines): + # Detect grid table start: line of +---+---+ (possibly indented) + if re.match(r'^\s*\+[-=+]+\+\s*$', lines[i]): + table_lines = [lines[i]] + j = i + 1 + while j < len(lines): + table_lines.append(lines[j]) + if re.match(r'^\s*\+[-=+]+\+\s*$', lines[j]): + # Check if next line continues the table + if j + 1 < len(lines) and ( + re.match(r'^\s*\|', lines[j + 1]) or + re.match(r'^\s*\+[-=+]+\+\s*$', lines[j + 1]) + ): + j += 1 + continue + else: + j += 1 + break + elif re.match(r'^\s*\|', lines[j]): + j += 1 + continue + else: + # Not a table line — the table ended at j-1 + table_lines.pop() # remove non-table line + break + else: + j = len(lines) + + fixed_table = rebuild_grid_table(table_lines) + if fixed_table is not None: + result.extend(fixed_table) + else: + result.extend(table_lines) + i = j + if j < len(lines) and not re.match(r'^\s*\+[-=+]+\+\s*$', lines[j - 1]): + # We popped the last line, so process it next + continue + else: + result.append(lines[i]) + i += 1 + + return '\n'.join(result) + + +def rebuild_grid_table(table_lines: list[str]) -> list[str] | None: + """Parse grid table and rebuild with consistent column widths.""" + # Find column positions from separator lines + sep_lines = [l for l in table_lines if re.match(r'^\s*\+[-=+]+\+\s*$', l)] + if not sep_lines: + return None + + # Detect indentation from first separator + first_sep = sep_lines[0] + indent = len(first_sep) - len(first_sep.lstrip()) + indent_str = first_sep[:indent] + + # Use the first separator (stripped) to determine number of columns + first_sep_stripped = first_sep.strip() + col_positions = [m.start() for m in re.finditer(r'\+', first_sep_stripped)] + if len(col_positions) < 2: + return None + n_cols = len(col_positions) - 1 + + # Calculate max width needed for each column from ALL rows (data + sep) + col_widths = [0] * n_cols + for line in table_lines: + if re.match(r'^\s*\|', line): + # Data row — extract cell contents + cells = extract_cells(line.strip(), n_cols) + if cells and len(cells) == n_cols: + for c, cell in enumerate(cells): + col_widths[c] = max(col_widths[c], len(cell)) + + # Ensure minimum width of 3 + col_widths = [max(w, 3) for w in col_widths] + + # Rebuild table + rebuilt = [] + for line in table_lines: + if re.match(r'^\s*\+[-=+]+\+\s*$', line): + # Separator line + char = '=' if '=' in line else '-' + parts = ['+'] + for w in col_widths: + parts.append(char * (w + 2)) + parts.append('+') + rebuilt.append(indent_str + ''.join(parts)) + elif re.match(r'^\s*\|', line): + # Data row + cells = extract_cells(line.strip(), n_cols) + if cells and len(cells) == n_cols: + parts = ['|'] + for c, cell in enumerate(cells): + parts.append(' ' + cell.ljust(col_widths[c]) + ' ') + parts.append('|') + rebuilt.append(indent_str + ''.join(parts)) + else: + rebuilt.append(line) # Can't parse, keep as-is + else: + rebuilt.append(line) + + return rebuilt + + +def extract_cells(line: str, expected_cols: int) -> list[str] | None: + """Extract cell contents from a grid table data row.""" + if not line.startswith('|'): + return None + # Split by | but be careful with RST links containing | + # Use a simple approach: split from the right edge + cells = [] + rest = line[1:] # skip leading | + for _ in range(expected_cols): + # Find the next | that's a cell boundary (not inside a link) + idx = find_cell_boundary(rest) + if idx < 0: + return None + cells.append(rest[:idx].strip()) + rest = rest[idx + 1:] + return cells + + +def find_cell_boundary(text: str) -> int: + """Find the next | that serves as a cell boundary.""" + depth = 0 + for i, ch in enumerate(text): + if ch == '`': + depth = 1 - depth # toggle + elif ch == '|' and depth == 0: + return i + return -1 + + +def fix_title_mismatch(content: str) -> str: + """Fix title overline/underline length mismatches.""" + lines = content.split('\n') + result = [] + underline_chars = set('=-~^"\'`_+#*') + i = 0 + while i < len(lines): + # Check for overline + title + underline pattern + if (i + 2 < len(lines) and + lines[i].strip() and + len(set(lines[i].strip())) == 1 and + lines[i].strip()[0] in underline_chars and + lines[i + 1].strip() and + lines[i + 2].strip() and + len(set(lines[i + 2].strip())) == 1 and + lines[i + 2].strip()[0] in underline_chars): + # Overline + title + underline + title = lines[i + 1].rstrip() + char = lines[i].strip()[0] + needed = max(len(title), 4) + result.append(char * needed) + result.append(title) + result.append(char * needed) + i += 3 + # Skip duplicate underlines + while i < len(lines) and lines[i].strip() and len(set(lines[i].strip())) == 1 and lines[i].strip()[0] in underline_chars: + i += 1 + continue + # Check for title + underline (no overline) + if (i + 1 < len(lines) and + lines[i].strip() and + lines[i + 1].strip() and + len(set(lines[i + 1].strip())) == 1 and + lines[i + 1].strip()[0] in underline_chars): + title = lines[i].rstrip() + char = lines[i + 1].strip()[0] + needed = max(len(title), 4) + underline = char * needed + if lines[i + 1].strip() != underline: + result.append(title) + result.append(underline) + i += 2 + continue + result.append(lines[i]) + i += 1 + return '\n'.join(result) + + +def fix_duplicate_substitutions(content: str) -> str: + """Fix duplicate substitution definition names by adding unique suffixes.""" + lines = content.split('\n') + seen = {} # name -> count + result = [] + subst_re = re.compile(r'^(\s*\.\. \|)([^|]+)(\| image::.*)') + for line in lines: + m = subst_re.match(line) + if m: + prefix, name, suffix = m.group(1), m.group(2), m.group(3) + if name in seen: + seen[name] += 1 + new_name = f"{name}_{seen[name]}" + result.append(f"{prefix}{new_name}{suffix}") + else: + seen[name] = 0 + result.append(line) + else: + result.append(line) + return '\n'.join(result) + + +def fix_undefined_substitution(content: str) -> str: + """Convert surviving DokuWiki image syntax to RST or remove it.""" + # Pattern: |*{{:path:image.jpg?300|| or |{{:path:image.jpg?300|text}}| + # Also handles: |*{{:resources:wechat_image_20210401114013.jpg?300|| + content = re.sub( + r'\|\*?\{\{:?[^}]*\}\}\|?', + '', + content, + ) + # Also fix patterns like: |*{{:path:image?param| + content = re.sub( + r'\|\*?\{\{:?[^|}\n]+\|?', + '', + content, + ) + # Fix patterns with {variables} in math-like expressions + # e.g., |counts = ADC value } {RS = 6e-3} ...| + content = re.sub( + r'\|[^|\n]*\} \{[^|\n]*\|', + '', + content, + ) + return content + + +def fix_bullet_list_blank_line(content: str) -> str: + """Add blank lines where bullet lists end without one.""" + lines = content.split('\n') + result = [] + for i, line in enumerate(lines): + result.append(line) + # If current line is in a list and next line is unindented non-list + if (re.match(r'^(\s+)[-*]', line) and + i + 1 < len(lines) and + lines[i + 1].strip() and + not re.match(r'^\s', lines[i + 1]) and + not re.match(r'^[-*+]', lines[i + 1])): + result.append('') + return '\n'.join(result) + + +def fix_anonymous_hyperlinks(content: str) -> str: + """Convert anonymous hyperlinks (__) to named (_) where mismatched.""" + # Count anonymous refs and targets + refs = len(re.findall(r'`[^`]+`__', content)) + targets = len(re.findall(r'\.\. __:', content)) + len(re.findall(r'__ https?://', content)) + if refs > 0 and targets == 0: + # All anonymous refs but no targets — convert to named + content = re.sub(r'(`[^`]+`(?:<[^>]+>)?)__', r'\1_', content) + return content + + +def fix_inline_markup(content: str) -> str: + """Fix inline markup issues (unmatched ** or * strings).""" + lines = content.split('\n') + result = [] + for line in lines: + # Fix unmatched ** (bold) — escape with backslash + if '**' in line: + count = line.count('**') + if count % 2 == 1: + # Odd count — escape the last unmatched ** + line = line.replace('**', r'\*\*', 1) + # Fix unmatched * (italic) not part of ** + # This is tricky, skip for now — most cases are ** issues + result.append(line) + return '\n'.join(result) + + +def fix_unexpected_indentation(content: str, error_lines: list[int]) -> str: + """Add blank lines before unexpectedly indented blocks.""" + lines = content.split('\n') + # Insert blank lines before the error lines (0-indexed) + offset = 0 + for line_no in sorted(error_lines): + idx = line_no - 1 + offset # Convert 1-indexed to 0-indexed + if 0 < idx < len(lines): + # Check if preceding line isn't already blank + if lines[idx - 1].strip(): + lines.insert(idx, '') + offset += 1 + return '\n'.join(lines) + + +def process_branch(branch: str, project: str, fixes: list[dict], + repo_root: Path, docs_dir: Path, dry_run: bool) -> bool: + """Apply fixes to a single branch.""" + print(f"\n{'='*60}") + print(f"Fixing: {branch} ({project})") + + r = git("-C", str(repo_root), "checkout", branch) + if r.returncode != 0: + print(f" ERROR: Can't checkout {branch}") + return False + + changed_files = [] + for fix in fixes: + fpath = docs_dir / fix['file'] + if not fpath.exists(): + print(f" WARNING: File not found: {fix['file']}") + continue + + content = fpath.read_text() + original = content + + if fix['type'] == 'malformed_table': + content = fix_grid_tables(content) + content = fix_simple_tables(content) + elif fix['type'] == 'title_mismatch': + content = fix_title_mismatch(content) + elif fix['type'] == 'unexpected_indentation': + content = fix_unexpected_indentation(content, fix.get('lines', [])) + elif fix['type'] == 'undefined_substitution': + content = fix_undefined_substitution(content) + elif fix['type'] == 'anonymous_hyperlink': + content = fix_anonymous_hyperlinks(content) + elif fix['type'] == 'duplicate_substitution': + content = fix_duplicate_substitutions(content) + elif fix['type'] == 'bullet_list': + content = fix_bullet_list_blank_line(content) + elif fix['type'] == 'add_title': + title = fix.get('title', 'Untitled') + underline = '=' * len(title) + content = f"{title}\n{underline}\n\n{content}" + elif fix['type'] == 'fix_inline_markup': + content = fix_inline_markup(content) + elif fix['type'] == 'move_file': + # Special: move file to new path + old_path = docs_dir / fix['old_file'] + new_path = docs_dir / fix['new_file'] + if old_path.exists(): + if dry_run: + print(f" [DRY] Would move: {fix['old_file']} → {fix['new_file']}") + changed_files.append(str(new_path.relative_to(repo_root))) + else: + new_path.parent.mkdir(parents=True, exist_ok=True) + import shutil + shutil.move(str(old_path), str(new_path)) + # Clean up empty dirs + try: + for p in [old_path.parent] + list(old_path.parents): + if p == docs_dir: + break + p.rmdir() + except OSError: + pass + changed_files.append(str(new_path.relative_to(repo_root))) + git("-C", str(repo_root), "add", str(old_path.relative_to(repo_root))) + print(f" Moved: {fix['old_file']} → {fix['new_file']}") + continue + elif fix['type'] == 'rewrite_toctree': + content = fix.get('new_content', content) + + if content != original: + changed_files.append(str(fpath.relative_to(repo_root))) + if dry_run: + print(f" [DRY] Would fix: {fix['file']} ({fix['type']})") + else: + fpath.write_text(content) + print(f" Fixed: {fix['file']} ({fix['type']})") + else: + print(f" No change: {fix['file']} ({fix['type']})") + + if not changed_files: + print(" No changes needed") + return False + + if dry_run: + print(f" [DRY] Would fix {len(changed_files)} files total") + return True + + # Stage, commit, push + for f in changed_files: + git("-C", str(repo_root), "add", f) + git("-C", str(repo_root), "commit", "-m", + f"fix: resolve RST build warnings in {project}\n\n" + f"Fix {len(changed_files)} files with RST formatting issues\n" + f"(malformed tables, indentation, substitutions, etc.)") + git("-C", str(repo_root), "push", "origin", branch) + print(f" Committed and pushed {len(changed_files)} fixes") + return True + + +# Error database: (branch, project, file, error_type, optional_lines) +FIXES = [ + # PR 236: Undefined substitution + ("wiki_migration/ad4130-8_landing", "ad4130-8", [ + {"file": "solutions/reference-designs/ad4130-8/ad4130-8.rst", + "type": "undefined_substitution"}, + ]), + # PR 237: Anonymous hyperlink mismatch + ("wiki_migration/ad4134_landing", "ad4134", [ + {"file": "solutions/reference-designs/ad4134/hdl.rst", + "type": "anonymous_hyperlink"}, + ]), + # PR 248: Malformed tables + ("wiki_migration/ad7606x-fmc_landing", "ad7606x-fmc", [ + {"file": "solutions/reference-designs/ad7606x-fmc/hdl.rst", + "type": "malformed_table"}, + ]), + # PR 255: Malformed table + ("wiki_migration/ad-fmcadc3-ebz_landing", "ad-fmcadc3-ebz", [ + {"file": "solutions/reference-designs/ad-fmcadc3-ebz/quickstart.rst", + "type": "malformed_table"}, + ]), + # PR 256: Malformed table + ("wiki_migration/ad-fmcadc4-ebz_landing", "ad-fmcadc4-ebz", [ + {"file": "solutions/reference-designs/ad-fmcadc4-ebz/quickstart.rst", + "type": "malformed_table"}, + ]), + # PR 258: Malformed table + ("wiki_migration/ad-fmcadc7-ebz_landing", "ad-fmcadc7-ebz", [ + {"file": "solutions/reference-designs/ad-fmcadc7-ebz/quickstart.rst", + "type": "malformed_table"}, + ]), + # PR 261: Undefined substitution + ("wiki_migration/ad-fmcmotcon1-ebz_landing", "ad-fmcmotcon1-ebz", [ + {"file": "solutions/reference-designs/ad-fmcmotcon1-ebz/hardware/signal_chain.rst", + "type": "undefined_substitution"}, + ]), + # PR 263: Malformed table + ("wiki_migration/ad-fmcomms1-ebz_landing", "ad-fmcomms1-ebz", [ + {"file": "solutions/reference-designs/ad-fmcomms1-ebz/hardware.rst", + "type": "malformed_table"}, + ]), + # PR 265: Malformed table + ("wiki_migration/ad-fmcomms6-ebz_landing", "ad-fmcomms6-ebz", [ + {"file": "solutions/reference-designs/ad-fmcomms6-ebz/hardware.rst", + "type": "malformed_table"}, + ]), + # PR 266: Malformed table + ("wiki_migration/ad-fmcxmwbr1-ebz_landing", "ad-fmcxmwbr1-ebz", [ + {"file": "solutions/reference-designs/ad-fmcxmwbr1-ebz/software/linux/zynqmp.rst", + "type": "malformed_table"}, + ]), + # PR 267: Malformed tables + ("wiki_migration/ad-freqcvt1-ebz_landing", "ad-freqcvt1-ebz", [ + {"file": "solutions/reference-designs/ad-freqcvt1-ebz/hardware/card_specification.rst", + "type": "malformed_table"}, + {"file": "solutions/reference-designs/ad-freqcvt1-ebz/hdl.rst", + "type": "malformed_table"}, + ]), + # PR 272: Malformed tables + ("wiki_migration/ad-pzsdr2400tdd-eb_landing", "ad-pzsdr2400tdd-eb", [ + {"file": "solutions/reference-designs/ad-pzsdr2400tdd-eb/reference_hdl.rst", + "type": "malformed_table"}, + ]), + # PR 275: Malformed tables + ("wiki_migration/adrv9002_landing", "adrv9002", [ + {"file": "solutions/reference-designs/adrv9002/axi_adrv9002.rst", + "type": "malformed_table"}, + ]), + # PR 276: Malformed table + ("wiki_migration/adrv936x_landing", "adrv936x", [ + {"file": "solutions/reference-designs/adrv936x/introduction.rst", + "type": "malformed_table"}, + ]), + # PR 285: Unexpected indentation + ("wiki_migration/dc2903a_landing", "dc2903a", [ + {"file": "solutions/reference-designs/dc2903a/no-os-setup.rst", + "type": "unexpected_indentation", + "lines": [716, 1348, 1980, 3532, 4164]}, + ]), + # PR 293: Malformed table + ("wiki_migration/eval-adbms2950-basic_landing", "eval-adbms2950-basic", [ + {"file": "solutions/reference-designs/eval-adbms2950-basic/eval-adbms2950-basic.rst", + "type": "malformed_table"}, + ]), + # PR 295: Bullet list ends without blank line + ("wiki_migration/eval-ade9000shieldz_landing", "eval-ade9000shieldz", [ + {"file": "solutions/reference-designs/eval-ade9000shieldz/sensor_node/demo.rst", + "type": "unexpected_indentation", + "lines": [95]}, + ]), + # PR 298: Title mismatch + malformed tables + ("wiki_migration/eval-adicup3029_landing", "eval-adicup3029", [ + {"file": "solutions/reference-designs/eval-adicup3029/reference_designs/demo_plc_modbus.rst", + "type": "title_mismatch"}, + {"file": "solutions/reference-designs/eval-adicup3029/reference_designs/demo_plc_modbus.rst", + "type": "malformed_table"}, + {"file": "solutions/reference-designs/eval-adicup3029/hardware/adicup3029.rst", + "type": "malformed_table"}, + ]), + # PR 299: Malformed table + ("wiki_migration/eval-adicup360_landing", "eval-adicup360", [ + {"file": "solutions/reference-designs/eval-adicup360/mechanical.rst", + "type": "malformed_table"}, + ]), + # PR 301: Malformed table + ("wiki_migration/eval-adsd3100-nxz_landing", "eval-adsd3100-nxz", [ + {"file": "solutions/reference-designs/eval-adsd3100-nxz/eval-adsd3100-nxz.rst", + "type": "malformed_table"}, + ]), + # PR 303: Unexpected indentation + ("wiki_migration/eval-adtf3175d-nxz_landing", "eval-adtf3175d-nxz", [ + {"file": "solutions/reference-designs/eval-adtf3175d-nxz/eval-adtf3175d-nxz.rst", + "type": "unexpected_indentation", + "lines": [146]}, + ]), + # PR 304: Malformed table + ("wiki_migration/eval-adtf3175-nxz_landing", "eval-adtf3175-nxz", [ + {"file": "solutions/reference-designs/eval-adtf3175-nxz/eval-adtf3175-nxz.rst", + "type": "malformed_table"}, + ]), + # PR 311: Unexpected indentation + ("wiki_migration/eval-ltc4306_landing", "eval-ltc4306", [ + {"file": "solutions/reference-designs/eval-ltc4306/no-os-setup.rst", + "type": "unexpected_indentation", + "lines": [729, 1361, 1993, 3545, 4177]}, + ]), + # PR 312: Unexpected indentation + ("wiki_migration/ev-cog-ad3029lz_landing", "ev-cog-ad3029lz", [ + {"file": "solutions/reference-designs/ev-cog-ad3029lz/quickstart.rst", + "type": "unexpected_indentation", + "lines": [88]}, + ]), + # PR 317: Unexpected indentation + ("wiki_migration/iio_demo_landing", "iio_demo", [ + {"file": "solutions/reference-designs/iio_demo/no-os-setup.rst", + "type": "unexpected_indentation", + "lines": [730, 1362, 1994, 3546, 4178]}, + ]), + # PR 318: Duplicate substitution + ("wiki_migration/inertial-mems_landing", "inertial-mems", [ + {"file": "solutions/reference-designs/inertial-mems/imu/isensor_evaluation_tool_selection_guide.rst", + "type": "duplicate_substitution"}, + ]), + # PR 320: Unexpected indentation + malformed table + ("wiki_migration/longrangewirelessradio_landing", "longrangewirelessradio", [ + {"file": "solutions/reference-designs/longrangewirelessradio/software.rst", + "type": "unexpected_indentation", + "lines": [29, 36]}, + {"file": "solutions/reference-designs/longrangewirelessradio/software.rst", + "type": "malformed_table"}, + ]), + # PR 321: Unexpected indentation + ("wiki_migration/max11205pmb1_landing", "max11205pmb1", [ + {"file": "solutions/reference-designs/max11205pmb1/no-os-setup.rst", + "type": "unexpected_indentation", + "lines": [714, 1346, 1978, 3530, 4162]}, + ]), + # PR 324: Duplicate substitution + unexpected indentation + ("wiki_migration/pzsdr_landing", "pzsdr", [ + {"file": "solutions/reference-designs/pzsdr/carriers/packrf/testing.rst", + "type": "duplicate_substitution"}, + {"file": "solutions/reference-designs/pzsdr/carriers/portable-radio-reference-design/assembly-instructions.rst", + "type": "unexpected_indentation", + "lines": [75]}, + {"file": "solutions/reference-designs/pzsdr/carriers/portable-radio-reference-design/features.rst", + "type": "unexpected_indentation", + "lines": [463, 470]}, + ]), + # PR 325: Malformed table + ("wiki_migration/quadmxfe_landing", "quadmxfe", [ + {"file": "solutions/reference-designs/quadmxfe/quick-start.rst", + "type": "malformed_table"}, + ]), + # PR 330: Malformed tables + ("wiki_migration/x-band-platform_landing", "x-band-platform", [ + {"file": "solutions/reference-designs/x-band-platform/software.rst", + "type": "malformed_table"}, + ]), + # PR 270: Bogus file path + toctree + ("wiki_migration/admx_landing", "admx", [ + {"file": "solutions/reference-designs/admx/admx6001resources/eval/user-guides/admx/admx6001_analog_devices_wiki.rst", + "type": "move_file", + "old_file": "solutions/reference-designs/admx/admx6001resources/eval/user-guides/admx/admx6001_analog_devices_wiki.rst", + "new_file": "solutions/reference-designs/admx/admx6001_analog_devices_wiki.rst"}, + {"file": "solutions/reference-designs/admx/index.rst", + "type": "rewrite_toctree", + "new_content": "ADMX\n====\n\n.. toctree::\n :titlesonly:\n\n admx100x\n admx5001\n admx6001\n admx6001_analog_devices_wiki\n eval-admx2001ebz\n eval-admx2001ebz/spi-interface\n"}, + ]), + # PR 315: No title in RST + ("wiki_migration/ev-cog-ad4050w_landing", "ev-cog-ad4050w", [ + {"file": "solutions/reference-designs/ev-cog-ad4050w/example_project.rst", + "type": "add_title", + "title": "Example Project"}, + ]), + # PR 328: Inline markup issues + ("wiki_migration/stingray_landing", "stingray", [ + {"file": "solutions/reference-designs/stingray/userguide.rst", + "type": "fix_inline_markup"}, + ]), +] + + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--dry-run", action="store_true") + parser.add_argument("--branches", nargs="+", help="Only fix these branches") + args = parser.parse_args() + + script_dir = Path(__file__).resolve().parent + repo_root = script_dir.parent + docs_dir = repo_root / "docs" + + orig_branch = git("-C", str(repo_root), "rev-parse", "--abbrev-ref", "HEAD").stdout.strip() + + success = 0 + for branch, project, fixes in FIXES: + if args.branches and branch not in args.branches and project not in args.branches: + continue + try: + if process_branch(branch, project, fixes, repo_root, docs_dir, args.dry_run): + success += 1 + except Exception as e: + print(f" ERROR: {e}") + import traceback + traceback.print_exc() + + git("-C", str(repo_root), "checkout", orig_branch, check=False) + print(f"\nDone: {success} branches fixed") + + +if __name__ == "__main__": + main() diff --git a/scripts/move-landing-pages b/scripts/move-landing-pages new file mode 100755 index 00000000000..d57b3ec4716 --- /dev/null +++ b/scripts/move-landing-pages @@ -0,0 +1,883 @@ +#!/usr/bin/env python3 +""" +move-landing-pages — Move wiki-migration landing pages to reference-designs/. + +Reads a CSV of (project_name, wiki_url) rows, and for each project: + 1. Collects the landing RST + subfolder from wiki-migration/ + 2. Creates a branch from main + 3. Writes files to solutions/reference-designs/{project}/ + 4. Updates :doc: links, includes, images, and binary artifacts + 5. Localizes images (exclusive vs shared) and resources + 6. Commits + +Usage: + ./scripts/move-landing-pages landing.csv [--dry-run] [--projects P1 P2 ...] [--verbose] +""" + +import argparse +import csv +import re +import shutil +import subprocess +import sys +import urllib.parse +from pathlib import Path + +# Import table fixers from the conversion script +sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent / "scripts")) +from importlib import import_module as _im +_convert = _im("04_convert_to_rst") +fix_grid_tables = _convert.fix_grid_tables +fix_simple_tables = _convert.fix_simple_tables + + +# --------------------------------------------------------------------------- +# Git helpers (from migrate-pages) +# --------------------------------------------------------------------------- + +def find_repo_root(path: Path) -> Path | None: + """Walk upward from path looking for .git/ directory.""" + p = path.resolve() + for parent in [p] + list(p.parents): + if (parent / ".git").exists(): + return parent + return None + + +def git_in(repo_root: Path, *args: str, check: bool = True) -> subprocess.CompletedProcess: + """Run git command in a specific repo. Prints stderr on failure.""" + result = subprocess.run( + ["git", "-C", str(repo_root), *args], + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0 and check: + print(f" ERROR: git {' '.join(args)}") + if result.stderr.strip(): + print(f" {result.stderr.strip()}") + sys.exit(1) + return result + + +def current_branch(repo_root: Path) -> str: + r = git_in(repo_root, "rev-parse", "--abbrev-ref", "HEAD") + return r.stdout.strip() + + +def branch_exists(repo_root: Path, branch: str) -> bool: + r = git_in(repo_root, "rev-parse", "--verify", branch, check=False) + return r.returncode == 0 + + +def resolve_base(repo_root: Path, base: str) -> str: + """Resolve base branch, falling back to origin/.""" + if branch_exists(repo_root, base): + return base + remote = f"origin/{base}" + if branch_exists(repo_root, remote): + return remote + print(f" ERROR: Base branch '{base}' not found") + sys.exit(1) + + +# --------------------------------------------------------------------------- +# Regex patterns +# --------------------------------------------------------------------------- + +# :doc:`Text ` or :doc:`/wiki-migration/path` +DOC_REF_RE = re.compile( + r':doc:`' + r'(?:' + r'(?P[^`<]*)<(?P[^`>]+)>' # Text form (greedy text) + r'|' + r'(?P[^`<>]+)' # bare path form (no angle brackets) + r')' + r'`' +) + +# .. include:: relative/path +INCLUDE_RE = re.compile(r'^(?P\s*)\.\. include:: (?P.+)$', re.MULTILINE) + +# .. image:: https://wiki.analog.com/_media/... +WIKI_IMAGE_RE = re.compile( + r'^(?P\s*)\.\. image:: https://wiki\.analog\.com/_media/(?P\S+)', + re.MULTILINE, +) + +# |subst| image definitions with wiki URLs +SUBST_IMAGE_RE = re.compile( + r'^(?P\s*)\.\. \|(?P[^|]+)\| image:: https://wiki\.analog\.com/_media/(?P\S+)', + re.MULTILINE, +) + +# Binary artifact URLs in links: `text `_ +BINARY_LINK_RE = re.compile( + r'`(?P[^`<]+?)\s*[^>]+\.(?:zip|exe|pdf|tar\.gz|tgz|gz|bz2|xz|rar|7z|msi|deb|rpm|bin|img|iso))>`_', + re.IGNORECASE, +) + +# General _media URL extraction (excludes RST syntax chars) +IMAGE_URL_RE = re.compile(r'https://wiki\.analog\.com/_media/([^\s>`\'"<]+)') + +BINARY_EXTS = { + '.zip', '.exe', '.pdf', '.tar.gz', '.tgz', '.gz', '.bz2', '.xz', + '.rar', '.7z', '.msi', '.deb', '.rpm', '.bin', '.img', '.iso', +} + + +# --------------------------------------------------------------------------- +# CSV parsing +# --------------------------------------------------------------------------- + +def parse_csv(csv_path: Path) -> list[tuple[str, str]]: + """Parse landing.csv → list of (project_name, wiki_path).""" + rows = [] + with open(csv_path) as f: + reader = csv.reader(f) + header = next(reader) # skip header + for row in reader: + if not row or not row[0].strip(): + continue + project = row[0].strip() + url = row[1].strip() + # Strip wiki base to get wiki_path + wiki_path = url.replace("https://wiki.analog.com/", "") + rows.append((project, wiki_path)) + return rows + + +# --------------------------------------------------------------------------- +# File collection +# --------------------------------------------------------------------------- + +def collect_files(docs_dir: Path, wiki_path: str, stub: bool = False) -> dict[Path, str]: + """ + Collect landing RST + all subpage RSTs from wiki-migration/. + + Returns {absolute_path: content} for all files to move. + When stub=True, landing RST is optional (subfolder-only projects). + """ + files = {} + wm_dir = docs_dir / "wiki-migration" + + # Landing page + landing = wm_dir / f"{wiki_path}.rst" + if landing.exists(): + files[landing] = landing.read_text() + elif not stub: + print(f" WARNING: Landing page not found: {landing}") + return files + + # Subfolder + subfolder = wm_dir / wiki_path + if subfolder.is_dir(): + for rst in sorted(subfolder.rglob("*.rst")): + files[rst] = rst.read_text() + + return files + + +def build_moved_set(docs_dir: Path, collected: dict[Path, str]) -> set[str]: + """ + Build set of doc paths (e.g. "wiki-migration/resources/eval/...") + for all collected files — used to check if a :doc: target is a moved sibling. + """ + moved = set() + for p in collected: + rel = p.relative_to(docs_dir) + # Strip .rst suffix for doc path + doc = str(rel.with_suffix("")) + moved.add(doc) + return moved + + +# --------------------------------------------------------------------------- +# Path mapping +# --------------------------------------------------------------------------- + +def source_to_dest(src_path: Path, docs_dir: Path, wiki_path: str, + project: str, stub: bool = False) -> Path: + """ + Map a source wiki-migration path to its destination under reference-designs/. + + Landing page → reference-designs/{project}/index.rst (or keeps name if stub) + Subpages → reference-designs/{project}/{relative}.rst + """ + wm_dir = docs_dir / "wiki-migration" + landing = wm_dir / f"{wiki_path}.rst" + + if src_path == landing: + if stub: + return docs_dir / "solutions" / "reference-designs" / project / landing.name + return docs_dir / "solutions" / "reference-designs" / project / "index.rst" + + # Subpage: preserve structure relative to the wiki_path folder + rel = src_path.relative_to(wm_dir / wiki_path) + return docs_dir / "solutions" / "reference-designs" / project / rel + + +def doc_path_remap(doc_ref: str, moved_set: set[str], wiki_path: str, + project: str, stub: bool = False) -> str | None: + """ + Given a :doc: reference (absolute, like /wiki-migration/resources/...), + return the new reference path if it's a moved sibling, else None. + """ + # Strip leading / + clean = doc_ref.lstrip("/") + + if clean in moved_set: + # It's a moved page — compute new path + wm_prefix = f"wiki-migration/{wiki_path}" + if clean == f"wiki-migration/{wiki_path}": + if stub: + basename = wiki_path.split("/")[-1] + return f"/solutions/reference-designs/{project}/{basename}" + # Landing page → index + return f"/solutions/reference-designs/{project}/index" + elif clean.startswith(wm_prefix + "/"): + # Subpage + suffix = clean[len(wm_prefix) + 1:] + return f"/solutions/reference-designs/{project}/{suffix}" + + return None + + +# --------------------------------------------------------------------------- +# Link updates +# --------------------------------------------------------------------------- + +def update_doc_refs(content: str, moved_set: set[str], wiki_path: str, + project: str, verbose: bool = False, + stub: bool = False) -> str: + """ + Update :doc: references: + - Moved siblings → new path under reference-designs/ + - Non-moved pages → external wiki.analog.com link + """ + def replace_doc(m): + text = (m.group("text") or "").strip() + path = m.group("path1") or m.group("path2") + path = path.strip() + + new_path = doc_path_remap(path, moved_set, wiki_path, project, stub) + + if new_path is not None: + # Moved sibling — update path + if text: + return f":doc:`{text} <{new_path}>`" + else: + return f":doc:`{new_path}`" + else: + # Non-moved — convert to external link + # Strip /wiki-migration/ prefix to get wiki path + wiki_ref = path.lstrip("/") + if wiki_ref.startswith("wiki-migration/"): + wiki_ref = wiki_ref[len("wiki-migration/"):] + display = text if text else wiki_ref.split("/")[-1] + url = f"https://wiki.analog.com/{wiki_ref}" + if verbose: + print(f" :doc: → external: {path} → {url}") + return f"`{display} <{url}>`_" + + return DOC_REF_RE.sub(replace_doc, content) + + +def update_includes(content: str, rst_path: Path, docs_dir: Path, + moved_set: set[str], wiki_path: str, project: str, + dest_path: Path, verbose: bool = False) -> str: + """ + Update .. include:: directives: + - If target is a moved sibling → update relative path + - If target is non-moved → replace with .. note:: + link + """ + def replace_include(m): + indent = m.group("indent") + inc_path = m.group("path") + + # Resolve the include target relative to the source RST + resolved = (rst_path.parent / inc_path).resolve() + + # Check if it's under docs/ and in moved_set + try: + rel_to_docs = resolved.relative_to(docs_dir) + doc_key = str(rel_to_docs.with_suffix("")) + except ValueError: + doc_key = None + + if doc_key and doc_key in moved_set: + # Moved sibling — compute new relative path from dest + dest_resolved = source_to_dest(resolved, docs_dir, wiki_path, project) + new_rel = Path(dest_resolved).relative_to(dest_path.parent, + walk_up=True) if hasattr(Path, 'relative_to') else None + # Use os.path.relpath for compatibility + import os + new_rel = os.path.relpath(dest_resolved, dest_path.parent) + return f"{indent}.. include:: {new_rel}" + else: + # Non-moved — replace with note + link + # Try to derive wiki path from the resolved include target + try: + rel = resolved.relative_to(docs_dir / "wiki-migration") + wiki_ref = str(rel.with_suffix("")) + except ValueError: + wiki_ref = inc_path + url = f"https://wiki.analog.com/{wiki_ref}" + # Use a readable title from the path + title = wiki_ref.split("/")[-1].replace("_", " ").replace("-", " ").title() + if verbose: + print(f" include → note: {inc_path} → {url}") + note = f"{indent}.. note::\n{indent} See `{title} <{url}>`_." + return note + + return INCLUDE_RE.sub(replace_include, content) + + +# --------------------------------------------------------------------------- +# Image localization +# --------------------------------------------------------------------------- + +def collect_image_urls(files: dict[Path, str]) -> set[str]: + """Extract all wiki.analog.com/_media/ image paths from RST content.""" + urls = set() + for content in files.values(): + for m in IMAGE_URL_RE.finditer(content): + media_path = m.group(1) + # Skip binary artifacts (handled separately) + if any(media_path.lower().endswith(ext) for ext in BINARY_EXTS): + continue + urls.add(media_path) + return urls + + +def collect_binary_urls(files: dict[Path, str]) -> set[str]: + """Extract all wiki.analog.com/_media/ binary artifact paths.""" + urls = set() + for content in files.values(): + for m in IMAGE_URL_RE.finditer(content): + media_path = m.group(1) + if any(media_path.lower().endswith(ext) for ext in BINARY_EXTS): + urls.add(media_path) + return urls + + +def check_image_shared(media_path: str, docs_dir: Path, wiki_mig_dir: Path) -> bool: + """ + Check if an image URL is referenced by RSTs outside wiki-migration/. + + Returns True if shared (referenced elsewhere), False if exclusive. + """ + url_pattern = f"wiki.analog.com/_media/{re.escape(media_path)}" + # Search only .rst files, exclude build artifacts + result = subprocess.run( + ["grep", "-rl", "--include=*.rst", url_pattern, str(docs_dir)], + capture_output=True, text=True, check=False, + ) + if result.returncode != 0: + return False + + build_dir = docs_dir / "_build" + for line in result.stdout.strip().splitlines(): + p = Path(line) + # Skip build artifacts + try: + p.relative_to(build_dir) + continue + except ValueError: + pass + # Skip wiki-migration files + try: + p.relative_to(wiki_mig_dir) + except ValueError: + # Found reference outside wiki-migration/ + return True + return False + + +def localize_images(files: dict[Path, str], dest_map: dict[Path, Path], + media_dir: Path, docs_dir: Path, project: str, + dry_run: bool, verbose: bool) -> tuple[dict[Path, str], list[tuple[Path, Path]]]: + """ + Localize wiki image URLs to local paths. + + Returns updated file contents and list of (src, dest) copies to make. + """ + image_urls = collect_image_urls(files) + wiki_mig_dir = docs_dir / "wiki-migration" + copies = [] + # media_path → local relative path (from project root) + url_to_local: dict[str, str] = {} + + ref_designs_dir = docs_dir / "solutions" / "reference-designs" + project_dir = ref_designs_dir / project + + for media_path in sorted(image_urls): + # URL-decode the media path for filesystem lookup + decoded = urllib.parse.unquote(media_path) + local_media = media_dir / decoded + if not local_media.is_file(): + if verbose: + print(f" Image not found locally: {media_path}") + continue + + filename = local_media.name + shared = check_image_shared(media_path, docs_dir, wiki_mig_dir) + + if shared: + dest = ref_designs_dir / "images" / filename + # Relative from project subdir files: ../images/filename + url_to_local[media_path] = ("shared", filename) + else: + dest = project_dir / "images" / filename + url_to_local[media_path] = ("exclusive", filename) + + copies.append((local_media, dest)) + if verbose: + kind = "shared" if shared else "exclusive" + print(f" Image: {media_path} → {kind}: {dest.relative_to(docs_dir)}") + + # Update content + updated = {} + for src_path, content in files.items(): + dest_path = dest_map[src_path] + new_content = content + for media_path, (kind, filename) in url_to_local.items(): + full_url = f"https://wiki.analog.com/_media/{media_path}" + if full_url not in new_content: + continue + # Compute relative path from this RST to the images dir + if kind == "shared": + images_dir = ref_designs_dir / "images" + else: + images_dir = project_dir / "images" + + import os + rel = os.path.relpath(images_dir / filename, dest_path.parent) + new_content = new_content.replace(full_url, rel) + + updated[src_path] = new_content + + return updated, copies + + +def localize_binaries(files: dict[Path, str], dest_map: dict[Path, Path], + media_dir: Path, docs_dir: Path, project: str, + dry_run: bool, verbose: bool) -> tuple[dict[Path, str], list[tuple[Path, Path]]]: + """ + Localize binary artifact URLs to local paths. + Same exclusive/shared logic as images but uses resources/ instead of images/. + """ + binary_urls = collect_binary_urls(files) + wiki_mig_dir = docs_dir / "wiki-migration" + copies = [] + url_to_local: dict[str, tuple[str, str]] = {} + + ref_designs_dir = docs_dir / "solutions" / "reference-designs" + project_dir = ref_designs_dir / project + + for media_path in sorted(binary_urls): + decoded = urllib.parse.unquote(media_path) + local_media = media_dir / decoded + if not local_media.is_file(): + if verbose: + print(f" Binary not found locally: {media_path}") + continue + + filename = local_media.name + shared = check_image_shared(media_path, docs_dir, wiki_mig_dir) + + if shared: + dest = ref_designs_dir / "resources" / filename + url_to_local[media_path] = ("shared", filename) + else: + dest = project_dir / "resources" / filename + url_to_local[media_path] = ("exclusive", filename) + + copies.append((local_media, dest)) + if verbose: + kind = "shared" if shared else "exclusive" + print(f" Binary: {media_path} → {kind}: {dest.relative_to(docs_dir)}") + + # Update content + updated = {} + for src_path, content in files.items(): + dest_path = dest_map[src_path] + new_content = content + for media_path, (kind, filename) in url_to_local.items(): + full_url = f"https://wiki.analog.com/_media/{media_path}" + if full_url not in new_content: + continue + if kind == "shared": + resources_dir = ref_designs_dir / "resources" + else: + resources_dir = project_dir / "resources" + + import os + rel = os.path.relpath(resources_dir / filename, dest_path.parent) + new_content = new_content.replace(full_url, rel) + + updated[src_path] = new_content + + return updated, copies + + +# --------------------------------------------------------------------------- +# Stub index generation +# --------------------------------------------------------------------------- + +def extract_title(content: str, dir_name: str) -> str: + """Extract the first RST heading from content, or generate from dir_name.""" + lines = content.split('\n') + underline_chars = set('=-~^"\'`_+#*') + for i in range(len(lines)): + line = lines[i].rstrip() + if not line: + continue + # Check if next line is an underline + if i + 1 < len(lines): + next_line = lines[i + 1].rstrip() + if (next_line and len(set(next_line)) == 1 and + next_line[0] in underline_chars and + len(next_line) >= len(line)): + return line + # Check if this line is an overline (title is next line) + if (len(set(line)) == 1 and line[0] in underline_chars and + i + 1 < len(lines) and lines[i + 1].strip()): + return lines[i + 1].strip() + # Fallback: uppercase dir_name with underscores → hyphens + return dir_name.upper().replace('_', '-') + + +def generate_stub_index(title: str, page_names: list[str]) -> str: + """Generate a minimal index.rst with a toctree listing all sub-pages.""" + underline = '=' * len(title) + toctree_entries = '\n'.join(f' {name}' for name in page_names) + return f"""{title} +{underline} + +.. toctree:: + :titlesonly: + +{toctree_entries} +""" + + +# --------------------------------------------------------------------------- +# Main per-project workflow +# --------------------------------------------------------------------------- + +def process_project(project: str, wiki_path: str, repo_root: Path, + docs_dir: Path, media_dir: Path, + dry_run: bool, verbose: bool, + stub: bool = False) -> bool: + """Process a single project. Returns True on success.""" + print(f"\n{'='*60}") + print(f"Project: {project}") + print(f" wiki_path: {wiki_path}") + + ref_designs = docs_dir / "solutions" / "reference-designs" + dest_dir = ref_designs / project + + # Step 1: Skip check — does dest exist on main? + # Check if the directory exists in the main branch + r = git_in(repo_root, "ls-tree", "--name-only", + resolve_base(repo_root, "main"), + f"docs/solutions/reference-designs/{project}/", + check=False) + if r.returncode == 0 and r.stdout.strip(): + print(f" SKIP: {project}/ already exists on main") + return False + + # Step 2: Check if branch already exists + branch_name = f"wiki_migration/{project}_landing" + if branch_exists(repo_root, branch_name): + print(f" SKIP: Branch {branch_name} already exists") + return False + + # Step 3: Collect files (on wiki-migration branch) + orig_branch = current_branch(repo_root) + if orig_branch != "wiki-migration": + git_in(repo_root, "checkout", "wiki-migration") + + collected = collect_files(docs_dir, wiki_path, stub) + if not collected: + print(f" SKIP: No files found for {wiki_path}") + if current_branch(repo_root) != orig_branch: + git_in(repo_root, "checkout", orig_branch) + return False + + print(f" Collected {len(collected)} files") + + # Build moved set and destination map + moved_set = build_moved_set(docs_dir, collected) + dest_map: dict[Path, Path] = {} + for src_path in collected: + dest_map[src_path] = source_to_dest(src_path, docs_dir, wiki_path, project, stub) + + if verbose: + print(f" Moved set ({len(moved_set)} pages):") + for p in sorted(moved_set): + print(f" {p}") + + if dry_run: + print(f"\n [DRY RUN] Would create branch: {branch_name}") + print(f" [DRY RUN] File mapping:") + for src, dst in sorted(dest_map.items()): + print(f" {src.relative_to(docs_dir)} → {dst.relative_to(docs_dir)}") + + # Still process links to show what would change + for src_path, content in collected.items(): + dest_path = dest_map[src_path] + updated = update_doc_refs(content, moved_set, wiki_path, project, verbose, stub) + updated = update_includes(updated, src_path, docs_dir, moved_set, + wiki_path, project, dest_path, verbose) + + # Show image localization preview + image_urls = collect_image_urls(collected) + binary_urls = collect_binary_urls(collected) + print(f" [DRY RUN] Images to localize: {len(image_urls)}") + print(f" [DRY RUN] Binaries to localize: {len(binary_urls)}") + if verbose: + for url in sorted(image_urls): + decoded = urllib.parse.unquote(url) + local = media_dir / decoded + exists = "✓" if local.exists() else "✗" + print(f" [{exists}] {url}") + for url in sorted(binary_urls): + decoded = urllib.parse.unquote(url) + local = media_dir / decoded + exists = "✓" if local.exists() else "✗" + print(f" [{exists}] {url}") + if stub: + print(f" [DRY RUN] Would generate stub index.rst") + + return True + + # Step 4: Create branch from main + resolved_main = resolve_base(repo_root, "main") + git_in(repo_root, "checkout", "-b", branch_name, resolved_main) + print(f" Created branch: {branch_name}") + + # Step 5: Update links in all moved RSTs + updated_files = {} + for src_path, content in collected.items(): + dest_path = dest_map[src_path] + updated = update_doc_refs(content, moved_set, wiki_path, project, verbose, stub) + updated = update_includes(updated, src_path, docs_dir, moved_set, + wiki_path, project, dest_path, verbose) + updated_files[src_path] = updated + + # Step 6: Localize images + updated_files, image_copies = localize_images( + updated_files, dest_map, media_dir, docs_dir, project, dry_run, verbose + ) + + # Step 7: Localize binaries + updated_files, binary_copies = localize_binaries( + updated_files, dest_map, media_dir, docs_dir, project, dry_run, verbose + ) + + # Step 7b: Re-fix table alignment after link/image updates + # Link conversion widens cell content (e.g. :doc: → external URL), + # so tables need realignment after all content modifications. + for src_path in list(updated_files): + updated_files[src_path] = fix_grid_tables(updated_files[src_path]) + updated_files[src_path] = fix_simple_tables(updated_files[src_path]) + + # Step 8: Write files + for src_path, content in updated_files.items(): + dest_path = dest_map[src_path] + dest_path.parent.mkdir(parents=True, exist_ok=True) + dest_path.write_text(content) + if verbose: + print(f" Wrote: {dest_path.relative_to(docs_dir)}") + + # Copy images + for src, dst in image_copies: + dst.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(src, dst) + if verbose: + print(f" Copied image: {dst.relative_to(docs_dir)}") + + # Copy binaries + for src, dst in binary_copies: + dst.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(src, dst) + if verbose: + print(f" Copied binary: {dst.relative_to(docs_dir)}") + + print(f" Wrote {len(updated_files)} RSTs, " + f"{len(image_copies)} images, {len(binary_copies)} binaries") + + # Step 8b: Generate stub index if needed + if stub: + wm_dir = docs_dir / "wiki-migration" + landing = wm_dir / f"{wiki_path}.rst" + if landing in collected: + title = extract_title(collected[landing], project) + else: + title = project.upper().replace('_', '-') + + # Build toctree entries + page_names = [] + landing_name = None + for src_path in collected: + dest_path = dest_map[src_path] + rel = dest_path.relative_to(dest_dir) + name = str(rel.with_suffix('')) + if src_path == landing: + landing_name = name + else: + page_names.append(name) + page_names.sort() + if landing_name: + page_names.insert(0, landing_name) + + stub_content = generate_stub_index(title, page_names) + index_path = dest_dir / "index.rst" + index_path.parent.mkdir(parents=True, exist_ok=True) + index_path.write_text(stub_content) + print(f" Generated stub index.rst with {len(page_names)} toctree entries") + + # Step 8c: Append hidden toctree to index.rst (non-stub mode) + # The landing page was renamed to index.rst but has no toctree, + # so sub-pages are orphaned (toc.not_included warnings). + if not stub: + index_path = dest_dir / "index.rst" + if index_path.exists(): + page_names = [] + for src_path in collected: + dest_path = dest_map[src_path] + if dest_path != index_path: + rel = dest_path.relative_to(dest_dir) + page_names.append(str(rel.with_suffix(''))) + if page_names: + page_names.sort() + toctree = "\n\n.. toctree::\n :hidden:\n\n" + toctree += "\n".join(f" {name}" for name in page_names) + "\n" + content = index_path.read_text() + index_path.write_text(content + toctree) + print(f" Appended hidden toctree with {len(page_names)} entries to index.rst") + + # Step 9: Stage and commit + git_in(repo_root, "add", f"docs/solutions/reference-designs/{project}/") + # Also add shared images/resources if any were created + shared_img = ref_designs / "images" + shared_res = ref_designs / "resources" + if shared_img.exists(): + git_in(repo_root, "add", str(shared_img.relative_to(repo_root))) + if shared_res.exists(): + git_in(repo_root, "add", str(shared_res.relative_to(repo_root))) + + if stub: + n_pages = len(collected) + msg = (f"wiki-migration: add {project} documentation to reference-designs/\n\n" + f"Move {n_pages} page{'s' if n_pages != 1 else ''} " + f"from wiki-migration/ to solutions/reference-designs/{project}/.\n" + f"Generated stub index.rst with toctree.\n" + f"Localized {len(image_copies)} images, {len(binary_copies)} binary artifacts.\n" + f"Updated :doc: links and includes.") + else: + msg = (f"wiki-migration: move {project} landing page to reference-designs/\n\n" + f"Move {wiki_path} landing page and {len(collected)-1} subpages\n" + f"from wiki-migration/ to solutions/reference-designs/{project}/.\n" + f"Localized {len(image_copies)} images, {len(binary_copies)} binary artifacts.\n" + f"Updated :doc: links and includes.") + git_in(repo_root, "commit", "-m", msg) + print(f" Committed on {branch_name}") + + # Return to wiki-migration for next project + git_in(repo_root, "checkout", "wiki-migration") + + return True + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser( + description="Move wiki-migration landing pages to reference-designs/", + ) + parser.add_argument("csv", type=Path, help="CSV file with (project, wiki_url) rows") + parser.add_argument("--dry-run", action="store_true", + help="Preview changes without creating branches or files") + parser.add_argument("--projects", nargs="+", metavar="P", + help="Only process these projects (default: all)") + parser.add_argument("--verbose", "-v", action="store_true", + help="Show detailed output") + parser.add_argument("--stub", action="store_true", + help="Generate stub index.rst instead of renaming landing page") + args = parser.parse_args() + + # Resolve paths + script_dir = Path(__file__).resolve().parent + repo_root = find_repo_root(script_dir) + if repo_root is None: + print("ERROR: Not inside a git repository") + sys.exit(1) + + docs_dir = repo_root / "docs" + media_dir = Path(__file__).resolve().parent.parent.parent / "wiki-web" / "media" + + if not docs_dir.exists(): + print(f"ERROR: docs/ not found at {docs_dir}") + sys.exit(1) + + if not media_dir.exists(): + print(f"WARNING: wiki-web/media/ not found at {media_dir}") + print(" Image localization will be skipped for missing files") + + # Parse CSV + rows = parse_csv(args.csv) + if not rows: + print("ERROR: No projects found in CSV") + sys.exit(1) + + # Filter projects if specified + if args.projects: + filter_set = set(args.projects) + rows = [(p, w) for p, w in rows if p in filter_set] + if not rows: + print(f"ERROR: None of {args.projects} found in CSV") + sys.exit(1) + + print(f"Processing {len(rows)} projects from {args.csv}") + if args.dry_run: + print("[DRY RUN MODE]") + + # Ensure we start on wiki-migration + orig_branch = current_branch(repo_root) + + success = 0 + skipped = 0 + for project, wiki_path in rows: + try: + if process_project(project, wiki_path, repo_root, docs_dir, + media_dir, args.dry_run, args.verbose, + args.stub): + success += 1 + else: + skipped += 1 + except Exception as e: + print(f" ERROR: {e}") + import traceback + traceback.print_exc() + # Try to return to wiki-migration + try: + git_in(repo_root, "checkout", "wiki-migration", check=False) + except Exception: + pass + skipped += 1 + + # Return to original branch + if current_branch(repo_root) != orig_branch: + git_in(repo_root, "checkout", orig_branch) + + print(f"\n{'='*60}") + print(f"Done: {success} processed, {skipped} skipped") + + +if __name__ == "__main__": + main() diff --git a/scripts/repo-cache.json b/scripts/repo-cache.json new file mode 100644 index 00000000000..2c7d967d5fc --- /dev/null +++ b/scripts/repo-cache.json @@ -0,0 +1,7 @@ +{ + "/home/a/doc-migration/hdl/docs/user_guide/build.rst": { + "repo": "hdl", + "doc_root": "docs", + "doc_rel": "user_guide/build" + } +}