📄 usrp_basic.cc
字号:
usrp_basic::_set_led (int which, bool on){ return usrp_set_led (d_udh, which, on);}//////////////////////////////////////////////////////////////////// usrp_basic_rx//////////////////////////////////////////////////////////////////static unsigned char rx_init_regs[] = { REG_RX_PWR_DN, 0, REG_RX_A, 0, // minimum gain = 0x00 (max gain = 0x14) REG_RX_B, 0, // minimum gain = 0x00 (max gain = 0x14) REG_RX_MISC, (RX_MISC_HS_DUTY_CYCLE | RX_MISC_CLK_DUTY), REG_RX_IF, (RX_IF_USE_CLKOUT1 | RX_IF_2S_COMP), REG_RX_DIGITAL, (RX_DIGITAL_2_CHAN)};usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nblocks, const std::string fpga_filename, const std::string firmware_filename ) : usrp_basic (which_board, open_rx_interface, fpga_filename, firmware_filename), d_devhandle (0), d_ephandle (0), d_bytes_seen (0), d_first_read (true), d_rx_enable (false){ // initialize rx specific registers if (!usrp_9862_write_many_all (d_udh, rx_init_regs, sizeof (rx_init_regs))){ fprintf (stderr, "usrp_basic_rx: failed to init AD9862 RX regs\n"); throw std::runtime_error ("usrp_basic_rx/init_9862"); } if (0){ // FIXME power down 2nd codec rx path usrp_9862_write (d_udh, 1, REG_RX_PWR_DN, 0x1); // power down everything } // Reset the rx path and leave it disabled. set_rx_enable (false); usrp_set_fpga_rx_reset (d_udh, true); usrp_set_fpga_rx_reset (d_udh, false); set_fpga_rx_sample_rate_divisor (2); // usually correct set_dc_offset_cl_enable(0xf, 0xf); // enable DC offset removal control loops probe_rx_slots (false); // check fusb buffering parameters if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE) throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size"); if (fusb_nblocks < 0) throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks"); if (fusb_block_size == 0) fusb_block_size = fusb_sysconfig::default_block_size(); if (fusb_nblocks == 0) fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size); d_devhandle = fusb_sysconfig::make_devhandle (d_udh); d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true, fusb_block_size, fusb_nblocks); _write_fpga_reg(FR_ATR_MASK_1, 0); // zero Rx side Auto Transmit/Receive regs _write_fpga_reg(FR_ATR_TXVAL_1, 0); _write_fpga_reg(FR_ATR_RXVAL_1, 0); _write_fpga_reg(FR_ATR_MASK_3, 0); _write_fpga_reg(FR_ATR_TXVAL_3, 0); _write_fpga_reg(FR_ATR_RXVAL_3, 0);}static unsigned char rx_fini_regs[] = { REG_RX_PWR_DN, 0x1 // power down everything};usrp_basic_rx::~usrp_basic_rx (){ if (!set_rx_enable (false)){ fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n"); usb_strerror (); } d_ephandle->stop (); delete d_ephandle; delete d_devhandle; if (!usrp_9862_write_many_all (d_udh, rx_fini_regs, sizeof (rx_fini_regs))){ fprintf (stderr, "usrp_basic_rx: failed to fini AD9862 RX regs\n"); }}boolusrp_basic_rx::start (){ if (!usrp_basic::start ()) // invoke parent's method return false; // fire off reads before asserting rx_enable if (!d_ephandle->start ()){ fprintf (stderr, "usrp_basic_rx: failed to start end point streaming"); usb_strerror (); return false; } if (!set_rx_enable (true)){ fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n"); usb_strerror (); return false; } return true;}boolusrp_basic_rx::stop (){ bool ok = usrp_basic::stop(); if (!set_rx_enable(false)){ fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n"); usb_strerror (); ok = false; } if (!d_ephandle->stop()){ fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming"); usb_strerror (); ok = false; } return ok;}usrp_basic_rx *usrp_basic_rx::make (int which_board, int fusb_block_size, int fusb_nblocks, const std::string fpga_filename, const std::string firmware_filename){ usrp_basic_rx *u = 0; try { u = new usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename); return u; } catch (...){ delete u; return 0; } return u;}boolusrp_basic_rx::set_fpga_rx_sample_rate_divisor (unsigned int div){ return _write_fpga_reg (FR_RX_SAMPLE_RATE_DIV, div - 1);}/* * \brief read data from the D/A's via the FPGA. * \p len must be a multiple of 512 bytes. * * \returns the number of bytes read, or -1 on error. * * If overrun is non-NULL it will be set true iff an RX overrun is detected. */intusrp_basic_rx::read (void *buf, int len, bool *overrun){ int r; if (overrun) *overrun = false; if (len < 0 || (len % 512) != 0){ fprintf (stderr, "usrp_basic_rx::read: invalid length = %d\n", len); return -1; } r = d_ephandle->read (buf, len); if (r > 0) d_bytes_seen += r; /* * In many cases, the FPGA reports an rx overrun right after we * enable the Rx path. If this is our first read, check for the * overrun to clear the condition, then ignore the result. */ if (0 && d_first_read){ // FIXME d_first_read = false; bool bogus_overrun; usrp_check_rx_overrun (d_udh, &bogus_overrun); } if (overrun != 0 && d_bytes_seen >= d_bytes_per_poll){ d_bytes_seen = 0; if (!usrp_check_rx_overrun (d_udh, overrun)){ fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n"); usb_strerror (); } } return r;}boolusrp_basic_rx::set_rx_enable (bool on){ d_rx_enable = on; return usrp_set_fpga_rx_enable (d_udh, on);}// conditional disable, return prev stateboolusrp_basic_rx::disable_rx (){ bool enabled = rx_enable (); if (enabled) set_rx_enable (false); return enabled;}// conditional setvoidusrp_basic_rx::restore_rx (bool on){ if (on != rx_enable ()) set_rx_enable (on);}boolusrp_basic_rx::set_pga (int which, double gain){ if (which < 0 || which > 3) return false; gain = std::max (pga_min (), gain); gain = std::min (pga_max (), gain); int codec = which >> 1; int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B; // read current value to get input buffer bypass flag. unsigned char cur_rx; if (!_read_9862 (codec, reg, &cur_rx)) return false; int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step()); cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f); return _write_9862 (codec, reg, cur_rx);}doubleusrp_basic_rx::pga (int which) const{ if (which < 0 || which > 3) return READ_FAILED; int codec = which >> 1; int reg = (which & 1) == 0 ? REG_RX_A : REG_RX_B; unsigned char v; bool ok = _read_9862 (codec, reg, &v); if (!ok) return READ_FAILED; return (pga_db_per_step() * (v & 0x1f)) + pga_min();}static intslot_id_to_oe_reg (int slot_id){ static int reg[4] = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 }; assert (0 <= slot_id && slot_id < 4); return reg[slot_id];}static intslot_id_to_io_reg (int slot_id){ static int reg[4] = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 }; assert (0 <= slot_id && slot_id < 4); return reg[slot_id];}voidusrp_basic_rx::probe_rx_slots (bool verbose){ struct usrp_dboard_eeprom eeprom; static int slot_id_map[2] = { SLOT_RX_A, SLOT_RX_B }; static const char *slot_name[2] = { "RX d'board A", "RX d'board B" }; for (int i = 0; i < 2; i++){ int slot_id = slot_id_map [i]; const char *msg = 0; usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom); switch (s){ case UDBE_OK: d_dbid[i] = eeprom.id; msg = usrp_dbid_to_string (eeprom.id).c_str (); set_adc_offset (2*i+0, eeprom.offset[0]); set_adc_offset (2*i+1, eeprom.offset[1]); _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe); _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000); break; case UDBE_NO_EEPROM: d_dbid[i] = -1; msg = "<none>"; _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000); _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000); break; case UDBE_INVALID_EEPROM: d_dbid[i] = -2; msg = "Invalid EEPROM contents"; _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000); _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000); break; case UDBE_BAD_SLOT: default: assert (0); } if (verbose){ fflush (stdout); fprintf (stderr, "%s: %s\n", slot_name[i], msg); } }}boolusrp_basic_rx::_write_oe (int which_dboard, int value, int mask){ if (! (0 <= which_dboard && which_dboard <= 1)) return false; return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)), (mask << 16) | (value & 0xffff));}boolusrp_basic_rx::write_io (int which_dboard, int value, int mask){ if (! (0 <= which_dboard && which_dboard <= 1)) return false; return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)), (mask << 16) | (value & 0xffff));}boolusrp_basic_rx::read_io (int which_dboard, int *value){ if (! (0 <= which_dboard && which_dboard <= 1)) return false; int t; int reg = which_dboard + 1; // FIXME, *very* magic number (fix in serial_io.v) bool ok = _read_fpga_reg (reg, &t); if (!ok) return false; *value = (t >> 16) & 0xffff; // FIXME, more magic return true;}intusrp_basic_rx::read_io (int which_dboard){ int value; if (!read_io (which_dboard, &value)) return READ_FAILED; return value;}boolusrp_basic_rx::write_aux_dac (int which_dboard, int which_dac, int value){ return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard), which_dac, value);}boolusrp_basic_rx::read_aux_adc (int which_dboard, int which_adc, int *value){ return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc, value);}intusrp_basic_rx::read_aux_adc (int which_dboard, int which_adc){ return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);}intusrp_basic_rx::block_size () const { return d_ephandle->block_size(); }bool
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -