Advertisement
Guest User

Soapy bladeRF - Settings section

a guest
Apr 28th, 2016
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.30 KB | None | 0 0
  1. /*******************************************************************
  2. * Settings API
  3. ******************************************************************/
  4.  
  5. SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const
  6. {
  7.     SoapySDR::ArgInfoList setArgs;
  8.  
  9.     // XB200 setting
  10.     SoapySDR::ArgInfo xb200SettingArg;
  11.     xb200SettingArg.key = "xb200";
  12.     xb200SettingArg.value = "disabled";
  13.     xb200SettingArg.name = "XB200 Transverter";
  14.     xb200SettingArg.description = "bladeRF XB200 Transverter Board";
  15.     xb200SettingArg.type = SoapySDR::ArgInfo::STRING;
  16.     xb200SettingArg.options.push_back("disabled");
  17.     xb200SettingArg.optionNames.push_back("Disabled");
  18.     xb200SettingArg.options.push_back("50M");
  19.     xb200SettingArg.optionNames.push_back("Filterbank: 50M");
  20.     xb200SettingArg.options.push_back("144M");
  21.     xb200SettingArg.optionNames.push_back("Filterbank: 144M");
  22.     xb200SettingArg.options.push_back("222M");
  23.     xb200SettingArg.optionNames.push_back("Filterbank: 222M");
  24.     xb200SettingArg.options.push_back("auto1db");
  25.     xb200SettingArg.optionNames.push_back("Filterbank: Auto (1dB)");
  26.     xb200SettingArg.options.push_back("auto3db");
  27.     xb200SettingArg.optionNames.push_back("Filterbank: Auto (3dB)");
  28.     xb200SettingArg.options.push_back("auto");
  29.     xb200SettingArg.optionNames.push_back("Filterbank: Auto");
  30.     xb200SettingArg.options.push_back("custom");
  31.     xb200SettingArg.optionNames.push_back("Filterbank: Custom");
  32.  
  33.     setArgs.push_back(xb200SettingArg);
  34.  
  35.     // Sampling mode
  36.     SoapySDR::ArgInfo samplingModeArg;
  37.     samplingModeArg.key = "sampling_mode";
  38.     samplingModeArg.value = "internal";
  39.     samplingModeArg.name = "Sampling Mode";
  40.     samplingModeArg.description = "Internal = Via RX/TX connectors, External = Direct sampling from J60/J61 connectors";
  41.     samplingModeArg.type = SoapySDR::ArgInfo::STRING;
  42.     samplingModeArg.options.push_back("internal");
  43.     samplingModeArg.optionNames.push_back("Internal (Default)");
  44.     samplingModeArg.options.push_back("external");
  45.     samplingModeArg.optionNames.push_back("Direct Sampling");
  46.  
  47.     setArgs.push_back(samplingModeArg);
  48.  
  49.     // Loopback
  50.     SoapySDR::ArgInfo lookbackArg;
  51.     lookbackArg.key = "loopback";
  52.     lookbackArg.value = "disabled";
  53.     lookbackArg.name = "Loopback Mode";
  54.     lookbackArg.description = "Enable/disable internal loopback";
  55.     lookbackArg.type = SoapySDR::ArgInfo::STRING;
  56.     lookbackArg.options.push_back("disabled");
  57.     lookbackArg.optionNames.push_back("Disabled");
  58.     lookbackArg.options.push_back("firmware");
  59.     lookbackArg.optionNames.push_back("FX3 Firmware");
  60.     lookbackArg.options.push_back("bb_txlpf_rxvga2");
  61.     lookbackArg.optionNames.push_back("Baseband: TXLPF to RXVGA2");
  62.     lookbackArg.options.push_back("bb_txvga1_rxvga2");
  63.     lookbackArg.optionNames.push_back("Baseband: TXVGA1 to RXVGA2");
  64.     lookbackArg.options.push_back("bb_txlpf_rxlpf");
  65.     lookbackArg.optionNames.push_back("Baseband: TXLPF to RXLPF");
  66.     lookbackArg.options.push_back("bb_txvga1_rxlpf");
  67.     lookbackArg.optionNames.push_back("Baseband: TXVGA1 to RXLPF");
  68.     lookbackArg.options.push_back("rf_lna1");
  69.     lookbackArg.optionNames.push_back("RF: TXMIX to LNA1");
  70.     lookbackArg.options.push_back("rf_lna2");
  71.     lookbackArg.optionNames.push_back("RF: TXMIX to LNA2");
  72.     lookbackArg.options.push_back("rf_lna3");
  73.     lookbackArg.optionNames.push_back("RF: TXMIX to LNA3");
  74.  
  75.     setArgs.push_back(lookbackArg);
  76.  
  77.     return setArgs;
  78. }
  79.  
  80. void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &value)
  81. {
  82.     if (key == "xb200")
  83.     {
  84.         // Verify that a valid setting has arrived
  85.         std::vector<std::string> xb200_validSettings{ "disabled", "50M", "144M", "222M", "auto1db", "auto3db", "auto", "custom" };
  86.         if (std::find(std::begin(xb200_validSettings), std::end(xb200_validSettings), value) != std::end(xb200_validSettings))
  87.         {
  88.             // --> Valid setting has arrived
  89.  
  90.             // Get attached expansion device
  91.             bladerf_xb _bladerf_xb_attached = bladerf_xb::BLADERF_XB_NONE;
  92.             bladerf_expansion_get_attached(_dev, &_bladerf_xb_attached);
  93.  
  94.             // If "disabled," ensure board is bypassed, if present, and return
  95.             if (value == "disabled")
  96.             {
  97.                 if (_bladerf_xb_attached == bladerf_xb::BLADERF_XB_200)
  98.                 {
  99.                     // Apply bypass around connected XB200
  100.                     SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Disabling connected XB200 by bypassing signal path");
  101.                     bladerf_xb200_set_path(_dev, bladerf_module::BLADERF_MODULE_RX, bladerf_xb200_path::BLADERF_XB200_BYPASS);
  102.                 }
  103.  
  104.                 return;
  105.             }
  106.  
  107.             // Attach the XB200, if it isn't already attached
  108.             if (_bladerf_xb_attached == bladerf_xb::BLADERF_XB_NONE)
  109.             {
  110.                 if (bladerf_expansion_attach(_dev, bladerf_xb::BLADERF_XB_200))
  111.                 {
  112.                     SoapySDR::logf(SOAPY_SDR_ERROR, "bladeRF: Could not attach to XB200");
  113.                     return;
  114.                 }
  115.             }
  116.             SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: XB200 is attached");
  117.  
  118.             // Which filterbank was selected?
  119.             bladerf_xb200_filter filter = bladerf_xb200_filter::BLADERF_XB200_AUTO_1DB;
  120.  
  121.             if (value == "50M")
  122.             {
  123.                 // 50-54 MHz (6 meter band) filterbank
  124.                 filter = bladerf_xb200_filter::BLADERF_XB200_50M;
  125.             }
  126.             else if (value == "144M")
  127.             {
  128.                 // 144-148 MHz (2 meter band) filterbank
  129.                 filter = bladerf_xb200_filter::BLADERF_XB200_144M;
  130.             }
  131.             else if (value == "222M")
  132.             {
  133.                 // 222-225 MHz (1.25 meter band) filterbank
  134.                 // Note that this filter option is technically wider, covering 206-235 MHz
  135.                 filter = bladerf_xb200_filter::BLADERF_XB200_222M;
  136.             }
  137.             else if (value == "auto1db")
  138.             {
  139.                 // The other filter options are automatically selected depending on the RX or TX
  140.                 // module's current frequency, based upon the 1dB points of the on-board filters
  141.                 // For frequencies outside the range of the on-board filters, the custom path is used
  142.                 filter = bladerf_xb200_filter::BLADERF_XB200_AUTO_1DB;
  143.             }
  144.             else if (value == "auto3db")
  145.             {
  146.                 // The other filter options are automatically selected depending on the RX or TX
  147.                 // module's current frequency, based upon the 3dB points of the on-board filters
  148.                 // For frequencies outside the range of the on-board filters, the custom path is used
  149.                 filter = bladerf_xb200_filter::BLADERF_XB200_AUTO_3DB;
  150.             }
  151.             else if (value == "custom")
  152.             {
  153.                 // The custom filter bank path across the FILT and FILT-ANT SMA connectors
  154.                 filter = bladerf_xb200_filter::BLADERF_XB200_CUSTOM;
  155.             }
  156.             else
  157.             {
  158.                 // Default: Auto, 1dB points
  159.                 // The other filter options are automatically selected depending on the RX or TX
  160.                 // module's current frequency, based upon the 1dB points of the on-board filters
  161.                 // For frequencies outside the range of the on-board filters, the custom path is used
  162.                 filter = bladerf_xb200_filter::BLADERF_XB200_AUTO_1DB;
  163.             }
  164.  
  165.             // Set the filterbank
  166.             SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Set XB200 filterbank '%s'", value);
  167.             int ret = bladerf_xb200_set_filterbank(_dev, bladerf_module::BLADERF_MODULE_RX, filter);
  168.             if (ret != 0)
  169.             {
  170.                 SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_xb200_set_filterbank(%s) returned %s", value, _err2str(ret).c_str());
  171.                 throw std::runtime_error("writeSetting() " + _err2str(ret));
  172.             }
  173.  
  174.             // Check signal path
  175.             bladerf_xb200_path _bladerf_xb200_path = bladerf_xb200_path::BLADERF_XB200_MIX;
  176.             bladerf_xb200_get_path(_dev, bladerf_module::BLADERF_MODULE_RX, &_bladerf_xb200_path);
  177.             if (_bladerf_xb200_path != bladerf_xb200_path::BLADERF_XB200_MIX)
  178.             {
  179.                 // Apply mix path through XB200
  180.                 SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Adjusting mix path through XB200");
  181.                 bladerf_xb200_set_path(_dev, bladerf_module::BLADERF_MODULE_RX, bladerf_xb200_path::BLADERF_XB200_MIX);
  182.             }
  183.         }
  184.         else
  185.         {
  186.             // --> Invalid setting has arrived
  187.             SoapySDR_logf(SOAPY_SDR_ERROR, "bladeRF: Invalid XB200 setting '%s'", value);
  188.             //throw std::runtime_error("writeSetting(" + key + "," + value + ") unknown value");
  189.         }
  190.     }
  191.     else if (key == "sampling_mode")
  192.     {
  193.         /* Configure the sampling of the LMS6002D to be either internal or external.
  194.         ** Internal sampling will read from the RXVGA2 driver internal to the chip.
  195.         ** External sampling will connect the ADC inputs to the external inputs for direct sampling.
  196.         */
  197.  
  198.         // Verify that a valid setting has arrived
  199.         std::vector<std::string> sampling_mode_validSettings{ "internal", "external" };
  200.         if (std::find(std::begin(sampling_mode_validSettings), std::end(sampling_mode_validSettings), value) != std::end(sampling_mode_validSettings))
  201.         {
  202.             // --> Valid setting has arrived
  203.  
  204.             // Set the sampling mode
  205.             int ret = 0;
  206.             if (value == "external")
  207.             {
  208.                 // External/direct sampling
  209.                 SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Set sampling mode to direct/external sampling", value);
  210.                 ret = bladerf_set_sampling(_dev, bladerf_sampling::BLADERF_SAMPLING_EXTERNAL);
  211.             }
  212.             else
  213.             {
  214.                 // Default: Internal
  215.                 SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Set sampling mode to internal sampling", value);
  216.                 ret = bladerf_set_sampling(_dev, bladerf_sampling::BLADERF_SAMPLING_INTERNAL);
  217.             }
  218.             if (ret != 0)
  219.             {
  220.                 SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_sampling(%s) returned %s", value, _err2str(ret).c_str());
  221.                 throw std::runtime_error("writeSetting() " + _err2str(ret));
  222.             }
  223.         }
  224.         else
  225.         {
  226.             // --> Invalid setting has arrived
  227.             SoapySDR_logf(SOAPY_SDR_ERROR, "bladeRF: Invalid sampling mode '%s'", value);
  228.             //throw std::runtime_error("writeSetting(" + key + "," + value + ") unknown value");
  229.         }
  230.     }
  231.     else if (key == "loopback")
  232.     {
  233.         // Verify that a valid setting has arrived
  234.         std::vector<std::string> loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3" };
  235.         if (std::find(std::begin(loopback_validSettings), std::end(loopback_validSettings), value) != std::end(loopback_validSettings))
  236.         {
  237.             // --> Valid setting has arrived
  238.  
  239.             // Which loopback mode was selected?
  240.             bladerf_loopback loopback = bladerf_loopback::BLADERF_LB_NONE;
  241.  
  242.             if (value == "firmware")
  243.             {
  244.                 // Firmware loopback inside of the FX3
  245.                 loopback = bladerf_loopback::BLADERF_LB_FIRMWARE;
  246.             }
  247.             else if (value == "bb_txlpf_rxvga2")
  248.             {
  249.                 // Baseband loopback. TXLPF output is connected to the RXVGA2 input.
  250.                 loopback = bladerf_loopback::BLADERF_LB_BB_TXLPF_RXVGA2;
  251.             }
  252.             else if (value == "bb_txvga1_rxvga2")
  253.             {
  254.                 // Baseband loopback. TXVGA1 output is connected to the RXVGA2 input.
  255.                 loopback = bladerf_loopback::BLADERF_LB_BB_TXVGA1_RXVGA2;
  256.             }
  257.             else if (value == "bb_txlpf_rxlpf")
  258.             {
  259.                 // Baseband loopback. TXLPF output is connected to the RXLPF input.
  260.                 loopback = bladerf_loopback::BLADERF_LB_BB_TXLPF_RXLPF;
  261.             }
  262.             else if (value == "bb_txvga1_rxlpf")
  263.             {
  264.                 // Baseband loopback. TXVGA1 output is connected to RXLPF input.
  265.                 loopback = bladerf_loopback::BLADERF_LB_BB_TXVGA1_RXLPF;
  266.             }
  267.             else if (value == "rf_lna1")
  268.             {
  269.                 // RF loopback. The TXMIX output, through the AUX PA, is connected to the output of LNA1.
  270.                 loopback = bladerf_loopback::BLADERF_LB_RF_LNA1;
  271.             }
  272.             else if (value == "rf_lna2")
  273.             {
  274.                 // RF loopback. The TXMIX output, through the AUX PA, is connected to the output of LNA2.
  275.                 loopback = bladerf_loopback::BLADERF_LB_RF_LNA2;
  276.             }
  277.             else if (value == "rf_lna3")
  278.             {
  279.                 // RF loopback. The TXMIX output, through the AUX PA, is connected to the output of LNA3.
  280.                 loopback = bladerf_loopback::BLADERF_LB_RF_LNA3;
  281.             }
  282.             else
  283.             {
  284.                 // Default: Disabled
  285.                 // Disables loopback and returns to normal operation
  286.                 loopback = bladerf_loopback::BLADERF_LB_NONE;
  287.             }
  288.  
  289.             // If the loopback isn't already set, set the loopback
  290.             bladerf_loopback _bladerf_loopback = bladerf_loopback::BLADERF_LB_NONE;
  291.             bladerf_get_loopback(_dev, &_bladerf_loopback);
  292.             if (_bladerf_loopback != loopback)
  293.             {
  294.                 SoapySDR_logf(SOAPY_SDR_INFO, "bladeRF: Loopback set '%s'", value);
  295.                 int ret = bladerf_set_loopback(_dev, loopback);
  296.                 if (ret != 0)
  297.                 {
  298.                     SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_loopback(%s) returned %s", value, _err2str(ret).c_str());
  299.                     throw std::runtime_error("writeSetting() " + _err2str(ret));
  300.                 }
  301.             }
  302.         }
  303.         else
  304.         {
  305.             // --> Invalid setting has arrived
  306.             SoapySDR_logf(SOAPY_SDR_ERROR, "bladeRF: Invalid loopback setting '%s'", value);
  307.             //throw std::runtime_error("writeSetting(" + key + "," + value + ") unknown value");
  308.         }
  309.     }
  310.     else
  311.     {
  312.         throw std::runtime_error("writeSetting(" + key + ") unknown setting");
  313.     }
  314. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement