?? usrp_primes.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;
}
bool
usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p)
{
return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);
}
bool
usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p)
{
return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);
}
bool
usrp_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;
}
bool
usrp_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;
}
bool
usrp_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;
}
bool
usrp_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;
}
bool
usrp_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);
}
bool
usrp_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);
}
bool
usrp_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;
}
bool
usrp_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 void
power_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;
bool
usrp_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;
}
bool
usrp_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 bool
slot_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 bool
tx_slot_p (int slot)
{
switch (slot){
case SLOT_TX_A:
case SLOT_TX_B:
return true;
default:
return false;
}
}
bool
usrp_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);
}
}
bool
usrp_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 void
set_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_t
read_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_t
usrp_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;
}
bool
usrp_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::string
usrp_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 + -