cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
norume
Adventurer
Adventurer
920 Views
Registered: ‎04-01-2015

Very large offset in RF ADC readings

Jump to solution

We're developing a custom analog signal conditioning board for use with the ZCU111.

The RF ADC channels are onfigured for no decimation, real mode, 8 samples per clock, 3.997 GHz sampling, DC link.

I used an oscilloscope to measure voltages at ADC inputs: - input is at 1.252 V, +input is at 1.255 V.  With inputs at these levels the ADC readings should be a around a few hundred counts (right?), but are actually showing up as around 11000.  That’s over a third of full scale!
 
Any ideas as to the source of this offset?  I originally thought the problem had to be in our signal conditioning, but the oscilloscope measurement of the ADC inputs seems to show that the offset is arising somewhere in the FPGA itself.  
 
Could the problem be in the way I start or synchronizae the RF ADCs?
 
Here's the code I use to initialize the ADCs:
void
rfADCinit(void)
{   
    int i;
    XRFdc_Config *configp;
    
    metal_set_log_handler(myLogHandler);
    metal_set_log_level(METAL_LOG_DEBUG);
    
    configp = XRFdc_LookupConfig(XPAR_XRFDC_0_DEVICE_ID);
    if (!configp) fatal("XRFdc_LookupConfig");
    i = XRFdc_CfgInitialize(&rfADC, configp);
    if (i != XST_SUCCESS) fatal("XRFdc_CfgInitialize=%d\n", i);
}
Followed by a multi-tile synchronization:
void
rfADCsync(void)
{
    int tile, latency;
    XRFdc_IPStatus IPStatus;
    XRFdc_MultiConverter_Sync_Config Config;

    if (XRFdc_GetIPStatus(&rfADC, &IPStatus) != 0) {
        printf("Can't get IP status.\n");
        return;
    }
    XRFdc_MultiConverter_Init(&Config, NULL, NULL);
    for (tile = 0 ; tile < NTILES ; tile++) {
        if (IPStatus.ADCTileStatus[tile].IsEnabled) {
            Config.Tiles |= 1 << tile;
        }
    }

    /*
     * Synchronize between tiles in each group
     */
    syncStatus = XRFdc_MultiConverter_Sync(&rfADC, XRFDC_ADC_TILE, &Config);
    if (syncStatus != XRFDC_MTS_OK) {
        warn("XRFdc_MultiConverter_Sync (tiles) failed: %d", syncStatus);
        return;
    }

    /*
     * Synchronize between groups as described on page 113 of PG269 (v2.0)
     * "Zynq UltraScale+ RFSoC RF Data Converter", "Advanced Multi-Converter
     * Sync API Usage".
     */
    latency = -1;
    for (tile = 0 ; tile < NTILES ; tile++) {
        if (Config.Latency[tile] > latency) {
            latency = Config.Latency[tile];
        }
    }
    Config.Target_Latency = latency + 8;
    syncStatus = XRFdc_MultiConverter_Sync(&rfADC, XRFDC_ADC_TILE, &Config);
    if (syncStatus != XRFDC_MTS_OK) {
        warn("XRFdc_MultiConverter_Sync (groups) failed: %d", syncStatus);
        return;
    }
    printf("ADC synchronization complete.\n");
}
0 Kudos
1 Solution

Accepted Solutions
klumsde
Moderator
Moderator
735 Views
Registered: ‎04-18-2011

OK it's good that the hint about calibration helped you. 

If there is anything present at the offset spur location (including DC) then you have to mute it or do as you've done here. 

Keith

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

0 Kudos
3 Replies
klumsde
Moderator
Moderator
798 Views
Registered: ‎04-18-2011

It could be an issue with your calibration.

This input is only something like - 47dBm

So you're meant to have power greater than - 40dBm for the background calibration to converge.

Can you take a look at an FFT here, maybe in RF analyser. This will show you where this is coming from

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
norume
Adventurer
Adventurer
760 Views
Registered: ‎04-01-2015

The problem was from the power-up foreground calibration operation -- the analog signal conditioning hardware wasn't producing 0.0 V(differential) at the ADC inputs when the FPGA powered up.  I added a

XRFdc_Reset(&rfADC, XRFDC_ADC_TILE, XRFDC_SELECT_ALL_TILES);

to rerun the foreground calibration after the signal conditioning hardware was set up and now the big offset has gone away.

FWIW the documentation does describe this (I emphasized the salient sentence):

Foreground Calibration Process

The foreground calibration step is part of the RF-ADC startup initialization state machine sequence. This is managed and carried out by the startup IP. The purpose of the foreground calibration is to provide correction through the OCB1 and OCB2 blocks for sub-RF-ADC offsets and skews of the sampling switches. The OCB2 block is then frozen and not updated again during operation mode. During this process there should ideally be no signal energy at any of the interleaving offset locations, namely frequency = k*Fs/N. Thus the input should be muted during this process. This is typically accomplished by sequencing the receiver front end enable after the RF-ADC startup process is complete. At the end of the foreground calibration process the OCB2 block is frozen, and OCB1, Time Skew and Gain Calibration blocks are set to enable to run in the background.

0 Kudos
klumsde
Moderator
Moderator
736 Views
Registered: ‎04-18-2011

OK it's good that the hint about calibration helped you. 

If there is anything present at the offset spur location (including DC) then you have to mute it or do as you've done here. 

Keith

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

0 Kudos