?? usrp_primes.cc
字號:
return r;
}
// ----------------------------------------------------------------
// load fpga
static bool
_usrp_load_fpga (struct usb_dev_handle *udh, const char *filename,
unsigned char hash[USRP_HASH_SIZE])
{
bool ok = true;
FILE *fp = fopen (filename, "rb");
if (fp == 0){
perror (filename);
return false;
}
unsigned char buf[MAX_EP0_PKTSIZE]; // 64 is max size of EP0 packet on FX2
int n;
usrp_set_led (udh, 1, 1); // led 1 on
// reset FPGA (and on rev1 both AD9862's, thus killing clock)
usrp_set_fpga_reset (udh, 1); // hold fpga in reset
if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_BEGIN, 0, 0) != 0)
goto fail;
while ((n = fread (buf, 1, sizeof (buf), fp)) > 0){
if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_XFER, buf, n) != n)
goto fail;
}
if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_END, 0, 0) != 0)
goto fail;
fclose (fp);
if (!usrp_set_hash (udh, FPGA_HASH_SLOT, hash))
fprintf (stderr, "usrp: failed to write fpga hash slot\n");
// On the rev1 USRP, the {tx,rx}_{enable,reset} bits are
// controlled over the serial bus, and hence aren't observed until
// we've got a good fpga bitstream loaded.
usrp_set_fpga_reset (udh, 0); // fpga out of master reset
// now these commands will work
ok &= usrp_set_fpga_tx_enable (udh, 0);
ok &= usrp_set_fpga_rx_enable (udh, 0);
ok &= usrp_set_fpga_tx_reset (udh, 1); // reset tx and rx paths
ok &= usrp_set_fpga_rx_reset (udh, 1);
ok &= usrp_set_fpga_tx_reset (udh, 0); // reset tx and rx paths
ok &= usrp_set_fpga_rx_reset (udh, 0);
if (!ok)
fprintf (stderr, "usrp: failed to reset tx and/or rx path\n");
// Manually reset all regs except master control to zero.
// FIXME may want to remove this when we rework FPGA reset strategy.
// In the mean while, this gets us reproducible behavior.
for (int i = 0; i < FR_USER_0; i++){
if (i == FR_MASTER_CTRL)
continue;
usrp_write_fpga_reg(udh, i, 0);
}
power_down_9862s (udh); // on the rev1, power these down!
usrp_set_led (udh, 1, 0); // led 1 off
return true;
fail:
power_down_9862s (udh); // on the rev1, power these down!
fclose (fp);
return false;
}
// ----------------------------------------------------------------
bool
usrp_set_led (struct usb_dev_handle *udh, int which, bool on)
{
int r = write_cmd (udh, VRQ_SET_LED, on, which, 0, 0);
return r == 0;
}
bool
usrp_set_hash (struct usb_dev_handle *udh, int which,
const unsigned char hash[USRP_HASH_SIZE])
{
which &= 1;
// we use the Cypress firmware down load command to jam it in.
int r = usb_control_msg (udh, 0x40, 0xa0, hash_slot_addr[which], 0,
(char *) hash, USRP_HASH_SIZE, 1000);
return r == USRP_HASH_SIZE;
}
bool
usrp_get_hash (struct usb_dev_handle *udh, int which,
unsigned char hash[USRP_HASH_SIZE])
{
which &= 1;
// we use the Cypress firmware upload command to fetch it.
int r = usb_control_msg (udh, 0xc0, 0xa0, hash_slot_addr[which], 0,
(char *) hash, USRP_HASH_SIZE, 1000);
return r == USRP_HASH_SIZE;
}
static bool
usrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on)
{
return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;
}
static bool
usrp1_fpga_write (struct usb_dev_handle *udh,
int regno, int value)
{
// on the rev1 usrp, we use the generic spi_write interface
unsigned char buf[4];
buf[0] = (value >> 24) & 0xff; // MSB first
buf[1] = (value >> 16) & 0xff;
buf[2] = (value >> 8) & 0xff;
buf[3] = (value >> 0) & 0xff;
return usrp_spi_write (udh, 0x00 | (regno & 0x7f),
SPI_ENABLE_FPGA,
SPI_FMT_MSB | SPI_FMT_HDR_1,
buf, sizeof (buf));
}
static bool
usrp1_fpga_read (struct usb_dev_handle *udh,
int regno, int *value)
{
*value = 0;
unsigned char buf[4];
bool ok = usrp_spi_read (udh, 0x80 | (regno & 0x7f),
SPI_ENABLE_FPGA,
SPI_FMT_MSB | SPI_FMT_HDR_1,
buf, sizeof (buf));
if (ok)
*value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
return ok;
}
bool
usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value)
{
switch (usrp_hw_rev (dev_handle_to_dev (udh))){
case 0: // not supported ;)
abort();
default:
return usrp1_fpga_write (udh, reg, value);
}
}
bool
usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value)
{
switch (usrp_hw_rev (dev_handle_to_dev (udh))){
case 0: // not supported ;)
abort();
default:
return usrp1_fpga_read (udh, reg, value);
}
}
bool
usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on)
{
return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on);
}
bool
usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on)
{
return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on);
}
bool
usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on)
{
return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on);
}
bool
usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on)
{
return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on);
}
bool
usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on)
{
return usrp_set_switch (udh, VRQ_FPGA_SET_RX_RESET, on);
}
// ----------------------------------------------------------------
// conditional load stuff
static bool
compute_hash (const char *filename, unsigned char hash[USRP_HASH_SIZE])
{
assert (USRP_HASH_SIZE == 16);
memset (hash, 0, USRP_HASH_SIZE);
FILE *fp = fopen (filename, "rb");
if (fp == 0){
perror (filename);
return false;
}
int r = md5_stream (fp, hash);
fclose (fp);
return r == 0;
}
static usrp_load_status_t
usrp_conditionally_load_something (struct usb_dev_handle *udh,
const char *filename,
bool force,
int slot,
bool loader (struct usb_dev_handle *,
const char *,
unsigned char [USRP_HASH_SIZE]))
{
unsigned char file_hash[USRP_HASH_SIZE];
unsigned char usrp_hash[USRP_HASH_SIZE];
if (access (filename, R_OK) != 0){
perror (filename);
return ULS_ERROR;
}
if (!compute_hash (filename, file_hash))
return ULS_ERROR;
if (!force
&& usrp_get_hash (udh, slot, usrp_hash)
&& memcmp (file_hash, usrp_hash, USRP_HASH_SIZE) == 0)
return ULS_ALREADY_LOADED;
bool r = loader (udh, filename, file_hash);
if (!r)
return ULS_ERROR;
return ULS_OK;
}
usrp_load_status_t
usrp_load_firmware (struct usb_dev_handle *udh,
const char *filename,
bool force)
{
return usrp_conditionally_load_something (udh, filename, force,
FIRMWARE_HASH_SLOT,
_usrp_load_firmware);
}
usrp_load_status_t
usrp_load_fpga (struct usb_dev_handle *udh,
const char *filename,
bool force)
{
return usrp_conditionally_load_something (udh, filename, force,
FPGA_HASH_SLOT,
_usrp_load_fpga);
}
static usb_dev_handle *
open_nth_cmd_interface (int nth)
{
struct usb_device *udev = usrp_find_device (nth);
if (udev == 0){
fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
return 0;
}
struct usb_dev_handle *udh;
udh = usrp_open_cmd_interface (udev);
if (udh == 0){
// FIXME this could be because somebody else has it open.
// We should delay and retry...
fprintf (stderr, "open_nth_cmd_interface: open_cmd_interface failed\n");
usb_strerror ();
return 0;
}
return udh;
}
static bool
our_nanosleep (const struct timespec *delay)
{
struct timespec new_delay = *delay;
struct timespec remainder;
while (1){
int r = nanosleep (&new_delay, &remainder);
if (r == 0)
return true;
if (errno == EINTR)
new_delay = remainder;
else {
perror ("nanosleep");
return false;
}
}
}
static bool
mdelay (int millisecs)
{
struct timespec ts;
ts.tv_sec = millisecs / 1000;
ts.tv_nsec = (millisecs - (1000 * ts.tv_sec)) * 1000000;
return our_nanosleep (&ts);
}
usrp_load_status_t
usrp_load_firmware_nth (int nth, const char *filename, bool force){
struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
if (udh == 0)
return ULS_ERROR;
usrp_load_status_t s = usrp_load_firmware (udh, filename, force);
usrp_close_interface (udh);
switch (s){
case ULS_ALREADY_LOADED: // nothing changed...
return ULS_ALREADY_LOADED;
break;
case ULS_OK:
// we loaded firmware successfully.
// It's highly likely that the board will renumerate (simulate a
// disconnect/reconnect sequence), invalidating our current
// handle.
// FIXME. Turn this into a loop that rescans until we refind ourselves
struct timespec t; // delay for 1 second
t.tv_sec = 2;
t.tv_nsec = 0;
our_nanosleep (&t);
usb_find_busses (); // rescan busses and devices
usb_find_devices ();
return ULS_OK;
default:
case ULS_ERROR: // some kind of problem
return ULS_ERROR;
}
}
static void
load_status_msg (usrp_load_status_t s, const char *type, const char *filename)
{
char *e = getenv("USRP_VERBOSE");
bool verbose = e != 0;
switch (s){
case ULS_ERROR:
fprintf (stderr, "usrp: failed to load %s %s.\n", type, filename);
break;
case ULS_ALREADY_LOADED:
if (verbose)
fprintf (stderr, "usrp: %s %s already loaded.\n", type, filename);
break;
case ULS_OK:
if (verbose)
fprintf (stderr, "usrp: %s %s loaded successfully.\n", type, filename);
break;
}
}
bool
usrp_load_standard_bits (int nth, bool force,
const std::string fpga_filename,
const std::string firmware_filename)
{
usrp_load_status_t s;
const char *filename;
const char *proto_filename;
int hw_rev;
// first, figure out what hardware rev we're dealing with
{
struct usb_device *udev = usrp_find_device (nth);
if (udev == 0){
fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
return false;
}
hw_rev = usrp_hw_rev (udev);
}
// start by loading the firmware
proto_filename = get_proto_filename(firmware_filename, "USRP_FIRMWARE",
default_firmware_filename);
filename = find_file(proto_filename, hw_rev);
if (filename == 0){
fprintf (stderr, "Can't find firmware: %s\n", proto_filename);
return false;
}
s = usrp_load_firmware_nth (nth, filename, force);
load_status_msg (s, "firmware", filename);
if (s == ULS_ERROR)
return false;
// if we actually loaded firmware, we must reload fpga ...
if (s == ULS_OK)
force = true;
// now move on to the fpga configuration bitstream
proto_filename = get_proto_filename(fpga_filename, "USRP_FPGA",
default_fpga_filename);
filename = find_file (proto_filename, hw_rev);
if (filename == 0){
fprintf (stderr, "Can't find fpga bitstream: %s\n", proto_filename);
return false;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -