Post Go back to editing

rf_port_select does not work

Category: Software
Product Number: iiolib

Good morning

for this

ret = iio_channel_attr_write(phy_chn_rx, "rf_port_select", rxcfg.rfport);

I get a -22

Other settings for the rx channel work

The 

 phy_chn_rx = iio_device_find_channel(phydev, "voltage0", false );

gives the channel for rx. This one works.

Additionally is of value to assign settings to altvoltage0 or altvoltage1 for the PLUTO?
It seems they are not available ...

Thank You

Pietro

Parents
  • On the Pluto, only the A Balanced inputs are used.

    Therefore the other settings are locked - please see here:

    https://github.com/analogdevicesinc/linux/blob/master/arch/arm/boot/dts/zynq-pluto-sdr.dtsi#L248

    You should be able to control the RX/TX LOs using altvoltage0 or altvoltage1.

    When you iio_device_find_channel() you need to make sure that you look for an output channel...

    -Michael

  • Hi 

    Thank You for the assistance. I will follow the indication.
    I have further questions.
    I want to reread the attribute.
    A list of what happens:
    1. iio_channel_attr_read( phy_chn_tx, "rf_port_select", (char*)txcfg.rfport, 10 )  -> -10014
    2. iio_channel_attr_read_longlong( phy_chn_tx, "rf_bandwidth", &txcfg.bw_hz ); -> -22
    3. iio_channel_attr_read_longlong( phy_chn_tx, "sampling_frequency", &txcfg.fs_hz ); -> 0
    4. iio_channel_attr_read_double(   phy_chn_tx, "hardwaregain", &txcfg.gain_db ); -> 0 but gain = 2600000
    5. iio_channel_attr_read_longlong( phy_chn_tx, "frequency", &txcfg.lo_hz); -> -2
    6. iio_channel_attr_read(          phy_chn_rx, "rf_port_select", (char*)rxcfg.rfport, 10 ); -> -5
    7. iio_channel_attr_read_longlong( phy_chn_rx, "rf_bandwidth", &rxcfg.bw_hz ); -> -10053
    8. iio_channel_attr_read_longlong( phy_chn_rx, "sampling_frequency", &rxcfg.fs_hz ); -> -10053
    9. iio_channel_attr_read_double(   phy_chn_rx, "hardwaregain", &rxcfg.gain_db ); -> -10053
    10. iio_channel_attr_read_longlong( phy_chn_rx, "frequency", &rxcfg.lo_hz); -> -2


    The attributes were written previously with return code 0.
    I suppose I should reread the same values. What happens?
    Where are the return codes ?
    Thank You

    Pietro

Reply
  • Hi 

    Thank You for the assistance. I will follow the indication.
    I have further questions.
    I want to reread the attribute.
    A list of what happens:
    1. iio_channel_attr_read( phy_chn_tx, "rf_port_select", (char*)txcfg.rfport, 10 )  -> -10014
    2. iio_channel_attr_read_longlong( phy_chn_tx, "rf_bandwidth", &txcfg.bw_hz ); -> -22
    3. iio_channel_attr_read_longlong( phy_chn_tx, "sampling_frequency", &txcfg.fs_hz ); -> 0
    4. iio_channel_attr_read_double(   phy_chn_tx, "hardwaregain", &txcfg.gain_db ); -> 0 but gain = 2600000
    5. iio_channel_attr_read_longlong( phy_chn_tx, "frequency", &txcfg.lo_hz); -> -2
    6. iio_channel_attr_read(          phy_chn_rx, "rf_port_select", (char*)rxcfg.rfport, 10 ); -> -5
    7. iio_channel_attr_read_longlong( phy_chn_rx, "rf_bandwidth", &rxcfg.bw_hz ); -> -10053
    8. iio_channel_attr_read_longlong( phy_chn_rx, "sampling_frequency", &rxcfg.fs_hz ); -> -10053
    9. iio_channel_attr_read_double(   phy_chn_rx, "hardwaregain", &rxcfg.gain_db ); -> -10053
    10. iio_channel_attr_read_longlong( phy_chn_rx, "frequency", &rxcfg.lo_hz); -> -2


    The attributes were written previously with return code 0.
    I suppose I should reread the same values. What happens?
    Where are the return codes ?
    Thank You

    Pietro

Children
  • Attribute values written may have different read values if the value is not possible. If you want to get the return code look at the doc for each function you call: http://analogdevicesinc.github.io/libiio/v0.24/libiio/index.html

    -Travis

  • Hi Travis

    Thank You
    I suppose if the value is different simply I get the value but not the error.
    Can You tell me which file to open for reading the error codes?

    Thank You

    Pietro

  • Hi

    I just tested the iio_strerror()
    For all of the codes I have Unlnown error..
    Just help
    Than You

    Pietro

  • Can you provide the specific libiio function and error code?

    -Travis

  • Good morning Travis,

    It seems there is no way to attach  files.
    I dump here the source. Sorry it is long..

    The setup of the pluto is here. The calls to the IIO_LIB are prepended with a IIO_lib_itf.
    I use wxSidgets and the DLL functions are loaded in a data stracture.

    // ctx = IIO_lib_itf.iio_create_default_context();
    ctx = IIO_lib_itf.iio_create_network_context("pluto.local");
    if (ctx == NULL)
    {
    char buf[1024];
    char str[1400];
    wxString String;
    IIO_lib_itf.iio_strerror(errno, buf, sizeof(buf));
    sprintf( str, "Failed creating IIO context: %s", buf);

    ListBox->AppendString(wxString(str));
    return;
    }
    else
    {
    ListBox->AppendString( " IIO context created" );
    }
    scan_ctx = IIO_lib_itf.iio_create_scan_context( NULL, 0 );
    if (scan_ctx) {
    int info_count = IIO_lib_itf.iio_scan_context_get_info_list( scan_ctx, &info );
    if (info_count > 0) {

    char *buf = (char *)IIO_lib_itf.iio_context_info_get_description( info[ 0 ] );
    sprintf(str, "* Found %s", buf);
    ListBox->AppendString( wxString( str ) );
    IIO_lib_itf.iio_context_info_list_free(info);
    }
    IIO_lib_itf.iio_scan_context_destroy( scan_ctx );
    scan_ctx = NULL;
    }

    ListBox->AppendString("* Acquiring devices\n");

    device_count = IIO_lib_itf.iio_context_get_devices_count( ctx );
    if (!device_count) {
    ListBox->AppendString( "No supported PLUTOSDR devices found");
    return;
    }

    sprintf(str, "* Context has %d device(s).\n", device_count );

    ListBox->AppendString( wxString(str) );

    ListBox->AppendString("* Acquiring TX device");
    tx = IIO_lib_itf.iio_context_find_device( ctx, "cf-ad9361-dds-core-lpc" );
    if (tx == NULL) {
    char buf[ 1024 ];
    IIO_lib_itf.iio_strerror(errno, buf, sizeof( buf ) );
    sprintf( str, "Error opening PLUTOSDR TX device: %s", buf );
    ListBox->AppendString( wxString( str ) );
    return;
    }
    else
    {
    ListBox->AppendString( wxString( "PLUTOSDR TX device open" ) );
    }
    IIO_lib_itf.iio_device_set_kernel_buffers_count(tx, 8);

    phydev = IIO_lib_itf.iio_context_find_device(ctx, "ad9361-phy");
    if ( phydev != NULL )
    {
    phy_chn_tx = IIO_lib_itf.iio_device_find_channel(phydev, "voltage0", true);
    if (phy_chn_tx == NULL)
    {
    ListBox->AppendString(wxString("voltage0 channel for TX NOT found"));
    return;
    }
    }
    else
    {
    ListBox->AppendString( wxString( "ad9361-phy dev for TX NOT found" ) );
    return;
    }
    ssize_t ret;
    /*
    ret = IIO_lib_itf.iio_channel_attr_write(phy_chn_tx, "rf_port_select", txcfg.rfport );
    if( ret < 0 )
    {
    ListBox->AppendString( wxString( "rf_port_select attribute for TX NOT written" ) );
    return;
    }
    */
    ret = IIO_lib_itf.iio_channel_attr_write_longlong(phy_chn_tx, "rf_bandwidth", txcfg.bw_hz );
    if (ret < 0)
    {
    ListBox->AppendString( wxString("rf_bandwidth attribute for TX NOT written"));
    return;
    }
    ret = IIO_lib_itf.iio_channel_attr_write_longlong( phy_chn_tx, "sampling_frequency", txcfg.fs_hz );
    if (ret < 0)
    {
    ListBox->AppendString( wxString("sampling_frequency attribute for TX NOT written"));
    return;
    }
    ret = IIO_lib_itf.iio_channel_attr_write_double( phy_chn_tx, "hardwaregain", txcfg.gain_db );
    if (ret < 0)
    {
    ListBox->AppendString( wxString( "hardwaregain attribute for TX NOT written" ) );
    return;
    }

    phy_chn_rx = IIO_lib_itf.iio_device_find_channel(phydev, "voltage0", false );
    if (phy_chn_rx == NULL)
    {
    ListBox->AppendString( wxString( "voltage0 channel for RX NOT found"));
    return;
    }

    /*
    ret = IIO_lib_itf.iio_channel_attr_write(phy_chn_rx, "rf_port_select", rxcfg.rfport);

    if (ret < 0)
    {
    ListBox->AppendString(wxString("rf_port_select attribute for RX NOT written"));
    return;
    }
    */

    ret = IIO_lib_itf.iio_channel_attr_write_longlong(phy_chn_rx, "rf_bandwidth", rxcfg.bw_hz);
    if (ret < 0)
    {
    ListBox->AppendString( wxString( "rf_bandwidth attribute for RX NOT written" ) );
    return;
    }
    ret = IIO_lib_itf.iio_channel_attr_write_longlong(phy_chn_rx, "sampling_frequency", rxcfg.fs_hz );
    if (ret < 0)
    {
    ListBox->AppendString(wxString( "sampling_frequency attribute for RX NOT written" ) );
    return;
    }
    ret = IIO_lib_itf.iio_channel_attr_write_double( phy_chn_rx, "hardwaregain", rxcfg.gain_db );
    if (ret < 0)
    {
    ListBox->AppendString(wxString("hardwaregain attribute for RX NOT written"));
    return;
    }

    ret = IIO_lib_itf.iio_channel_attr_write_bool(
    IIO_lib_itf.iio_device_find_channel(phydev, "altvoltage0", true)
    , "powerdown", true ); // Turn OFF RX LO
    if (ret < 0)
    {
    ListBox->AppendString( wxString("powerdown attribute on avoltage0 NOT written") );
    return;
    }

    ret = IIO_lib_itf.iio_channel_attr_write_longlong(
    IIO_lib_itf.iio_device_find_channel(phydev, "altvoltage1", true)
    , "frequency", txcfg.lo_hz ); // Set TX LO frequency
    if (ret < 0)
    {
    ListBox->AppendString(wxString("frequency attribute on avoltage1 NOT written"));
    return;
    }

    ListBox->AppendString( "* Initializing streaming channels" );

    tx0_i = IIO_lib_itf.iio_device_find_channel(tx, "voltage0", true);
    if (!tx0_i)
    {
    ListBox->AppendString(wxString("Tx0_i buffer NOT found"));
    return;ReadAllPlutoSettings

    }
    // tx0_i = IIO_lib_itf.iio_device_find_channel(tx, "altvoltage0", true);

    tx0_q = IIO_lib_itf.iio_device_find_channel(tx, "voltage1", true);
    if (!tx0_q)
    {
    ListBox->AppendString(wxString("Tx0_q buffer NOT found"));
    return;

    }
    // tx0_q = IIO_lib_itf.iio_device_find_channel(tx, "altvoltage1", true);

    ListBox->AppendString( "* Enabling IIO streaming channels\n" );
    IIO_lib_itf.iio_channel_enable(tx0_i);
    IIO_lib_itf.iio_channel_enable(tx0_q);

    int iret = AD9361_lib_itf.ad9361_set_bb_rate(IIO_lib_itf.iio_context_find_device(ctx, "ad9361-phy"), txcfg.fs_hz);
    if ( iret < 0 )
    {
    ListBox->AppendString( wxString( "ad9361-phy bb rate NOT written" ) );
    return;
    }

    ListBox->AppendString( "* Creating TX buffer" );

    tx_buffer = IIO_lib_itf.iio_device_create_buffer( tx, NUM_SAMPLES, false );
    if ( !tx_buffer ) {
    ListBox->AppendString( "Could not create TX buffer." );
    return;
    }

    // ntx = 0;
    iret = IIO_lib_itf.iio_channel_attr_write_bool(
    IIO_lib_itf.iio_device_find_channel( IIO_lib_itf.iio_context_find_device(ctx, "ad9361-phy"), "altvoltage1", true )
    , "powerdown", false); // Turn ON TX LO
    if (iret < 0)
    {
    ListBox->AppendString(wxString("altvoltage1 powerdown NOT written"));
    return;
    }

    ptx_buffer = (short*)IIO_lib_itf.iio_buffer_start(tx_buffer);
    ListBox->AppendString("* Transmit starts...\n");
    PlutoInitDone = true;

    ListBox->AppendString(" ");
    ListBox->AppendString(" ");

    ReadAllPlutoSettings( &txcfg, &rxcfg );

    //////     The ReadAllPlutoSettings(...) reread all of the settings. It is here  ///////////

    void CPlutoDlg::ReadAllPlutoSettings( struct stream_cfg * p_txcfg, struct stream_cfg * p_rxcfg )
    {
    // IIO_lib_itf.iio_device_find_channel( phydev, "voltage0", true);

    char buf[200];

    ssize_t sz = IIO_lib_itf.iio_channel_attr_read( phy_chn_tx, "rf_port_select", (char*)txcfg.rfport, 10 );
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror( sz, buf, 200 );
    ListBox->AppendString(wxString( buf ));
    // ListBox->AppendString(wxString("rf port TX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_tx, "rf_bandwidth", &txcfg.bw_hz );
    if (sz != 0)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString( wxString( "rf_bandwidth TX not correctly read " ) );
    }

    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_tx, "sampling_frequency", &txcfg.fs_hz );
    if (sz != 0)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString( wxString( "sampling_frequency TX not correctly read " ) );
    }

    sz = IIO_lib_itf.iio_channel_attr_read_double( phy_chn_tx, "hardwaregain", &txcfg.gain_db );
    if (sz != 0)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("hardwaregain TX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_tx, "frequency", &txcfg.lo_hz);
    if (sz != 0)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("frequency TX not correctly read "));
    }


    sz = IIO_lib_itf.iio_channel_attr_read( phy_chn_rx, "rf_port_select", (char*)rxcfg.rfport, 10 );
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("rf port RX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_rx, "rf_bandwidth", &rxcfg.bw_hz );
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("rf_bandwidth RX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_rx, "sampling_frequency", &rxcfg.fs_hz );
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("sampling_frequency RX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_double( phy_chn_rx, "hardwaregain", &rxcfg.gain_db );
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("hardwaregain RX not correctly read "));
    }
    sz = IIO_lib_itf.iio_channel_attr_read_longlong( phy_chn_rx, "frequency", &rxcfg.lo_hz);
    if (sz != 1)
    {
    IIO_lib_itf.iio_strerror(sz, buf, 200);
    ListBox->AppendString(wxString(buf));
    // ListBox->AppendString(wxString("frequency RX not correctly read "));
    }

    }

    Not one of the readout is correct,  

    Thank You

    Pietro

  • Can you provide a simple example in just C?

    -Travis

  • Hi Travis

    The initialization appears correct ..
    The readout is totally out of order.

    printf("* Initializing streaming channels\n");
    tx0_i = iio_device_find_channel(tx, "voltage0", true);
    if (!tx0_i)
    tx0_i = iio_device_find_channel(tx, "altvoltage0", true);

    tx0_q = iio_device_find_channel(tx, "voltage1", true);
    if (!tx0_q)
    tx0_q = iio_device_find_channel(tx, "altvoltage1", true);

    // Up to here it is correct

    // Now I want to read and nothing works

    struct stream_cfg txcfg_read;


    {
    txcfg_read.rfport = " ";
    txcfg_read.bw_hz = 0;
    txcfg_read.fs_hz = 0;
    txcfg_read.gain_db = 0;
    sz = iio_channel_attr_read(tx0_i, "rf_port_select", (char*)txcfg_read.rfport, 10);
    int err2 = iio_channel_attr_read_longlong(tx0_i, "rf_bandwidth", &txcfg_read.bw_hz);
    err2 = iio_channel_attr_read_longlong(tx0_i, "sampling_frequency", &txcfg_read.fs_hz);
    err2 = iio_channel_attr_read_double(tx0_i, "hardwaregain", &txcfg_read.gain_db);
    }

    Thank     You

    Pietro

  • It looks like you reading channels from the wrong device.

    For Pluto there are 3 relevant IIO devices...

    Can you start with the iio_info command?

  • Is this the outcome?

    This example is working for streaming it does the initialization without any problem. I just add the lines of code for reading what is already written. 

    Can You modify the example for streaming and show this  API work?

    Thank You

    Pietro

  • So Michael was referring to the IIO devices that you reference for pulling back information. You can use iio_info and iio_attr to examine what is available. First I would start with iio_attr to list the devices as so:

    iio_attr -u ip:pluto.local -d
    IIO context has 5 devices:
    	iio:device0, adm1177: found 0 device attributes
    	iio:device1, ad9361-phy: found 18 device attributes
    	iio:device2, xadc: found 1 device attributes
    	iio:device3, cf-ad9361-dds-core-lpc: found 0 device attributes
    	iio:device4, cf-ad9361-lpc: found 0 device attributes

    The devices cf-ad9361-dds-core-lpc and cf-ad9361-lpc are the controls for data streaming and DDS control. You can tell since they have scan elements (that's an IIO concept for buffer management):

    iio_attr -u ip:pluto.local -s -c cf-ad9361-lpc
    dev 'cf-ad9361-lpc', channel 'voltage0' (input, index: 0, format: le:S12/16>>0)
    found 6 channel-specific attributes
    dev 'cf-ad9361-lpc', channel 'voltage1' (input, index: 1, format: le:S12/16>>0)
    found 6 channel-specific attributes
    
    iio_attr -u ip:pluto.local -s -c cf-ad9361-dds-core-lpc
    dev 'cf-ad9361-dds-core-lpc', channel 'voltage0' (output, index: 0, format: le:S16/16>>0)
    found 4 channel-specific attributes
    dev 'cf-ad9361-dds-core-lpc', channel 'voltage1' (output, index: 1, format: le:S16/16>>0)
    found 4 channel-specific attributes

    The ad9361-phy is where all the main control attributes for the transceiver live:

    iio_attr -u ip:pluto.local -c ad9361-phy .
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'external', value '0'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'fastlock_load', value '0'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'fastlock_recall', ERROR: Invalid argument (22)
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'fastlock_save', value '0 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'fastlock_store', value '0'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'frequency', value '2450000000'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'frequency_available', value '[325000000 1 3800000000]'
    dev 'ad9361-phy', channel 'altvoltage1' (output), id 'TX_LO', attr 'powerdown', value '0'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'bb_dc_offset_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'filter_fir_en', value '0'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'gain_control_mode', value 'slow_attack'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'gain_control_mode_available', value 'manual fast_attack slow_attack hybrid'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'hardwaregain', value '71.000000 dB'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'hardwaregain_available', value '[-3 1 71]'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'quadrature_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rf_bandwidth', value '18000000'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rf_bandwidth_available', value '[200000 1 56000000]'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rf_dc_offset_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rf_port_select', value 'A_BALANCED'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rf_port_select_available', value 'A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'rssi', value '114.25 dB'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'sampling_frequency', value '30720000'
    dev 'ad9361-phy', channel 'voltage0' (input), attr 'sampling_frequency_available', value '[2083333 1 61440000]'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'filter_fir_en', value '0'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'raw', value '306'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'rf_bandwidth', value '18000000'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'rf_bandwidth_available', value '[200000 1 40000000]'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'rf_port_select_available', value 'A B'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'sampling_frequency', value '30720000'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'sampling_frequency_available', value '[2083333 1 61440000]'
    dev 'ad9361-phy', channel 'voltage3' (output), attr 'scale', value '1.000000'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'external', value '0'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'fastlock_load', value '0'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'fastlock_recall', ERROR: Invalid argument (22)
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'fastlock_save', value '0 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'fastlock_store', value '0'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'frequency', value '2400000000'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'frequency_available', value '[325000000 1 3800000000]'
    dev 'ad9361-phy', channel 'altvoltage0' (output), id 'RX_LO', attr 'powerdown', value '0'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'filter_fir_en', value '0'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'raw', value '306'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'rf_bandwidth', value '18000000'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'rf_bandwidth_available', value '[200000 1 40000000]'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'rf_port_select_available', value 'A B'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'sampling_frequency', value '30720000'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'sampling_frequency_available', value '[2083333 1 61440000]'
    dev 'ad9361-phy', channel 'voltage2' (output), attr 'scale', value '1.000000'
    dev 'ad9361-phy', channel 'temp0' (input), attr 'input', value '30702'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'filter_fir_en', value '0'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain', value '-10.000000 dB'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain_available', value '[-89.750000 0.250000 0.000000]'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'rf_bandwidth', value '18000000'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'rf_bandwidth_available', value '[200000 1 40000000]'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'rf_port_select', value 'A'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'rf_port_select_available', value 'A B'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'rssi', value '0.00 dB'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'sampling_frequency', value '30720000'
    dev 'ad9361-phy', channel 'voltage0' (output), attr 'sampling_frequency_available', value '[2083333 1 61440000]'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'bb_dc_offset_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'filter_fir_en', value '0'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'gain_control_mode_available', value 'manual fast_attack slow_attack hybrid'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'offset', value '57'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'quadrature_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'raw', value '1255'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'rf_bandwidth', value '18000000'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'rf_bandwidth_available', value '[200000 1 56000000]'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'rf_dc_offset_tracking_en', value '1'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'rf_port_select_available', value 'A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'sampling_frequency', value '30720000'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'sampling_frequency_available', value '[2083333 1 61440000]'
    dev 'ad9361-phy', channel 'voltage2' (input), attr 'scale', value '0.305250'
    dev 'ad9361-phy', channel 'out' (input), attr 'voltage_filter_fir_en', value '0'

    Since you don't specify in your code how "tx" is created, our guess is that its not from ad9361-phy.

    -Travis