aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/fx2
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-06-14 17:15:38 -0700
committerJosh Blum <josh@joshknows.com>2011-06-14 17:56:54 -0700
commitdeae10bc1c85726ed7c206abca37a869c6f77cea (patch)
tree1bd8f8dc2734af460d8434e508d33ecdb9cf5fe7 /firmware/fx2
parent2d8d1a4d1ad15482e25f52e1fa3ad8ae94490a8e (diff)
downloaduhd-deae10bc1c85726ed7c206abca37a869c6f77cea.tar.gz
uhd-deae10bc1c85726ed7c206abca37a869c6f77cea.tar.bz2
uhd-deae10bc1c85726ed7c206abca37a869c6f77cea.zip
b100: added b100 firmware (squashed)
Diffstat (limited to 'firmware/fx2')
-rw-r--r--firmware/fx2/CMakeLists.txt2
-rw-r--r--firmware/fx2/b100/.gitignore19
-rw-r--r--firmware/fx2/b100/CMakeLists.txt88
-rw-r--r--firmware/fx2/b100/board_specific.c70
-rw-r--r--firmware/fx2/b100/eeprom_io.c65
-rw-r--r--firmware/fx2/b100/eeprom_io.h38
-rw-r--r--firmware/fx2/b100/fpga_load.c193
-rw-r--r--firmware/fx2/b100/fpga_rev2.c51
-rw-r--r--firmware/fx2/b100/fpga_rev2.h44
-rw-r--r--firmware/fx2/b100/gpif.c292
-rw-r--r--firmware/fx2/b100/usb_descriptors.a51499
-rw-r--r--firmware/fx2/b100/usrp_common.c108
-rw-r--r--firmware/fx2/b100/usrp_main.c394
-rw-r--r--firmware/fx2/b100/usrp_regs.h126
-rw-r--r--firmware/fx2/common/fx2regs.h4
-rw-r--r--firmware/fx2/common/usrp_commands.h6
-rwxr-xr-xfirmware/fx2/utils/build_eeprom.py12
-rwxr-xr-xfirmware/fx2/utils/edit-gpif-b100.py120
18 files changed, 2127 insertions, 4 deletions
diff --git a/firmware/fx2/CMakeLists.txt b/firmware/fx2/CMakeLists.txt
index 80f16363f..f7f6e96ca 100644
--- a/firmware/fx2/CMakeLists.txt
+++ b/firmware/fx2/CMakeLists.txt
@@ -39,9 +39,11 @@ set(CMAKE_C_FLAGS "--no-xinit-opt")
########################################################################
set(REG_GENERATOR ${CMAKE_SOURCE_DIR}/utils/generate_regs.py)
set(EDIT_GPIF_USRP1 ${CMAKE_SOURCE_DIR}/utils/edit-gpif.py)
+set(EDIT_GPIF_B100 ${CMAKE_SOURCE_DIR}/utils/edit-gpif-b100.py)
set(BUILD_EEPROM ${CMAKE_SOURCE_DIR}/utils/build_eeprom.py)
########################################################################
# Add the subdirectories
########################################################################
ADD_SUBDIRECTORY(usrp1)
+ADD_SUBDIRECTORY(b100)
diff --git a/firmware/fx2/b100/.gitignore b/firmware/fx2/b100/.gitignore
new file mode 100644
index 000000000..e27ec2046
--- /dev/null
+++ b/firmware/fx2/b100/.gitignore
@@ -0,0 +1,19 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/Makefile
+/Makefile.in
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile.in
+/burn-usrp1p-eeprom
diff --git a/firmware/fx2/b100/CMakeLists.txt b/firmware/fx2/b100/CMakeLists.txt
new file mode 100644
index 000000000..438aa9207
--- /dev/null
+++ b/firmware/fx2/b100/CMakeLists.txt
@@ -0,0 +1,88 @@
+#
+# Copyright 2010 Ettus Research LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+include_directories(${CMAKE_SOURCE_DIR}/common)
+
+#for usrp_common.h and the regs files...
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+#now make a lib to link against
+set(libb100_sources
+ ${CMAKE_SOURCE_DIR}/common/delay.c
+ ${CMAKE_SOURCE_DIR}/common/fx2utils.c
+ ${CMAKE_SOURCE_DIR}/common/i2c.c
+ ${CMAKE_SOURCE_DIR}/common/init_gpif.c
+ ${CMAKE_SOURCE_DIR}/common/isr.c
+ ${CMAKE_SOURCE_DIR}/common/timer.c
+ ${CMAKE_SOURCE_DIR}/common/usb_common.c
+# ${CMAKE_SOURCE_DIR}/common/spi.c
+)
+
+#file(GLOB libb100_c_sources ${CMAKE_SOURCE_DIR}/common/*.c)
+#file(GLOB libb100_a51_sources ${CMAKE_SOURCE_DIR}/common/*.a51)
+#list(APPEND libb100_sources ${libb100_c_sources} ${libb100_a51_sources})
+
+add_library(libb100 STATIC ${libb100_sources})
+
+# edit-gpif hacks up gpif.c for our purposes. no major surgery, just moving stuff around.
+set(GPIF_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/gpif.c)
+set(GPIF_SOURCE_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/usrp_gpif.c)
+set(GPIF_HEADER_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/usrp_gpif_inline.h)
+
+add_custom_command(
+ OUTPUT ${GPIF_SOURCE_OUTPUT}
+ DEPENDS ${EDIT_GPIF_B100}
+ COMMAND ${PYTHON_EXECUTABLE} ${EDIT_GPIF_B100} ${GPIF_SOURCE} ${GPIF_SOURCE_OUTPUT} ${GPIF_HEADER_OUTPUT}
+ COMMENT "Generating ${GPIF_SOURCE_OUTPUT}"
+)
+
+#file(GLOB b100_sources *.c)
+set(b100_sources
+ ${CMAKE_SOURCE_DIR}/common/vectors.a51
+ usrp_main.c
+ usrp_common.c
+ board_specific.c
+ fpga_load.c
+ fpga_rev2.c
+ usrp_gpif.c
+ usb_descriptors.a51
+ eeprom_io.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+
+set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/usrp_main.c
+ PROPERTIES COMPILE_FLAGS "--std-sdcc99 --opt-code-speed --fommit-frame-pointer"
+)
+
+add_executable(b100_fw ${b100_sources})
+target_link_libraries(b100_fw libb100)
+
+set(eeprom1p_sources
+ ${CMAKE_SOURCE_DIR}/common/eeprom_boot.a51
+ ${CMAKE_SOURCE_DIR}/common/eeprom_init.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+
+add_custom_target(b100_eeprom ALL
+ DEPENDS b100_boot
+ COMMAND objcopy -I ihex -O binary b100_boot.ihx b100_boot.bin
+ COMMAND ${PYTHON_EXECUTABLE} ${BUILD_EEPROM} -r2 b100_boot.bin b100_eeprom.bin
+)
+
+add_executable(b100_boot ${eeprom1p_sources})
+target_link_libraries(b100_boot libb100)
diff --git a/firmware/fx2/b100/board_specific.c b/firmware/fx2/b100/board_specific.c
new file mode 100644
index 000000000..993d925b3
--- /dev/null
+++ b/firmware/fx2/b100/board_specific.c
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "usrp_common.h"
+
+void
+set_led_0 (unsigned char on)
+{
+ if (!on) // active low
+ USRP_PC |= bmPC_LED0;
+ else
+ USRP_PC &= ~bmPC_LED0;
+}
+
+void
+set_led_1 (unsigned char on)
+{
+ if (!on) // active low
+ USRP_PC |= bmPC_LED1;
+ else
+ USRP_PC &= ~bmPC_LED1;
+}
+
+void
+toggle_led_0 (void)
+{
+ USRP_PC ^= bmPC_LED0;
+}
+
+void
+toggle_led_1 (void)
+{
+ USRP_PC ^= bmPC_LED1;
+}
+
+void
+set_sleep_bits (unsigned char bits, unsigned char mask)
+{
+ // NOP on usrp1
+}
+
+static xdata unsigned char xbuf[1];
+
+void
+init_board (void)
+{
+ //init_spi ();
+
+ //USRP_PC &= ~bmPC_nRESET; // active low reset
+ //USRP_PC |= bmPC_nRESET;
+}
diff --git a/firmware/fx2/b100/eeprom_io.c b/firmware/fx2/b100/eeprom_io.c
new file mode 100644
index 000000000..9eeb53636
--- /dev/null
+++ b/firmware/fx2/b100/eeprom_io.c
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "eeprom_io.h"
+#include "i2c.h"
+#include "delay.h"
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+ xdata unsigned char *buf, unsigned char len)
+{
+ // We setup a random read by first doing a "zero byte write".
+ // Writes carry an address. Reads use an implicit address.
+
+ static xdata unsigned char cmd[1];
+ cmd[0] = eeprom_offset;
+ if (!i2c_write(i2c_addr, cmd, 1))
+ return 0;
+
+ return i2c_read(i2c_addr, buf, len);
+}
+
+
+#if 0
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+ const xdata unsigned char *buf, unsigned char len)
+{
+ static xdata unsigned char cmd[2];
+ unsigned char ok;
+
+ while (len-- > 0){
+ cmd[0] = eeprom_offset++;
+ cmd[1] = *buf++;
+ ok = i2c_write(i2c_addr, cmd, 2);
+ mdelay(10); // delay 10ms worst case write time
+ if (!ok)
+ return 0;
+ }
+ return 1;
+}
+
+#endif
diff --git a/firmware/fx2/b100/eeprom_io.h b/firmware/fx2/b100/eeprom_io.h
new file mode 100644
index 000000000..558017b12
--- /dev/null
+++ b/firmware/fx2/b100/eeprom_io.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_EEPROM_IO_H
+#define INCLUDED_EEPROM_IO_H
+
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+ xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+ const xdata unsigned char *buf, unsigned char len);
+
+
+#endif /* INCLUDED_EEPROM_IO_H */
diff --git a/firmware/fx2/b100/fpga_load.c b/firmware/fx2/b100/fpga_load.c
new file mode 100644
index 000000000..54ef54ab3
--- /dev/null
+++ b/firmware/fx2/b100/fpga_load.c
@@ -0,0 +1,193 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#include "usrp_common.h"
+#include "fpga_load.h"
+#include "delay.h"
+
+/*
+ * setup altera FPGA serial load (PS).
+ *
+ * On entry:
+ * don't care
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_begin (void)
+{
+ USRP_ALTERA_CONFIG &= ~bmALTERA_BITS; // clear all bits (NCONFIG low)
+ udelay (40); // wait 40 us
+ USRP_ALTERA_CONFIG |= bmALTERA_NCONFIG; // set NCONFIG high
+
+ if (UC_BOARD_HAS_FPGA){
+ // FIXME should really cap this loop with a counter so we
+ // don't hang forever on a hardware failure.
+ while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
+ ;
+ }
+
+ // ready to xfer now
+
+ return 1;
+}
+
+/*
+ * clock out the low bit of bits.
+ *
+ * On entry:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+
+
+#if 0
+
+static void
+clock_out_config_byte (unsigned char bits)
+{
+ unsigned char i;
+
+ // clock out configuration byte, least significant bit first
+
+ for (i = 0; i < 8; i++){
+
+ USRP_ALTERA_CONFIG = ((USRP_ALTERA_CONFIG & ~bmALTERA_DATA0) | ((bits & 1) ? bmALTERA_DATA0 : 0));
+ USRP_ALTERA_CONFIG |= bmALTERA_DCLK; /* set DCLK to 1 */
+ USRP_ALTERA_CONFIG &= ~bmALTERA_DCLK; /* set DCLK to 0 */
+
+ bits = bits >> 1;
+ }
+}
+
+#else
+
+static void
+clock_out_config_byte (unsigned char bits) _naked
+{
+ _asm
+ mov a, dpl
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ ret
+
+ _endasm;
+}
+
+#endif
+
+static void
+clock_out_bytes (unsigned char bytecount,
+ unsigned char xdata *p)
+{
+ while (bytecount-- > 0)
+ clock_out_config_byte (*p++);
+}
+
+/*
+ * Transfer block of bytes from packet to FPGA serial configuration port
+ *
+ * On entry:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_xfer (xdata unsigned char *p, unsigned char bytecount)
+{
+ clock_out_bytes (bytecount, p);
+ return 1;
+}
+
+/*
+ * check for successful load...
+ */
+unsigned char
+fpga_load_end (void)
+{
+ unsigned char status = USRP_ALTERA_CONFIG;
+
+ if (!UC_BOARD_HAS_FPGA) // always true if we don't have FPGA
+ return 1;
+
+ if ((status & bmALTERA_NSTATUS) == 0) // failed to program
+ return 0;
+
+ if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
+ return 1; // everything's cool
+
+ // I don't think this should happen. It indicates that
+ // programming is still in progress.
+
+ return 0;
+}
diff --git a/firmware/fx2/b100/fpga_rev2.c b/firmware/fx2/b100/fpga_rev2.c
new file mode 100644
index 000000000..326a01732
--- /dev/null
+++ b/firmware/fx2/b100/fpga_rev2.c
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "fpga.h"
+#include "fpga_regs_common.h"
+#include "usrp_common.h"
+#include "usrp_globals.h"
+
+unsigned char g_tx_reset = 0;
+unsigned char g_rx_reset = 0;
+
+void
+fpga_write_reg (unsigned char regno, const xdata unsigned char *regval)
+{
+ //nop
+}
+
+
+static xdata unsigned char regval[4] = {0, 0, 0, 0};
+
+// Resets both AD9862's and the FPGA serial bus interface.
+
+void
+fpga_set_reset (unsigned char on)
+{
+ on &= 0x1;
+
+ if (on){
+ }
+ else
+ ;
+}
diff --git a/firmware/fx2/b100/fpga_rev2.h b/firmware/fx2/b100/fpga_rev2.h
new file mode 100644
index 000000000..0773d1cd7
--- /dev/null
+++ b/firmware/fx2/b100/fpga_rev2.h
@@ -0,0 +1,44 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#ifndef INCLUDED_FPGA_REV1_H
+#define INCLUDED_FPGA_REV1_H
+
+/*
+ * return TRUE if FPGA internal fifo has room for a single packet
+ */
+#define fpga_has_room_for_data_packet() (!(GPIFREADYSTAT & bmDATA_FIFO_FULL))
+#define fpga_has_room_for_ctrl_packet() (!(GPIFREADYSTAT & bmCTRL_FIFO_FULL))
+
+/*
+ * return TRUE if FPGA internal fifo has at least one packet available
+ */
+#define fpga_has_data_packet_avail() (!(GPIFREADYSTAT & bmDATA_EMPTY))
+#define fpga_has_ctrl_packet_avail() (!(GPIFREADYSTAT & bmCTRL_EMPTY))
+
+#define fx2_has_ctrl_packet_avail() (!(EP24FIFOFLGS & EP4FIFOEMPTY))
+#define fx2_has_data_packet_avail() (!(EP24FIFOFLGS & EP2FIFOEMPTY))
+
+#define fx2_has_room_for_ctrl_packet() (!(EP8CS & bmEPFULL))
+#define fx2_has_room_for_data_packet() (!(EP6CS & bmEPFULL))
+
+#define fx2_gpif_is_idle() (GPIFTRIG & bmGPIF_IDLE)
+
+#endif /* INCLUDED_FPGA_REV1_H */
diff --git a/firmware/fx2/b100/gpif.c b/firmware/fx2/b100/gpif.c
new file mode 100644
index 000000000..b499e4fcf
--- /dev/null
+++ b/firmware/fx2/b100/gpif.c
@@ -0,0 +1,292 @@
+// This program configures the General Programmable Interface (GPIF) for FX2.
+// Please do not modify sections of text which are marked as "DO NOT EDIT ...".
+//
+// DO NOT EDIT ...
+// GPIF Initialization
+// Interface Timing Async
+// Internal Ready Init IntRdy=1
+// CTL Out Tristate-able Binary
+// SingleWrite WF Select 1
+// SingleRead WF Select 0
+// FifoWrite WF Select 3
+// FifoRead WF Select 2
+// Data Bus Idle Drive Tristate
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+// GPIF Wave Names
+// Wave 0 = singlerd
+// Wave 1 = singlewr
+// Wave 2 = FIFORd
+// Wave 3 = FIFOWr
+
+// GPIF Ctrl Outputs Level
+// CTL 0 = WEN# CMOS
+// CTL 1 = REN# CMOS
+// CTL 2 = OE# CMOS
+// CTL 3 = EP CMOS
+// CTL 4 = unused CMOS
+// CTL 5 = unused CMOS
+
+// GPIF Rdy Inputs
+// RDY0 = EF#
+// RDY1 = FF#
+// RDY2 = DRDY
+// RDY3 = CRDY
+// RDY4 = unused
+// RDY5 = TCXpire
+// FIFOFlag = FIFOFlag
+// IntReady = IntReady
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 0: singlerd
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data NO Data NO Data NO Data NO Data NO Data NO Data
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A
+// LFunc
+// Term B
+// Branch1
+// Branch0
+// Re-Exec
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 1: singlewr
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode Activate Activate Activate Activate Activate Activate Activate
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A EF#
+// LFunc AND
+// Term B EF#
+// Branch1 ThenIdle
+// Branch0 ElseIdle
+// Re-Exec No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 1 1 1 1 1 1 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 2: FIFORd
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data Activate NO Data NO Data NO Data NO Data NO Data
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 IF Wait 1 Wait 1 Wait 1
+// Term A TCXpire TCXpire
+// LFunc AND AND
+// Term B TCXpire TCXpire
+// Branch1 Then 2 ThenIdle
+// Branch0 Else 1 ElseIdle
+// Re-Exec No No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 1 0 0 0 0 0 0 0
+// OE# 1 1 1 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 3: FIFOWr
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data Activate Activate Activate Activate Activate Activate
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A TCXpire
+// LFunc AND
+// Term B TCXpire
+// Branch1 ThenIdle
+// Branch0 Else 1
+// Re-Exec No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+
+// GPIF Program Code
+
+// DO NOT EDIT ...
+#include "fx2.h"
+#include "fx2regs.h"
+#include "fx2sdly.h" // SYNCDELAY macro
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata WaveData[128] =
+{
+// Wave 0
+/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* Output*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+// Wave 1
+/* LenBr */ 0x01, 0x3F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x22, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
+/* Output*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+// Wave 2
+/* LenBr */ 0x01, 0x11, 0x01, 0x3F, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+/* Output*/ 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x2D, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
+// Wave 3
+/* LenBr */ 0x01, 0x39, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
+/* Output*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+};
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata FlowStates[36] =
+{
+/* Wave 0 FlowStates */ 0x81,0x2D,0x0E,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 1 FlowStates */ 0x81,0x2D,0x09,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x06,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x01,0x00,0x00,0x04,0x03,0x02,0x00,
+};
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata InitData[7] =
+{
+/* Regs */ 0xA0,0x00,0x00,0x00,0xEE,0x4E,0x00
+};
+// END DO NOT EDIT
+
+// TO DO: You may add additional code below.
+
+void GpifInit( void )
+{
+ BYTE i;
+
+ // Registers which require a synchronization delay, see section 15.14
+ // FIFORESET FIFOPINPOLAR
+ // INPKTEND OUTPKTEND
+ // EPxBCH:L REVCTL
+ // GPIFTCB3 GPIFTCB2
+ // GPIFTCB1 GPIFTCB0
+ // EPxFIFOPFH:L EPxAUTOINLENH:L
+ // EPxFIFOCFG EPxGPIFFLGSEL
+ // PINFLAGSxx EPxFIFOIRQ
+ // EPxFIFOIE GPIFIRQ
+ // GPIFIE GPIFADRH:L
+ // UDMACRCH:L EPxGPIFTRIG
+ // GPIFTRIG
+
+ // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
+ // ...these have been replaced by GPIFTC[B3:B0] registers
+
+ // 8051 doesn't have access to waveform memories 'til
+ // the part is in GPIF mode.
+
+ IFCONFIG = 0xEE;
+ // IFCLKSRC=1 , FIFOs executes on internal clk source
+ // xMHz=1 , 48MHz internal clk rate
+ // IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
+ // IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
+ // ASYNC=1 , master samples asynchronous
+ // GSTATE=1 , Drive GPIF states out on PORTE[2:0], debug WF
+ // IFCFG[1:0]=10, FX2 in GPIF master mode
+
+ GPIFABORT = 0xFF; // abort any waveforms pending
+
+ GPIFREADYCFG = InitData[ 0 ];
+ GPIFCTLCFG = InitData[ 1 ];
+ GPIFIDLECS = InitData[ 2 ];
+ GPIFIDLECTL = InitData[ 3 ];
+ GPIFWFSELECT = InitData[ 5 ];
+ GPIFREADYSTAT = InitData[ 6 ];
+
+ // use dual autopointer feature...
+ AUTOPTRSETUP = 0x07; // inc both pointers,
+ // ...warning: this introduces pdata hole(s)
+ // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
+
+ // source
+ AUTOPTRH1 = MSB( &WaveData );
+ AUTOPTRL1 = LSB( &WaveData );
+
+ // destination
+ AUTOPTRH2 = 0xE4;
+ AUTOPTRL2 = 0x00;
+
+ // transfer
+ for ( i = 0x00; i < 128; i++ )
+ {
+ EXTAUTODAT2 = EXTAUTODAT1;
+ }
+
+// Configure GPIF Address pins, output initial value,
+ PORTCCFG = 0xFF; // [7:0] as alt. func. GPIFADR[7:0]
+ OEC = 0xFF; // and as outputs
+ PORTECFG |= 0x80; // [8] as alt. func. GPIFADR[8]
+ OEE |= 0x80; // and as output
+
+// ...OR... tri-state GPIFADR[8:0] pins
+// PORTCCFG = 0x00; // [7:0] as port I/O
+// OEC = 0x00; // and as inputs
+// PORTECFG &= 0x7F; // [8] as port I/O
+// OEE &= 0x7F; // and as input
+
+// GPIF address pins update when GPIFADRH/L written
+ SYNCDELAY; //
+ GPIFADRH = 0x00; // bits[7:1] always 0
+ SYNCDELAY; //
+ GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
+
+// Configure GPIF FlowStates registers for Wave 0 of WaveData
+ FLOWSTATE = FlowStates[ 0 ];
+ FLOWLOGIC = FlowStates[ 1 ];
+ FLOWEQ0CTL = FlowStates[ 2 ];
+ FLOWEQ1CTL = FlowStates[ 3 ];
+ FLOWHOLDOFF = FlowStates[ 4 ];
+ FLOWSTB = FlowStates[ 5 ];
+ FLOWSTBEDGE = FlowStates[ 6 ];
+ FLOWSTBHPERIOD = FlowStates[ 7 ];
+}
+
diff --git a/firmware/fx2/b100/usb_descriptors.a51 b/firmware/fx2/b100/usb_descriptors.a51
new file mode 100644
index 000000000..cc71833fe
--- /dev/null
+++ b/firmware/fx2/b100/usb_descriptors.a51
@@ -0,0 +1,499 @@
+;;; -*- asm -*-
+;;;
+;;; Copyright 2003 Free Software Foundation, Inc.
+;;;
+;;; This file is part of GNU Radio
+;;;
+;;; GNU Radio is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3, or (at your option)
+;;; any later version.
+;;;
+;;; GNU Radio is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Radio; see the file COPYING. If not, write to
+;;; the Free Software Foundation, Inc., 51 Franklin Street,
+;;; Boston, MA 02110-1301, USA.
+;;;
+
+;;; USB Descriptor table for the B100
+;;;
+;;; We're a high-speed only device (480 Mb/sec) with 1 configuration
+;;; and 5 interfaces.
+;;;
+;;; interface 0: command and status (ep0 COMMAND)
+;;; interface 1: Transmit path (ep2 OUT BULK)
+;;; interface 2: Receive path (ep6 IN BULK)
+
+;;; interface 3: Command transmit path (ep4 OUT BULK) for FPGA comms
+;;; interface 4: Command receive path (ep8 IN BULK) for FPGA comms
+
+ .module usb_descriptors
+
+ VID_FREE = 0x2500 ; Free Software Folks
+ PID_USRP = 0x0001 ; B100
+
+ ;; We distinguish configured from unconfigured USRPs using the Device ID.
+ ;; If the MSB of the DID is 0, the device is unconfigured.
+ ;; The LSB of the DID is reserved for hardware revs.
+
+ DID_USRP = 0x0100 ; Device ID (bcd)
+
+
+ DSCR_DEVICE = 1 ; Descriptor type: Device
+ DSCR_CONFIG = 2 ; Descriptor type: Configuration
+ DSCR_STRING = 3 ; Descriptor type: String
+ DSCR_INTRFC = 4 ; Descriptor type: Interface
+ DSCR_ENDPNT = 5 ; Descriptor type: Endpoint
+ DSCR_DEVQUAL = 6 ; Descriptor type: Device Qualifier
+
+ DSCR_DEVICE_LEN = 18
+ DSCR_CONFIG_LEN = 9
+ DSCR_INTRFC_LEN = 9
+ DSCR_ENDPNT_LEN = 7
+ DSCR_DEVQUAL_LEN = 10
+
+ ET_CONTROL = 0 ; Endpoint type: Control
+ ET_ISO = 1 ; Endpoint type: Isochronous
+ ET_BULK = 2 ; Endpoint type: Bulk
+ ET_INT = 3 ; Endpoint type: Interrupt
+
+
+ ;; configuration attributes
+ bmSELF_POWERED = 1 << 6
+
+;;; --------------------------------------------------------
+;;; external ram data
+;;;--------------------------------------------------------
+
+ .area USBDESCSEG (XDATA)
+
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at high speed (480Mb/sec)
+;;; ----------------------------------------------------------------
+
+ .even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work
+
+ ;; The .even directive isn't really honored by the linker. Bummer!
+ ;; (There's no way to specify an alignment requirement for a given area,
+ ;; hence when they're concatenated together, even doesn't work.)
+ ;;
+ ;; We work around this by telling the linker to put USBDESCSEG
+ ;; at 0xE000 absolute. This means that the maximimum length of this
+ ;; segment is 480 bytes, leaving room for the two hash slots
+ ;; at 0xE1EO to 0xE1FF.
+ ;;
+ ;; As of July 7, 2004, this segment is 326 bytes long
+ ;; As of Sept 2, 2010, this segment is 416 bytes long
+
+_high_speed_device_descr::
+ .db DSCR_DEVICE_LEN
+ .db DSCR_DEVICE
+ .db <0x0200 ; Specification version (LSB)
+ .db >0x0200 ; Specification version (MSB)
+ .db 0xff ; device class (vendor specific)
+ .db 0xff ; device subclass (vendor specific)
+ .db 0xff ; device protocol (vendor specific)
+ .db 64 ; bMaxPacketSize0 for endpoint 0
+ .db <VID_FREE ; idVendor
+ .db >VID_FREE ; idVendor
+ .db <PID_USRP ; idProduct
+ .db >PID_USRP ; idProduct
+_usb_desc_hw_rev_binary_patch_location_0::
+ .db <DID_USRP ; bcdDevice
+ .db >DID_USRP ; bcdDevice
+ .db SI_VENDOR ; iManufacturer (string index)
+ .db SI_PRODUCT ; iProduct (string index)
+ .db SI_SERIAL ; iSerial number (string index)
+ .db 1 ; bNumConfigurations
+
+;;; describes the other speed (12Mb/sec)
+ .even
+_high_speed_devqual_descr::
+ .db DSCR_DEVQUAL_LEN
+ .db DSCR_DEVQUAL
+ .db <0x0200 ; bcdUSB (LSB)
+ .db >0x0200 ; bcdUSB (MSB)
+ .db 0xff ; bDeviceClass
+ .db 0xff ; bDeviceSubClass
+ .db 0xff ; bDeviceProtocol
+ .db 64 ; bMaxPacketSize0
+ .db 1 ; bNumConfigurations (one config at 12Mb/sec)
+ .db 0 ; bReserved
+
+ .even
+_high_speed_config_descr::
+ .db DSCR_CONFIG_LEN
+ .db DSCR_CONFIG
+ .db <(_high_speed_config_descr_end - _high_speed_config_descr) ; LSB
+ .db >(_high_speed_config_descr_end - _high_speed_config_descr) ; MSB
+ .db 5 ; bNumInterfaces
+ .db 1 ; bConfigurationValue
+ .db 0 ; iConfiguration
+ .db 0x80 | bmSELF_POWERED ; bmAttributes
+ .db 0 ; bMaxPower
+
+ ;; interface descriptor 0 (command & status, ep0 COMMAND)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 0 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 0 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_COMMAND_AND_STATUS ; iInterface (description)
+
+ ;; interface descriptor 1 (transmit path, ep2 OUT BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 1 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_TX_PATH ; iInterface (description)
+
+ ;; interface 1's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x02 ; bEndpointAddress (ep 2 OUT)
+ .db ET_BULK ; bmAttributes
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 2 (receive path, ep6 IN BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 2 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_RX_PATH ; iInterface (description)
+
+ ;; interface 2's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x86 ; bEndpointAddress (ep 6 IN)
+ .db ET_BULK ; bmAttributes
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 3 (FPGA command OUT path, ep4 OUT BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 3 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_FPGA_COMMAND_OUT_PATH ; iInterface (description)
+
+ ;; interface 3's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x04 ; bEndpointAddress (ep 4 OUT)
+ .db ET_BULK ; bmAttributes
+ .db <32 ; wMaxPacketSize (LSB)
+ .db >32 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 4 (FPGA command IN path, ep8 IN BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 4 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_FPGA_COMMAND_IN_PATH ; iInterface (description)
+
+ ;; interface 4's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x88 ; bEndpointAddress (ep 8 IN)
+ .db ET_BULK ; bmAttributes
+ .db <32 ; wMaxPacketSize (LSB)
+ .db >32 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+
+_high_speed_config_descr_end:
+
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at full speed (12Mb/sec)
+;;; ----------------------------------------------------------------
+
+ .even
+_full_speed_device_descr::
+ .db DSCR_DEVICE_LEN
+ .db DSCR_DEVICE
+ .db <0x0200 ; Specification version (LSB)
+ .db >0x0200 ; Specification version (MSB)
+ .db 0xff ; device class (vendor specific)
+ .db 0xff ; device subclass (vendor specific)
+ .db 0xff ; device protocol (vendor specific)
+ .db 64 ; bMaxPacketSize0 for endpoint 0
+ .db <VID_FREE ; idVendor
+ .db >VID_FREE ; idVendor
+ .db <PID_USRP ; idProduct
+ .db >PID_USRP ; idProduct
+_usb_desc_hw_rev_binary_patch_location_1::
+ .db <DID_USRP ; bcdDevice
+ .db >DID_USRP ; bcdDevice
+ .db SI_VENDOR ; iManufacturer (string index)
+ .db SI_PRODUCT ; iProduct (string index)
+ .db SI_NONE ; iSerial number (None)
+ .db 1 ; bNumConfigurations
+
+
+;;; describes the other speed (480Mb/sec)
+ .even
+_full_speed_devqual_descr::
+ .db DSCR_DEVQUAL_LEN
+ .db DSCR_DEVQUAL
+ .db <0x0200 ; bcdUSB
+ .db >0x0200 ; bcdUSB
+ .db 0xff ; bDeviceClass
+ .db 0xff ; bDeviceSubClass
+ .db 0xff ; bDeviceProtocol
+ .db 64 ; bMaxPacketSize0
+ .db 1 ; bNumConfigurations (one config at 480Mb/sec)
+ .db 0 ; bReserved
+
+ .even
+_full_speed_config_descr::
+ .db DSCR_CONFIG_LEN
+ .db DSCR_CONFIG
+ .db <(_full_speed_config_descr_end - _full_speed_config_descr) ; LSB
+ .db >(_full_speed_config_descr_end - _full_speed_config_descr) ; MSB
+ .db 1 ; bNumInterfaces
+ .db 1 ; bConfigurationValue
+ .db 0 ; iConfiguration
+ .db 0x80 | bmSELF_POWERED ; bmAttributes
+ .db 0 ; bMaxPower
+
+ ;; interface descriptor 0 (command & status, ep0 COMMAND)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 0 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 0 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_COMMAND_AND_STATUS ; iInterface (description)
+
+_full_speed_config_descr_end:
+
+;;; ----------------------------------------------------------------
+;;; string descriptors
+;;; ----------------------------------------------------------------
+
+_nstring_descriptors::
+ .db (_string_descriptors_end - _string_descriptors) / 2
+
+_string_descriptors::
+ .db <str0, >str0
+ .db <str1, >str1
+ .db <str2, >str2
+ .db <str3, >str3
+ .db <str4, >str4
+ .db <str5, >str5
+ .db <str6, >str6
+ .db <str7, >str7
+ .db <str8, >str8
+_string_descriptors_end:
+
+ SI_NONE = 0
+ ;; str0 contains the language ID's.
+ .even
+str0: .db str0_end - str0
+ .db DSCR_STRING
+ .db 0
+ .db 0
+ .db <0x0409 ; magic code for US English (LSB)
+ .db >0x0409 ; magic code for US English (MSB)
+str0_end:
+
+ SI_VENDOR = 1
+ .even
+str1: .db str1_end - str1
+ .db DSCR_STRING
+ .db 'F, 0 ; 16-bit unicode
+ .db 'r, 0
+ .db 'e, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'S, 0
+ .db 'o, 0
+ .db 'f, 0
+ .db 't, 0
+ .db 'w, 0
+ .db 'a, 0
+ .db 'r, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'F, 0
+ .db 'o, 0
+ .db 'l, 0
+ .db 'k, 0
+ .db 's, 0
+str1_end:
+
+ SI_PRODUCT = 2
+ .even
+str2: .db str2_end - str2
+ .db DSCR_STRING
+ .db 'U, 0
+ .db 'S, 0
+ .db 'R, 0
+ .db 'P, 0
+ .db '1, 0
+ .db 'P, 0
+ .db ' , 0
+ .db 'R, 0
+ .db 'e, 0
+ .db 'v, 0
+ .db ' , 0
+_usb_desc_hw_rev_ascii_patch_location_0::
+ .db '?, 0
+str2_end:
+
+ SI_COMMAND_AND_STATUS = 3
+ .even
+str3: .db str3_end - str3
+ .db DSCR_STRING
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db '&, 0
+ .db ' , 0
+ .db 'S, 0
+ .db 't, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'u, 0
+ .db 's, 0
+str3_end:
+
+ SI_TX_PATH = 4
+ .even
+str4: .db str4_end - str4
+ .db DSCR_STRING
+ .db 'T, 0
+ .db 'r, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 's, 0
+ .db 'm, 0
+ .db 'i, 0
+ .db 't, 0
+ .db ' , 0
+ .db 'P, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'h, 0
+str4_end:
+
+ SI_RX_PATH = 5
+ .even
+str5: .db str5_end - str5
+ .db DSCR_STRING
+ .db 'R, 0
+ .db 'e, 0
+ .db 'c, 0
+ .db 'e, 0
+ .db 'i, 0
+ .db 'v, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'P, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'h, 0
+str5_end:
+
+ SI_SERIAL = 6
+ .even
+str6: .db str6_end - str6
+ .db DSCR_STRING
+_usb_desc_serial_number_ascii::
+ .db '3, 0
+ .db '., 0
+ .db '1, 0
+ .db '4, 0
+ .db '1, 0
+ .db '5, 0
+ .db '9, 0
+ .db '3, 0
+str6_end:
+
+ SI_FPGA_COMMAND_OUT_PATH = 7
+ .even
+str7: .db str7_end - str7
+ .db DSCR_STRING
+ .db 'F, 0
+ .db 'P, 0
+ .db 'G, 0
+ .db 'A, 0
+ .db ' , 0
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db 'O, 0
+ .db 'u, 0
+ .db 't, 0
+str7_end:
+
+ SI_FPGA_COMMAND_IN_PATH = 8
+ .even
+str8: .db str8_end - str8
+ .db DSCR_STRING
+ .db 'F, 0
+ .db 'P, 0
+ .db 'G, 0
+ .db 'A, 0
+ .db ' , 0
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db 'I, 0
+ .db 'n, 0
+str8_end:
diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c
new file mode 100644
index 000000000..4b6dde881
--- /dev/null
+++ b/firmware/fx2/b100/usrp_common.c
@@ -0,0 +1,108 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * common code for USRP
+ */
+
+#include "usrp_common.h"
+
+void init_board (void);
+
+void
+init_usrp (void)
+{
+ CPUCS = bmCLKSPD1; // CPU runs @ 48 MHz
+ CKCON = 0; // MOVX takes 2 cycles
+
+ // IFCLK is generated internally and runs at 48 MHz; GPIF "master mode"
+
+ IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFCLKPOL | bmIFGPIF;
+ SYNCDELAY;
+
+ // configure IO ports (B and D are used by GPIF)
+
+ IOA = bmPORT_A_INITIAL; // Port A initial state
+ OEA = bmPORT_A_OUTPUTS; // Port A direction register
+
+ IOC = bmPORT_C_INITIAL; // Port C initial state
+ OEC = bmPORT_C_OUTPUTS; // Port C direction register
+
+ IOE = bmPORT_E_INITIAL; // Port E initial state
+ OEE = bmPORT_E_OUTPUTS; // Port E direction register
+
+
+ //REVCTL = bmDYN_OUT | bmENH_PKT; // highly recommended by docs
+ // SYNCDELAY;
+
+ // configure end points
+
+ EP1OUTCFG = bmVALID | bmBULK; SYNCDELAY;
+ EP1INCFG = bmVALID | bmBULK | bmIN; SYNCDELAY;
+
+ EP2CFG = bmVALID | bmBULK | bmDOUBLEBUF; SYNCDELAY; // 512 dbl bulk OUT
+ EP4CFG = bmVALID | bmBULK | bmDOUBLEBUF; SYNCDELAY; // 512 dbl bulk OUT
+ EP6CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN
+ EP8CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN
+
+ // reset FIFOs
+
+ FIFORESET = bmNAKALL; SYNCDELAY;
+ FIFORESET = 2; SYNCDELAY;
+ FIFORESET = 4; SYNCDELAY;
+ FIFORESET = 6; SYNCDELAY;
+ FIFORESET = 8; SYNCDELAY;
+ FIFORESET = 0; SYNCDELAY;
+
+ // configure end point FIFOs
+
+ // let core see 0 to 1 transistion of autoout bit
+
+ EP2FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY;
+ EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY;
+ //EP6FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP4FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP4FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY;
+ EP8FIFOCFG = bmAUTOIN | bmWORDWIDE; SYNCDELAY;
+
+ EP0BCH = 0; SYNCDELAY;
+
+ // arm EP1OUT so we can receive "out" packets (TRM pg 8-8)
+
+ EP1OUTBC = 0; SYNCDELAY;
+
+ EP2GPIFFLGSEL = 0x00; SYNCDELAY; // For EP2OUT, GPIF uses EF flag
+ EP6GPIFFLGSEL = 0x00; SYNCDELAY; // For EP6IN, GPIF uses FF flag
+ EP4GPIFFLGSEL = 0x00; SYNCDELAY;
+ EP8GPIFFLGSEL = 0x00; SYNCDELAY;
+
+ // set autoin length for EP6
+ // FIXME should be f(enumeration)
+
+ EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed
+ EP6AUTOINLENL = (512) & 0xff; SYNCDELAY;
+
+ EP8AUTOINLENH = (32) >> 8; SYNCDELAY;
+ EP8AUTOINLENL = (32) & 0xff; SYNCDELAY;
+
+ init_board ();
+}
+
diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c
new file mode 100644
index 000000000..7558fadb8
--- /dev/null
+++ b/firmware/fx2/b100/usrp_main.c
@@ -0,0 +1,394 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#include "usrp_common.h"
+#include "usrp_commands.h"
+#include "fpga.h"
+#include "usrp_gpif_inline.h"
+#include "timer.h"
+#include "i2c.h"
+#include "isr.h"
+#include "usb_common.h"
+#include "fx2utils.h"
+#include "usrp_globals.h"
+#include "usrp_i2c_addr.h"
+#include <string.h>
+#include "eeprom_io.h"
+#include "usb_descriptors.h"
+
+/*
+ * offsets into boot eeprom for configuration values
+ */
+#define HW_REV_OFFSET 5
+#define SERIAL_NO_OFFSET 248
+#define SERIAL_NO_LEN 8
+
+
+#define bRequestType SETUPDAT[0]
+#define bRequest SETUPDAT[1]
+#define wValueL SETUPDAT[2]
+#define wValueH SETUPDAT[3]
+#define wIndexL SETUPDAT[4]
+#define wIndexH SETUPDAT[5]
+#define wLengthL SETUPDAT[6]
+#define wLengthH SETUPDAT[7]
+
+
+unsigned char g_tx_enable = 0;
+unsigned char g_rx_enable = 0;
+unsigned char g_rx_overrun = 0;
+unsigned char g_tx_underrun = 0;
+bit enable_gpif = 0;
+
+/*
+ * the host side fpga loader code pushes an MD5 hash of the bitstream
+ * into hash1.
+ */
+#define USRP_HASH_SIZE 16
+xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE];
+
+void clear_fpga_data_fifo(void);
+
+static void
+get_ep0_data (void)
+{
+ EP0BCL = 0; // arm EP0 for OUT xfer. This sets the busy bit
+
+ while (EP0CS & bmEPBUSY) // wait for busy to clear
+ ;
+}
+
+static void initialize_gpif_buffer(int ep) {
+ //clear the GPIF buffers on startup to keep crap out of the data path
+ FIFORESET = 0x80; SYNCDELAY; //activate NAKALL
+ FIFORESET = ep; SYNCDELAY;
+ FIFORESET = 0x00; SYNCDELAY;
+}
+
+/*
+ * Handle our "Vendor Extension" commands on endpoint 0.
+ * If we handle this one, return non-zero.
+ */
+unsigned char
+app_vendor_cmd (void)
+{
+ if (bRequestType == VRT_VENDOR_IN){
+
+ /////////////////////////////////
+ // handle the IN requests
+ /////////////////////////////////
+
+ switch (bRequest){
+
+ case VRQ_GET_STATUS: //this is no longer done via FX2 -- the FPGA will be queried instead
+ return 0;
+ break;
+
+ case VRQ_I2C_READ:
+ if (!i2c_read (wValueL, EP0BUF, wLengthL)) return 0;
+ EP0BCH = 0;
+ EP0BCL = wLengthL;
+ break;
+
+ case VRQ_SPI_READ:
+ return 0;
+
+ case VRQ_FW_COMPAT:
+ EP0BCH = 0;
+ EP0BCL = 2;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ else if (bRequestType == VRT_VENDOR_OUT){
+
+ /////////////////////////////////
+ // handle the OUT requests
+ /////////////////////////////////
+
+ switch (bRequest){
+
+ case VRQ_SET_LED:
+ switch (wIndexL){
+ case 0:
+ set_led_0 (wValueL);
+ break;
+
+ case 1:
+ set_led_1 (wValueL);
+ break;
+
+ default:
+ return 0;
+ }
+ break;
+
+ case VRQ_FPGA_LOAD:
+ switch (wIndexL){ // sub-command
+ case FL_BEGIN:
+ return fpga_load_begin ();
+
+ case FL_XFER:
+ get_ep0_data ();
+ return fpga_load_xfer (EP0BUF, EP0BCL);
+
+ case FL_END:
+ return fpga_load_end ();
+
+ default:
+ return 0;
+ }
+ break;
+
+ case VRQ_FPGA_SET_RESET:
+ //fpga_set_reset (wValueL);
+ break;
+
+ case VRQ_I2C_WRITE:
+ get_ep0_data ();
+ if (!i2c_write (wValueL, EP0BUF, EP0BCL)) return 0;
+ //USRP_LED_REG ^= bmLED1;
+ break;
+
+ case VRQ_RESET_GPIF:
+ initialize_gpif_buffer(wValueL);
+ break;
+
+ case VRQ_ENABLE_GPIF:
+ enable_gpif = (wValueL != 0) ? 1 : 0;
+ set_led_1(enable_gpif);
+ break;
+
+ case VRQ_CLEAR_FPGA_FIFO:
+ clear_fpga_data_fifo();
+ break;
+
+ default:
+ return 0;
+ }
+
+ }
+ else
+ return 0; // invalid bRequestType
+
+ return 1;
+}
+
+static int short_pkt_state = 0;
+#define SHORT_PACKET_DETECTED (short_pkt_state != bitSHORT_PACKET_SIGNAL)
+
+//yes, this is a little opaque
+//basically this is necessary because while all the logic to inform the FPGA
+//of what we're trying to do via the CTL pins is contained within the flowstates,
+//we need to assert the endpoint select pin one clock cycle before the flowstate starts.
+//this is the job of the wave descriptor. rather than switch between waves, since that
+//involves a little more setup, we just modify the wave table on the fly.
+inline static void setup_wave_data_read(void) {
+ GPIF_WAVE_DATA[80] = 0x06;
+ GPIF_WAVE_DATA[81] = 0x06;
+}
+
+inline static void setup_wave_ctrl_read(void) {
+ GPIF_WAVE_DATA[80] = 0x0E;
+ GPIF_WAVE_DATA[81] = 0x0E;
+}
+
+inline static void setup_wave_data_write(void) {
+ GPIF_WAVE_DATA[112] = 0x00;
+ GPIF_WAVE_DATA[113] = 0x00;
+}
+
+inline static void setup_wave_ctrl_write(void) {
+ GPIF_WAVE_DATA[112] = 0x08;
+ GPIF_WAVE_DATA[113] = 0x08;
+}
+
+inline static void handle_data_write(void) {
+ GPIFTCB1 = 0x01; //SYNCDELAY;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_write ();
+ setup_wave_data_write();
+ GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+}
+
+inline static void handle_ctrl_write(void) {
+ GPIFTCB1 = 0x00;
+ GPIFTCB0 = 0x10;
+ setup_flowstate_ctrl_write ();
+ setup_wave_ctrl_write();
+ GPIFTRIG = bmGPIF_EP4_START | bmGPIF_WRITE; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+}
+
+inline static void handle_data_read(void) {
+ GPIFTCB1 = 0x01;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_read ();
+ setup_wave_data_read();
+ short_pkt_state = bitSHORT_PACKET_SIGNAL;
+ GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ INPKTEND = 0x06; // tell USB we filled buffer (6 is our endpoint num)
+ SYNCDELAY;
+ if(SHORT_PACKET_DETECTED) {
+ while(!(EP6CS & bmEPEMPTY)); //wait for packet to send
+ INPKTEND = 0x06; //send a ZLP
+ //toggle_led_1(); //FIXME DEBUG
+ }
+}
+
+inline static void handle_ctrl_read(void) {
+ GPIFTCB1 = 0x00;
+ GPIFTCB0 = 0x10;
+ setup_flowstate_ctrl_read ();
+ setup_wave_ctrl_read();
+ GPIFTRIG = bmGPIF_EP8_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ INPKTEND = 8; // tell USB we filled buffer (8 is our endpoint num)
+}
+
+//clear the FPGA datapath by reading but not submitting, instead clearing the FIFO after each transaction
+void clear_fpga_data_fifo(void) {
+ while(fpga_has_data_packet_avail()) {
+ GPIFTCB1 = 0x01;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_read ();
+ setup_wave_data_read();
+ GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ initialize_gpif_buffer(6); //reset the FIFO instead of committing it
+ }
+}
+
+static void
+main_loop (void)
+{
+ while (1){
+ if (usb_setup_packet_avail ())
+ usb_handle_setup_packet ();
+
+ if(enable_gpif){
+ if (fx2_has_ctrl_packet_avail() && fpga_has_room_for_ctrl_packet()) handle_ctrl_write();
+ if (fx2_has_room_for_ctrl_packet() && fpga_has_ctrl_packet_avail()) handle_ctrl_read();
+
+ //we do this
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //five times so that
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //we can piggyback
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //data transfers
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //without loop overhead
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ }
+ }
+}
+
+/*
+ * called at 100 Hz from timer2 interrupt
+ *
+ * Toggle led 0
+ */
+void
+isr_tick (void) interrupt
+{
+ static unsigned char count = 1;
+
+ if (--count == 0){
+ count = 50;
+ USRP_LED_REG ^= bmLED0;
+ }
+
+ clear_timer_irq ();
+}
+
+/*
+ * Read h/w rev code and serial number out of boot eeprom and
+ * patch the usb descriptors with the values.
+ */
+void
+patch_usb_descriptors(void)
+{
+ static xdata unsigned char hw_rev;
+ static xdata unsigned char serial_no[8];
+ unsigned char i;
+
+ eeprom_read(I2C_ADDR_BOOT, HW_REV_OFFSET, &hw_rev, 1); // LSB of device id
+ usb_desc_hw_rev_binary_patch_location_0[0] = hw_rev;
+ usb_desc_hw_rev_binary_patch_location_1[0] = hw_rev;
+ usb_desc_hw_rev_ascii_patch_location_0[0] = hw_rev + '0'; // FIXME if we get > 9
+
+ eeprom_read(I2C_ADDR_BOOT, SERIAL_NO_OFFSET, serial_no, SERIAL_NO_LEN);
+
+ for (i = 0; i < SERIAL_NO_LEN; i++){
+ unsigned char ch = serial_no[i];
+ if (ch == 0xff) // make unprogrammed EEPROM default to '0'
+ ch = '0';
+ usb_desc_serial_number_ascii[i << 1] = ch;
+ }
+}
+
+void
+main (void)
+{
+ enable_gpif = 0;
+
+ memset (hash1, 0, USRP_HASH_SIZE); // zero fpga bitstream hash. This forces reload
+
+ init_usrp ();
+ init_gpif ();
+
+ // if (UC_START_WITH_GSTATE_OUTPUT_ENABLED)
+ //IFCONFIG |= bmGSTATE; // no conflict, start with it on
+
+ set_led_0 (0);
+ set_led_1 (0);
+
+ EA = 0; // disable all interrupts
+
+ patch_usb_descriptors();
+
+ setup_autovectors ();
+ usb_install_handlers ();
+ //hook_timer_tick ((unsigned short) isr_tick);
+
+ EIEX4 = 1; // disable INT4 FIXME
+ EA = 1; // global interrupt enable
+
+ fx2_renumerate (); // simulates disconnect / reconnect
+
+ setup_flowstate_common();
+ main_loop ();
+}
diff --git a/firmware/fx2/b100/usrp_regs.h b/firmware/fx2/b100/usrp_regs.h
new file mode 100644
index 000000000..775b5dfd3
--- /dev/null
+++ b/firmware/fx2/b100/usrp_regs.h
@@ -0,0 +1,126 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * These are the register definitions for the Rev 1 USRP prototype
+ * The Rev 1 is the version with the AD9862's and daughterboards
+ */
+
+#ifndef _B100_REGS_H_
+#define _B100_REGS_H_
+
+#include "fx2regs.h"
+
+/*
+ * Port A (bit addressable):
+ */
+
+#define USRP_PA IOA // Port A
+#define USRP_PA_OE OEA // Port A direction register
+
+#define USRP_ALTERA_CONFIG USRP_PA // Now on port A, not C
+
+#define bmALTERA_DCLK bmBIT0
+#define bmALTERA_NCONFIG bmBIT1
+#define bmALTERA_DATA0 bmBIT3
+#define bmALTERA_NSTATUS bmBIT4
+#define bmALTERA_CONF_DONE bmBIT5
+#define bmRESET_FPGA_FIFOS bmBIT7
+
+
+#define bmALTERA_BITS (bmALTERA_DCLK \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DATA0 \
+ | bmALTERA_NSTATUS \
+ | bmALTERA_CONF_DONE \
+ )
+
+
+#define bmPORT_A_OUTPUTS (bmALTERA_DCLK \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DATA0 \
+ )
+
+#define bmPORT_A_INITIAL 0
+
+sbit at 0x80+0 bitALTERA_DCLK; // 0x80 is the bit address of PORT A
+sbit at 0x80+2 bitSHORT_PACKET_SIGNAL;
+sbit at 0x80+3 bitALTERA_DATA0;
+
+
+/* Port B: GPIF FD[7:0] */
+
+/*
+ * Port C (bit addressable):
+ * 5:1 FPGA configuration
+ */
+
+#define USRP_PC IOC // Port C
+#define USRP_PC_OE OEC // Port C direction register
+
+#define bmPC_nRESET 0 //bmBIT0 // reset line to codecs (active low)
+#define bmPC_LED0 bmBIT0 // active low
+#define bmPC_LED1 bmBIT1 // active low
+
+#define bmPORT_C_OUTPUTS (bmPC_LED0 | bmPC_LED1)
+#define bmPORT_C_INITIAL (bmPC_LED0 | bmPC_LED1)
+
+
+#define USRP_LED_REG USRP_PC
+#define bmLED0 bmPC_LED0
+#define bmLED1 bmPC_LED1
+
+
+/* Port D: GPIF FD[15:8] */
+
+/* Port E: not bit addressible */
+
+#define USRP_PE IOE // Port E
+#define USRP_PE_OE OEE // Port E direction register
+
+#define bmPORT_E_OUTPUTS (0)
+#define bmPORT_E_INITIAL (0)
+
+/*
+ * FPGA output lines that are tied to FX2 RDYx inputs.
+ * These are readable using GPIFREADYSTAT.
+ */
+//#define bmFPGA_HAS_SPACE bmBIT0 // usbrdy[0] has room for 512 byte packet
+//#define bmFPGA_PKT_AVAIL bmBIT1 // usbrdy[1] has >= 512 bytes available
+
+#define bmDATA_EMPTY bmBIT0 //data output FIFO has no data ready
+#define bmDATA_FIFO_FULL bmBIT1 //data input FIFO is full
+#define bmCTRL_EMPTY bmBIT2 //control output FIFO has no data ready
+#define bmCTRL_FIFO_FULL bmBIT3 //control input FIFO is full
+
+// #define bmTX_UNDERRUN bmBIT2 // usbrdy[2] D/A ran out of data
+// #define bmRX_OVERRUN bmBIT3 // usbrdy[3] A/D ran out of buffer
+
+/*
+ * FPGA input lines that are tied to the FX2 CTLx outputs.
+ *
+ * These are controlled by the GPIF microprogram...
+ */
+// WE bmBIT0 // usbctl[0] write enable
+// RE bmBIT1 // usbctl[1] read enable
+// OE bmBIT2 // usbctl[2] output enable
+// EP bmBIT3 // usbctl[3] endpoint select (data/ctrl)
+
+#endif /* _USRP_REV1_REGS_H_ */
diff --git a/firmware/fx2/common/fx2regs.h b/firmware/fx2/common/fx2regs.h
index 2f210f567..aa44791d0 100644
--- a/firmware/fx2/common/fx2regs.h
+++ b/firmware/fx2/common/fx2regs.h
@@ -664,6 +664,10 @@ sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
// must be zero bmBIT1
#define bmWORDWIDE bmBIT0
+/* EP 24 FIFO Flag bits (EP24FIFOFLGS) */
+#define EP2FIFOEMPTY bmBIT1
+#define EP4FIFOEMPTY bmBIT5
+
/*
* Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specific features
*/
diff --git a/firmware/fx2/common/usrp_commands.h b/firmware/fx2/common/usrp_commands.h
index 20c28e264..2466729b2 100644
--- a/firmware/fx2/common/usrp_commands.h
+++ b/firmware/fx2/common/usrp_commands.h
@@ -54,6 +54,8 @@
// wIndexL: format
// len: how much to read
+#define VRQ_FW_COMPAT 0x83 //low 16 bits
+
// OUT commands
#define VRQ_SET_LED 0x01 // wValueL off/on {0,1}; wIndexL: which {0,1}
@@ -87,6 +89,10 @@
#define VRQ_FPGA_SET_TX_RESET 0x0a // wValueL: {0, 1}
#define VRQ_FPGA_SET_RX_RESET 0x0b // wValueL: {0, 1}
+#define VRQ_RESET_GPIF 0x0c
+#define VRQ_ENABLE_GPIF 0x0d
+#define VRQ_CLEAR_FPGA_FIFO 0x0e
+
// -------------------------------------------------------------------
// we store the hashes at fixed addresses in the FX2 internal memory
diff --git a/firmware/fx2/utils/build_eeprom.py b/firmware/fx2/utils/build_eeprom.py
index 298ccc00c..af425554a 100755
--- a/firmware/fx2/utils/build_eeprom.py
+++ b/firmware/fx2/utils/build_eeprom.py
@@ -27,8 +27,10 @@ from optparse import OptionParser
# USB Vendor and Product ID's
-VID = 0xfffe # Free Software Folks
-
+USRP1VID = 0xfffe # Free Software Folks
+USRP1PID = 0x0002
+USRP1PVID= 0x2500 # Ettus Research
+USRP1PPID= 0x0001
def msb (x):
return (x >> 8) & 0xff
@@ -50,9 +52,11 @@ def build_eeprom_image (filename, rev):
start_addr = 0 #prove me wrong
if(rev == 1):
- PID = 0x0002 #USRP1
+ VID = USRP1VID
+ PID = USRP1PPID
else:
- PID = 0x0003 #USRP1P
+ VID = USRP1PVID
+ PID = USRP1PPID
rom_header = [
0xC2, # boot from EEPROM
diff --git a/firmware/fx2/utils/edit-gpif-b100.py b/firmware/fx2/utils/edit-gpif-b100.py
new file mode 100755
index 000000000..fd949cd8a
--- /dev/null
+++ b/firmware/fx2/utils/edit-gpif-b100.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# -*- Python -*-
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+
+# Edit the gpif.c file generated by the Cypress GPIF Designer Tool and
+# produce usrp_gpif.c, and usrp_gpif_inline.h, files suitable for our
+# uses.
+
+import re
+import string
+import sys
+
+def check_flow_state (line, flow_state_dict):
+ mo = re.match (r'/\* Wave (\d) FlowStates \*/ (.*),', line)
+ if mo:
+ wave = int (mo.group (1))
+ data = mo.group (2)
+ split = data.split (',', 8)
+ v = map (lambda x : int (x, 16), split)
+ # print "%s, %s" % (wave, data)
+ # print "split: ", split
+ # print "v : ", v
+ flow_state_dict[wave] = v
+
+
+def delta (xseq, yseq):
+ # set subtraction
+ z = []
+ for x in xseq:
+ if x not in yseq:
+ z.append (x)
+ return z
+
+
+def write_define (output, name, pairs):
+ output.write ('#define %s()\t\\\n' % name)
+ output.write ('do {\t\t\t\t\t\\\n')
+ for reg, val in pairs:
+ output.write ('%14s = 0x%02x;\t\t\t\\\n' % (reg, val))
+ output.write ('} while (0)\n\n')
+
+def write_inlines (output, dict):
+ regs = ['FLOWSTATE', 'FLOWLOGIC', 'FLOWEQ0CTL', 'FLOWEQ1CTL', 'FLOWHOLDOFF',
+ 'FLOWSTB', 'FLOWSTBEDGE', 'FLOWSTBHPERIOD', 'GPIFHOLDAMOUNT']
+
+ READ_CTRL_FLOW_STATE = 0
+ WRITE_CTRL_FLOW_STATE = 1
+ READ_DATA_FLOW_STATE = 2
+ WRITE_DATA_FLOW_STATE = 3
+
+ read_data_info = zip (regs, dict[READ_DATA_FLOW_STATE])
+ write_data_info = zip (regs, dict[WRITE_DATA_FLOW_STATE])
+ read_ctrl_info = zip (regs, dict[READ_CTRL_FLOW_STATE])
+ write_ctrl_info = zip (regs, dict[WRITE_CTRL_FLOW_STATE])
+
+ output.write ('''/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+''')
+ write_define (output, 'setup_flowstate_common', read_data_info) #assumes that the same registers will change, this isn't really good
+ write_define (output, 'setup_flowstate_data_read', delta (read_data_info, write_data_info))
+ write_define (output, 'setup_flowstate_data_write', delta (write_data_info, read_data_info))
+ write_define (output, 'setup_flowstate_ctrl_read', delta (read_ctrl_info, write_ctrl_info))
+ write_define (output, 'setup_flowstate_ctrl_write', delta (write_ctrl_info, read_ctrl_info))
+
+
+def edit_gpif (input_name, output_name, inline_name):
+ input = open (input_name, 'r')
+ output = open (output_name, 'w')
+ inline = open (inline_name, 'w')
+ flow_state_dict = {}
+
+ output.write ('''/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+''')
+
+ while 1:
+ line = input.readline ()
+ line = string.replace (line, '\r','')
+ line = re.sub (r' *$', r'', line)
+
+ check_flow_state (line, flow_state_dict)
+
+ line = re.sub (r'#include', r'// #include', line)
+ line = re.sub (r'xdata ', r'', line)
+ if re.search (r'GpifInit', line):
+ break
+
+ output.write (line)
+
+ output.close ()
+ write_inlines (inline, flow_state_dict)
+ inline.close ()
+
+
+# gpif.c usrp_gpif.c usrp_gpif_inline.h
+edit_gpif (sys.argv[1], sys.argv[2], sys.argv[3])