Could you share how you're setting up LO sharing in your code, as well as
how you're setting the system clock on the N321?

The functions "configure_channels" and "set_lo_hw_exports" are used to set
up the LO sharing.

The functions "sync_sources" and "sync_all_devices" are used to set up the
system clock on the N321.

How do you measure the relative delay?

We are measuring the offset of the LO's by just measuring the phase
difference of the RF coming out of the Ettus with an Oscilloscope (picture
attached as
Scope_Trace_SingleStream_LO.png
<https://mail.google.com/mail/u/0?ui=2&ik=34abf4583b&attid=0.1&permmsgid=msg-a:r-1207093291428225864&view=att&disp=safe&realattid=f_lijcykt50>).
Yellow is Channel 1, Green is Channel 2; using a single streamer we still
appear to have a 2.64ns delta or ~135 degree phase shift.

Thanks Marcus and Rob for your assistance.

Michael Toussaint

def sync_sources(usrp):
    logging.info('Setting Sync Sources')

    usrp.set_sync_source(clock_source = 'gpsdo',
                         time_source = 'gpsdo')

def sync_all_devices(hw_info):
    logging.info('Syncing All Devices')

    mb_with_gps_locked = -1

    while 1:
        time.sleep(1.0)

        all_ref_locked = True

        for board in range(hw_info.usrp.get_num_mboards()):
            all_ref_locked = all_ref_locked and \
                hw_info.usrp.get_mboard_sensor('ref_locked',
                                               board).to_bool()

            if (mb_with_gps_locked == -1) and \
                hw_info.usrp.get_mboard_sensor('gps_locked',
                                               board).to_bool():
                mb_with_gps_locked = board

        if all_ref_locked:
            logging.info('All Devices are REF locked')
            break

    logging.info('GPS Locked on MB #%d', mb_with_gps_locked)

    time.sleep(1.0)
    hw_info.usrp.set_time_next_pps(
        uhd.types.TimeSpec(
        hw_info.usrp.get_mboard_sensor('gps_time',
                                       mb_with_gps_locked).to_int() +
                                       1.0)
    )
    time.sleep(1.0)


def configure_channels(usrp, rf_type, hw_info):
    rf_channel_index = None
    set_rf_rate = None
    set_rf_freq = None
    set_rf_gain = None
    set_rf_lo_source = None
    get_rf_lo_source = None
    get_rf_lo_freq = None
    get_rf_lo_freq_range = None

    if (rf_type == 'rx'):
        if (len(hw_info.rx_channel_index) > 0):
            rf_channel_index = hw_info.rx_channel_index
            set_rf_rate = usrp.set_rx_rate
            set_rf_freq = usrp.set_rx_freq
            set_rf_gain = usrp.set_rx_gain
            set_rf_lo_source = usrp.set_rx_lo_source
            get_rf_lo_source = usrp.get_rx_lo_source
            get_rf_lo_freq = usrp.get_rx_lo_freq
            get_rf_lo_freq_range = usrp.get_rx_lo_freq_range
        else:
            return
    elif (rf_type == 'tx'):
        if (len(hw_info.tx_channel_index) > 0):
            rf_channel_index = hw_info.tx_channel_index
            set_rf_rate = usrp.set_tx_rate
            set_rf_freq = usrp.set_tx_freq
            set_rf_gain = usrp.set_tx_gain
            set_rf_lo_source = usrp.set_tx_lo_source
            get_rf_lo_source = usrp.get_tx_lo_source
            get_rf_lo_freq = usrp.get_tx_lo_freq
            get_rf_lo_freq_range = usrp.get_tx_lo_freq_range
        else:
            return

    logging.info('Configuring %s Channels', rf_type.upper())

    for rf_ch_name, rf_ch_index in rf_channel_index.items():
        logging.info('Configuring %s channel %s (channel #%d)',
                     rf_type.upper(), rf_ch_name, rf_ch_index)

        ch_def = hw_info.channel_def[rf_ch_name]

        # LO Channel Setup
        current_lo_name = 'unknown'
        current_lo_src = 'unknown'

        if ch_def.lo_inputs is not None:
            logging.info('  Setting %s LO for Channel %s (#%d)',
                         rf_type.upper(), rf_ch_name, rf_ch_index)

            set_rf_lo_source(ch_def.lo_inputs.source,
                             ch_def.lo_inputs.name,
                             rf_ch_index)
            current_lo_name = ch_def.lo_inputs.name

            logging.info('    (#%d) Requested %s LO name %s, src %s',
                         rf_ch_index,
                         rf_type.upper(),
                         ch_def.lo_inputs.name,
                         ch_def.lo_inputs.source)
        else:
            logging.info('  No %s LO inputs for Channel %s (#%d)',
                         rf_type.upper(), rf_ch_name, rf_ch_index)

            current_lo_name = 'lo1'

        current_lo_src = get_rf_lo_source(current_lo_name,
                                          rf_ch_index)

        logging.info('    (#%d) Current %s LO name %s, src %s',
                     rf_ch_index,
                     rf_type.upper(),
                     current_lo_name,
                     current_lo_src)

        rf_lo_freq = get_rf_lo_freq(current_lo_name,
                                    rf_ch_index)

        logging.info('    (#%d) [%s] Current %s LO freq %d',
                         rf_ch_index,
                         current_lo_name,
                         rf_type.upper(),
                         rf_lo_freq)

        rf_lo_freq_range = get_rf_lo_freq_range(
            current_lo_name, rf_ch_index)

        temp = '    (#%d) [%s] Current %s LO freq range' + \
            ' [%d, %d] step %d'

        logging.info(temp,
                     rf_ch_index,
                     current_lo_name,
                     rf_type.upper(),
                     rf_lo_freq_range.start(),
                     rf_lo_freq_range.stop(),
                     rf_lo_freq_range.step())

        logging.info('  Setting Sampling Rate %s', hw_info.fs)
        set_rf_rate(hw_info.fs, rf_ch_index)

        logging.info('  Setting Center Freq %s', hw_info.fc)
        tr = set_rf_freq(uhd.libpyuhd.types.tune_request(hw_info.fc),
                         rf_ch_index)

        logging.info('    (#%d) %s Tune Result:',
                     rf_ch_index, rf_type.upper())
        log_tune_result(tr)

        logging.info('  Setting %s Gain: %2.3f db',
                     rf_type.upper(),
                     ch_def.gain)
        set_rf_gain(ch_def.gain, rf_ch_index)

def set_lo_hw_exports(usrp, node_name, dirx, lo_enabled, output_array):
    """Set LO HW Exports"""
    if (lo_enabled is None) or (output_array is None):
        return

    logging.info('Setting %s LO Export Enabled for %s',
                 dirx.upper(), node_name)

    if dirx.lower() == 'rx':
        usrp.set_rx_lo_export_enabled(lo_enabled, 'lo1', 0)
        enable_val = usrp.get_rx_lo_export_enabled('lo1')
    elif dirx.lower() == 'tx':
        usrp.set_tx_lo_export_enabled(lo_enabled, 'lo1', 0)
        enable_val = usrp.get_tx_lo_export_enabled('lo1')
    else:
        logging.warning('Invalid direction %s', dirx)
        return

    logging.info('  %s LO Export Enabled = %s, requested %s',
                 dirx.upper(), enable_val, lo_enabled)

    temp_path = 'blocks/0/Radio#0/dboard/' + \
        f'{dirx.lower()}_frontends/' + \
        '0/los/lo1/lo_distribution/LO_OUT_{}/export'

    logging.info('Setting %s LO HW Outputs for %s',
                 dirx.upper(), node_name)

    for out_num in range(len(output_array)):
        hw_lo_export_path = temp_path.format(out_num)

        if usrp.get_tree().exists(hw_lo_export_path):
            usrp.get_tree().access_bool(hw_lo_export_path).set(
                output_array[out_num])

            logging.info('  %s LO HW Export Out[%d] = %s, %s %s',
                         dirx.upper(), out_num,
                         usrp.get_tree().access_bool(
                            hw_lo_export_path).get(),
                        'requested',
                        output_array[out_num])
        else:
            logging.warning('  %s LO HW Export Out[%d] does not exist',
                            dirx.upper(), out_num)


On Thu, May 25, 2023 at 6:45 AM Rob Kossler <rkoss...@nd.edu> wrote:

> On Thu, May 25, 2023 at 3:54 AM Michael Toussaint
> <mtoussa...@chaosinc.com> wrote:
> >
> > Used a single streamer and saw the delay slightly improve to between 2.5
> - 3 ns.
> >
> > Any other suggestions to improve the delay to match the results from the
> knowledge base, https://kb.ettus.com/USRP_N320/N321_LO_Distribution?
>
> How do you measure the relative delay?
>
_______________________________________________
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-le...@lists.ettus.com

Reply via email to