📄 usrp_prims.cc
字号:
struct usb_dev_handle *udh = open_nth_cmd_interface (nth); if (udh == 0) return false; s = usrp_load_fpga (udh, filename, force); usrp_close_interface (udh); load_status_msg (s, "fpga bitstream", filename); if (s == ULS_ERROR) return false; return true;}bool_usrp_get_status (struct usb_dev_handle *udh, int which, bool *trouble){ unsigned char status; *trouble = true; if (write_cmd (udh, VRQ_GET_STATUS, 0, which, &status, sizeof (status)) != sizeof (status)) return false; *trouble = status; return true;}boolusrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p){ return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);}boolusrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p){ return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);}boolusrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr, const void *buf, int len){ if (len < 1 || len > MAX_EP0_PKTSIZE) return false; return write_cmd (udh, VRQ_I2C_WRITE, i2c_addr, 0, (unsigned char *) buf, len) == len;}boolusrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr, void *buf, int len){ if (len < 1 || len > MAX_EP0_PKTSIZE) return false; return write_cmd (udh, VRQ_I2C_READ, i2c_addr, 0, (unsigned char *) buf, len) == len;}boolusrp_spi_write (struct usb_dev_handle *udh, int optional_header, int enables, int format, const void *buf, int len){ if (len < 0 || len > MAX_EP0_PKTSIZE) return false; return write_cmd (udh, VRQ_SPI_WRITE, optional_header, ((enables & 0xff) << 8) | (format & 0xff), (unsigned char *) buf, len) == len;}boolusrp_spi_read (struct usb_dev_handle *udh, int optional_header, int enables, int format, void *buf, int len){ if (len < 0 || len > MAX_EP0_PKTSIZE) return false; return write_cmd (udh, VRQ_SPI_READ, optional_header, ((enables & 0xff) << 8) | (format & 0xff), (unsigned char *) buf, len) == len;}boolusrp_9862_write (struct usb_dev_handle *udh, int which_codec, int regno, int value){ if (0) fprintf (stderr, "usrp_9862_write which = %d, reg = %2d, val = %3d (0x%02x)\n", which_codec, regno, value, value); unsigned char buf[1]; buf[0] = value; return usrp_spi_write (udh, 0x00 | (regno & 0x3f), which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B, SPI_FMT_MSB | SPI_FMT_HDR_1, buf, 1);}boolusrp_9862_read (struct usb_dev_handle *udh, int which_codec, int regno, unsigned char *value){ return usrp_spi_read (udh, 0x80 | (regno & 0x3f), which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B, SPI_FMT_MSB | SPI_FMT_HDR_1, value, 1);}boolusrp_9862_write_many (struct usb_dev_handle *udh, int which_codec, const unsigned char *buf, int len){ if (len & 0x1) return false; // must be even bool result = true; while (len > 0){ result &= usrp_9862_write (udh, which_codec, buf[0], buf[1]); len -= 2; buf += 2; } return result;}boolusrp_9862_write_many_all (struct usb_dev_handle *udh, const unsigned char *buf, int len){ // FIXME handle 2/2 and 4/4 versions bool result; result = usrp_9862_write_many (udh, 0, buf, len); result &= usrp_9862_write_many (udh, 1, buf, len); return result;}static voidpower_down_9862s (struct usb_dev_handle *udh){ static const unsigned char regs[] = { REG_RX_PWR_DN, 0x01, // everything REG_TX_PWR_DN, 0x0f, // pwr dn digital and analog_both REG_TX_MODULATOR, 0x00 // coarse & fine modulators disabled }; switch (usrp_hw_rev (dev_handle_to_dev (udh))){ case 0: break; default: usrp_9862_write_many_all (udh, regs, sizeof (regs)); break; }}static const int EEPROM_PAGESIZE = 16;boolusrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, int eeprom_offset, const void *buf, int len){ unsigned char cmd[2]; const unsigned char *p = (unsigned char *) buf; // The simplest thing that could possibly work: // all writes are single byte writes. // // We could speed this up using the page write feature, // but we write so infrequently, why bother... while (len-- > 0){ cmd[0] = eeprom_offset++; cmd[1] = *p++; bool r = usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd)); mdelay (10); // delay 10ms worst case write time if (!r) return false; } return true;}boolusrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, int eeprom_offset, void *buf, int len){ unsigned char *p = (unsigned char *) buf; // We setup a random read by first doing a "zero byte write". // Writes carry an address. Reads use an implicit address. unsigned char cmd[1]; cmd[0] = eeprom_offset; if (!usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd))) return false; while (len > 0){ int n = std::min (len, MAX_EP0_PKTSIZE); if (!usrp_i2c_read (udh, i2c_addr, p, n)) return false; len -= n; p += n; } return true;} // ----------------------------------------------------------------static boolslot_to_codec (int slot, int *which_codec){ *which_codec = 0; switch (slot){ case SLOT_TX_A: case SLOT_RX_A: *which_codec = 0; break; case SLOT_TX_B: case SLOT_RX_B: *which_codec = 1; break; default: fprintf (stderr, "usrp_prims:slot_to_codec: invalid slot = %d\n", slot); return false; } return true;}static booltx_slot_p (int slot){ switch (slot){ case SLOT_TX_A: case SLOT_TX_B: return true; default: return false; }}boolusrp_write_aux_dac (struct usb_dev_handle *udh, int slot, int which_dac, int value){ int which_codec; if (!slot_to_codec (slot, &which_codec)) return false; if (!(0 <= which_dac && which_dac < 4)){ fprintf (stderr, "usrp_write_aux_dac: invalid dac = %d\n", which_dac); return false; } value &= 0x0fff; // mask to 12-bits if (which_dac == 3){ // dac 3 is really 12-bits. Use value as is. bool r = true; r &= usrp_9862_write (udh, which_codec, 43, (value >> 4)); // most sig r &= usrp_9862_write (udh, which_codec, 42, (value & 0xf) << 4); // least sig return r; } else { // dac 0, 1, and 2 are really 8 bits. value = value >> 4; // shift value appropriately return usrp_9862_write (udh, which_codec, 36 + which_dac, value); }}boolusrp_read_aux_adc (struct usb_dev_handle *udh, int slot, int which_adc, int *value){ *value = 0; int which_codec; if (!slot_to_codec (slot, &which_codec)) return false; if (!(0 <= which_codec && which_codec < 2)){ fprintf (stderr, "usrp_read_aux_adc: invalid adc = %d\n", which_adc); return false; } unsigned char aux_adc_control = AUX_ADC_CTRL_REFSEL_A // on chip reference | AUX_ADC_CTRL_REFSEL_B; // on chip reference int rd_reg = 26; // base address of two regs to read for result // program the ADC mux bits if (tx_slot_p (slot)) aux_adc_control |= AUX_ADC_CTRL_SELECT_A2 | AUX_ADC_CTRL_SELECT_B2; else { rd_reg += 2; aux_adc_control |= AUX_ADC_CTRL_SELECT_A1 | AUX_ADC_CTRL_SELECT_B1; } // I'm not sure if we can set the mux and issue a start conversion // in the same cycle, so let's do them one at a time. usrp_9862_write (udh, which_codec, 34, aux_adc_control); if (which_adc == 0) aux_adc_control |= AUX_ADC_CTRL_START_A; else { rd_reg += 4; aux_adc_control |= AUX_ADC_CTRL_START_B; } // start the conversion usrp_9862_write (udh, which_codec, 34, aux_adc_control); // read the 10-bit result back unsigned char v_lo = 0; unsigned char v_hi = 0; bool r = usrp_9862_read (udh, which_codec, rd_reg, &v_lo); r &= usrp_9862_read (udh, which_codec, rd_reg + 1, &v_hi); if (r) *value = ((v_hi << 2) | ((v_lo >> 6) & 0x3)) << 2; // format as 12-bit return r;}// ----------------------------------------------------------------static int slot_to_i2c_addr (int slot){ switch (slot){ case SLOT_TX_A: return I2C_ADDR_TX_A; case SLOT_RX_A: return I2C_ADDR_RX_A; case SLOT_TX_B: return I2C_ADDR_TX_B; case SLOT_RX_B: return I2C_ADDR_RX_B; default: return -1; }}static voidset_chksum (unsigned char *buf){ int sum = 0; unsigned int i; for (i = 0; i < DB_EEPROM_CLEN - 1; i++) sum += buf[i]; buf[i] = -sum;}static usrp_dbeeprom_status_tread_dboard_eeprom (struct usb_dev_handle *udh, int slot_id, unsigned char *buf){ int i2c_addr = slot_to_i2c_addr (slot_id); if (i2c_addr == -1) return UDBE_BAD_SLOT; if (!usrp_eeprom_read (udh, i2c_addr, 0, buf, DB_EEPROM_CLEN)) return UDBE_NO_EEPROM; if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE) return UDBE_INVALID_EEPROM; int sum = 0; for (unsigned int i = 0; i < DB_EEPROM_CLEN; i++) sum += buf[i]; if ((sum & 0xff) != 0) return UDBE_INVALID_EEPROM; return UDBE_OK;}usrp_dbeeprom_status_tusrp_read_dboard_eeprom (struct usb_dev_handle *udh, int slot_id, usrp_dboard_eeprom *eeprom){ unsigned char buf[DB_EEPROM_CLEN]; memset (eeprom, 0, sizeof (*eeprom)); usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf); if (s != UDBE_OK) return s; eeprom->id = (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB]; eeprom->oe = (buf[DB_EEPROM_OE_MSB] << 8) | buf[DB_EEPROM_OE_LSB]; eeprom->offset[0] = (buf[DB_EEPROM_OFFSET_0_MSB] << 8) | buf[DB_EEPROM_OFFSET_0_LSB]; eeprom->offset[1] = (buf[DB_EEPROM_OFFSET_1_MSB] << 8) | buf[DB_EEPROM_OFFSET_1_LSB]; return UDBE_OK;}boolusrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id, short offset0, short offset1){ unsigned char buf[DB_EEPROM_CLEN]; usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf); if (s != UDBE_OK) return false; buf[DB_EEPROM_OFFSET_0_LSB] = (offset0 >> 0) & 0xff; buf[DB_EEPROM_OFFSET_0_MSB] = (offset0 >> 8) & 0xff; buf[DB_EEPROM_OFFSET_1_LSB] = (offset1 >> 0) & 0xff; buf[DB_EEPROM_OFFSET_1_MSB] = (offset1 >> 8) & 0xff; set_chksum (buf); return usrp_eeprom_write (udh, slot_to_i2c_addr (slot_id), 0, buf, sizeof (buf));}std::stringusrp_serial_number(struct usb_dev_handle *udh){ unsigned char iserial = usb_device(udh)->descriptor.iSerialNumber; if (iserial == 0) return ""; char buf[1024]; if (usb_get_string_simple(udh, iserial, buf, sizeof(buf)) < 0) return ""; return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -