📄 usrp_standard.cc
字号:
// To avoid quiet failures, check for things that our code cares about.static boolrx_format_is_valid(unsigned int format){ int width = usrp_standard_rx::format_width(format); int want_q = usrp_standard_rx::format_want_q(format); if (!(width == 8 || width == 16)) // FIXME add other widths when valid return false; if (!want_q) // FIXME remove check when the rest of the code can handle I only return false; return true;}boolusrp_standard_rx::set_format(unsigned int format){ if (!rx_format_is_valid(format)) return false; return _write_fpga_reg(FR_RX_FORMAT, format);}unsigned intusrp_standard_rx::format() const{ return d_fpga_shadows[FR_RX_FORMAT];}// ----------------------------------------------------------------unsigned int usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband){ unsigned int format = (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK) | (shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK); if (want_q) format |= bmFR_RX_FORMAT_WANT_Q; if (bypass_halfband) format |= bmFR_RX_FORMAT_BYPASS_HB; return format;}intusrp_standard_rx::format_width(unsigned int format){ return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;}intusrp_standard_rx::format_shift(unsigned int format){ return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;}boolusrp_standard_rx::format_want_q(unsigned int format){ return (format & bmFR_RX_FORMAT_WANT_Q) != 0;}boolusrp_standard_rx::format_bypass_halfband(unsigned int format){ return (format & bmFR_RX_FORMAT_BYPASS_HB) != 0;}//////////////////////////////////////////////////////////////////// tx data is timed to CLKOUT1 (64 MHz)// interpolate 4x// fine modulator enabledstatic unsigned char tx_regs_use_nco[] = { REG_TX_IF, (TX_IF_USE_CLKOUT1 | TX_IF_I_FIRST | TX_IF_2S_COMP | TX_IF_INTERLEAVED), REG_TX_DIGITAL, (TX_DIGITAL_2_DATA_PATHS | TX_DIGITAL_INTERPOLATE_4X)};static intreal_tx_mux_value (int mux, int nchan){ if (mux != -1) return mux; switch (nchan){ case 1: return 0x0098; case 2: return 0xba98; default: assert (0); }}usrp_standard_tx::usrp_standard_tx (int which_board, unsigned int interp_rate, int nchan, int mux, int fusb_block_size, int fusb_nblocks, const std::string fpga_filename, const std::string firmware_filename ) : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename), usrp_standard_common(this), d_sw_mux (0x8), d_hw_mux (0x81){ if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){ fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n"); throw std::runtime_error ("usrp_standard_tx::ctor"); } if (!set_nchannels (nchan)){ fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n"); throw std::runtime_error ("usrp_standard_tx::ctor"); } if (!set_interp_rate (interp_rate)){ fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n"); throw std::runtime_error ("usrp_standard_tx::ctor"); } if (!set_mux (real_tx_mux_value (mux, nchan))){ fprintf (stderr, "usrp_standard_tx: set_mux failed\n"); throw std::runtime_error ("usrp_standard_tx::ctor"); } for (int i = 0; i < MAX_CHAN; i++){ d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO | TX_MODULATOR_COARSE_MODULATION_NONE); d_coarse_mod[i] = CM_OFF; set_tx_freq (i, 0); }}usrp_standard_tx::~usrp_standard_tx (){ // fprintf(stderr, "\nusrp_standard_tx: dtor\n");}boolusrp_standard_tx::start (){ if (!usrp_basic_tx::start ()) return false; // add our code here return true;}boolusrp_standard_tx::stop (){ bool ok = usrp_basic_tx::stop (); // add our code here return ok;}usrp_standard_tx *usrp_standard_tx::make (int which_board, unsigned int interp_rate, int nchan, int mux, int fusb_block_size, int fusb_nblocks, const std::string fpga_filename, const std::string firmware_filename ){ usrp_standard_tx *u = 0; try { u = new usrp_standard_tx (which_board, interp_rate, nchan, mux, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename); return u; } catch (...){ delete u; return 0; } return u;}boolusrp_standard_tx::set_interp_rate (unsigned int rate){ // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n"); if ((rate & 0x3) || rate < 4 || rate > 512){ fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n"); return false; } d_interp_rate = rate; set_usb_data_rate ((dac_rate () / rate * nchannels ()) * (2 * sizeof (short))); // We're using the interp by 4 feature of the 9862 so that we can // use its fine modulator. Thus, we reduce the FPGA's interpolation rate // by a factor of 4. bool s = disable_tx (); bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1); restore_tx (s); return ok;}boolusrp_standard_tx::set_nchannels (int nchan){ if (!(nchan == 1 || nchan == 2)) return false; if (nchan > nducs()) return false; d_nchan = nchan; return write_hw_mux_reg ();}boolusrp_standard_tx::set_mux (int mux){ d_sw_mux = mux; d_hw_mux = mux << 4; return write_hw_mux_reg ();}boolusrp_standard_tx::write_hw_mux_reg (){ bool s = disable_tx (); bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan); restore_tx (s); return ok;}#ifdef USE_FPGA_TX_CORDICboolusrp_standard_tx::set_tx_freq (int channel, double freq){ if (channel < 0 || channel >= MAX_CHAN) return false; // This assumes we're running the 4x on-chip interpolator. unsigned int v = compute_freq_control_word_fpga (dac_freq () / 4, freq, &d_tx_freq[channel], d_verbose); return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);}#elseboolusrp_standard_tx::set_tx_freq (int channel, double freq){ if (channel < 0 || channel >= MAX_CHAN) return false; // split freq into fine and coarse components coarse_mod_t cm; double coarse; assert (dac_freq () == 128000000); if (freq < -44e6) // too low return false; else if (freq < -24e6){ // [-44, -24) cm = CM_NEG_FDAC_OVER_4; coarse = -dac_freq () / 4; } else if (freq < -8e6){ // [-24, -8) cm = CM_NEG_FDAC_OVER_8; coarse = -dac_freq () / 8; } else if (freq < 8e6){ // [-8, 8) cm = CM_OFF; coarse = 0; } else if (freq < 24e6){ // [8, 24) cm = CM_POS_FDAC_OVER_8; coarse = dac_freq () / 8; } else if (freq <= 44e6){ // [24, 44] cm = CM_POS_FDAC_OVER_4; coarse = dac_freq () / 4; } else // too high return false; set_coarse_modulator (channel, cm); // set bits in d_tx_modulator_shadow double fine = freq - coarse; // Compute fine tuning word... // This assumes we're running the 4x on-chip interpolator. // (This is required to use the fine modulator.) unsigned int v = compute_freq_control_word_9862 (dac_freq () / 4, fine, &d_tx_freq[channel], d_verbose); d_tx_freq[channel] += coarse; // adjust actual unsigned char high, mid, low; high = (v >> 16) & 0xff; mid = (v >> 8) & 0xff; low = (v >> 0) & 0xff; bool ok = true; // write the fine tuning word ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high); ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8, mid); ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0, low); d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO; if (fine < 0) d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE; else d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE; ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]); return ok;}#endifboolusrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm){ if (channel < 0 || channel >= MAX_CHAN) return false; switch (cm){ case CM_NEG_FDAC_OVER_4: d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK; d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4; d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE; break; case CM_NEG_FDAC_OVER_8: d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK; d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8; d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE; break; case CM_OFF: d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK; break; case CM_POS_FDAC_OVER_8: d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK; d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8; break; case CM_POS_FDAC_OVER_4: d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK; d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4; break; default: return false; } d_coarse_mod[channel] = cm; return true;}unsigned intusrp_standard_tx::interp_rate () const { return d_interp_rate; }intusrp_standard_tx::nchannels () const { return d_nchan; }intusrp_standard_tx::mux () const { return d_sw_mux; }doubleusrp_standard_tx::tx_freq (int channel) const{ if (channel < 0 || channel >= MAX_CHAN) return 0; return d_tx_freq[channel];}usrp_standard_tx::coarse_mod_tusrp_standard_tx::coarse_modulator (int channel) const{ if (channel < 0 || channel >= MAX_CHAN) return CM_OFF; return d_coarse_mod[channel];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -