diff --git a/doc/sphinx/source/drivers/talise.rst b/doc/sphinx/source/drivers/talise.rst new file mode 100644 index 00000000000..541b5104878 --- /dev/null +++ b/doc/sphinx/source/drivers/talise.rst @@ -0,0 +1 @@ +.. include:: ../../../../drivers/rf-transceiver/talise/README.rst \ No newline at end of file diff --git a/doc/sphinx/source/drivers_doc.rst b/doc/sphinx/source/drivers_doc.rst index 0576816d7ea..f8510efb8bc 100644 --- a/doc/sphinx/source/drivers_doc.rst +++ b/doc/sphinx/source/drivers_doc.rst @@ -100,6 +100,7 @@ RF TRANSCEIVER :maxdepth: 1 drivers/madura + drivers/talise TEMPERATURE ============== diff --git a/drivers/rf-transceiver/talise/README.rst b/drivers/rf-transceiver/talise/README.rst new file mode 100644 index 00000000000..0a1b356ade9 --- /dev/null +++ b/drivers/rf-transceiver/talise/README.rst @@ -0,0 +1,476 @@ +ADRV9009 no-OS Driver +===================== + +Supported Devices +----------------- + +- :adi:`ADRV9009` + +Overview +-------- + +The ADRV9009 is a highly integrated radio frequency (RF) agile +transceiver offering dual transmitters and receivers, integrated +synthesizers, and digital signal processing functions. The IC delivers a +versatile combination of high performance and low power consumption +demanded by 3G, 4G, and 5G macro cell time division duplex (TDD) base +station applications. The receive path consists of two independent, wide +bandwidth, direct conversion receivers with state-of-the-art dynamic +range, and it supports a wide bandwidth, time-shared observation +receiver (ORx) for use in TDD applications. The transmitters use an +innovative direct conversion modulator that achieves high modulation +accuracy with exceptionally low noise, while the fully integrated +phase-locked loop (PLL) provides high performance, low power, +fractional-N RF frequency synthesis for the transmitter (Tx) and +receiver (Rx) signal paths. + +Applications +------------ + +- 3G, 4G, and 5G TDD macrocell base stations +- TDD active antenna systems +- Massive multiple input, multiple output (MIMO) +- Phased array radar +- Electronic warfare +- Military communications +- Portable test equipment + +Device Configuration +-------------------- + +Device Initialization and Core Control +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Initialization functions allocate and initialize core data structures, +set up SPI, clocks, and JESD204B settings, and parse user-provided or +default AGC parameters. Key routines include: + +- ``adrv9009_init`` – Allocates the RF PHY structure, copies + initialization parameters, and invokes helper routines such as AGC + parameter parsing. + +- ``adrv9009_setup`` – Performs low‑level hardware initialization + including SPI configuration and clock descriptor setup for various + sample clocks, while reading device revision and API versions. + +- ``adrv9009_post_setup`` – Finalizes ADC/DAC configuration by + programming per‑channel conversion settings, updating DAC rate + registers, and computing DAC clock frequency. + + Additional helper macros (e.g., __adrv9009_of_get_param and + ADRV9009_OF_PROP) are used to apply default values when necessary. + +JESD204B Link Configuration and Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This function group is dedicated to setting up and monitoring the high‑speed +JESD204B serial interface that connects the transceiver with downstream +processing. These routines configure serializer/deserializer hardware, +manage framer/deframer parameters, and enable SYSREF signals for proper +synchronization. Notable functions include: + +- ``adrv9009_jesd204_link_init`` – Initializes JESD204 links by + assigning lane mappings and calculating lane rates. + +- ``TALISE_setupSerializers`` or ``TALISE_setupDeserializers`` – Configure + serializer and deserializer settings such as pre‑emphasis and lane + polarity. + +- ``TALISE_setupJesd204bFramer`` or ``TALISE_setupJesd204bDeframer`` – + Program framer/deframer parameters including bank IDs and SYSREF + routing. + +- ``adrv9009_jesd204_clks_enable`` and ``adrv9009_jesd204_link_enable`` + – Enable SYSREF signals and activate the JESD204B links. + +- ``adrv9009_jesd204_setup_stage1 … stage5`` – Execute a multi‑stage + state machine covering multi‑chip sync, ARM/stream processor binary + loading, PLL lock verification, and calibration triggering. + + These routines combine low‑level SPI operations with integrated + error handling to ensure robust JESD204B communication. + +Automatic Gain Control (AGC) Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +AGC routines dynamically adjust signal strength to optimize performance +under varying conditions. These functions set gain limits, adjust delay +parameters, manage peak detection timing, and handle power measurement +settings. Essential routines include: + +- ``TALISE_setupRxAgc`` and ``TALISE_resetRxAgc`` – Initialize and reset + the AGC for Rx channels by writing configuration values to device + registers. + +- ``TALISE_setupDualBandRxAgc`` – Configure dual‑band AGC for Rx + channels when external LNAs are used, including setting 3.3V GPIO + parameters for dual‑band LNA gains. + +- Readback functions such as ``TALISE_getAgcCtrlRegisters``, + ``TALISE_getAgcPeakRegisters``, and ``TALISE_getAgcPowerRegisters`` + provide monitoring capabilities. + +- ``TALISE_setRxAgcMinMaxGainIndex`` – Dynamically adjusts the gain + range for receive channels. + +Transmit (Tx) Path Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tx configuration routines control output attenuation, DAC full‑scale +settings, test tone generation via NCOs, and PA protection. This section +enables fine‑grained manipulation of transmit signal characteristics. +Key functions include: + +- ``TALISE_setTxAttenuation`` and ``TALISE_getTxAttenuation`` – Set or + retrieve Tx attenuation levels by converting milli‑dB values into + register settings. + +- ``TALISE_setTxAttenCtrlPin`` and ``TALISE_getTxAttenCtrlPin`` – Manage + GPIO‑based controls for dynamic attenuation adjustments. + +- ``TALISE_setDacFullScale`` – Program the Tx DAC’s full‑scale value + before the ARM firmware is loaded. + +- ``TALISE_txNcoShifterSet`` and ``TALISE_enableTxNco`` – Configure the + on‑chip NCO for generating test tones with precise phase control. + +- ``TALISE_setPaProtectionCfg``, ``TALISE_getPaProtectionCfg``, and + ``TALISE_enablePaProtection`` – Set PA protection thresholds and + monitor power levels to prevent overdriving. + +- ``TALISE_getTxSamplePower`` – Read and convert raw ADC values to + dBFS for transmit power monitoring. + +Receive (Rx) Path and Data Formatting Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rx configuration involves setting gain tables, controlling gain modes, +and formatting ADC output for subsequent processing. This section +provides routines for both manual and automated gain adjustments, as +well as for selecting data output formats. Featured functions include: + +- ``TALISE_programRxGainTable`` and ``TALISE_programOrxGainTable`` – + Load gain table entries for normal and observation Rx channels, + establishing front‑end, external, and digital gain settings. + +- ``TALISE_setRxManualGain``, ``TALISE_getRxGain``, + ``TALISE_setObsRxManualGain``, and ``TALISE_getObsRxGain`` – Enable + and query manual gain modes. + +- ``TALISE_setRxGainControlMode`` – Select between manual gain control + and various AGC modes. + +- ``TALISE_setRxDataFormat``, ``TALISE_getRxDataFormat``, and + ``TALISE_getSlicerPosition`` – Define the digital data output format, + whether floating‑point or integer with slicer bits. + +- ``TALISE_setRxGainCtrlPin`` and ``TALISE_getRxGainCtrlPin`` – Allow + external gain control via GPIO, and + ``TALISE_setGainTableExtCtrlPins`` maps GPIO outputs to the current + gain index. + +Calibration and Tracking +~~~~~~~~~~~~~~~~~~~~~~~~ + +Calibration routines optimize performance across both the Tx and Rx +paths by correcting DC offsets, IQ imbalances, and phase misalignments. +This section is divided into initialization and continuous tracking +calibrations. Core functions include: + +- ``TALISE_runInitCals``, ``TALISE_waitInitCals``, + ``TALISE_checkInitCalComplete``, ``TALISE_abortInitCals``, and + ``TALISE_getInitCalStatus`` – Execute and verify the initial + calibration process (including DC offset, LO leakage, and quadrature + corrections). + +- ``TALISE_enableTrackingCals``, ``TALISE_getEnabledTrackingCals``, + ``TALISE_getPendingTrackingCals``, ``TALISE_rescheduleTrackingCal``, + ``TALISE_setAllTrackCalState``, and ``TALISE_getAllTrackCalState`` – + Manage continuous tracking calibrations to adapt to changing + operational conditions. + +- Status query functions like ``TALISE_getTxLolStatus``, + ``TALISE_getTxQecStatus``, ``TALISE_getRxQecStatus``, + ``TALISE_getOrxQecStatus``, and ``TALISE_getRxHd2Status`` provide + detailed metrics on calibration performance. + +ARM Processor Interface +~~~~~~~~~~~~~~~~~~~~~~~ + +The Talise transceiver integrates an embedded ARM processor to offload +tasks such as calibration, digital processing, and system monitoring. +The ARM interface provides functions for memory transfer, command +execution, and debugging. Key routines include: + +- ``TALISE_initArm``, ``TALISE_writeArmProfile``, + ``TALISE_loadArmFromBinary``, and ``TALISE_loadAdcProfiles`` – + Initialize the ARM processor by loading firmware and configuration + profiles, setting DMA, and verifying firmware integrity. + +- ``TALISE_readArmMem``, ``TALISE_writeArmMem``, + ``TALISE_writeArmConfig``, and ``TALISE_readArmConfig`` – Perform + low‑level memory operations using DMA and auto‑increment mechanisms. + +- ``TALISE_sendArmCommand``, ``TALISE_readArmCmdStatus``, and + ``TALISE_waitArmCmdStatus`` – Facilitate a command-control interface + via the ARM mailbox. + +- ``TALISE_getArmVersion_v2`` and ``TALISE_verifyArmChecksum`` – + Retrieve firmware version info and verify checksum integrity. + Additional error handling functions such as + ``talGetArmErrorMessage`` and ``talArmCmdErrorHandler`` ensure + reliable ARM communication. + +Hardware Abstraction Layer (HAL) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +HAL functions provide a consistent interface for low‑level SPI +operations and logging, abstracting the hardware details away from +higher‑level configuration routines. These functions manage timeout +settings, handle retries, and encapsulate register read/write +operations. Core routines include: + +- ``talSpiReadByte`` and ``talSpiWriteByte`` – Handle single‑byte SPI + transactions with built‑in timeout and retry logic. + +- ``talSpiReadBytes`` and ``talSpiWriteBytes`` – Manage multi‑byte + buffer SPI transfers. + +- ``talSpiReadField`` and ``talSpiWriteField`` – Offer fine‑grained + access to specific bit fields within registers. + +- ``talWriteToLog`` – Integrate logging support via ADI HAL routines for + error and diagnostic tracking. + +GPIO Configuration +~~~~~~~~~~~~~~~~~~ + +GPIO configuration functions provide control over various pin operations +used for SPI, external gain control, debug signal monitoring, and +auxiliary interfacing. These functions are organized into logical +groups: + +Low Voltage & 3.3V GPIO Control +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- ``TALISE_setGpioOe`` and ``TALISE_getGpioOe`` – Set and read output + enable settings for low‑voltage GPIOs. + +- ``TALISE_setGpioSourceCtrl`` and ``TALISE_getGpioSourceCtrl`` – + Configure multiplexer selections for low‑voltage GPIOs. + +- ``TALISE_setGpioPinLevel``, ``TALISE_getGpioPinLevel``, and + ``TALISE_getGpioSetLevel`` – Drive and verify pin levels in bit‑bang + mode; similar functions with the 3v3 prefix handle 3.3V GPIOs. + +Monitor, Interrupt, and Auxiliary Interfaces +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These functions cover the routing of debug signals, interrupt management, +and auxiliary DAC/ADC operations. Key routines include: + +- ``TALISE_setGpioMonitorOut`` and ``TALISE_getGpioMonitorOut`` – Route + internal signals for external debugging. + +- ``TALISE_setGpIntMask``, ``TALISE_getGpIntMask``, + ``TALISE_getGpIntStatus``, and ``TALISE_gpIntHandler`` – Manage + general purpose interrupts. + +- ``TALISE_setupAuxDacs`` and ``TALISE_writeAuxDac`` – Configure and + update auxiliary DAC outputs. + +- ``TALISE_setAuxAdcPinModeGpio``, ``TALISE_getAuxAdcPinModeGpio``, + ``TALISE_startAuxAdc``, and ``TALISE_readAuxAdc`` – Set up and read + from the auxiliary ADC. + +- ``TALISE_setSpi2Enable`` and ``TALISE_getSpi2Enable`` – Control the + secondary SPI interface used for Tx attenuation. + +- ``TALISE_getTemperature`` – Retrieve on‑chip temperature sensor data + via the ARM processor, with ``talGetGpioErrorMessage`` providing + human‑readable error descriptions. + +Radio Control and Pin Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Radio control functions integrate firmware streaming, power management, +and frequency configuration to enable dynamic adaptation of the +transceiver. These routines handle control pin settings, LO +configuration, and mapping between transmit and observation channels. +Featured functions include: + +- ``TALISE_loadStreamFromBinary`` – Load the stream processor’s firmware + image. + +- ``TALISE_setArmGpioPins`` – Configure ARM‑assigned GPIOs for + time‑division duplex and radio control purposes. + +- ``TALISE_setRadioCtlPinMode`` and ``TALISE_getRadioCtlPinMode`` – Set + and query radio control pin modes. + +- ``TALISE_setOrxLoCfg`` and ``TALISE_getOrxLoCfg`` – Configure + observation receiver LO settings. + +- ``TALISE_radioOn``, ``TALISE_radioOff``, and ``TALISE_getRadioState`` + – Control and monitor the overall radio power state. + +- ``TALISE_setRxTxEnable`` and ``TALISE_getRxTxEnable`` – Manage signal + path enablement and channel mapping. + +- ``TALISE_setTxToOrxMapping`` – Map Tx channels to ORx channels for + calibration purposes. + + Additional routines control RF PLL frequency, set loop filters, + manage frequency hopping (e.g., ``TALISE_setFhmConfig``, + ``TALISE_setFhmMode``, ``TALISE_setFhmHop``, etc.), and adjust + external LO outputs. + +Driver Initialization Example +----------------------------- + +.. code-block:: C + + #include "no_os_error.h" + #include "no_os_alloc.h" + #include "no_os_delay.h" + #include "adrv9009.h" + #include "talise_types.h" + + /* Platform-specific objects defined elsewhere */ + extern struct no_os_spi_init_param adrv9009_spi_ip; + extern struct no_os_clk_desc *dev_clk; + extern taliseDevice_t *adrv9009_device_ptr; + + /* Example RX AGC configuration parameters; populate with valid values */ + taliseAgcCfg_t rxAgcCfg = { + .agcPeak = { + .agcUnderRangeLowInterval_ns = 205, + .agcUnderRangeMidInterval = 2, + .agcUnderRangeHighInterval = 4, + .apdHighThresh = 39, + .apdLowGainModeHighThresh = 36, + .apdLowThresh = 23, + .apdLowGainModeLowThresh = 19, + .apdUpperThreshPeakExceededCnt = 6, + .apdLowerThreshPeakExceededCnt = 3, + .apdGainStepAttack = 4, + .apdGainStepRecovery = 2 + }, + .agcPower = { + .powerEnableMeasurement = 1, + .powerUseRfirOut = 1, + .powerUseBBDC2 = 0, + .underRangeHighPowerThresh = 9, + .underRangeLowPowerThresh = 2, + .underRangeHighPowerGainStepRecovery= 4, + .underRangeLowPowerGainStepRecovery = 4, + .powerMeasurementDuration = 5, + .rx1TddPowerMeasDuration = 5, + .rx1TddPowerMeasDelay = 1, + .rx2TddPowerMeasDuration = 5, + .rx2TddPowerMeasDelay = 1, + .upper0PowerThresh = 2, + .upper1PowerThresh = 0, + .powerLogShift = 0 + }, + .agcPeakWaitTime = 4, + .agcRx1MaxGainIndex = 255, + .agcRx1MinGainIndex = 195, + .agcRx2MaxGainIndex = 255, + .agcRx2MinGainIndex = 195, + .agcGainUpdateCounter_us = 250, + .agcRx1AttackDelay = 10, + .agcRx2AttackDelay = 10, + .agcSlowLoopSettlingDelay = 16, + .agcLowThreshPreventGain = 0, + .agcChangeGainIfThreshHigh = 1, + .agcPeakThreshGainControlMode = 1, + .agcResetOnRxon = 0, + .agcEnableSyncPulseForGainCounter = 0, + .agcEnableIp3OptimizationThresh = 0, + .ip3OverRangeThresh = 31, + .ip3OverRangeThreshIndex = 246, + .ip3PeakExceededCnt = 4, + .agcEnableFastRecoveryLoop = 0 + }; + + adrv9009_init_param init_param = { + .spi_init = &adrv9009_spi_ip, + .dev_clk = dev_clk, + .adrv9009_device = adrv9009_device_ptr, + .streamImageFile = "stream.bin", + .armImageFile = "arm.bin", + .rxAgcConfig_init_param = &rxAgcCfg, + .trx_lo_frequency = 2400000000ULL, + .tx_pa_protection = { + .tx1PowerThreshold = 4096, + .tx2PowerThreshold = 4096, + .tx1PeakThreshold = 128, + .tx2PeakThreshold = 128, + } + }; + + struct adrv9009_rf_phy *phy; + int ret; + + /* Initialize the ADRV9009 device */ + ret = adrv9009_init(&phy, &init_param); + if (ret) { + printf("ADRV9009 initialization failed: %d\n", ret); + goto init_error; + } + printf("ADRV9009 initialization successful\n"); + + /* Set AGC min/max gain index for RX1 */ + ret = TALISE_setRxAgcMinMaxGainIndex(phy->talise, TAL_RX1, 195, 255); + if (ret) { + printf("Failed to set RX1 AGC min/max gain index: %d\n", ret); + goto init_error; + } + + /* Read back AGC control registers */ + taliseAgcCtrl_t agc_ctrl = {0}; + ret = TALISE_getAgcCtrlRegisters(phy->talise, TAL_RX1, &agc_ctrl); + if (ret) { + printf("Failed to read RX1 AGC control registers: %d\n", ret); + goto init_error; + } + + /* Reset AGC for RX1 */ + ret = TALISE_resetRxAgc(phy->talise, TAL_RX1); + if (ret) { + printf("Failed to reset RX1 AGC: %d\n", ret); + goto init_error; + } + + /* Enable radio */ + ret = TALISE_radioOn(phy->talise); + if (ret) { + printf("Failed to turn radio on: %d\n", ret); + goto init_error; + } + + /* Set Tx attenuation for channel 1 */ + ret = TALISE_setTxAttenuation(phy->talise, TAL_TX1, 10000); /* 10 dB */ + if (ret) { + printf("Failed to set TX1 attenuation: %d\n", ret); + goto init_error; + } + + /* Get temperature */ + int16_t temp = 0; /* Initialize to a default value */ + ret = TALISE_getTemperature(phy->talise, &temp); + if (ret) { + printf("Failed to read temperature: %d\n", ret); + goto init_error; + } + printf("Device temperature: %d\n", temp); + + printf("AGC configuration and queries successful\n"); + goto exit; + + init_error: + printf("Error encountered during ADRV9009 initialization or AGC configuration\n"); + + exit: + ;