Post Go back to editing

Change in Tx channel latency after recovery from sleep mode

Category: Hardware
Product Number: ADRV9004

Hello,

As the title says, during my recent product development I discovered the problem with Tx channel latency on my custom board with the ADRV9004 chip on it. I observe an additional, randomly changing Tx channel latency after recovering from sleep mode. It varies between 0 and 6 samples. Once the chip wakes up this value remains constant. However, after the first power up the latency is deterministic and always the same. I managed to connect the MCS signal from the chip to the FPGA although I hadn't considered this in my design, in the hope that it would help, but it seems that MCS synchronisation is only available after calibration and cannot be done later. My initial thought was that some output data would get stuck in the FPGA's FIFO after LSSI shuts down, but it seems that is not the case. What I now think is that the data is somehow stuck inside the ADRV9004 somewhere at the interpolation stage.

Could you please tell me if there is a way to keep the latency constant or at least to determine the additional latency value?

Kind regards,

bartk

  • Hi bartk,

    We will get back to you.

    Regards 

    Rahul 

  • Thank you, I'm looking forward to your reply.

    In the meantime, I have observed situations where my transmitted signal is delayed by 12 samples (more than I described before). I checked my generated profile settings in the TES GUI and the interpolation factor is exactly 12, supporting my last thesis.

  • Hi Bartk,

    Can you provide us with the test bench block diagram and taxidi file so that we can replicate the issue at our side.

    Regards 

    Rahul 

  • Hi Rahul,

    I've just made a simple block diagram to show the design. The signal called SYNC is generated synchronously with each first Tx sample and is used as a time reference


     

    In the meantime, I have found a workaround by enabling and disabling LSSI test modes. The code is attached below. I run it after every sleep recovery. It seems to clean up some buffers under the hood. Any RF signal generated is now stable, with constant time to the SYNC signal. The only problem is my lack of trust to this solution but I think it might be helpful for you.

     adi_adrv9001_TxSsiTestModeCfg_t txCfg = {.fixedDataPatternToCheck = 0, .testData = ADI_ADRV9001_SSI_TESTMODE_DATA_FIXED_PATTERN};
     adi_adrv9001_RxSsiTestModeCfg_t rxCfg = {.fixedDataPatternToTransmit = 0, .testData = ADI_ADRV9001_SSI_TESTMODE_DATA_FIXED_PATTERN} ;
     
     adi_adrv9001_Ssi_Tx_TestMode_Configure(device, ADI_CHANNEL_1, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &txCfg);
     adi_adrv9001_Ssi_Tx_TestMode_Configure(device, ADI_CHANNEL_2, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &txCfg);
     adi_adrv9001_Ssi_Rx_TestMode_Configure(device, ADI_CHANNEL_1, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &rxCfg);
     adi_adrv9001_Ssi_Rx_TestMode_Configure(device, ADI_CHANNEL_2, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &rxCfg);
    
     txCfg.testData = ADI_ADRV9001_SSI_TESTMODE_DATA_NORMAL;
     rxCfg.testData = ADI_ADRV9001_SSI_TESTMODE_DATA_NORMAL;
    
     adi_adrv9001_Ssi_Tx_TestMode_Configure(device, ADI_CHANNEL_1, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &txCfg);
     adi_adrv9001_Ssi_Tx_TestMode_Configure(device, ADI_CHANNEL_2, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &txCfg);
     adi_adrv9001_Ssi_Rx_TestMode_Configure(device, ADI_CHANNEL_1, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &rxCfg);
     adi_adrv9001_Ssi_Rx_TestMode_Configure(device, ADI_CHANNEL_2, ADI_ADRV9001_SSI_TYPE_LVDS, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &rxCfg);



    But it's not over yet because I'm seeing the same thing on the Rx channels and I'm about to debug if it's not my fault this time.

    Attachment below.
    profile.zip

  • Hi Rahul,

    Would it be possible to receive an update?

    Regards,
    bartk

  • Hi Bartk,

    We are looking into the issue and trying to replicate. Once we replicate it we will update you if this is a normal behavior or a bug.

    Can I know how did you measure the sample delays?

    Regards

    Rahul 

  • I connected the RF output and the SYNC signal to an oscilloscope and measured the delay between the SYNC signal and the RF pulse with and without the sleep function, and it changed between measurements and after each sleep mode recovery. Then I described the time difference in sampling time domain.


    Regards,

    Bartk

  • Hi Bartk,

    We have tried to replicate the issue using your profile and measured the tx latency before and after the chip power up. We have used tx enable and HOP pin as the reference to see the variation in the signal for the defined carrier and frequency hopping mode respectively. We have observed that there is a signal variation of ~12 samples in FH mode when using the MUX real time but not when using the LO retune as configured in the provided taxidi file and no variation using the defined carrier.

    Before the LDO turned off 

    The above figure shows the latency between the Tx enable and the signal which is around 6.3504 us and the variation within the signal itself which is about 49.4ns.

    After turning off and on the LDO we can see the variation between Tx enable and signal of about 6.578us which is 0.2276us (227.6ns). The time taken for one sample is 20.8ns for 48MSPS data port rate. So the total variation between the TX Enable and signal after the LDO power on/off is about ~12 samples. Also we can notice that the signal itself is interrupted as can be notices from both the figures.

    I would like to point out that we couldn't able to see this issue using the taxidi file provided by you. So I would like to confirm is this behavior you are also seeing at your end and have you chose HOP mode as MUX Real-Time or Dual HOP LO retune.

    Currently we are still investigating this issue and we will get back to you.

    Regards

    Rahul 

  • Hi Rahul,

    Thank you for providing the update. I am pleased to hear that you were able to replicate the issue. The behaviour is the same as I've seen.

    I have just checked the provided taxidi file and can confirm that it is the configuration which revealed the issue.

    To be more specific the way we use FH is based on answer from the thread initiated by my colleague:
    ez.analog.com/.../adrv9002-lo-assignment

    During initialisation, we run the following code:

    adi_adrv9001_FhHopFrame_t hopTable1090[] = {
        {
            .rx1OffsetFrequencyHz = 0,
            .rx2OffsetFrequencyHz = 0,
            .tx1Attenuation_fifthdB = 0U,
            .tx2Attenuation_fifthdB = 0U,
            .rx1GainIndex = 255U,
            .rx2GainIndex = 255U,
            .hopFrequencyHz = 1090000000ULL
        }
    };
    
    adi_adrv9001_FhHopFrame_t hopTable1030[] = {
        {
            .rx1OffsetFrequencyHz = 0,
            .rx2OffsetFrequencyHz = 0,
            .tx1Attenuation_fifthdB = 0U,
            .tx2Attenuation_fifthdB = 0U,
            .rx1GainIndex = 255U,
            .rx2GainIndex = 255U,
            .hopFrequencyHz = 1030000000ULL
        }
    };
    
    
        funResult = adi_adrv9001_fh_HopTable_Static_Configure(device, ADI_ADRV9001_FHMODE_LO_RETUNE_REALTIME_PROCESS_DUAL_HOP, ADI_ADRV9001_FH_HOP_SIGNAL_1, ADI_ADRV9001_FHHOPTABLE_A, hopTable1090, sizeof(hopTable1090)/sizeof(hopTable1090[0]));
        ADRV9001INITIALISE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001InitFhHopTableCfgErr);
        funResult = adi_adrv9001_fh_HopTable_Static_Configure(device, ADI_ADRV9001_FHMODE_LO_RETUNE_REALTIME_PROCESS_DUAL_HOP, ADI_ADRV9001_FH_HOP_SIGNAL_2, ADI_ADRV9001_FHHOPTABLE_A, hopTable1030, sizeof(hopTable1030)/sizeof(hopTable1030[0]));
        ADRV9001INITIALISE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001InitFhHopTableCfgErr);


    After each sleep mode recovery, RF channels are enabled and the HOP functions are called:

      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_RX, ADI_CHANNEL_1, true);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableRxChanToEnRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_RX, ADI_CHANNEL_2, true);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableRxChanToEnRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_TX, ADI_CHANNEL_1, true);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableTxChanToEnRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_TX, ADI_CHANNEL_2, true);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableTxChanToEnRfErr);
    
      funResult = adi_adrv9001_fh_Hop(device, ADI_ADRV9001_FH_HOP_SIGNAL_1);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableFhHopSigErr);
      funResult = adi_adrv9001_fh_Hop(device, ADI_ADRV9001_FH_HOP_SIGNAL_2);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001EnableFhHopSigErr);
    


    The RF channels are disabled and the HOP functions are called before each sleep mode activation:

      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_RX, ADI_CHANNEL_1, false);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableRxChanToDisableRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_RX, ADI_CHANNEL_2, false);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableRxChanToDisableRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_TX, ADI_CHANNEL_1, false);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableTxChanToDisableRfErr);
      funResult = adi_adrv9001_Radio_Channel_EnableRf(device, ADI_TX, ADI_CHANNEL_2, false);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableTxChanToDisableRfErr);
    
      funResult = adi_adrv9001_fh_Hop(device, ADI_ADRV9001_FH_HOP_SIGNAL_1);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableFhHopSigErr);
      funResult = adi_adrv9001_fh_Hop(device, ADI_ADRV9001_FH_HOP_SIGNAL_2);
      ADRV9001ENABLE_ERROR_RETURN_AUTOGENERATOR(funResult, ADRV9001DisableFhHopSigErr);


    I'm looking forward to your next advances.

    Regards,
    Bartk

  • Hi Rahul,

    Any updates?

    Regards,
    bartk