📄 usrp_prims.cc
字号:
return r;}// ----------------------------------------------------------------// load fpgastatic 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;}boolusrp_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;}boolusrp_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 boolusrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on){ return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;}static boolusrp1_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 boolusrp1_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;}boolusrp_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); }}boolusrp_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 stuffstatic boolcompute_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_tusrp_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_tusrp_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_tusrp_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 boolour_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 boolmdelay (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_tusrp_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 voidload_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; }}boolusrp_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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -