aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/fx2
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/fx2')
-rw-r--r--firmware/fx2/.gitignore2
-rw-r--r--firmware/fx2/AUTHORS4
-rw-r--r--firmware/fx2/CMakeLists.txt47
-rw-r--r--firmware/fx2/common/.gitignore18
-rw-r--r--firmware/fx2/common/_startup.a5180
-rw-r--r--firmware/fx2/common/_startup.a51.brittle78
-rw-r--r--firmware/fx2/common/delay.c76
-rw-r--r--firmware/fx2/common/delay.h38
-rw-r--r--firmware/fx2/common/eeprom_boot.a51573
-rw-r--r--firmware/fx2/common/eeprom_init.c75
-rw-r--r--firmware/fx2/common/fpga.h31
-rw-r--r--firmware/fx2/common/fpga_load.h28
-rw-r--r--firmware/fx2/common/fpga_regs0.h42
-rw-r--r--firmware/fx2/common/fpga_regs_common.h150
-rw-r--r--firmware/fx2/common/fpga_regs_common.v117
-rw-r--r--firmware/fx2/common/fpga_regs_standard.h300
-rw-r--r--firmware/fx2/common/fpga_regs_standard.v256
-rw-r--r--firmware/fx2/common/fx2regs.h716
-rw-r--r--firmware/fx2/common/fx2utils.c54
-rw-r--r--firmware/fx2/common/fx2utils.h31
-rw-r--r--firmware/fx2/common/i2c.c123
-rw-r--r--firmware/fx2/common/i2c.h32
-rw-r--r--firmware/fx2/common/init_gpif.c59
-rw-r--r--firmware/fx2/common/isr.c167
-rw-r--r--firmware/fx2/common/isr.h172
-rw-r--r--firmware/fx2/common/spi.c472
-rw-r--r--firmware/fx2/common/spi.h50
-rw-r--r--firmware/fx2/common/syncdelay.h65
-rw-r--r--firmware/fx2/common/timer.c49
-rw-r--r--firmware/fx2/common/timer.h35
-rw-r--r--firmware/fx2/common/usb_common.c386
-rw-r--r--firmware/fx2/common/usb_common.h37
-rw-r--r--firmware/fx2/common/usb_descriptors.h40
-rw-r--r--firmware/fx2/common/usb_requests.h88
-rw-r--r--firmware/fx2/common/usrp_commands.h106
-rw-r--r--firmware/fx2/common/usrp_common.h77
-rw-r--r--firmware/fx2/common/usrp_config.h44
-rw-r--r--firmware/fx2/common/usrp_globals.h32
-rw-r--r--firmware/fx2/common/usrp_i2c_addr.h78
-rw-r--r--firmware/fx2/common/usrp_ids.h68
-rw-r--r--firmware/fx2/common/usrp_interfaces.h47
-rw-r--r--firmware/fx2/common/usrp_spi_defs.h86
-rw-r--r--firmware/fx2/common/vectors.a51179
-rw-r--r--firmware/fx2/config/CMakeASM_SDCCInformation.cmake28
-rw-r--r--firmware/fx2/config/CMakeDetermineASM_SDCCCompiler.cmake22
-rw-r--r--firmware/fx2/config/CMakeTestASM_SDCCCompiler.cmake23
-rw-r--r--firmware/fx2/config/Rename.cmake37
-rw-r--r--firmware/fx2/config/Toolchain-sdcc.cmake32
-rw-r--r--firmware/fx2/usrp1/CMakeLists.txt84
-rw-r--r--firmware/fx2/usrp1/board_specific.c113
-rw-r--r--firmware/fx2/usrp1/eeprom_io.c65
-rw-r--r--firmware/fx2/usrp1/eeprom_io.h38
-rw-r--r--firmware/fx2/usrp1/fpga_load.c193
-rw-r--r--firmware/fx2/usrp1/fpga_rev2.c122
-rw-r--r--firmware/fx2/usrp1/fpga_rev2.h58
-rw-r--r--firmware/fx2/usrp1/gpif.c292
-rwxr-xr-xfirmware/fx2/usrp1/gpif.gpfbin0 -> 5341 bytes
-rw-r--r--firmware/fx2/usrp1/usb_descriptors.a51404
-rw-r--r--firmware/fx2/usrp1/usrp_common.c109
-rw-r--r--firmware/fx2/usrp1/usrp_gpif.c206
-rw-r--r--firmware/fx2/usrp1/usrp_gpif_inline.h27
-rw-r--r--firmware/fx2/usrp1/usrp_main.c389
-rw-r--r--firmware/fx2/usrp1/usrp_regs.h163
-rwxr-xr-xfirmware/fx2/utils/build_eeprom.py112
-rwxr-xr-xfirmware/fx2/utils/edit-gpif.py114
-rwxr-xr-xfirmware/fx2/utils/generate_regs.py57
66 files changed, 7896 insertions, 0 deletions
diff --git a/firmware/fx2/.gitignore b/firmware/fx2/.gitignore
new file mode 100644
index 000000000..e9fd37231
--- /dev/null
+++ b/firmware/fx2/.gitignore
@@ -0,0 +1,2 @@
+/build
+*.sym
diff --git a/firmware/fx2/AUTHORS b/firmware/fx2/AUTHORS
new file mode 100644
index 000000000..c9cd35778
--- /dev/null
+++ b/firmware/fx2/AUTHORS
@@ -0,0 +1,4 @@
+Eric Blossom <eb@comsec.org>
+Josh Blum <josh@joshknows.com>
+Thomas Tsou <ttsou@vt.edu>
+Nick Foster <nick@nerdnetworks.org>
diff --git a/firmware/fx2/CMakeLists.txt b/firmware/fx2/CMakeLists.txt
new file mode 100644
index 000000000..80f16363f
--- /dev/null
+++ b/firmware/fx2/CMakeLists.txt
@@ -0,0 +1,47 @@
+#
+# 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/>.
+#
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/config/Toolchain-sdcc.cmake)
+PROJECT(USRP1 C)
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/config/")
+INCLUDE(FindPythonInterp)
+
+########################################################################
+# Set toolchain to use SDCC
+########################################################################
+# we're doing mixed ASM and C
+ENABLE_LANGUAGE(ASM_SDCC)
+
+########################################################################
+# C flags and linking flags
+########################################################################
+ADD_DEFINITIONS(-DHAVE_USRP2)
+set(CMAKE_C_LINK_FLAGS "--code-loc 0x0000 --code-size 0x1800 --xram-loc 0x1800 --xram-size 0x0800 -Wl '-b USBDESCSEG = 0xE000'")
+set(CMAKE_C_FLAGS "--no-xinit-opt")
+
+########################################################################
+# Setup precompile tools
+########################################################################
+set(REG_GENERATOR ${CMAKE_SOURCE_DIR}/utils/generate_regs.py)
+set(EDIT_GPIF_USRP1 ${CMAKE_SOURCE_DIR}/utils/edit-gpif.py)
+set(BUILD_EEPROM ${CMAKE_SOURCE_DIR}/utils/build_eeprom.py)
+
+########################################################################
+# Add the subdirectories
+########################################################################
+ADD_SUBDIRECTORY(usrp1)
diff --git a/firmware/fx2/common/.gitignore b/firmware/fx2/common/.gitignore
new file mode 100644
index 000000000..04f253234
--- /dev/null
+++ b/firmware/fx2/common/.gitignore
@@ -0,0 +1,18 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/*.lib
+/Makefile
+/Makefile.in
diff --git a/firmware/fx2/common/_startup.a51 b/firmware/fx2/common/_startup.a51
new file mode 100644
index 000000000..30a907857
--- /dev/null
+++ b/firmware/fx2/common/_startup.a51
@@ -0,0 +1,80 @@
+;;; -*- asm -*-
+;;;
+;;; Copyright 2003,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.
+
+
+;;; The default external memory initialization provided by sdcc is not
+;;; appropriate to the FX2. This is derived from the sdcc code, but uses
+;;; the FX2 specific _MPAGE sfr.
+
+
+ ;; .area XISEG (XDATA) ; the initialized external data area
+ ;; .area XINIT (CODE) ; the code space consts to init XISEG
+ .area XSEG (XDATA) ; zero initialized xdata
+ .area USBDESCSEG (XDATA) ; usb descriptors
+
+
+ .area CSEG (CODE)
+
+ ;; sfr that sets upper address byte of MOVX using @r0 or @r1
+ _MPAGE = 0x0092
+
+__sdcc_external_startup::
+ ;; This system is now compiled with the --no-xinit-opt
+ ;; which means that any initialized XDATA is handled
+ ;; inline by code in the GSINIT segs emitted for each file.
+ ;;
+ ;; We zero XSEG and all of the internal ram to ensure
+ ;; a known good state for uninitialized variables.
+
+; _mcs51_genRAMCLEAR() start
+ mov r0,#l_XSEG
+ mov a,r0
+ orl a,#(l_XSEG >> 8)
+ jz 00002$
+ mov r1,#((l_XSEG + 255) >> 8)
+ mov dptr,#s_XSEG
+ clr a
+
+00001$: movx @dptr,a
+ inc dptr
+ djnz r0,00001$
+ djnz r1,00001$
+
+ ;; We're about to clear internal memory. This will overwrite
+ ;; the stack which contains our return address.
+ ;; Pop our return address into DPH, DPL
+00002$: pop dph
+ pop dpl
+
+ ;; R0 and A contain 0. This loop will execute 256 times.
+ ;;
+ ;; FWIW the first iteration writes direct address 0x00,
+ ;; which is the location of r0. We get lucky, we're
+ ;; writing the correct value (0)
+
+00003$: mov @r0,a
+ djnz r0,00003$
+
+ push dpl ; restore our return address
+ push dph
+
+ mov dpl,#0 ; indicate that data init is still required
+ ret
diff --git a/firmware/fx2/common/_startup.a51.brittle b/firmware/fx2/common/_startup.a51.brittle
new file mode 100644
index 000000000..2996275cf
--- /dev/null
+++ b/firmware/fx2/common/_startup.a51.brittle
@@ -0,0 +1,78 @@
+;;; -*- 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.
+
+
+;;; The default external memory initialization provided by sdcc is not
+;;; appropriate to the FX2. This is derived from the sdcc code, but uses
+;;; the FX2 specific _MPAGE sfr.
+
+
+ .area XISEG (XDATA) ; the initialized external data area
+ .area XINIT (CODE) ; the code space consts to init XISEG
+ .area XSEG (XDATA) ; zero initialized xdata
+ .area USBDESCSEG (XDATA); usb descriptors
+
+
+ ;; BIG TIME KLUDGE!
+ ;; Look at usrp_main.rst and count the bytes from our
+ ;; "normal return location" to the first instruction following
+ ;; the comment: "_mcs51_getRAMCLEAR () start"
+
+ INSTRUCTION_BYTES_TO_SKIP = 0x29 ; valid for sdcc 2.4.0
+
+
+ .area CSEG (CODE)
+
+ ;; sfr that sets upper address byte of MOVX using @r0 or @r1
+ _MPAGE = 0x0092
+
+__sdcc_external_startup::
+; _mcs51_genXINIT() start
+ mov r1,#l_XINIT
+ mov a,r1
+ orl a,#(l_XINIT >> 8)
+ jz 00003$
+ mov r2,#((l_XINIT+255) >> 8)
+ mov dptr,#s_XINIT
+ mov r0,#s_XISEG
+ mov _MPAGE,#(s_XISEG >> 8)
+00001$: clr a
+ movc a,@a+dptr
+ movx @r0,a
+ inc dptr
+ inc r0
+ cjne r0,#0,00002$
+ inc _MPAGE
+00002$: djnz r1,00001$
+ djnz r2,00001$
+ mov _MPAGE,#0xFF
+00003$:
+
+ ;; Danger! Total KLUDGE!
+ ;; We pop the return address, add a magic number to it
+ ;; then jump to that address. Believe it or not, this
+ ;; looks like the least kludgy way to handle this,
+ ;; short of patching the compiler...
+
+ pop dph
+ pop dpl
+ mov a,#INSTRUCTION_BYTES_TO_SKIP
+ jmp @a+dptr
diff --git a/firmware/fx2/common/delay.c b/firmware/fx2/common/delay.c
new file mode 100644
index 000000000..13cf0eec8
--- /dev/null
+++ b/firmware/fx2/common/delay.c
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+/*
+ * Delay approximately 1 microsecond (including overhead in udelay).
+ */
+static void
+udelay1 (void) _naked
+{
+ _asm ; lcall that got us here took 4 bus cycles
+ ret ; 4 bus cycles
+ _endasm;
+}
+
+/*
+ * delay for approximately usecs microseconds
+ */
+void
+udelay (unsigned char usecs)
+{
+ do {
+ udelay1 ();
+ } while (--usecs != 0);
+}
+
+
+/*
+ * Delay approximately 1 millisecond.
+ * We're running at 48 MHz, so we need 48,000 clock cycles.
+ *
+ * Note however, that each bus cycle takes 4 clock cycles (not obvious,
+ * but explains the factor of 4 problem below).
+ */
+static void
+mdelay1 (void) _naked
+{
+ _asm
+ mov dptr,#(-1200 & 0xffff)
+002$:
+ inc dptr ; 3 bus cycles
+ mov a, dpl ; 2 bus cycles
+ orl a, dph ; 2 bus cycles
+ jnz 002$ ; 3 bus cycles
+
+ ret
+ _endasm;
+}
+
+void
+mdelay (unsigned int msecs)
+{
+ do {
+ mdelay1 ();
+ } while (--msecs != 0);
+}
+
+
diff --git a/firmware/fx2/common/delay.h b/firmware/fx2/common/delay.h
new file mode 100644
index 000000000..f5df779e1
--- /dev/null
+++ b/firmware/fx2/common/delay.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _DELAY_H_
+#define _DELAY_H_
+
+/*
+ * delay for approximately usecs microseconds
+ * Note limit of 255 usecs.
+ */
+void udelay (unsigned char usecs);
+
+/*
+ * delay for approximately msecs milliseconds
+ */
+void mdelay (unsigned short msecs);
+
+
+#endif /* _DELAY_H_ */
diff --git a/firmware/fx2/common/eeprom_boot.a51 b/firmware/fx2/common/eeprom_boot.a51
new file mode 100644
index 000000000..65e452668
--- /dev/null
+++ b/firmware/fx2/common/eeprom_boot.a51
@@ -0,0 +1,573 @@
+;--------------------------------------------------------
+; Hand tweaked minimal eeprom boot code
+;--------------------------------------------------------
+ .module eeprom_boot
+ .optsdcc -mmcs51 --model-small
+
+;--------------------------------------------------------
+; Public variables in this module
+;--------------------------------------------------------
+ .globl _eeprom_init
+ .globl _EP8FIFOBUF
+ .globl _EP6FIFOBUF
+ .globl _EP4FIFOBUF
+ .globl _EP2FIFOBUF
+ .globl _EP1INBUF
+ .globl _EP1OUTBUF
+ .globl _EP0BUF
+ .globl _CT4
+ .globl _CT3
+ .globl _CT2
+ .globl _CT1
+ .globl _USBTEST
+ .globl _TESTCFG
+ .globl _DBUG
+ .globl _UDMACRCQUAL
+ .globl _UDMACRCL
+ .globl _UDMACRCH
+ .globl _GPIFHOLDAMOUNT
+ .globl _FLOWSTBHPERIOD
+ .globl _FLOWSTBEDGE
+ .globl _FLOWSTB
+ .globl _FLOWHOLDOFF
+ .globl _FLOWEQ1CTL
+ .globl _FLOWEQ0CTL
+ .globl _FLOWLOGIC
+ .globl _FLOWSTATE
+ .globl _GPIFABORT
+ .globl _GPIFREADYSTAT
+ .globl _GPIFREADYCFG
+ .globl _XGPIFSGLDATLNOX
+ .globl _XGPIFSGLDATLX
+ .globl _XGPIFSGLDATH
+ .globl _EP8GPIFTRIG
+ .globl _EP8GPIFPFSTOP
+ .globl _EP8GPIFFLGSEL
+ .globl _EP6GPIFTRIG
+ .globl _EP6GPIFPFSTOP
+ .globl _EP6GPIFFLGSEL
+ .globl _EP4GPIFTRIG
+ .globl _EP4GPIFPFSTOP
+ .globl _EP4GPIFFLGSEL
+ .globl _EP2GPIFTRIG
+ .globl _EP2GPIFPFSTOP
+ .globl _EP2GPIFFLGSEL
+ .globl _GPIFTCB0
+ .globl _GPIFTCB1
+ .globl _GPIFTCB2
+ .globl _GPIFTCB3
+ .globl _GPIFADRL
+ .globl _GPIFADRH
+ .globl _GPIFCTLCFG
+ .globl _GPIFIDLECTL
+ .globl _GPIFIDLECS
+ .globl _GPIFWFSELECT
+ .globl _SETUPDAT
+ .globl _SUDPTRCTL
+ .globl _SUDPTRL
+ .globl _SUDPTRH
+ .globl _EP8FIFOBCL
+ .globl _EP8FIFOBCH
+ .globl _EP6FIFOBCL
+ .globl _EP6FIFOBCH
+ .globl _EP4FIFOBCL
+ .globl _EP4FIFOBCH
+ .globl _EP2FIFOBCL
+ .globl _EP2FIFOBCH
+ .globl _EP8FIFOFLGS
+ .globl _EP6FIFOFLGS
+ .globl _EP4FIFOFLGS
+ .globl _EP2FIFOFLGS
+ .globl _EP8CS
+ .globl _EP6CS
+ .globl _EP4CS
+ .globl _EP2CS
+ .globl _EP1INCS
+ .globl _EP1OUTCS
+ .globl _EP0CS
+ .globl _EP8BCL
+ .globl _EP8BCH
+ .globl _EP6BCL
+ .globl _EP6BCH
+ .globl _EP4BCL
+ .globl _EP4BCH
+ .globl _EP2BCL
+ .globl _EP2BCH
+ .globl _EP1INBC
+ .globl _EP1OUTBC
+ .globl _EP0BCL
+ .globl _EP0BCH
+ .globl _FNADDR
+ .globl _MICROFRAME
+ .globl _USBFRAMEL
+ .globl _USBFRAMEH
+ .globl _TOGCTL
+ .globl _WAKEUPCS
+ .globl _SUSPEND
+ .globl _USBCS
+ .globl _XAUTODAT2
+ .globl _XAUTODAT1
+ .globl _I2CTL
+ .globl _I2DAT
+ .globl _I2CS
+ .globl _PORTECFG
+ .globl _PORTCCFG
+ .globl _PORTACFG
+ .globl _INTSETUP
+ .globl _INT4IVEC
+ .globl _INT2IVEC
+ .globl _CLRERRCNT
+ .globl _ERRCNTLIM
+ .globl _USBERRIRQ
+ .globl _USBERRIE
+ .globl _GPIFIRQ
+ .globl _GPIFIE
+ .globl _EPIRQ
+ .globl _EPIE
+ .globl _USBIRQ
+ .globl _USBIE
+ .globl _NAKIRQ
+ .globl _NAKIE
+ .globl _IBNIRQ
+ .globl _IBNIE
+ .globl _EP8FIFOIRQ
+ .globl _EP8FIFOIE
+ .globl _EP6FIFOIRQ
+ .globl _EP6FIFOIE
+ .globl _EP4FIFOIRQ
+ .globl _EP4FIFOIE
+ .globl _EP2FIFOIRQ
+ .globl _EP2FIFOIE
+ .globl _OUTPKTEND
+ .globl _INPKTEND
+ .globl _EP8ISOINPKTS
+ .globl _EP6ISOINPKTS
+ .globl _EP4ISOINPKTS
+ .globl _EP2ISOINPKTS
+ .globl _EP8FIFOPFL
+ .globl _EP8FIFOPFH
+ .globl _EP6FIFOPFL
+ .globl _EP6FIFOPFH
+ .globl _EP4FIFOPFL
+ .globl _EP4FIFOPFH
+ .globl _EP2FIFOPFL
+ .globl _EP2FIFOPFH
+ .globl _EP8AUTOINLENL
+ .globl _EP8AUTOINLENH
+ .globl _EP6AUTOINLENL
+ .globl _EP6AUTOINLENH
+ .globl _EP4AUTOINLENL
+ .globl _EP4AUTOINLENH
+ .globl _EP2AUTOINLENL
+ .globl _EP2AUTOINLENH
+ .globl _EP8FIFOCFG
+ .globl _EP6FIFOCFG
+ .globl _EP4FIFOCFG
+ .globl _EP2FIFOCFG
+ .globl _EP8CFG
+ .globl _EP6CFG
+ .globl _EP4CFG
+ .globl _EP2CFG
+ .globl _EP1INCFG
+ .globl _EP1OUTCFG
+ .globl _REVCTL
+ .globl _REVID
+ .globl _FIFOPINPOLAR
+ .globl _UART230
+ .globl _BPADDRL
+ .globl _BPADDRH
+ .globl _BREAKPT
+ .globl _FIFORESET
+ .globl _PINFLAGSCD
+ .globl _PINFLAGSAB
+ .globl _IFCONFIG
+ .globl _CPUCS
+ .globl _RES_WAVEDATA_END
+ .globl _GPIF_WAVE_DATA
+;--------------------------------------------------------
+; special function registers
+;--------------------------------------------------------
+_IOA = 0x0080
+_SP = 0x0081
+_DPL = 0x0082
+_DPH = 0x0083
+_DPL1 = 0x0084
+_DPH1 = 0x0085
+_DPS = 0x0086
+_PCON = 0x0087
+_TCON = 0x0088
+_TMOD = 0x0089
+_TL0 = 0x008a
+_TL1 = 0x008b
+_TH0 = 0x008c
+_TH1 = 0x008d
+_CKCON = 0x008e
+_IOB = 0x0090
+_EXIF = 0x0091
+_MPAGE = 0x0092
+_SCON0 = 0x0098
+_SBUF0 = 0x0099
+_APTR1H = 0x009a
+_APTR1L = 0x009b
+_AUTODAT1 = 0x009c
+_AUTOPTRH2 = 0x009d
+_AUTOPTRL2 = 0x009e
+_AUTODAT2 = 0x009f
+_IOC = 0x00a0
+_INT2CLR = 0x00a1
+_INT4CLR = 0x00a2
+_IE = 0x00a8
+_EP2468STAT = 0x00aa
+_EP24FIFOFLGS = 0x00ab
+_EP68FIFOFLGS = 0x00ac
+_AUTOPTRSETUP = 0x00af
+_IOD = 0x00b0
+_IOE = 0x00b1
+_OEA = 0x00b2
+_OEB = 0x00b3
+_OEC = 0x00b4
+_OED = 0x00b5
+_OEE = 0x00b6
+_IP = 0x00b8
+_EP01STAT = 0x00ba
+_GPIFTRIG = 0x00bb
+_GPIFSGLDATH = 0x00bd
+_GPIFSGLDATLX = 0x00be
+_GPIFSGLDATLNOX = 0x00bf
+_SCON1 = 0x00c0
+_SBUF1 = 0x00c1
+_T2CON = 0x00c8
+_RCAP2L = 0x00ca
+_RCAP2H = 0x00cb
+_TL2 = 0x00cc
+_TH2 = 0x00cd
+_PSW = 0x00d0
+_EICON = 0x00d8
+_ACC = 0x00e0
+_EIE = 0x00e8
+_B = 0x00f0
+_EIP = 0x00f8
+;--------------------------------------------------------
+; special function bits
+;--------------------------------------------------------
+_SEL = 0x0086
+_IT0 = 0x0088
+_IE0 = 0x0089
+_IT1 = 0x008a
+_IE1 = 0x008b
+_TR0 = 0x008c
+_TF0 = 0x008d
+_TR1 = 0x008e
+_TF1 = 0x008f
+_RI = 0x0098
+_TI = 0x0099
+_RB8 = 0x009a
+_TB8 = 0x009b
+_REN = 0x009c
+_SM2 = 0x009d
+_SM1 = 0x009e
+_SM0 = 0x009f
+_EX0 = 0x00a8
+_ET0 = 0x00a9
+_EX1 = 0x00aa
+_ET1 = 0x00ab
+_ES0 = 0x00ac
+_ET2 = 0x00ad
+_ES1 = 0x00ae
+_EA = 0x00af
+_PX0 = 0x00b8
+_PT0 = 0x00b9
+_PX1 = 0x00ba
+_PT1 = 0x00bb
+_PS0 = 0x00bc
+_PT2 = 0x00bd
+_PS1 = 0x00be
+_RI1 = 0x00c0
+_TI1 = 0x00c1
+_RB81 = 0x00c2
+_TB81 = 0x00c3
+_REN1 = 0x00c4
+_SM21 = 0x00c5
+_SM11 = 0x00c6
+_SM01 = 0x00c7
+_CP_RL2 = 0x00c8
+_C_T2 = 0x00c9
+_TR2 = 0x00ca
+_EXEN2 = 0x00cb
+_TCLK = 0x00cc
+_RCLK = 0x00cd
+_EXF2 = 0x00ce
+_TF2 = 0x00cf
+_P = 0x00d0
+_FL = 0x00d1
+_OV = 0x00d2
+_RS0 = 0x00d3
+_RS1 = 0x00d4
+_F0 = 0x00d5
+_AC = 0x00d6
+_CY = 0x00d7
+_INT6 = 0x00db
+_RESI = 0x00dc
+_ERESI = 0x00dd
+_SMOD1 = 0x00df
+_EIUSB = 0x00e8
+_EI2C = 0x00e9
+_EIEX4 = 0x00ea
+_EIEX5 = 0x00eb
+_EIEX6 = 0x00ec
+_PUSB = 0x00f8
+_PI2C = 0x00f9
+_EIPX4 = 0x00fa
+_EIPX5 = 0x00fb
+_EIPX6 = 0x00fc
+_bitS_CLK = 0x0080
+_bitS_OUT = 0x0081
+_bitS_IN = 0x0082
+_bitALTERA_DATA0 = 0x00a1
+_bitALTERA_DCLK = 0x00a3
+;--------------------------------------------------------
+; overlayable register banks
+;--------------------------------------------------------
+ .area REG_BANK_0 (REL,OVR,DATA)
+ .ds 8
+;--------------------------------------------------------
+; internal ram data
+;--------------------------------------------------------
+ .area DSEG (DATA)
+;--------------------------------------------------------
+; overlayable items in internal ram
+;--------------------------------------------------------
+ .area OSEG (OVR,DATA)
+;--------------------------------------------------------
+; Stack segment in internal ram
+;--------------------------------------------------------
+ .area SSEG (DATA)
+__start__stack:
+ .ds 1
+
+;--------------------------------------------------------
+; indirectly addressable internal ram data
+;--------------------------------------------------------
+ .area ISEG (DATA)
+;--------------------------------------------------------
+; bit data
+;--------------------------------------------------------
+ .area BSEG (BIT)
+;--------------------------------------------------------
+; external ram data
+;--------------------------------------------------------
+ .area XSEG (XDATA)
+_GPIF_WAVE_DATA = 0xe400
+_RES_WAVEDATA_END = 0xe480
+_CPUCS = 0xe600
+_IFCONFIG = 0xe601
+_PINFLAGSAB = 0xe602
+_PINFLAGSCD = 0xe603
+_FIFORESET = 0xe604
+_BREAKPT = 0xe605
+_BPADDRH = 0xe606
+_BPADDRL = 0xe607
+_UART230 = 0xe608
+_FIFOPINPOLAR = 0xe609
+_REVID = 0xe60a
+_REVCTL = 0xe60b
+_EP1OUTCFG = 0xe610
+_EP1INCFG = 0xe611
+_EP2CFG = 0xe612
+_EP4CFG = 0xe613
+_EP6CFG = 0xe614
+_EP8CFG = 0xe615
+_EP2FIFOCFG = 0xe618
+_EP4FIFOCFG = 0xe619
+_EP6FIFOCFG = 0xe61a
+_EP8FIFOCFG = 0xe61b
+_EP2AUTOINLENH = 0xe620
+_EP2AUTOINLENL = 0xe621
+_EP4AUTOINLENH = 0xe622
+_EP4AUTOINLENL = 0xe623
+_EP6AUTOINLENH = 0xe624
+_EP6AUTOINLENL = 0xe625
+_EP8AUTOINLENH = 0xe626
+_EP8AUTOINLENL = 0xe627
+_EP2FIFOPFH = 0xe630
+_EP2FIFOPFL = 0xe631
+_EP4FIFOPFH = 0xe632
+_EP4FIFOPFL = 0xe633
+_EP6FIFOPFH = 0xe634
+_EP6FIFOPFL = 0xe635
+_EP8FIFOPFH = 0xe636
+_EP8FIFOPFL = 0xe637
+_EP2ISOINPKTS = 0xe640
+_EP4ISOINPKTS = 0xe641
+_EP6ISOINPKTS = 0xe642
+_EP8ISOINPKTS = 0xe643
+_INPKTEND = 0xe648
+_OUTPKTEND = 0xe649
+_EP2FIFOIE = 0xe650
+_EP2FIFOIRQ = 0xe651
+_EP4FIFOIE = 0xe652
+_EP4FIFOIRQ = 0xe653
+_EP6FIFOIE = 0xe654
+_EP6FIFOIRQ = 0xe655
+_EP8FIFOIE = 0xe656
+_EP8FIFOIRQ = 0xe657
+_IBNIE = 0xe658
+_IBNIRQ = 0xe659
+_NAKIE = 0xe65a
+_NAKIRQ = 0xe65b
+_USBIE = 0xe65c
+_USBIRQ = 0xe65d
+_EPIE = 0xe65e
+_EPIRQ = 0xe65f
+_GPIFIE = 0xe660
+_GPIFIRQ = 0xe661
+_USBERRIE = 0xe662
+_USBERRIRQ = 0xe663
+_ERRCNTLIM = 0xe664
+_CLRERRCNT = 0xe665
+_INT2IVEC = 0xe666
+_INT4IVEC = 0xe667
+_INTSETUP = 0xe668
+_PORTACFG = 0xe670
+_PORTCCFG = 0xe671
+_PORTECFG = 0xe672
+_I2CS = 0xe678
+_I2DAT = 0xe679
+_I2CTL = 0xe67a
+_XAUTODAT1 = 0xe67b
+_XAUTODAT2 = 0xe67c
+_USBCS = 0xe680
+_SUSPEND = 0xe681
+_WAKEUPCS = 0xe682
+_TOGCTL = 0xe683
+_USBFRAMEH = 0xe684
+_USBFRAMEL = 0xe685
+_MICROFRAME = 0xe686
+_FNADDR = 0xe687
+_EP0BCH = 0xe68a
+_EP0BCL = 0xe68b
+_EP1OUTBC = 0xe68d
+_EP1INBC = 0xe68f
+_EP2BCH = 0xe690
+_EP2BCL = 0xe691
+_EP4BCH = 0xe694
+_EP4BCL = 0xe695
+_EP6BCH = 0xe698
+_EP6BCL = 0xe699
+_EP8BCH = 0xe69c
+_EP8BCL = 0xe69d
+_EP0CS = 0xe6a0
+_EP1OUTCS = 0xe6a1
+_EP1INCS = 0xe6a2
+_EP2CS = 0xe6a3
+_EP4CS = 0xe6a4
+_EP6CS = 0xe6a5
+_EP8CS = 0xe6a6
+_EP2FIFOFLGS = 0xe6a7
+_EP4FIFOFLGS = 0xe6a8
+_EP6FIFOFLGS = 0xe6a9
+_EP8FIFOFLGS = 0xe6aa
+_EP2FIFOBCH = 0xe6ab
+_EP2FIFOBCL = 0xe6ac
+_EP4FIFOBCH = 0xe6ad
+_EP4FIFOBCL = 0xe6ae
+_EP6FIFOBCH = 0xe6af
+_EP6FIFOBCL = 0xe6b0
+_EP8FIFOBCH = 0xe6b1
+_EP8FIFOBCL = 0xe6b2
+_SUDPTRH = 0xe6b3
+_SUDPTRL = 0xe6b4
+_SUDPTRCTL = 0xe6b5
+_SETUPDAT = 0xe6b8
+_GPIFWFSELECT = 0xe6c0
+_GPIFIDLECS = 0xe6c1
+_GPIFIDLECTL = 0xe6c2
+_GPIFCTLCFG = 0xe6c3
+_GPIFADRH = 0xe6c4
+_GPIFADRL = 0xe6c5
+_GPIFTCB3 = 0xe6ce
+_GPIFTCB2 = 0xe6cf
+_GPIFTCB1 = 0xe6d0
+_GPIFTCB0 = 0xe6d1
+_EP2GPIFFLGSEL = 0xe6d2
+_EP2GPIFPFSTOP = 0xe6d3
+_EP2GPIFTRIG = 0xe6d4
+_EP4GPIFFLGSEL = 0xe6da
+_EP4GPIFPFSTOP = 0xe6db
+_EP4GPIFTRIG = 0xe6dc
+_EP6GPIFFLGSEL = 0xe6e2
+_EP6GPIFPFSTOP = 0xe6e3
+_EP6GPIFTRIG = 0xe6e4
+_EP8GPIFFLGSEL = 0xe6ea
+_EP8GPIFPFSTOP = 0xe6eb
+_EP8GPIFTRIG = 0xe6ec
+_XGPIFSGLDATH = 0xe6f0
+_XGPIFSGLDATLX = 0xe6f1
+_XGPIFSGLDATLNOX = 0xe6f2
+_GPIFREADYCFG = 0xe6f3
+_GPIFREADYSTAT = 0xe6f4
+_GPIFABORT = 0xe6f5
+_FLOWSTATE = 0xe6c6
+_FLOWLOGIC = 0xe6c7
+_FLOWEQ0CTL = 0xe6c8
+_FLOWEQ1CTL = 0xe6c9
+_FLOWHOLDOFF = 0xe6ca
+_FLOWSTB = 0xe6cb
+_FLOWSTBEDGE = 0xe6cc
+_FLOWSTBHPERIOD = 0xe6cd
+_GPIFHOLDAMOUNT = 0xe60c
+_UDMACRCH = 0xe67d
+_UDMACRCL = 0xe67e
+_UDMACRCQUAL = 0xe67f
+_DBUG = 0xe6f8
+_TESTCFG = 0xe6f9
+_USBTEST = 0xe6fa
+_CT1 = 0xe6fb
+_CT2 = 0xe6fc
+_CT3 = 0xe6fd
+_CT4 = 0xe6fe
+_EP0BUF = 0xe740
+_EP1OUTBUF = 0xe780
+_EP1INBUF = 0xe7c0
+_EP2FIFOBUF = 0xf000
+_EP4FIFOBUF = 0xf400
+_EP6FIFOBUF = 0xf800
+_EP8FIFOBUF = 0xfc00
+;--------------------------------------------------------
+; external initialized ram data
+;--------------------------------------------------------
+;--------------------------------------------------------
+; interrupt vector
+;--------------------------------------------------------
+ .area CSEG (CODE)
+__interrupt_vect:
+ ljmp __sdcc_gsinit_startup
+;--------------------------------------------------------
+; global & static initialisations
+;--------------------------------------------------------
+ .area GSINIT (CODE)
+ .area GSFINAL (CODE)
+ .area GSINIT (CODE)
+__sdcc_gsinit_startup:
+ mov sp,#__start__stack - 1
+ lcall __sdcc_external_startup
+ mov a,dpl
+ jz __sdcc_init_data
+ ljmp __sdcc_program_startup
+__sdcc_init_data:
+ .area GSFINAL (CODE)
+ ljmp __sdcc_program_startup
+;--------------------------------------------------------
+; Home
+;--------------------------------------------------------
+ .area HOME (CODE)
+ .area CSEG (CODE)
+;--------------------------------------------------------
+; code
+;--------------------------------------------------------
+ .area CSEG (CODE)
+__sdcc_program_startup:
+ lcall _eeprom_init
+; return from _eeprom_init will spin here
+ sjmp .
+ .area CSEG (CODE)
diff --git a/firmware/fx2/common/eeprom_init.c b/firmware/fx2/common/eeprom_init.c
new file mode 100644
index 000000000..07902dcca
--- /dev/null
+++ b/firmware/fx2/common/eeprom_init.c
@@ -0,0 +1,75 @@
+/* -*- 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"
+#include "usrp_commands.h"
+
+/*
+ * 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_0_ADDR unsigned char hash0[USRP_HASH_SIZE];
+
+
+#define REG_RX_PWR_DN 1
+#define REG_TX_PWR_DN 8
+#define REG_TX_MODULATOR 20
+
+void eeprom_init (void)
+{
+ unsigned short counter;
+ unsigned char i;
+
+ // 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
+
+ EP0BCH = 0; SYNCDELAY;
+
+ // USBCS &= ~bmRENUM; // chip firmware handles commands
+ USBCS = 0; // chip firmware handles commands
+
+ //USRP_PC &= ~bmPC_nRESET; // active low reset
+ //USRP_PC |= bmPC_nRESET;
+
+ // zero firmware hash slot
+ i = 0;
+ do {
+ hash0[i] = 0;
+ i++;
+ } while (i != USRP_HASH_SIZE);
+
+ counter = 0;
+ while (1){
+ counter++;
+ if (counter & 0x8000)
+ IOC ^= bmPC_LED0;
+ }
+}
diff --git a/firmware/fx2/common/fpga.h b/firmware/fx2/common/fpga.h
new file mode 100644
index 000000000..6cd5de8e2
--- /dev/null
+++ b/firmware/fx2/common/fpga.h
@@ -0,0 +1,31 @@
+/* -*- 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.
+ */
+#ifndef INCLUDED_FPGA_H
+#define INCLUDED_FPGA_H
+
+#include "fpga_load.h"
+
+#if defined(HAVE_USRP2)
+#include "fpga_rev2.h"
+#endif
+
+#endif /* INCLUDED_FPGA_H */
diff --git a/firmware/fx2/common/fpga_load.h b/firmware/fx2/common/fpga_load.h
new file mode 100644
index 000000000..7c36a04c8
--- /dev/null
+++ b/firmware/fx2/common/fpga_load.h
@@ -0,0 +1,28 @@
+/*
+ * 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
+ */
+
+#ifndef INCLUDED_FPGA_LOAD_H
+#define INCLUDED_FPGA_LOAD_H
+
+unsigned char fpga_load_begin (void);
+unsigned char fpga_load_xfer (xdata unsigned char *p, unsigned char len);
+unsigned char fpga_load_end (void);
+
+#endif /* INCLUDED_FPGA_LOAD_H */
diff --git a/firmware/fx2/common/fpga_regs0.h b/firmware/fx2/common/fpga_regs0.h
new file mode 100644
index 000000000..883798301
--- /dev/null
+++ b/firmware/fx2/common/fpga_regs0.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _FPGA_REGS0_H_
+#define _FPGA_REGS0_H_
+
+#define FR_RX_FREQ_0 0
+#define FR_RX_FREQ_1 1
+#define FR_RX_FREQ_2 2
+#define FR_RX_FREQ_3 3
+#define FR_TX_FREQ_0 4
+#define FR_TX_FREQ_1 5
+#define FR_TX_FREQ_2 6
+#define FR_TX_FREQ_3 7
+#define FR_COMBO 8
+
+
+#define FR_ADC_CLK_DIV 128 // pseudo regs mapped to FR_COMBO by f/w
+#define FR_EXT_CLK_DIV 129
+#define FR_INTERP 130
+#define FR_DECIM 131
+
+#endif
diff --git a/firmware/fx2/common/fpga_regs_common.h b/firmware/fx2/common/fpga_regs_common.h
new file mode 100644
index 000000000..b4a496af7
--- /dev/null
+++ b/firmware/fx2/common/fpga_regs_common.h
@@ -0,0 +1,150 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+#ifndef INCLUDED_FPGA_REGS_COMMON_H
+#define INCLUDED_FPGA_REGS_COMMON_H
+
+// This file defines registers common to all FPGA configurations.
+// Registers 0 to 31 are reserved for use in this file.
+
+
+// The FPGA needs to know the rate that samples are coming from and
+// going to the A/D's and D/A's. div = 128e6 / sample_rate
+
+#define FR_TX_SAMPLE_RATE_DIV 0
+#define FR_RX_SAMPLE_RATE_DIV 1
+
+// 2 and 3 are defined in the ATR section
+
+#define FR_MASTER_CTRL 4 // master enable and reset controls
+# define bmFR_MC_ENABLE_TX (1 << 0)
+# define bmFR_MC_ENABLE_RX (1 << 1)
+# define bmFR_MC_RESET_TX (1 << 2)
+# define bmFR_MC_RESET_RX (1 << 3)
+
+// i/o direction registers for pins that go to daughterboards.
+// Setting the bit makes it an output from the FPGA to the d'board.
+// top 16 is mask, low 16 is value
+
+#define FR_OE_0 5 // slot 0
+#define FR_OE_1 6
+#define FR_OE_2 7
+#define FR_OE_3 8
+
+// i/o registers for pins that go to daughterboards.
+// top 16 is a mask, low 16 is value
+
+#define FR_IO_0 9 // slot 0
+#define FR_IO_1 10
+#define FR_IO_2 11
+#define FR_IO_3 12
+
+#define FR_MODE 13
+# define bmFR_MODE_NORMAL 0
+# define bmFR_MODE_LOOPBACK (1 << 0) // enable digital loopback
+# define bmFR_MODE_RX_COUNTING (1 << 1) // Rx is counting
+# define bmFR_MODE_RX_COUNTING_32BIT (1 << 2) // Rx is counting with a 32 bit counter
+ // low and high 16 bits are multiplexed across channel I and Q
+
+
+// If the corresponding bit is set, internal FPGA debug circuitry
+// controls the i/o pins for the associated bank of daughterboard
+// i/o pins. Typically used for debugging FPGA designs.
+
+#define FR_DEBUG_EN 14
+# define bmFR_DEBUG_EN_TX_A (1 << 0) // debug controls TX_A i/o
+# define bmFR_DEBUG_EN_RX_A (1 << 1) // debug controls RX_A i/o
+# define bmFR_DEBUG_EN_TX_B (1 << 2) // debug controls TX_B i/o
+# define bmFR_DEBUG_EN_RX_B (1 << 3) // debug controls RX_B i/o
+
+
+// If the corresponding bit is set, enable the automatic DC
+// offset correction control loop.
+//
+// The 4 low bits are significant:
+//
+// ADC0 = (1 << 0)
+// ADC1 = (1 << 1)
+// ADC2 = (1 << 2)
+// ADC3 = (1 << 3)
+//
+// This control loop works if the attached daugherboard blocks DC.
+// Currently all daughterboards do block DC. This includes:
+// basic rx, dbs_rx, tv_rx, flex_xxx_rx.
+
+#define FR_DC_OFFSET_CL_EN 15 // DC Offset Control Loop Enable
+
+
+// offset corrections for ADC's and DAC's (2's complement)
+
+#define FR_ADC_OFFSET_0 16
+#define FR_ADC_OFFSET_1 17
+#define FR_ADC_OFFSET_2 18
+#define FR_ADC_OFFSET_3 19
+
+
+// ------------------------------------------------------------------------
+// Automatic Transmit/Receive switching
+//
+// If automatic transmit/receive (ATR) switching is enabled in the
+// FR_ATR_CTL register, the presence or absence of data in the FPGA
+// transmit fifo selects between two sets of values for each of the 4
+// banks of daughterboard i/o pins.
+//
+// Each daughterboard slot has 3 16-bit registers associated with it:
+// FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
+//
+// FR_ATR_MASK_{0,1,2,3}:
+//
+// These registers determine which of the daugherboard i/o pins are
+// affected by ATR switching. If a bit in the mask is set, the
+// corresponding i/o bit is controlled by ATR, else it's output
+// value comes from the normal i/o pin output register:
+// FR_IO_{0,1,2,3}.
+//
+// FR_ATR_TXVAL_{0,1,2,3}:
+// FR_ATR_RXVAL_{0,1,2,3}:
+//
+// If the Tx fifo contains data, then the bits from TXVAL that are
+// selected by MASK are output. Otherwise, the bits from RXVAL that
+// are selected by MASK are output.
+
+#define FR_ATR_MASK_0 20 // slot 0
+#define FR_ATR_TXVAL_0 21
+#define FR_ATR_RXVAL_0 22
+
+#define FR_ATR_MASK_1 23 // slot 1
+#define FR_ATR_TXVAL_1 24
+#define FR_ATR_RXVAL_1 25
+
+#define FR_ATR_MASK_2 26 // slot 2
+#define FR_ATR_TXVAL_2 27
+#define FR_ATR_RXVAL_2 28
+
+#define FR_ATR_MASK_3 29 // slot 3
+#define FR_ATR_TXVAL_3 30
+#define FR_ATR_RXVAL_3 31
+
+// Clock ticks to delay rising and falling edge of T/R signal
+#define FR_ATR_TX_DELAY 2
+#define FR_ATR_RX_DELAY 3
+
+#endif /* INCLUDED_FPGA_REGS_COMMON_H */
diff --git a/firmware/fx2/common/fpga_regs_common.v b/firmware/fx2/common/fpga_regs_common.v
new file mode 100644
index 000000000..8035d8565
--- /dev/null
+++ b/firmware/fx2/common/fpga_regs_common.v
@@ -0,0 +1,117 @@
+//
+// This file is machine generated from ./fpga_regs_common.h
+// Do not edit by hand; your edits will be overwritten.
+//
+
+// This file defines registers common to all FPGA configurations.
+// Registers 0 to 31 are reserved for use in this file.
+
+
+// The FPGA needs to know the rate that samples are coming from and
+// going to the A/D's and D/A's. div = 128e6 / sample_rate
+
+`define FR_TX_SAMPLE_RATE_DIV 7'd0
+`define FR_RX_SAMPLE_RATE_DIV 7'd1
+
+// 2 and 3 are defined in the ATR section
+
+`define FR_MASTER_CTRL 7'd4 // master enable and reset controls
+
+// i/o direction registers for pins that go to daughterboards.
+// Setting the bit makes it an output from the FPGA to the d'board.
+// top 16 is mask, low 16 is value
+
+`define FR_OE_0 7'd5 // slot 0
+`define FR_OE_1 7'd6
+`define FR_OE_2 7'd7
+`define FR_OE_3 7'd8
+
+// i/o registers for pins that go to daughterboards.
+// top 16 is a mask, low 16 is value
+
+`define FR_IO_0 7'd9 // slot 0
+`define FR_IO_1 7'd10
+`define FR_IO_2 7'd11
+`define FR_IO_3 7'd12
+
+`define FR_MODE 7'd13
+
+
+// If the corresponding bit is set, internal FPGA debug circuitry
+// controls the i/o pins for the associated bank of daughterboard
+// i/o pins. Typically used for debugging FPGA designs.
+
+`define FR_DEBUG_EN 7'd14
+
+
+// If the corresponding bit is set, enable the automatic DC
+// offset correction control loop.
+//
+// The 4 low bits are significant:
+//
+// ADC0 = (1 << 0)
+// ADC1 = (1 << 1)
+// ADC2 = (1 << 2)
+// ADC3 = (1 << 3)
+//
+// This control loop works if the attached daugherboard blocks DC.
+// Currently all daughterboards do block DC. This includes:
+// basic rx, dbs_rx, tv_rx, flex_xxx_rx.
+
+`define FR_DC_OFFSET_CL_EN 7'd15 // DC Offset Control Loop Enable
+
+
+// offset corrections for ADC's and DAC's (2's complement)
+
+`define FR_ADC_OFFSET_0 7'd16
+`define FR_ADC_OFFSET_1 7'd17
+`define FR_ADC_OFFSET_2 7'd18
+`define FR_ADC_OFFSET_3 7'd19
+
+
+// ------------------------------------------------------------------------
+// Automatic Transmit/Receive switching
+//
+// If automatic transmit/receive (ATR) switching is enabled in the
+// FR_ATR_CTL register, the presence or absence of data in the FPGA
+// transmit fifo selects between two sets of values for each of the 4
+// banks of daughterboard i/o pins.
+//
+// Each daughterboard slot has 3 16-bit registers associated with it:
+// FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
+//
+// FR_ATR_MASK_{0,1,2,3}:
+//
+// These registers determine which of the daugherboard i/o pins are
+// affected by ATR switching. If a bit in the mask is set, the
+// corresponding i/o bit is controlled by ATR, else it's output
+// value comes from the normal i/o pin output register:
+// FR_IO_{0,1,2,3}.
+//
+// FR_ATR_TXVAL_{0,1,2,3}:
+// FR_ATR_RXVAL_{0,1,2,3}:
+//
+// If the Tx fifo contains data, then the bits from TXVAL that are
+// selected by MASK are output. Otherwise, the bits from RXVAL that
+// are selected by MASK are output.
+
+`define FR_ATR_MASK_0 7'd20 // slot 0
+`define FR_ATR_TXVAL_0 7'd21
+`define FR_ATR_RXVAL_0 7'd22
+
+`define FR_ATR_MASK_1 7'd23 // slot 1
+`define FR_ATR_TXVAL_1 7'd24
+`define FR_ATR_RXVAL_1 7'd25
+
+`define FR_ATR_MASK_2 7'd26 // slot 2
+`define FR_ATR_TXVAL_2 7'd27
+`define FR_ATR_RXVAL_2 7'd28
+
+`define FR_ATR_MASK_3 7'd29 // slot 3
+`define FR_ATR_TXVAL_3 7'd30
+`define FR_ATR_RXVAL_3 7'd31
+
+// Clock ticks to delay rising and falling edge of T/R signal
+`define FR_ATR_TX_DELAY 7'd2
+`define FR_ATR_RX_DELAY 7'd3
+
diff --git a/firmware/fx2/common/fpga_regs_standard.h b/firmware/fx2/common/fpga_regs_standard.h
new file mode 100644
index 000000000..7485e2bab
--- /dev/null
+++ b/firmware/fx2/common/fpga_regs_standard.h
@@ -0,0 +1,300 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,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_FPGA_REGS_STANDARD_H
+#define INCLUDED_FPGA_REGS_STANDARD_H
+
+// Register numbers 0 to 31 are reserved for use in fpga_regs_common.h.
+// Registers 64 to 79 are available for custom FPGA builds.
+
+
+// DDC / DUC
+
+#define FR_INTERP_RATE 32 // [1,1024]
+#define FR_DECIM_RATE 33 // [1,256]
+
+// DDC center freq
+
+#define FR_RX_FREQ_0 34
+#define FR_RX_FREQ_1 35
+#define FR_RX_FREQ_2 36
+#define FR_RX_FREQ_3 37
+
+// See below for DDC Starting Phase
+
+// ------------------------------------------------------------------------
+// configure FPGA Rx mux
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// | must be zero | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+//
+// There are a maximum of 4 digital downconverters in the the FPGA.
+// Each DDC has two 16-bit inputs, I and Q, and two 16-bit outputs, I & Q.
+//
+// DDC I inputs are specified by the two bit fields I3, I2, I1 & I0
+//
+// 0 = DDC input is from ADC 0
+// 1 = DDC input is from ADC 1
+// 2 = DDC input is from ADC 2
+// 3 = DDC input is from ADC 3
+//
+// If Z == 1, all DDC Q inputs are set to zero
+// If Z == 0, DDC Q inputs are specified by the two bit fields Q3, Q2, Q1 & Q0
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB. The legal values are 1, 2 or 4, corresponding to 2, 4 or
+// 8 16-bit values.
+
+#define FR_RX_MUX 38
+
+// ------------------------------------------------------------------------
+// configure FPGA Tx Mux.
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// | | DAC3 | DAC2 | DAC1 | DAC0 |0| NCH |
+// +-----------------------------------------------+-------+-+-----+
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB. The legal values are 1 or 2, corresponding to 2 or 4
+// 16-bit values.
+//
+// There are two interpolators with complex inputs and outputs.
+// There are four DACs. (We use the DUC in each AD9862.)
+//
+// Each 4-bit DACx field specifies the source for the DAC and
+// whether or not that DAC is enabled. Each subfield is coded
+// like this:
+//
+// 3 2 1 0
+// +-+-----+
+// |E| N |
+// +-+-----+
+//
+// Where E is set if the DAC is enabled, and N specifies which
+// interpolator output is connected to this DAC.
+//
+// N which interp output
+// --- -------------------
+// 0 chan 0 I
+// 1 chan 0 Q
+// 2 chan 1 I
+// 3 chan 1 Q
+
+#define FR_TX_MUX 39
+
+// ------------------------------------------------------------------------
+// REFCLK control
+//
+// Control whether a reference clock is sent to the daughterboards,
+// and what frequency. The refclk is sent on d'board i/o pin 0.
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------------+-+------------+
+// | Reserved (Must be zero) |E| DIVISOR |
+// +-----------------------------------------------+-+------------+
+
+//
+// Bit 7 -- 1 turns on refclk, 0 allows IO use
+// Bits 6:0 Divider value
+
+#define FR_TX_A_REFCLK 40
+#define FR_RX_A_REFCLK 41
+#define FR_TX_B_REFCLK 42
+#define FR_RX_B_REFCLK 43
+
+# define bmFR_REFCLK_EN 0x80
+# define bmFR_REFCLK_DIVISOR_MASK 0x7f
+
+// ------------------------------------------------------------------------
+// DDC Starting Phase
+
+#define FR_RX_PHASE_0 44
+#define FR_RX_PHASE_1 45
+#define FR_RX_PHASE_2 46
+#define FR_RX_PHASE_3 47
+
+// ------------------------------------------------------------------------
+// Tx data format control register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-------------------------------------------------------+-------+
+// | Reserved (Must be zero) | FMT |
+// +-------------------------------------------------------+-------+
+//
+// FMT values:
+
+#define FR_TX_FORMAT 48
+# define bmFR_TX_FORMAT_16_IQ 0 // 16-bit I, 16-bit Q
+
+// ------------------------------------------------------------------------
+// Rx data format control register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------+-+-+---------+-------+
+// | Reserved (Must be zero) |B|Q| WIDTH | SHIFT |
+// +-----------------------------------------+-+-+---------+-------+
+//
+// FMT values:
+
+#define FR_RX_FORMAT 49
+
+# define bmFR_RX_FORMAT_SHIFT_MASK (0x0f << 0) // arithmetic right shift [0, 15]
+# define bmFR_RX_FORMAT_SHIFT_SHIFT 0
+# define bmFR_RX_FORMAT_WIDTH_MASK (0x1f << 4) // data width in bits [1, 16] (not all valid)
+# define bmFR_RX_FORMAT_WIDTH_SHIFT 4
+# define bmFR_RX_FORMAT_WANT_Q (0x1 << 9) // deliver both I & Q, else just I
+# define bmFR_RX_FORMAT_BYPASS_HB (0x1 << 10) // bypass half-band filter
+
+// The valid combinations currently are:
+//
+// B Q WIDTH SHIFT
+// 0 1 16 0
+// 0 1 8 8
+
+
+// Possible future values of WIDTH = {4, 2, 1}
+// 12 takes a bit more work, since we need to know packet alignment.
+
+// ------------------------------------------------------------------------
+// FIXME register numbers 50 to 63 are available
+
+// ------------------------------------------------------------------------
+// Registers 64 to 95 are reserved for user custom FPGA builds.
+// The standard USRP software will not touch these.
+
+#define FR_USER_0 64
+#define FR_USER_1 65
+#define FR_USER_2 66
+#define FR_USER_3 67
+#define FR_USER_4 68
+#define FR_USER_5 69
+#define FR_USER_6 70
+#define FR_USER_7 71
+#define FR_USER_8 72
+#define FR_USER_9 73
+#define FR_USER_10 74
+#define FR_USER_11 75
+#define FR_USER_12 76
+#define FR_USER_13 77
+#define FR_USER_14 78
+#define FR_USER_15 79
+#define FR_USER_16 80
+#define FR_USER_17 81
+#define FR_USER_18 82
+#define FR_USER_19 83
+#define FR_USER_20 84
+#define FR_USER_21 85
+#define FR_USER_22 86
+#define FR_USER_23 87
+#define FR_USER_24 88
+#define FR_USER_25 89
+#define FR_USER_26 90
+#define FR_USER_27 91
+#define FR_USER_28 92
+#define FR_USER_29 93
+#define FR_USER_30 94
+#define FR_USER_31 95
+
+//Registers needed for multi usrp master/slave configuration
+//
+//Rx Master/slave control register (FR_RX_MASTER_SLAVE = FR_USER_0)
+//
+#define FR_RX_MASTER_SLAVE 64
+#define bitnoFR_RX_SYNC 0
+#define bitnoFR_RX_SYNC_MASTER 1
+#define bitnoFR_RX_SYNC_SLAVE 2
+# define bmFR_RX_SYNC (1 <<bitnoFR_RX_SYNC) //1 If this is a master "sync now" and send sync to slave.
+ // If this is a slave "sync now" (testing purpose only)
+ // Sync is allmost the same as reset (clear all counters and buffers)
+ // except that the io outputs and settings don't get reset (otherwise it couldn't send the sync to the slave)
+ //0 Normal operation
+
+# define bmFR_RX_SYNC_MASTER (1 <<bitnoFR_RX_SYNC_MASTER) //1 This is a rx sync master, output sync_rx on rx_a_io[15]
+ //0 This is not a rx sync master
+# define bmFR_RX_SYNC_SLAVE (1 <<bitnoFR_RX_SYNC_SLAVE) //1 This is a rx sync slave, follow sync_rx on rx_a_io[bitnoFR_RX_SYNC_INPUT_IOPIN]
+ //0 This is not an rx sync slave.
+
+//Caution The master settings will output values on the io lines.
+//They inheritely enable these lines as output. If you have a daughtercard which uses these lines also as output then you will burn your usrp and daughtercard.
+//If you set the slave bits then your usrp won't do anything if you don't connect a master.
+// Rx Master/slave control register
+//
+// The way this is supposed to be used is connecting a (short) 16pin flatcable from an rx daughterboard in RXA master io_rx[8..15] to slave io_rx[8..15] on RXA of slave usrp
+// This can be done with basic_rx boards or dbsrx boards
+//dbsrx: connect master-J25 to slave-J25
+//basic rx: connect J25 to slave-J25
+//CAUTION: pay attention to the lineup of your connector.
+//The red line (pin1) should be at the same side of the daughterboards on master and slave.
+//If you turnaround the cable on one end you will burn your usrp.
+
+//You cannot use a 16pin flatcable if you are using FLEX400 or FLEX2400 daughterboards, since these use a lot of the io pins.
+//You can still link them but you must use only a 2pin or 1pin cable
+//You can also use a 2-wire link. put a 2pin header on io[15],gnd of the master RXA daughterboard and connect it to io15,gnd of the slave RXA db.
+//You can use a cable like the ones found with the leds on the mainbord of a PC.
+//Make sure you don't twist the cable, otherwise you connect the sync output to ground.
+//To be save you could also just use a single wire from master io[15] to slave io[15], but this is not optimal for signal integrity.
+
+
+// Since rx_io[0] can normally be used as a refclk and is not exported on all daughterboards this line
+// still has the refclk function if you use the master/slave setup (it is not touched by the master/slave settings).
+// The master/slave circuitry will only use io pin 15 and does not touch any of the other io pins.
+#define bitnoFR_RX_SYNC_INPUT_IOPIN 15
+#define bmFR_RX_SYNC_INPUT_IOPIN (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+//TODO the output pin is still hardcoded in the verilog code, make it listen to the following define
+#define bitnoFR_RX_SYNC_OUTPUT_IOPIN 15
+#define bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+// =======================================================================
+// READBACK Registers
+// =======================================================================
+
+#define FR_RB_IO_RX_A_IO_TX_A 1 // read back a-side i/o pins
+#define FR_RB_IO_RX_B_IO_TX_B 2 // read back b-side i/o pins
+
+// ------------------------------------------------------------------------
+// FPGA Capability register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------------+-+-----+-+-----+
+// | Reserved (Must be zero) |T|NDUC |R|NDDC |
+// +-----------------------------------------------+-+-----+-+-----+
+//
+// Bottom 4-bits are Rx capabilities
+// Next 4-bits are Tx capabilities
+
+#define FR_RB_CAPS 3
+# define bmFR_RB_CAPS_NDDC_MASK (0x7 << 0) // # of digital down converters 0,1,2,4
+# define bmFR_RB_CAPS_NDDC_SHIFT 0
+# define bmFR_RB_CAPS_RX_HAS_HALFBAND (0x1 << 3)
+# define bmFR_RB_CAPS_NDUC_MASK (0x7 << 4) // # of digital up converters 0,1,2
+# define bmFR_RB_CAPS_NDUC_SHIFT 4
+# define bmFR_RB_CAPS_TX_HAS_HALFBAND (0x1 << 7)
+
+
+#endif /* INCLUDED_FPGA_REGS_STANDARD_H */
diff --git a/firmware/fx2/common/fpga_regs_standard.v b/firmware/fx2/common/fpga_regs_standard.v
new file mode 100644
index 000000000..d09aa6116
--- /dev/null
+++ b/firmware/fx2/common/fpga_regs_standard.v
@@ -0,0 +1,256 @@
+//
+// This file is machine generated from ./fpga_regs_standard.h
+// Do not edit by hand; your edits will be overwritten.
+//
+
+// Register numbers 0 to 31 are reserved for use in fpga_regs_common.h.
+// Registers 64 to 79 are available for custom FPGA builds.
+
+
+// DDC / DUC
+
+`define FR_INTERP_RATE 7'd32 // [1,1024]
+`define FR_DECIM_RATE 7'd33 // [1,256]
+
+// DDC center freq
+
+`define FR_RX_FREQ_0 7'd34
+`define FR_RX_FREQ_1 7'd35
+`define FR_RX_FREQ_2 7'd36
+`define FR_RX_FREQ_3 7'd37
+
+// See below for DDC Starting Phase
+
+// ------------------------------------------------------------------------
+// configure FPGA Rx mux
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// | must be zero | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+//
+// There are a maximum of 4 digital downconverters in the the FPGA.
+// Each DDC has two 16-bit inputs, I and Q, and two 16-bit outputs, I & Q.
+//
+// DDC I inputs are specified by the two bit fields I3, I2, I1 & I0
+//
+// 0 = DDC input is from ADC 0
+// 1 = DDC input is from ADC 1
+// 2 = DDC input is from ADC 2
+// 3 = DDC input is from ADC 3
+//
+// If Z == 1, all DDC Q inputs are set to zero
+// If Z == 0, DDC Q inputs are specified by the two bit fields Q3, Q2, Q1 & Q0
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB. The legal values are 1, 2 or 4, corresponding to 2, 4 or
+// 8 16-bit values.
+
+`define FR_RX_MUX 7'd38
+
+// ------------------------------------------------------------------------
+// configure FPGA Tx Mux.
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// | | DAC3 | DAC2 | DAC1 | DAC0 |0| NCH |
+// +-----------------------------------------------+-------+-+-----+
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB. The legal values are 1 or 2, corresponding to 2 or 4
+// 16-bit values.
+//
+// There are two interpolators with complex inputs and outputs.
+// There are four DACs. (We use the DUC in each AD9862.)
+//
+// Each 4-bit DACx field specifies the source for the DAC and
+// whether or not that DAC is enabled. Each subfield is coded
+// like this:
+//
+// 3 2 1 0
+// +-+-----+
+// |E| N |
+// +-+-----+
+//
+// Where E is set if the DAC is enabled, and N specifies which
+// interpolator output is connected to this DAC.
+//
+// N which interp output
+// --- -------------------
+// 0 chan 0 I
+// 1 chan 0 Q
+// 2 chan 1 I
+// 3 chan 1 Q
+
+`define FR_TX_MUX 7'd39
+
+// ------------------------------------------------------------------------
+// REFCLK control
+//
+// Control whether a reference clock is sent to the daughterboards,
+// and what frequency. The refclk is sent on d'board i/o pin 0.
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------------+-+------------+
+// | Reserved (Must be zero) |E| DIVISOR |
+// +-----------------------------------------------+-+------------+
+
+//
+// Bit 7 -- 1 turns on refclk, 0 allows IO use
+// Bits 6:0 Divider value
+
+`define FR_TX_A_REFCLK 7'd40
+`define FR_RX_A_REFCLK 7'd41
+`define FR_TX_B_REFCLK 7'd42
+`define FR_RX_B_REFCLK 7'd43
+
+
+// ------------------------------------------------------------------------
+// DDC Starting Phase
+
+`define FR_RX_PHASE_0 7'd44
+`define FR_RX_PHASE_1 7'd45
+`define FR_RX_PHASE_2 7'd46
+`define FR_RX_PHASE_3 7'd47
+
+// ------------------------------------------------------------------------
+// Tx data format control register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-------------------------------------------------------+-------+
+// | Reserved (Must be zero) | FMT |
+// +-------------------------------------------------------+-------+
+//
+// FMT values:
+
+`define FR_TX_FORMAT 7'd48
+
+// ------------------------------------------------------------------------
+// Rx data format control register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------+-+-+---------+-------+
+// | Reserved (Must be zero) |B|Q| WIDTH | SHIFT |
+// +-----------------------------------------+-+-+---------+-------+
+//
+// FMT values:
+
+`define FR_RX_FORMAT 7'd49
+
+
+// The valid combinations currently are:
+//
+// B Q WIDTH SHIFT
+// 0 1 16 0
+// 0 1 8 8
+
+
+// Possible future values of WIDTH = {4, 2, 1}
+// 12 takes a bit more work, since we need to know packet alignment.
+
+// ------------------------------------------------------------------------
+// FIXME register numbers 50 to 63 are available
+
+// ------------------------------------------------------------------------
+// Registers 64 to 95 are reserved for user custom FPGA builds.
+// The standard USRP software will not touch these.
+
+`define FR_USER_0 7'd64
+`define FR_USER_1 7'd65
+`define FR_USER_2 7'd66
+`define FR_USER_3 7'd67
+`define FR_USER_4 7'd68
+`define FR_USER_5 7'd69
+`define FR_USER_6 7'd70
+`define FR_USER_7 7'd71
+`define FR_USER_8 7'd72
+`define FR_USER_9 7'd73
+`define FR_USER_10 7'd74
+`define FR_USER_11 7'd75
+`define FR_USER_12 7'd76
+`define FR_USER_13 7'd77
+`define FR_USER_14 7'd78
+`define FR_USER_15 7'd79
+`define FR_USER_16 7'd80
+`define FR_USER_17 7'd81
+`define FR_USER_18 7'd82
+`define FR_USER_19 7'd83
+`define FR_USER_20 7'd84
+`define FR_USER_21 7'd85
+`define FR_USER_22 7'd86
+`define FR_USER_23 7'd87
+`define FR_USER_24 7'd88
+`define FR_USER_25 7'd89
+`define FR_USER_26 7'd90
+`define FR_USER_27 7'd91
+`define FR_USER_28 7'd92
+`define FR_USER_29 7'd93
+`define FR_USER_30 7'd94
+`define FR_USER_31 7'd95
+
+//Registers needed for multi usrp master/slave configuration
+//
+//Rx Master/slave control register (FR_RX_MASTER_SLAVE = FR_USER_0)
+//
+`define FR_RX_MASTER_SLAVE 7'd64
+`define bitnoFR_RX_SYNC 0
+`define bitnoFR_RX_SYNC_MASTER 1
+`define bitnoFR_RX_SYNC_SLAVE 2
+
+
+//Caution The master settings will output values on the io lines.
+//They inheritely enable these lines as output. If you have a daughtercard which uses these lines also as output then you will burn your usrp and daughtercard.
+//If you set the slave bits then your usrp won't do anything if you don't connect a master.
+// Rx Master/slave control register
+//
+// The way this is supposed to be used is connecting a (short) 16pin flatcable from an rx daughterboard in RXA master io_rx[8..15] to slave io_rx[8..15] on RXA of slave usrp
+// This can be done with basic_rx boards or dbsrx boards
+//dbsrx: connect master-J25 to slave-J25
+//basic rx: connect J25 to slave-J25
+//CAUTION: pay attention to the lineup of your connector.
+//The red line (pin1) should be at the same side of the daughterboards on master and slave.
+//If you turnaround the cable on one end you will burn your usrp.
+
+//You cannot use a 16pin flatcable if you are using FLEX400 or FLEX2400 daughterboards, since these use a lot of the io pins.
+//You can still link them but you must use only a 2pin or 1pin cable
+//You can also use a 2-wire link. put a 2pin header on io[15],gnd of the master RXA daughterboard and connect it to io15,gnd of the slave RXA db.
+//You can use a cable like the ones found with the leds on the mainbord of a PC.
+//Make sure you don't twist the cable, otherwise you connect the sync output to ground.
+//To be save you could also just use a single wire from master io[15] to slave io[15], but this is not optimal for signal integrity.
+
+
+// Since rx_io[0] can normally be used as a refclk and is not exported on all daughterboards this line
+// still has the refclk function if you use the master/slave setup (it is not touched by the master/slave settings).
+// The master/slave circuitry will only use io pin 15 and does not touch any of the other io pins.
+`define bitnoFR_RX_SYNC_INPUT_IOPIN 15
+`define bmFR_RX_SYNC_INPUT_IOPIN (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+//TODO the output pin is still hardcoded in the verilog code, make it listen to the following define
+`define bitnoFR_RX_SYNC_OUTPUT_IOPIN 15
+`define bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+// =======================================================================
+// READBACK Registers
+// =======================================================================
+
+`define FR_RB_IO_RX_A_IO_TX_A 7'd1 // read back a-side i/o pins
+`define FR_RB_IO_RX_B_IO_TX_B 7'd2 // read back b-side i/o pins
+
+// ------------------------------------------------------------------------
+// FPGA Capability register
+//
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------------------------------+-+-----+-+-----+
+// | Reserved (Must be zero) |T|NDUC |R|NDDC |
+// +-----------------------------------------------+-+-----+-+-----+
+//
+// Bottom 4-bits are Rx capabilities
+// Next 4-bits are Tx capabilities
+
+`define FR_RB_CAPS 7'd3
+
+
diff --git a/firmware/fx2/common/fx2regs.h b/firmware/fx2/common/fx2regs.h
new file mode 100644
index 000000000..2f210f567
--- /dev/null
+++ b/firmware/fx2/common/fx2regs.h
@@ -0,0 +1,716 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+/*
+//-----------------------------------------------------------------------------
+// File: FX2regs.h
+// Contents: EZ-USB FX2 register declarations and bit mask definitions.
+//
+// $Archive: /USB/Target/Inc/fx2regs.h $
+// $Date$
+// $Revision$
+//
+//
+// Copyright (c) 2000 Cypress Semiconductor, All rights reserved
+//-----------------------------------------------------------------------------
+*/
+
+
+#ifndef FX2REGS_H /* Header Sentry */
+#define FX2REGS_H
+
+#define ALLOCATE_EXTERN // required for "right thing to happen" with fx2regs.h
+
+/*
+//-----------------------------------------------------------------------------
+// FX2 Related Register Assignments
+//-----------------------------------------------------------------------------
+
+// The Ez-USB FX2 registers are defined here. We use FX2regs.h for register
+// address allocation by using "#define ALLOCATE_EXTERN".
+// When using "#define ALLOCATE_EXTERN", you get (for instance):
+// xdata volatile BYTE OUT7BUF[64] _at_ 0x7B40;
+// Such lines are created from FX2.h by using the preprocessor.
+// Incidently, these lines will not generate any space in the resulting hex
+// file; they just bind the symbols to the addresses for compilation.
+// You just need to put "#define ALLOCATE_EXTERN" in your main program file;
+// i.e. fw.c or a stand-alone C source file.
+// Without "#define ALLOCATE_EXTERN", you just get the external reference:
+// extern xdata volatile BYTE OUT7BUF[64] ;// 0x7B40;
+// This uses the concatenation operator "##" to insert a comment "//"
+// to cut off the end of the line, "_at_ 0x7B40;", which is not wanted.
+*/
+
+
+#ifdef ALLOCATE_EXTERN
+#define EXTERN
+#define _AT_(a) at a
+#else
+#define EXTERN extern
+#define _AT_ ;/ ## /
+#endif
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+
+EXTERN xdata _AT_(0xE400) volatile BYTE GPIF_WAVE_DATA[128];
+EXTERN xdata _AT_(0xE480) volatile BYTE RES_WAVEDATA_END ;
+
+// General Configuration
+
+EXTERN xdata _AT_(0xE600) volatile BYTE CPUCS ; // Control & Status
+EXTERN xdata _AT_(0xE601) volatile BYTE IFCONFIG ; // Interface Configuration
+EXTERN xdata _AT_(0xE602) volatile BYTE PINFLAGSAB ; // FIFO FLAGA and FLAGB Assignments
+EXTERN xdata _AT_(0xE603) volatile BYTE PINFLAGSCD ; // FIFO FLAGC and FLAGD Assignments
+EXTERN xdata _AT_(0xE604) volatile BYTE FIFORESET ; // Restore FIFOS to default state
+EXTERN xdata _AT_(0xE605) volatile BYTE BREAKPT ; // Breakpoint
+EXTERN xdata _AT_(0xE606) volatile BYTE BPADDRH ; // Breakpoint Address H
+EXTERN xdata _AT_(0xE607) volatile BYTE BPADDRL ; // Breakpoint Address L
+EXTERN xdata _AT_(0xE608) volatile BYTE UART230 ; // 230 Kbaud clock for T0,T1,T2
+EXTERN xdata _AT_(0xE609) volatile BYTE FIFOPINPOLAR ; // FIFO polarities
+EXTERN xdata _AT_(0xE60A) volatile BYTE REVID ; // Chip Revision
+EXTERN xdata _AT_(0xE60B) volatile BYTE REVCTL ; // Chip Revision Control
+
+// Endpoint Configuration
+
+EXTERN xdata _AT_(0xE610) volatile BYTE EP1OUTCFG ; // Endpoint 1-OUT Configuration
+EXTERN xdata _AT_(0xE611) volatile BYTE EP1INCFG ; // Endpoint 1-IN Configuration
+EXTERN xdata _AT_(0xE612) volatile BYTE EP2CFG ; // Endpoint 2 Configuration
+EXTERN xdata _AT_(0xE613) volatile BYTE EP4CFG ; // Endpoint 4 Configuration
+EXTERN xdata _AT_(0xE614) volatile BYTE EP6CFG ; // Endpoint 6 Configuration
+EXTERN xdata _AT_(0xE615) volatile BYTE EP8CFG ; // Endpoint 8 Configuration
+EXTERN xdata _AT_(0xE618) volatile BYTE EP2FIFOCFG ; // Endpoint 2 FIFO configuration
+EXTERN xdata _AT_(0xE619) volatile BYTE EP4FIFOCFG ; // Endpoint 4 FIFO configuration
+EXTERN xdata _AT_(0xE61A) volatile BYTE EP6FIFOCFG ; // Endpoint 6 FIFO configuration
+EXTERN xdata _AT_(0xE61B) volatile BYTE EP8FIFOCFG ; // Endpoint 8 FIFO configuration
+EXTERN xdata _AT_(0xE620) volatile BYTE EP2AUTOINLENH ; // Endpoint 2 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE621) volatile BYTE EP2AUTOINLENL ; // Endpoint 2 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE622) volatile BYTE EP4AUTOINLENH ; // Endpoint 4 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE623) volatile BYTE EP4AUTOINLENL ; // Endpoint 4 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE624) volatile BYTE EP6AUTOINLENH ; // Endpoint 6 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE625) volatile BYTE EP6AUTOINLENL ; // Endpoint 6 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE626) volatile BYTE EP8AUTOINLENH ; // Endpoint 8 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE627) volatile BYTE EP8AUTOINLENL ; // Endpoint 8 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE630) volatile BYTE EP2FIFOPFH ; // EP2 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE631) volatile BYTE EP2FIFOPFL ; // EP2 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE632) volatile BYTE EP4FIFOPFH ; // EP4 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE633) volatile BYTE EP4FIFOPFL ; // EP4 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE634) volatile BYTE EP6FIFOPFH ; // EP6 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE635) volatile BYTE EP6FIFOPFL ; // EP6 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE636) volatile BYTE EP8FIFOPFH ; // EP8 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE637) volatile BYTE EP8FIFOPFL ; // EP8 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE640) volatile BYTE EP2ISOINPKTS ; // EP2 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE641) volatile BYTE EP4ISOINPKTS ; // EP4 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE642) volatile BYTE EP6ISOINPKTS ; // EP6 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE643) volatile BYTE EP8ISOINPKTS ; // EP8 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE648) volatile BYTE INPKTEND ; // Force IN Packet End
+EXTERN xdata _AT_(0xE649) volatile BYTE OUTPKTEND ; // Force OUT Packet End
+
+// Interrupts
+
+EXTERN xdata _AT_(0xE650) volatile BYTE EP2FIFOIE ; // Endpoint 2 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE651) volatile BYTE EP2FIFOIRQ ; // Endpoint 2 Flag Interrupt Request
+EXTERN xdata _AT_(0xE652) volatile BYTE EP4FIFOIE ; // Endpoint 4 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE653) volatile BYTE EP4FIFOIRQ ; // Endpoint 4 Flag Interrupt Request
+EXTERN xdata _AT_(0xE654) volatile BYTE EP6FIFOIE ; // Endpoint 6 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE655) volatile BYTE EP6FIFOIRQ ; // Endpoint 6 Flag Interrupt Request
+EXTERN xdata _AT_(0xE656) volatile BYTE EP8FIFOIE ; // Endpoint 8 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE657) volatile BYTE EP8FIFOIRQ ; // Endpoint 8 Flag Interrupt Request
+EXTERN xdata _AT_(0xE658) volatile BYTE IBNIE ; // IN-BULK-NAK Interrupt Enable
+EXTERN xdata _AT_(0xE659) volatile BYTE IBNIRQ ; // IN-BULK-NAK interrupt Request
+EXTERN xdata _AT_(0xE65A) volatile BYTE NAKIE ; // Endpoint Ping NAK interrupt Enable
+EXTERN xdata _AT_(0xE65B) volatile BYTE NAKIRQ ; // Endpoint Ping NAK interrupt Request
+EXTERN xdata _AT_(0xE65C) volatile BYTE USBIE ; // USB Int Enables
+EXTERN xdata _AT_(0xE65D) volatile BYTE USBIRQ ; // USB Interrupt Requests
+EXTERN xdata _AT_(0xE65E) volatile BYTE EPIE ; // Endpoint Interrupt Enables
+EXTERN xdata _AT_(0xE65F) volatile BYTE EPIRQ ; // Endpoint Interrupt Requests
+EXTERN xdata _AT_(0xE660) volatile BYTE GPIFIE ; // GPIF Interrupt Enable
+EXTERN xdata _AT_(0xE661) volatile BYTE GPIFIRQ ; // GPIF Interrupt Request
+EXTERN xdata _AT_(0xE662) volatile BYTE USBERRIE ; // USB Error Interrupt Enables
+EXTERN xdata _AT_(0xE663) volatile BYTE USBERRIRQ ; // USB Error Interrupt Requests
+EXTERN xdata _AT_(0xE664) volatile BYTE ERRCNTLIM ; // USB Error counter and limit
+EXTERN xdata _AT_(0xE665) volatile BYTE CLRERRCNT ; // Clear Error Counter EC[3..0]
+EXTERN xdata _AT_(0xE666) volatile BYTE INT2IVEC ; // Interupt 2 (USB) Autovector
+EXTERN xdata _AT_(0xE667) volatile BYTE INT4IVEC ; // Interupt 4 (FIFOS & GPIF) Autovector
+EXTERN xdata _AT_(0xE668) volatile BYTE INTSETUP ; // Interrupt 2&4 Setup
+
+// Input/Output
+
+EXTERN xdata _AT_(0xE670) volatile BYTE PORTACFG ; // I/O PORTA Alternate Configuration
+EXTERN xdata _AT_(0xE671) volatile BYTE PORTCCFG ; // I/O PORTC Alternate Configuration
+EXTERN xdata _AT_(0xE672) volatile BYTE PORTECFG ; // I/O PORTE Alternate Configuration
+EXTERN xdata _AT_(0xE678) volatile BYTE I2CS ; // Control & Status
+EXTERN xdata _AT_(0xE679) volatile BYTE I2DAT ; // Data
+EXTERN xdata _AT_(0xE67A) volatile BYTE I2CTL ; // I2C Control
+EXTERN xdata _AT_(0xE67B) volatile BYTE XAUTODAT1 ; // Autoptr1 MOVX access
+EXTERN xdata _AT_(0xE67C) volatile BYTE XAUTODAT2 ; // Autoptr2 MOVX access
+
+#define EXTAUTODAT1 XAUTODAT1
+#define EXTAUTODAT2 XAUTODAT2
+
+// USB Control
+
+EXTERN xdata _AT_(0xE680) volatile BYTE USBCS ; // USB Control & Status
+EXTERN xdata _AT_(0xE681) volatile BYTE SUSPEND ; // Put chip into suspend
+EXTERN xdata _AT_(0xE682) volatile BYTE WAKEUPCS ; // Wakeup source and polarity
+EXTERN xdata _AT_(0xE683) volatile BYTE TOGCTL ; // Toggle Control
+EXTERN xdata _AT_(0xE684) volatile BYTE USBFRAMEH ; // USB Frame count H
+EXTERN xdata _AT_(0xE685) volatile BYTE USBFRAMEL ; // USB Frame count L
+EXTERN xdata _AT_(0xE686) volatile BYTE MICROFRAME ; // Microframe count, 0-7
+EXTERN xdata _AT_(0xE687) volatile BYTE FNADDR ; // USB Function address
+
+// Endpoints
+
+EXTERN xdata _AT_(0xE68A) volatile BYTE EP0BCH ; // Endpoint 0 Byte Count H
+EXTERN xdata _AT_(0xE68B) volatile BYTE EP0BCL ; // Endpoint 0 Byte Count L
+EXTERN xdata _AT_(0xE68D) volatile BYTE EP1OUTBC ; // Endpoint 1 OUT Byte Count
+EXTERN xdata _AT_(0xE68F) volatile BYTE EP1INBC ; // Endpoint 1 IN Byte Count
+EXTERN xdata _AT_(0xE690) volatile BYTE EP2BCH ; // Endpoint 2 Byte Count H
+EXTERN xdata _AT_(0xE691) volatile BYTE EP2BCL ; // Endpoint 2 Byte Count L
+EXTERN xdata _AT_(0xE694) volatile BYTE EP4BCH ; // Endpoint 4 Byte Count H
+EXTERN xdata _AT_(0xE695) volatile BYTE EP4BCL ; // Endpoint 4 Byte Count L
+EXTERN xdata _AT_(0xE698) volatile BYTE EP6BCH ; // Endpoint 6 Byte Count H
+EXTERN xdata _AT_(0xE699) volatile BYTE EP6BCL ; // Endpoint 6 Byte Count L
+EXTERN xdata _AT_(0xE69C) volatile BYTE EP8BCH ; // Endpoint 8 Byte Count H
+EXTERN xdata _AT_(0xE69D) volatile BYTE EP8BCL ; // Endpoint 8 Byte Count L
+EXTERN xdata _AT_(0xE6A0) volatile BYTE EP0CS ; // Endpoint Control and Status
+EXTERN xdata _AT_(0xE6A1) volatile BYTE EP1OUTCS ; // Endpoint 1 OUT Control and Status
+EXTERN xdata _AT_(0xE6A2) volatile BYTE EP1INCS ; // Endpoint 1 IN Control and Status
+EXTERN xdata _AT_(0xE6A3) volatile BYTE EP2CS ; // Endpoint 2 Control and Status
+EXTERN xdata _AT_(0xE6A4) volatile BYTE EP4CS ; // Endpoint 4 Control and Status
+EXTERN xdata _AT_(0xE6A5) volatile BYTE EP6CS ; // Endpoint 6 Control and Status
+EXTERN xdata _AT_(0xE6A6) volatile BYTE EP8CS ; // Endpoint 8 Control and Status
+EXTERN xdata _AT_(0xE6A7) volatile BYTE EP2FIFOFLGS ; // Endpoint 2 Flags
+EXTERN xdata _AT_(0xE6A8) volatile BYTE EP4FIFOFLGS ; // Endpoint 4 Flags
+EXTERN xdata _AT_(0xE6A9) volatile BYTE EP6FIFOFLGS ; // Endpoint 6 Flags
+EXTERN xdata _AT_(0xE6AA) volatile BYTE EP8FIFOFLGS ; // Endpoint 8 Flags
+EXTERN xdata _AT_(0xE6AB) volatile BYTE EP2FIFOBCH ; // EP2 FIFO total byte count H
+EXTERN xdata _AT_(0xE6AC) volatile BYTE EP2FIFOBCL ; // EP2 FIFO total byte count L
+EXTERN xdata _AT_(0xE6AD) volatile BYTE EP4FIFOBCH ; // EP4 FIFO total byte count H
+EXTERN xdata _AT_(0xE6AE) volatile BYTE EP4FIFOBCL ; // EP4 FIFO total byte count L
+EXTERN xdata _AT_(0xE6AF) volatile BYTE EP6FIFOBCH ; // EP6 FIFO total byte count H
+EXTERN xdata _AT_(0xE6B0) volatile BYTE EP6FIFOBCL ; // EP6 FIFO total byte count L
+EXTERN xdata _AT_(0xE6B1) volatile BYTE EP8FIFOBCH ; // EP8 FIFO total byte count H
+EXTERN xdata _AT_(0xE6B2) volatile BYTE EP8FIFOBCL ; // EP8 FIFO total byte count L
+EXTERN xdata _AT_(0xE6B3) volatile BYTE SUDPTRH ; // Setup Data Pointer high address byte
+EXTERN xdata _AT_(0xE6B4) volatile BYTE SUDPTRL ; // Setup Data Pointer low address byte
+EXTERN xdata _AT_(0xE6B5) volatile BYTE SUDPTRCTL ; // Setup Data Pointer Auto Mode
+EXTERN xdata _AT_(0xE6B8) volatile BYTE SETUPDAT[8] ; // 8 bytes of SETUP data
+
+// GPIF
+
+EXTERN xdata _AT_(0xE6C0) volatile BYTE GPIFWFSELECT ; // Waveform Selector
+EXTERN xdata _AT_(0xE6C1) volatile BYTE GPIFIDLECS ; // GPIF Done, GPIF IDLE drive mode
+EXTERN xdata _AT_(0xE6C2) volatile BYTE GPIFIDLECTL ; // Inactive Bus, CTL states
+EXTERN xdata _AT_(0xE6C3) volatile BYTE GPIFCTLCFG ; // CTL OUT pin drive
+EXTERN xdata _AT_(0xE6C4) volatile BYTE GPIFADRH ; // GPIF Address H
+EXTERN xdata _AT_(0xE6C5) volatile BYTE GPIFADRL ; // GPIF Address L
+
+EXTERN xdata _AT_(0xE6CE) volatile BYTE GPIFTCB3 ; // GPIF Transaction Count Byte 3
+EXTERN xdata _AT_(0xE6CF) volatile BYTE GPIFTCB2 ; // GPIF Transaction Count Byte 2
+EXTERN xdata _AT_(0xE6D0) volatile BYTE GPIFTCB1 ; // GPIF Transaction Count Byte 1
+EXTERN xdata _AT_(0xE6D1) volatile BYTE GPIFTCB0 ; // GPIF Transaction Count Byte 0
+
+#define EP2GPIFTCH GPIFTCB1 // these are here for backwards compatibility
+#define EP2GPIFTCL GPIFTCB0 // before REVE silicon (ie. REVB and REVD)
+#define EP4GPIFTCH GPIFTCB1 // these are here for backwards compatibility
+#define EP4GPIFTCL GPIFTCB0 // before REVE silicon (ie. REVB and REVD)
+#define EP6GPIFTCH GPIFTCB1 // these are here for backwards compatibility
+#define EP6GPIFTCL GPIFTCB0 // before REVE silicon (ie. REVB and REVD)
+#define EP8GPIFTCH GPIFTCB1 // these are here for backwards compatibility
+#define EP8GPIFTCL GPIFTCB0 // before REVE silicon (ie. REVB and REVD)
+
+// EXTERN xdata volatile BYTE EP2GPIFTCH _AT_ 0xE6D0; // EP2 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP2GPIFTCL _AT_ 0xE6D1; // EP2 GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6D2) volatile BYTE EP2GPIFFLGSEL ; // EP2 GPIF Flag select
+EXTERN xdata _AT_(0xE6D3) volatile BYTE EP2GPIFPFSTOP ; // Stop GPIF EP2 transaction on prog. flag
+EXTERN xdata _AT_(0xE6D4) volatile BYTE EP2GPIFTRIG ; // EP2 FIFO Trigger
+// EXTERN xdata volatile BYTE EP4GPIFTCH _AT_ 0xE6D8; // EP4 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP4GPIFTCL _AT_ 0xE6D9; // EP4 GPIF Transactionr Count Low
+EXTERN xdata _AT_(0xE6DA) volatile BYTE EP4GPIFFLGSEL ; // EP4 GPIF Flag select
+EXTERN xdata _AT_(0xE6DB) volatile BYTE EP4GPIFPFSTOP ; // Stop GPIF EP4 transaction on prog. flag
+EXTERN xdata _AT_(0xE6DC) volatile BYTE EP4GPIFTRIG ; // EP4 FIFO Trigger
+// EXTERN xdata volatile BYTE EP6GPIFTCH _AT_ 0xE6E0; // EP6 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP6GPIFTCL _AT_ 0xE6E1; // EP6 GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6E2) volatile BYTE EP6GPIFFLGSEL ; // EP6 GPIF Flag select
+EXTERN xdata _AT_(0xE6E3) volatile BYTE EP6GPIFPFSTOP ; // Stop GPIF EP6 transaction on prog. flag
+EXTERN xdata _AT_(0xE6E4) volatile BYTE EP6GPIFTRIG ; // EP6 FIFO Trigger
+// EXTERN xdata volatile BYTE EP8GPIFTCH _AT_ 0xE6E8; // EP8 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP8GPIFTCL _AT_ 0xE6E9; // EP8GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6EA) volatile BYTE EP8GPIFFLGSEL ; // EP8 GPIF Flag select
+EXTERN xdata _AT_(0xE6EB) volatile BYTE EP8GPIFPFSTOP ; // Stop GPIF EP8 transaction on prog. flag
+EXTERN xdata _AT_(0xE6EC) volatile BYTE EP8GPIFTRIG ; // EP8 FIFO Trigger
+EXTERN xdata _AT_(0xE6F0) volatile BYTE XGPIFSGLDATH ; // GPIF Data H (16-bit mode only)
+EXTERN xdata _AT_(0xE6F1) volatile BYTE XGPIFSGLDATLX ; // Read/Write GPIF Data L & trigger transac
+EXTERN xdata _AT_(0xE6F2) volatile BYTE XGPIFSGLDATLNOX ; // Read GPIF Data L, no transac trigger
+EXTERN xdata _AT_(0xE6F3) volatile BYTE GPIFREADYCFG ; // Internal RDY,Sync/Async, RDY5CFG
+EXTERN xdata _AT_(0xE6F4) volatile BYTE GPIFREADYSTAT ; // RDY pin states
+EXTERN xdata _AT_(0xE6F5) volatile BYTE GPIFABORT ; // Abort GPIF cycles
+
+// UDMA
+
+EXTERN xdata _AT_(0xE6C6) volatile BYTE FLOWSTATE ; //Defines GPIF flow state
+EXTERN xdata _AT_(0xE6C7) volatile BYTE FLOWLOGIC ; //Defines flow/hold decision criteria
+EXTERN xdata _AT_(0xE6C8) volatile BYTE FLOWEQ0CTL ; //CTL states during active flow state
+EXTERN xdata _AT_(0xE6C9) volatile BYTE FLOWEQ1CTL ; //CTL states during hold flow state
+EXTERN xdata _AT_(0xE6CA) volatile BYTE FLOWHOLDOFF ;
+EXTERN xdata _AT_(0xE6CB) volatile BYTE FLOWSTB ; //CTL/RDY Signal to use as master data strobe
+EXTERN xdata _AT_(0xE6CC) volatile BYTE FLOWSTBEDGE ; //Defines active master strobe edge
+EXTERN xdata _AT_(0xE6CD) volatile BYTE FLOWSTBHPERIOD ; //Half Period of output master strobe
+EXTERN xdata _AT_(0xE60C) volatile BYTE GPIFHOLDAMOUNT ; //Data delay shift
+EXTERN xdata _AT_(0xE67D) volatile BYTE UDMACRCH ; //CRC Upper byte
+EXTERN xdata _AT_(0xE67E) volatile BYTE UDMACRCL ; //CRC Lower byte
+EXTERN xdata _AT_(0xE67F) volatile BYTE UDMACRCQUAL ; //UDMA In only, host terminated use only
+
+
+// Debug/Test
+
+EXTERN xdata _AT_(0xE6F8) volatile BYTE DBUG ; // Debug
+EXTERN xdata _AT_(0xE6F9) volatile BYTE TESTCFG ; // Test configuration
+EXTERN xdata _AT_(0xE6FA) volatile BYTE USBTEST ; // USB Test Modes
+EXTERN xdata _AT_(0xE6FB) volatile BYTE CT1 ; // Chirp Test--Override
+EXTERN xdata _AT_(0xE6FC) volatile BYTE CT2 ; // Chirp Test--FSM
+EXTERN xdata _AT_(0xE6FD) volatile BYTE CT3 ; // Chirp Test--Control Signals
+EXTERN xdata _AT_(0xE6FE) volatile BYTE CT4 ; // Chirp Test--Inputs
+
+// Endpoint Buffers
+
+EXTERN xdata _AT_(0xE740) volatile BYTE EP0BUF[64] ; // EP0 IN-OUT buffer
+EXTERN xdata _AT_(0xE780) volatile BYTE EP1OUTBUF[64] ; // EP1-OUT buffer
+EXTERN xdata _AT_(0xE7C0) volatile BYTE EP1INBUF[64] ; // EP1-IN buffer
+EXTERN xdata _AT_(0xF000) volatile BYTE EP2FIFOBUF[1024] ; // 512/1024-byte EP2 buffer (IN or OUT)
+EXTERN xdata _AT_(0xF400) volatile BYTE EP4FIFOBUF[1024] ; // 512 byte EP4 buffer (IN or OUT)
+EXTERN xdata _AT_(0xF800) volatile BYTE EP6FIFOBUF[1024] ; // 512/1024-byte EP6 buffer (IN or OUT)
+EXTERN xdata _AT_(0xFC00) volatile BYTE EP8FIFOBUF[1024] ; // 512 byte EP8 buffer (IN or OUT)
+
+#undef EXTERN
+#undef _AT_
+
+/*-----------------------------------------------------------------------------
+ Special Function Registers (SFRs)
+ The byte registers and bits defined in the following list are based
+ on the Synopsis definition of the 8051 Special Function Registers for EZ-USB.
+ If you modify the register definitions below, please regenerate the file
+ "ezregs.inc" which includes the same basic information for assembly inclusion.
+-----------------------------------------------------------------------------*/
+
+sfr at 0x80 IOA;
+sfr at 0x81 SP;
+sfr at 0x82 DPL;
+sfr at 0x83 DPH;
+sfr at 0x84 DPL1;
+sfr at 0x85 DPH1;
+sfr at 0x86 DPS;
+ /* DPS */
+ sbit at 0x86+0 SEL;
+sfr at 0x87 PCON; /* PCON */
+ //sbit IDLE = 0x87+0;
+ //sbit STOP = 0x87+1;
+ //sbit GF0 = 0x87+2;
+ //sbit GF1 = 0x87+3;
+ //sbit SMOD0 = 0x87+7;
+sfr at 0x88 TCON;
+ /* TCON */
+ sbit at 0x88+0 IT0;
+ sbit at 0x88+1 IE0;
+ sbit at 0x88+2 IT1;
+ sbit at 0x88+3 IE1;
+ sbit at 0x88+4 TR0;
+ sbit at 0x88+5 TF0;
+ sbit at 0x88+6 TR1;
+ sbit at 0x88+7 TF1;
+sfr at 0x89 TMOD;
+ /* TMOD */
+ //sbit M00 = 0x89+0;
+ //sbit M10 = 0x89+1;
+ //sbit CT0 = 0x89+2;
+ //sbit GATE0 = 0x89+3;
+ //sbit M01 = 0x89+4;
+ //sbit M11 = 0x89+5;
+ //sbit CT1 = 0x89+6;
+ //sbit GATE1 = 0x89+7;
+sfr at 0x8A TL0;
+sfr at 0x8B TL1;
+sfr at 0x8C TH0;
+sfr at 0x8D TH1;
+sfr at 0x8E CKCON;
+ /* CKCON */
+ //sbit MD0 = 0x89+0;
+ //sbit MD1 = 0x89+1;
+ //sbit MD2 = 0x89+2;
+ //sbit T0M = 0x89+3;
+ //sbit T1M = 0x89+4;
+ //sbit T2M = 0x89+5;
+// sfr at 0x8F SPC_FNC; // Was WRS in Reg320
+ /* CKCON */
+ //sbit WRS = 0x8F+0;
+sfr at 0x90 IOB;
+sfr at 0x91 EXIF; // EXIF Bit Values differ from Reg320
+ /* EXIF */
+ //sbit USBINT = 0x91+4;
+ //sbit I2CINT = 0x91+5;
+ //sbit IE4 = 0x91+6;
+ //sbit IE5 = 0x91+7;
+sfr at 0x92 MPAGE;
+sfr at 0x98 SCON0;
+ /* SCON0 */
+ sbit at 0x98+0 RI;
+ sbit at 0x98+1 TI;
+ sbit at 0x98+2 RB8;
+ sbit at 0x98+3 TB8;
+ sbit at 0x98+4 REN;
+ sbit at 0x98+5 SM2;
+ sbit at 0x98+6 SM1;
+ sbit at 0x98+7 SM0;
+sfr at 0x99 SBUF0;
+
+sfr at 0x9A APTR1H;
+sfr at 0x9B APTR1L;
+sfr at 0x9C AUTODAT1;
+sfr at 0x9D AUTOPTRH2;
+sfr at 0x9E AUTOPTRL2;
+sfr at 0x9F AUTODAT2;
+sfr at 0xA0 IOC;
+sfr at 0xA1 INT2CLR;
+sfr at 0xA2 INT4CLR;
+
+#define AUTOPTRH1 APTR1H
+#define AUTOPTRL1 APTR1L
+
+sfr at 0xA8 IE;
+ /* IE */
+ sbit at 0xA8+0 EX0;
+ sbit at 0xA8+1 ET0;
+ sbit at 0xA8+2 EX1;
+ sbit at 0xA8+3 ET1;
+ sbit at 0xA8+4 ES0;
+ sbit at 0xA8+5 ET2;
+ sbit at 0xA8+6 ES1;
+ sbit at 0xA8+7 EA;
+
+sfr at 0xAA EP2468STAT;
+ /* EP2468STAT */
+ //sbit EP2E = 0xAA+0;
+ //sbit EP2F = 0xAA+1;
+ //sbit EP4E = 0xAA+2;
+ //sbit EP4F = 0xAA+3;
+ //sbit EP6E = 0xAA+4;
+ //sbit EP6F = 0xAA+5;
+ //sbit EP8E = 0xAA+6;
+ //sbit EP8F = 0xAA+7;
+
+sfr at 0xAB EP24FIFOFLGS;
+sfr at 0xAC EP68FIFOFLGS;
+sfr at 0xAF AUTOPTRSETUP;
+ /* AUTOPTRSETUP */
+ // sbit EXTACC = 0xAF+0;
+ // sbit APTR1FZ = 0xAF+1;
+ // sbit APTR2FZ = 0xAF+2;
+
+sfr at 0xB0 IOD;
+sfr at 0xB1 IOE;
+sfr at 0xB2 OEA;
+sfr at 0xB3 OEB;
+sfr at 0xB4 OEC;
+sfr at 0xB5 OED;
+sfr at 0xB6 OEE;
+
+sfr at 0xB8 IP;
+ /* IP */
+ sbit at 0xB8+0 PX0;
+ sbit at 0xB8+1 PT0;
+ sbit at 0xB8+2 PX1;
+ sbit at 0xB8+3 PT1;
+ sbit at 0xB8+4 PS0;
+ sbit at 0xB8+5 PT2;
+ sbit at 0xB8+6 PS1;
+
+sfr at 0xBA EP01STAT;
+sfr at 0xBB GPIFTRIG;
+
+sfr at 0xBD GPIFSGLDATH;
+sfr at 0xBE GPIFSGLDATLX;
+sfr at 0xBF GPIFSGLDATLNOX;
+
+sfr at 0xC0 SCON1;
+ /* SCON1 */
+ sbit at 0xC0+0 RI1;
+ sbit at 0xC0+1 TI1;
+ sbit at 0xC0+2 RB81;
+ sbit at 0xC0+3 TB81;
+ sbit at 0xC0+4 REN1;
+ sbit at 0xC0+5 SM21;
+ sbit at 0xC0+6 SM11;
+ sbit at 0xC0+7 SM01;
+sfr at 0xC1 SBUF1;
+sfr at 0xC8 T2CON;
+ /* T2CON */
+ sbit at 0xC8+0 CP_RL2;
+ sbit at 0xC8+1 C_T2;
+ sbit at 0xC8+2 TR2;
+ sbit at 0xC8+3 EXEN2;
+ sbit at 0xC8+4 TCLK;
+ sbit at 0xC8+5 RCLK;
+ sbit at 0xC8+6 EXF2;
+ sbit at 0xC8+7 TF2;
+sfr at 0xCA RCAP2L;
+sfr at 0xCB RCAP2H;
+sfr at 0xCC TL2;
+sfr at 0xCD TH2;
+sfr at 0xD0 PSW;
+ /* PSW */
+ sbit at 0xD0+0 P;
+ sbit at 0xD0+1 FL;
+ sbit at 0xD0+2 OV;
+ sbit at 0xD0+3 RS0;
+ sbit at 0xD0+4 RS1;
+ sbit at 0xD0+5 F0;
+ sbit at 0xD0+6 AC;
+ sbit at 0xD0+7 CY;
+sfr at 0xD8 EICON; // Was WDCON in DS80C320 EICON; Bit Values differ from Reg320
+ /* EICON */
+ sbit at 0xD8+3 INT6;
+ sbit at 0xD8+4 RESI;
+ sbit at 0xD8+5 ERESI;
+ sbit at 0xD8+7 SMOD1;
+sfr at 0xE0 ACC;
+sfr at 0xE8 EIE; // EIE Bit Values differ from Reg320
+ /* EIE */
+ sbit at 0xE8+0 EIUSB;
+ sbit at 0xE8+1 EI2C;
+ sbit at 0xE8+2 EIEX4;
+ sbit at 0xE8+3 EIEX5;
+ sbit at 0xE8+4 EIEX6;
+sfr at 0xF0 B;
+sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
+ /* EIP */
+ sbit at 0xF8+0 PUSB;
+ sbit at 0xF8+1 PI2C;
+ sbit at 0xF8+2 EIPX4;
+ sbit at 0xF8+3 EIPX5;
+ sbit at 0xF8+4 EIPX6;
+
+/*-----------------------------------------------------------------------------
+ Bit Masks
+-----------------------------------------------------------------------------*/
+
+#define bmBIT0 1
+#define bmBIT1 2
+#define bmBIT2 4
+#define bmBIT3 8
+#define bmBIT4 16
+#define bmBIT5 32
+#define bmBIT6 64
+#define bmBIT7 128
+
+/* CPU Control & Status Register (CPUCS) */
+#define bmPRTCSTB bmBIT5
+#define bmCLKSPD (bmBIT4 | bmBIT3)
+#define bmCLKSPD1 bmBIT4
+#define bmCLKSPD0 bmBIT3
+#define bmCLKINV bmBIT2
+#define bmCLKOE bmBIT1
+#define bm8051RES bmBIT0
+/* Port Alternate Configuration Registers */
+/* Port A (PORTACFG) */
+#define bmFLAGD bmBIT7
+#define bmINT1 bmBIT1
+#define bmINT0 bmBIT0
+/* Port C (PORTCCFG) */
+#define bmGPIFA7 bmBIT7
+#define bmGPIFA6 bmBIT6
+#define bmGPIFA5 bmBIT5
+#define bmGPIFA4 bmBIT4
+#define bmGPIFA3 bmBIT3
+#define bmGPIFA2 bmBIT2
+#define bmGPIFA1 bmBIT1
+#define bmGPIFA0 bmBIT0
+/* Port E (PORTECFG) */
+#define bmGPIFA8 bmBIT7
+#define bmT2EX bmBIT6
+#define bmINT6 bmBIT5
+#define bmRXD1OUT bmBIT4
+#define bmRXD0OUT bmBIT3
+#define bmT2OUT bmBIT2
+#define bmT1OUT bmBIT1
+#define bmT0OUT bmBIT0
+
+/* I2C Control & Status Register (I2CS) */
+#define bmSTART bmBIT7
+#define bmSTOP bmBIT6
+#define bmLASTRD bmBIT5
+#define bmID (bmBIT4 | bmBIT3)
+#define bmBERR bmBIT2
+#define bmACK bmBIT1
+#define bmDONE bmBIT0
+/* I2C Control Register (I2CTL) */
+#define bmSTOPIE bmBIT1
+#define bm400KHZ bmBIT0
+/* Interrupt 2 (USB) Autovector Register (INT2IVEC) */
+#define bmIV4 bmBIT6
+#define bmIV3 bmBIT5
+#define bmIV2 bmBIT4
+#define bmIV1 bmBIT3
+#define bmIV0 bmBIT2
+/* USB Interrupt Request & Enable Registers (USBIE/USBIRQ) */
+#define bmEP0ACK bmBIT6
+#define bmHSGRANT bmBIT5
+#define bmURES bmBIT4
+#define bmSUSP bmBIT3
+#define bmSUTOK bmBIT2
+#define bmSOF bmBIT1
+#define bmSUDAV bmBIT0
+/* Breakpoint register (BREAKPT) */
+#define bmBREAK bmBIT3
+#define bmBPPULSE bmBIT2
+#define bmBPEN bmBIT1
+/* Interrupt 2 & 4 Setup (INTSETUP) */
+#define bmAV2EN bmBIT3
+#define bmINT4IN bmBIT1
+#define bmAV4EN bmBIT0
+/* USB Control & Status Register (USBCS) */
+#define bmHSM bmBIT7
+#define bmDISCON bmBIT3
+#define bmNOSYNSOF bmBIT2
+#define bmRENUM bmBIT1
+#define bmSIGRESUME bmBIT0
+/* Wakeup Control and Status Register (WAKEUPCS) */
+#define bmWU2 bmBIT7
+#define bmWU bmBIT6
+#define bmWU2POL bmBIT5
+#define bmWUPOL bmBIT4
+#define bmDPEN bmBIT2
+#define bmWU2EN bmBIT1
+#define bmWUEN bmBIT0
+/* End Point 0 Control & Status Register (EP0CS) */
+#define bmHSNAK bmBIT7
+/* End Point 0-1 Control & Status Registers (EP0CS/EP1OUTCS/EP1INCS) */
+#define bmEPBUSY bmBIT1
+#define bmEPSTALL bmBIT0
+/* End Point 2-8 Control & Status Registers (EP2CS/EP4CS/EP6CS/EP8CS) */
+#define bmNPAK (bmBIT6 | bmBIT5 | bmBIT4)
+#define bmEPFULL bmBIT3
+#define bmEPEMPTY bmBIT2
+/* Endpoint Status (EP2468STAT) SFR bits */
+#define bmEP8FULL bmBIT7
+#define bmEP8EMPTY bmBIT6
+#define bmEP6FULL bmBIT5
+#define bmEP6EMPTY bmBIT4
+#define bmEP4FULL bmBIT3
+#define bmEP4EMPTY bmBIT2
+#define bmEP2FULL bmBIT1
+#define bmEP2EMPTY bmBIT0
+/* SETUP Data Pointer Auto Mode (SUDPTRCTL) */
+#define bmSDPAUTO bmBIT0
+/* Endpoint Data Toggle Control (TOGCTL) */
+#define bmQUERYTOGGLE bmBIT7
+#define bmSETTOGGLE bmBIT6
+#define bmRESETTOGGLE bmBIT5
+#define bmTOGCTLEPMASK bmBIT3 | bmBIT2 | bmBIT1 | bmBIT0
+/* IBN (In Bulk Nak) enable and request bits (IBNIE/IBNIRQ) */
+#define bmEP8IBN bmBIT5
+#define bmEP6IBN bmBIT4
+#define bmEP4IBN bmBIT3
+#define bmEP2IBN bmBIT2
+#define bmEP1IBN bmBIT1
+#define bmEP0IBN bmBIT0
+
+/* PING-NAK enable and request bits (NAKIE/NAKIRQ) */
+#define bmEP8PING bmBIT7
+#define bmEP6PING bmBIT6
+#define bmEP4PING bmBIT5
+#define bmEP2PING bmBIT4
+#define bmEP1PING bmBIT3
+#define bmEP0PING bmBIT2
+#define bmIBN bmBIT0
+
+/* Interface Configuration bits (IFCONFIG) */
+#define bmIFCLKSRC bmBIT7 // set == INTERNAL
+#define bm3048MHZ bmBIT6 // set == 48 MHz
+#define bmIFCLKOE bmBIT5
+#define bmIFCLKPOL bmBIT4
+#define bmASYNC bmBIT3
+#define bmGSTATE bmBIT2
+#define bmIFCFG1 bmBIT1
+#define bmIFCFG0 bmBIT0
+#define bmIFCFGMASK (bmIFCFG0 | bmIFCFG1)
+#define bmIFGPIF bmIFCFG1
+
+/* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */
+#define bmINFM bmBIT6
+#define bmOEP bmBIT5
+#define bmAUTOOUT bmBIT4
+#define bmAUTOIN bmBIT3
+#define bmZEROLENIN bmBIT2
+// must be zero bmBIT1
+#define bmWORDWIDE bmBIT0
+
+/*
+ * Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specific features
+ */
+#define bmNOAUTOARM bmBIT1 // these don't match the docs
+#define bmSKIPCOMMIT bmBIT0 // these don't match the docs
+
+#define bmDYN_OUT bmBIT1 // these do...
+#define bmENH_PKT bmBIT0
+
+
+/* Fifo Reset bits (FIFORESET) */
+#define bmNAKALL bmBIT7
+
+/* Endpoint Configuration (EPxCFG) */
+#define bmVALID bmBIT7
+#define bmIN bmBIT6
+#define bmTYPE1 bmBIT5
+#define bmTYPE0 bmBIT4
+#define bmISOCHRONOUS bmTYPE0
+#define bmBULK bmTYPE1
+#define bmINTERRUPT (bmTYPE1 | bmTYPE0)
+#define bm1KBUF bmBIT3
+#define bmBUF1 bmBIT1
+#define bmBUF0 bmBIT0
+#define bmQUADBUF 0
+#define bmINVALIDBUF bmBUF0
+#define bmDOUBLEBUF bmBUF1
+#define bmTRIPLEBUF (bmBUF1 | bmBUF0)
+
+/* OUTPKTEND */
+#define bmSKIP bmBIT7 // low 4 bits specify which end point
+
+/* GPIFTRIG defs */
+#define bmGPIF_IDLE bmBIT7 // status bit
+
+#define bmGPIF_EP2_START 0
+#define bmGPIF_EP4_START 1
+#define bmGPIF_EP6_START 2
+#define bmGPIF_EP8_START 3
+#define bmGPIF_READ bmBIT2
+#define bmGPIF_WRITE 0
+
+/* EXIF bits */
+#define bmEXIF_USBINT bmBIT4
+#define bmEXIF_I2CINT bmBIT5
+#define bmEXIF_IE4 bmBIT6
+#define bmEXIF_IE5 bmBIT7
+
+
+#endif /* FX2REGS_H */
diff --git a/firmware/fx2/common/fx2utils.c b/firmware/fx2/common/fx2utils.c
new file mode 100644
index 000000000..64ffcc896
--- /dev/null
+++ b/firmware/fx2/common/fx2utils.c
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include "fx2utils.h"
+#include "fx2regs.h"
+#include "delay.h"
+
+void
+fx2_stall_ep0 (void)
+{
+ EP0CS |= bmEPSTALL;
+}
+
+void
+fx2_reset_data_toggle (unsigned char ep)
+{
+ TOGCTL = ((ep & 0x80) >> 3 | (ep & 0x0f));
+ TOGCTL |= bmRESETTOGGLE;
+}
+
+void
+fx2_renumerate (void)
+{
+ USBCS |= bmDISCON | bmRENUM;
+
+ // mdelay (1500); // FIXME why 1.5 seconds?
+ mdelay (250); // FIXME why 1.5 seconds?
+
+ USBIRQ = 0xff; // clear any pending USB irqs...
+ EPIRQ = 0xff; // they're from before the renumeration
+
+ EXIF &= ~bmEXIF_USBINT;
+
+ USBCS &= ~bmDISCON; // reconnect USB
+}
diff --git a/firmware/fx2/common/fx2utils.h b/firmware/fx2/common/fx2utils.h
new file mode 100644
index 000000000..b184dec27
--- /dev/null
+++ b/firmware/fx2/common/fx2utils.h
@@ -0,0 +1,31 @@
+/* -*- c -*- */
+/*
+ * 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.
+ */
+#ifndef _FX2UTILS_H_
+#define _FX2UTILS_H_
+
+void fx2_stall_ep0 (void);
+void fx2_reset_data_toggle (unsigned char ep);
+void fx2_renumerate (void);
+
+
+
+#endif /* _FX2UTILS_H_ */
diff --git a/firmware/fx2/common/i2c.c b/firmware/fx2/common/i2c.c
new file mode 100644
index 000000000..0f238b5cf
--- /dev/null
+++ b/firmware/fx2/common/i2c.c
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include "i2c.h"
+#include "fx2regs.h"
+#include <string.h>
+
+
+// issue a stop bus cycle and wait for completion
+
+
+// returns non-zero if successful, else 0
+unsigned char
+i2c_read (unsigned char addr, xdata unsigned char *buf, unsigned char len)
+{
+ volatile unsigned char junk;
+
+ if (len == 0) // reading zero bytes always works
+ return 1;
+
+ while (I2CS & bmSTOP) // wait for stop to clear
+ ;
+
+ I2CS = bmSTART;
+ I2DAT = (addr << 1) | 1; // write address and direction (1's the read bit)
+
+ while ((I2CS & bmDONE) == 0)
+ ;
+
+ if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...
+ goto fail;
+
+ if (len == 1)
+ I2CS |= bmLASTRD;
+
+ junk = I2DAT; // trigger the first read cycle
+
+ while (--len != 0){
+ while ((I2CS & bmDONE) == 0)
+ ;
+
+ if (I2CS & bmBERR)
+ goto fail;
+
+ if (len == 1)
+ I2CS |= bmLASTRD;
+
+ *buf++ = I2DAT; // get data, trigger another read
+ }
+
+ // wait for final byte
+
+ while ((I2CS & bmDONE) == 0)
+ ;
+
+ if (I2CS & bmBERR)
+ goto fail;
+
+ I2CS |= bmSTOP;
+ *buf = I2DAT;
+
+ return 1;
+
+ fail:
+ I2CS |= bmSTOP;
+ return 0;
+}
+
+
+
+// returns non-zero if successful, else 0
+unsigned char
+i2c_write (unsigned char addr, xdata const unsigned char *buf, unsigned char len)
+{
+ while (I2CS & bmSTOP) // wait for stop to clear
+ ;
+
+ I2CS = bmSTART;
+ I2DAT = (addr << 1) | 0; // write address and direction (0's the write bit)
+
+ while ((I2CS & bmDONE) == 0)
+ ;
+
+ if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...
+ goto fail;
+
+ while (len > 0){
+ I2DAT = *buf++;
+ len--;
+
+ while ((I2CS & bmDONE) == 0)
+ ;
+
+ if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...
+ goto fail;
+ }
+
+ I2CS |= bmSTOP;
+ return 1;
+
+ fail:
+ I2CS |= bmSTOP;
+ return 0;
+}
diff --git a/firmware/fx2/common/i2c.h b/firmware/fx2/common/i2c.h
new file mode 100644
index 000000000..273526dad
--- /dev/null
+++ b/firmware/fx2/common/i2c.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+// returns non-zero if successful, else 0
+unsigned char i2c_read (unsigned char addr, xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char i2c_write (unsigned char addr, xdata const unsigned char *buf, unsigned char len);
+
+#endif /* _I2C_H_ */
diff --git a/firmware/fx2/common/init_gpif.c b/firmware/fx2/common/init_gpif.c
new file mode 100644
index 000000000..edde919be
--- /dev/null
+++ b/firmware/fx2/common/init_gpif.c
@@ -0,0 +1,59 @@
+/*
+ * 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"
+
+// These are the tables generated by the Cypress GPIF Designer
+
+extern const char WaveData[128];
+extern const char FlowStates[36];
+extern const char InitData[7];
+
+// The tool is kind of screwed up, in that it doesn't configure some
+// of the ports correctly. We just use their tables and handle the
+// initialization ourselves. They also declare that their static
+// initialized data is in xdata, which screws us too.
+
+void
+init_gpif (void)
+{
+ // we've already setup IFCONFIG before calling this...
+
+ GPIFABORT = 0xFF; // abort any waveforms pending
+ SYNCDELAY;
+
+ GPIFREADYCFG = InitData[ 0 ];
+ GPIFCTLCFG = InitData[ 1 ];
+ GPIFIDLECS = InitData[ 2 ];
+ GPIFIDLECTL = InitData[ 3 ];
+ // Hmmm, what's InitData[ 4 ] ...
+ GPIFWFSELECT = InitData[ 5 ];
+ // GPIFREADYSTAT = InitData[ 6 ]; // I think this register is read only...
+
+ {
+ BYTE i;
+
+ for (i = 0; i < 128; i++){
+ GPIF_WAVE_DATA[i] = WaveData[i];
+ }
+ }
+
+ FLOWSTATE = 0; /* ensure it's off */
+}
diff --git a/firmware/fx2/common/isr.c b/firmware/fx2/common/isr.c
new file mode 100644
index 000000000..05412daf5
--- /dev/null
+++ b/firmware/fx2/common/isr.c
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include "isr.h"
+#include "fx2regs.h"
+#include "syncdelay.h"
+
+extern xdata unsigned char _standard_interrupt_vector[];
+extern xdata unsigned char _usb_autovector[];
+extern xdata unsigned char _fifo_gpif_autovector[];
+
+#define LJMP_OPCODE 0x02
+
+/*
+ * Hook standard interrupt vector.
+ *
+ * vector_number is from the SV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void
+hook_sv (unsigned char vector_number, unsigned short addr)
+{
+ bit t;
+
+ // sanity checks
+
+ if (vector_number < SV_MIN || vector_number > SV_MAX)
+ return;
+
+ if ((vector_number & 0x0f) != 0x03 && (vector_number & 0x0f) != 0x0b)
+ return;
+
+ t = EA;
+ EA = 0;
+ _standard_interrupt_vector[vector_number] = LJMP_OPCODE;
+ _standard_interrupt_vector[vector_number + 1] = addr >> 8;
+ _standard_interrupt_vector[vector_number + 2] = addr & 0xff;
+ EA = t;
+}
+
+/*
+ * Hook usb interrupt vector.
+ *
+ * vector_number is from the UV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void
+hook_uv (unsigned char vector_number, unsigned short addr)
+{
+ bit t;
+
+ // sanity checks
+
+ if (vector_number < UV_MIN || vector_number > UV_MAX)
+ return;
+
+ if ((vector_number & 0x3) != 0)
+ return;
+
+ t = EA;
+ EA = 0;
+ _usb_autovector[vector_number] = LJMP_OPCODE;
+ _usb_autovector[vector_number + 1] = addr >> 8;
+ _usb_autovector[vector_number + 2] = addr & 0xff;
+ EA = t;
+}
+
+/*
+ * Hook fifo/gpif interrupt vector.
+ *
+ * vector_number is from the FGV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void
+hook_fgv (unsigned char vector_number, unsigned short addr)
+{
+ bit t;
+
+ // sanity checks
+
+ if (vector_number < FGV_MIN || vector_number > FGV_MAX)
+ return;
+
+ if ((vector_number & 0x3) != 0)
+ return;
+
+ t = EA;
+ EA = 0;
+ _fifo_gpif_autovector[vector_number] = LJMP_OPCODE;
+ _fifo_gpif_autovector[vector_number + 1] = addr >> 8;
+ _fifo_gpif_autovector[vector_number + 2] = addr & 0xff;
+ EA = t;
+}
+
+/*
+ * One time call to enable autovectoring for both USB and FIFO/GPIF.
+ *
+ * This disables all USB and FIFO/GPIF interrupts and clears
+ * any pending interrupts too. It leaves the master USB and FIFO/GPIF
+ * interrupts enabled.
+ */
+void
+setup_autovectors (void)
+{
+ // disable master usb and fifo/gpif interrupt enables
+ EIUSB = 0;
+ EIEX4 = 0;
+
+ hook_sv (SV_INT_2, (unsigned short) _usb_autovector);
+ hook_sv (SV_INT_4, (unsigned short) _fifo_gpif_autovector);
+
+ // disable all fifo interrupt enables
+ SYNCDELAY;
+ EP2FIFOIE = 0; SYNCDELAY;
+ EP4FIFOIE = 0; SYNCDELAY;
+ EP6FIFOIE = 0; SYNCDELAY;
+ EP8FIFOIE = 0; SYNCDELAY;
+
+ // clear all pending fifo irqs
+ EP2FIFOIRQ = 0xff; SYNCDELAY;
+ EP4FIFOIRQ = 0xff; SYNCDELAY;
+ EP6FIFOIRQ = 0xff; SYNCDELAY;
+ EP8FIFOIRQ = 0xff; SYNCDELAY;
+
+ IBNIE = 0;
+ IBNIRQ = 0xff;
+ NAKIE = 0;
+ NAKIRQ = 0xff;
+ USBIE = 0;
+ USBIRQ = 0xff;
+ EPIE = 0;
+ EPIRQ = 0xff;
+ SYNCDELAY; GPIFIE = 0;
+ SYNCDELAY; GPIFIRQ = 0xff;
+ USBERRIE = 0;
+ USBERRIRQ = 0xff;
+ CLRERRCNT = 0;
+
+ INTSETUP = bmAV2EN | bmAV4EN | bmINT4IN;
+
+ // clear master irq's for usb and fifo/gpif
+ EXIF &= ~bmEXIF_USBINT;
+ EXIF &= ~bmEXIF_IE4;
+
+ // enable master usb and fifo/gpif interrrupts
+ EIUSB = 1;
+ EIEX4 = 1;
+}
diff --git a/firmware/fx2/common/isr.h b/firmware/fx2/common/isr.h
new file mode 100644
index 000000000..856532890
--- /dev/null
+++ b/firmware/fx2/common/isr.h
@@ -0,0 +1,172 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _ISR_H_
+#define _ISR_H_
+
+/*
+ * ----------------------------------------------------------------
+ * routines for managing interrupt services routines
+ * ----------------------------------------------------------------
+ */
+
+/*
+ * The FX2 has three discrete sets of interrupt vectors.
+ * The first set is the standard 8051 vector (13 8-byte entries).
+ * The second set is USB interrupt autovector (32 4-byte entries).
+ * The third set is the FIFO/GPIF autovector (14 4-byte entries).
+ *
+ * Since all the code we're running in the FX2 is ram based, we
+ * forego the typical "initialize the interrupt vectors at link time"
+ * strategy, in favor of calls at run time that install the correct
+ * pointers to functions.
+ */
+
+/*
+ * Standard Vector numbers
+ */
+
+#define SV_INT_0 0x03
+#define SV_TIMER_0 0x0b
+#define SV_INT_1 0x13
+#define SV_TIMER_1 0x1b
+#define SV_SERIAL_0 0x23
+#define SV_TIMER_2 0x2b
+#define SV_RESUME 0x33
+#define SV_SERIAL_1 0x3b
+#define SV_INT_2 0x43 // (INT_2) points at USB autovector
+#define SV_I2C 0x4b
+#define SV_INT_4 0x53 // (INT_4) points at FIFO/GPIF autovector
+#define SV_INT_5 0x5b
+#define SV_INT_6 0x63
+
+#define SV_MIN SV_INT_0
+#define SV_MAX SV_INT_6
+
+/*
+ * USB Auto Vector numbers
+ */
+
+#define UV_SUDAV 0x00
+#define UV_SOF 0x04
+#define UV_SUTOK 0x08
+#define UV_SUSPEND 0x0c
+#define UV_USBRESET 0x10
+#define UV_HIGHSPEED 0x14
+#define UV_EP0ACK 0x18
+#define UV_SPARE_1C 0x1c
+#define UV_EP0IN 0x20
+#define UV_EP0OUT 0x24
+#define UV_EP1IN 0x28
+#define UV_EP1OUT 0x2c
+#define UV_EP2 0x30
+#define UV_EP4 0x34
+#define UV_EP6 0x38
+#define UV_EP8 0x3c
+#define UV_IBN 0x40
+#define UV_SPARE_44 0x44
+#define UV_EP0PINGNAK 0x48
+#define UV_EP1PINGNAK 0x4c
+#define UV_EP2PINGNAK 0x50
+#define UV_EP4PINGNAK 0x54
+#define UV_EP6PINGNAK 0x58
+#define UV_EP8PINGNAK 0x5c
+#define UV_ERRLIMIT 0x60
+#define UV_SPARE_64 0x64
+#define UV_SPARE_68 0x68
+#define UV_SPARE_6C 0x6c
+#define UV_EP2ISOERR 0x70
+#define UV_EP4ISOERR 0x74
+#define UV_EP6ISOERR 0x78
+#define UV_EP8ISOERR 0x7c
+
+#define UV_MIN UV_SUDAV
+#define UV_MAX UV_EP8ISOERR
+
+/*
+ * FIFO/GPIF Auto Vector numbers
+ */
+
+#define FGV_EP2PF 0x00
+#define FGV_EP4PF 0x04
+#define FGV_EP6PF 0x08
+#define FGV_EP8PF 0x0c
+#define FGV_EP2EF 0x10
+#define FGV_EP4EF 0x14
+#define FGV_EP6EF 0x18
+#define FGV_EP8EF 0x1c
+#define FGV_EP2FF 0x20
+#define FGV_EP4FF 0x24
+#define FGV_EP6FF 0x28
+#define FGV_EP8FF 0x2c
+#define FGV_GPIFDONE 0x30
+#define FGV_GPIFWF 0x34
+
+#define FGV_MIN FGV_EP2PF
+#define FGV_MAX FGV_GPIFWF
+
+
+/*
+ * Hook standard interrupt vector.
+ *
+ * vector_number is from the SV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_sv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * Hook usb interrupt vector.
+ *
+ * vector_number is from the UV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_uv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * Hook fifo/gpif interrupt vector.
+ *
+ * vector_number is from the FGV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_fgv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * One time call to enable autovectoring for both USB and FIFO/GPIF
+ */
+void setup_autovectors (void);
+
+
+/*
+ * Must be called in each usb interrupt handler
+ */
+#define clear_usb_irq() \
+ EXIF &= ~bmEXIF_USBINT; \
+ INT2CLR = 0
+
+/*
+ * Must be calledin each fifo/gpif interrupt handler
+ */
+#define clear_fifo_gpif_irq() \
+ EXIF &= ~bmEXIF_IE4; \
+ INT4CLR = 0
+
+#endif /* _ISR_H_ */
diff --git a/firmware/fx2/common/spi.c b/firmware/fx2/common/spi.c
new file mode 100644
index 000000000..0c4f63d5a
--- /dev/null
+++ b/firmware/fx2/common/spi.c
@@ -0,0 +1,472 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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 "spi.h"
+#include "usrp_regs.h"
+
+static void
+setup_enables (unsigned char enables)
+{
+ // Software eanbles are active high.
+ // Hardware enables are active low.
+
+ // Uhh, the CODECs are active low, but the FPGA is active high...
+ enables ^= SPI_ENABLE_FPGA;
+
+ // KLUDGE: This code is fragile, but reasonably fast...
+ // low three bits of enables go into port A
+ USRP_PA = USRP_PA | (0x7 << 3); // disable FPGA, CODEC_A, CODEC_B
+ USRP_PA ^= (enables & 0x7) << 3; // enable specified devs
+
+ // high four bits of enables go into port E
+ USRP_PE = USRP_PE | (0xf << 4); // disable TX_A, RX_A, TX_B, RX_B
+ USRP_PE ^= (enables & 0xf0); // enable specified devs
+}
+
+#define disable_all() setup_enables (0)
+
+void
+init_spi (void)
+{
+ disable_all (); /* disable all devs */
+ bitS_OUT = 0; /* idle state has CLK = 0 */
+}
+
+#if 0
+static unsigned char
+count_bits8 (unsigned char v)
+{
+ static unsigned char count4[16] = {
+ 0, // 0
+ 1, // 1
+ 1, // 2
+ 2, // 3
+ 1, // 4
+ 2, // 5
+ 2, // 6
+ 3, // 7
+ 1, // 8
+ 2, // 9
+ 2, // a
+ 3, // b
+ 2, // c
+ 3, // d
+ 3, // e
+ 4 // f
+ };
+ return count4[v & 0xf] + count4[(v >> 4) & 0xf];
+}
+
+#else
+
+static unsigned char
+count_bits8 (unsigned char v)
+{
+ unsigned char count = 0;
+ if (v & (1 << 0)) count++;
+ if (v & (1 << 1)) count++;
+ if (v & (1 << 2)) count++;
+ if (v & (1 << 3)) count++;
+ if (v & (1 << 4)) count++;
+ if (v & (1 << 5)) count++;
+ if (v & (1 << 6)) count++;
+ if (v & (1 << 7)) count++;
+ return count;
+}
+#endif
+
+static void
+write_byte_msb (unsigned char v);
+
+unsigned char
+transact_byte_msb (unsigned char v);
+
+static void
+write_bytes_msb (const xdata unsigned char *buf, unsigned char len);
+
+static void
+read_bytes_msb (xdata unsigned char *buf, unsigned char len);
+
+static void
+transact_bytes_msb (xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_read (unsigned char header_hi, unsigned char header_lo,
+ unsigned char enables, unsigned char format,
+ xdata unsigned char *buf, unsigned char len)
+{
+ if (count_bits8 (enables) > 1)
+ return 0; // error, too many enables set
+
+ setup_enables (enables);
+
+ if (format & SPI_FMT_LSB){ // order: LSB
+#if 1
+ return 0; // error, not implemented
+#else
+ switch (format & SPI_FMR_HDR_MASK){
+ case SPI_FMT_HDR_0:
+ break;
+ case SPI_FMT_HDR_1:
+ write_byte_lsb (header_lo);
+ break;
+ case SPI_FMT_HDR_2:
+ write_byte_lsb (header_lo);
+ write_byte_lsb (header_hi);
+ break;
+ default:
+ return 0; // error
+ }
+ if (len != 0)
+ read_bytes_lsb (buf, len);
+#endif
+ }
+
+ else { // order: MSB
+
+ switch (format & SPI_FMT_HDR_MASK){
+ case SPI_FMT_HDR_0:
+ break;
+ case SPI_FMT_HDR_1:
+ write_byte_msb (header_lo);
+ break;
+ case SPI_FMT_HDR_2:
+ write_byte_msb (header_hi);
+ write_byte_msb (header_lo);
+ break;
+ default:
+ return 0; // error
+ }
+ if (len != 0)
+ read_bytes_msb (buf, len);
+ }
+
+ disable_all ();
+ return 1; // success
+}
+
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_write (unsigned char header_hi, unsigned char header_lo,
+ unsigned char enables, unsigned char format,
+ const xdata unsigned char *buf, unsigned char len)
+{
+ setup_enables (enables);
+
+ if (format & SPI_FMT_LSB){ // order: LSB
+#if 1
+ return 0; // error, not implemented
+#else
+ switch (format & SPI_FMR_HDR_MASK){
+ case SPI_FMT_HDR_0:
+ break;
+ case SPI_FMT_HDR_1:
+ write_byte_lsb (header_lo);
+ break;
+ case SPI_FMT_HDR_2:
+ write_byte_lsb (header_lo);
+ write_byte_lsb (header_hi);
+ break;
+ default:
+ return 0; // error
+ }
+ if (len != 0)
+ write_bytes_lsb (buf, len);
+#endif
+ }
+
+ else { // order: MSB
+
+ switch (format & SPI_FMT_HDR_MASK){
+ case SPI_FMT_HDR_0:
+ break;
+ case SPI_FMT_HDR_1:
+ write_byte_msb (header_lo);
+ break;
+ case SPI_FMT_HDR_2:
+ write_byte_msb (header_hi);
+ write_byte_msb (header_lo);
+ break;
+ default:
+ return 0; // error
+ }
+ if (len != 0)
+ write_bytes_msb (buf, len);
+ }
+
+ disable_all ();
+ return 1; // success
+}
+
+unsigned char
+spi_transact (unsigned char data0, unsigned char data1,
+ unsigned char data2, unsigned char data3,
+ unsigned char enables, xdata unsigned char *buf,
+ unsigned char len)
+{
+ if (count_bits8 (enables) > 1)
+ return 0; // error, too many enables set
+
+ if (len > 4)
+ return 0;
+
+ setup_enables (enables);
+
+ buf[0] = data0;
+ buf[1] = data1;
+ buf[2] = data2;
+ buf[3] = data3;
+
+ if (len != 0)
+ transact_bytes_msb(buf, len);
+
+ disable_all ();
+ return 1; // success
+}
+
+static unsigned char
+transact_byte_msb (unsigned char v)
+{
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN; // read into bottom bit
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7);
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ return v;
+}
+
+static void
+transact_bytes_msb (xdata unsigned char *buf, unsigned char len)
+{
+ while (len-- != 0){
+ *buf++ = transact_byte_msb (*buf);
+ }
+}
+
+static void
+write_byte_msb (unsigned char v)
+{
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+}
+
+static void
+write_bytes_msb (const xdata unsigned char *buf, unsigned char len)
+{
+ while (len-- != 0){
+ write_byte_msb (*buf++);
+ }
+}
+
+#if 0
+/*
+ * This is incorrectly compiled by SDCC 2.4.0
+ */
+static unsigned char
+read_byte_msb (void)
+{
+ unsigned char v = 0;
+
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ v = v << 1;
+ bitS_CLK = 1;
+ v |= bitS_IN;
+ bitS_CLK = 0;
+
+ return v;
+}
+#else
+static unsigned char
+read_byte_msb (void) _naked
+{
+ _asm
+ clr a
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ setb _bitS_CLK
+ mov c, _bitS_IN
+ rlc a
+ clr _bitS_CLK
+
+ mov dpl,a
+ ret
+ _endasm;
+}
+#endif
+
+static void
+read_bytes_msb (xdata unsigned char *buf, unsigned char len)
+{
+ while (len-- != 0){
+ *buf++ = read_byte_msb ();
+ }
+}
+
diff --git a/firmware/fx2/common/spi.h b/firmware/fx2/common/spi.h
new file mode 100644
index 000000000..5342b82b8
--- /dev/null
+++ b/firmware/fx2/common/spi.h
@@ -0,0 +1,50 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_SPI_H
+#define INCLUDED_SPI_H
+
+#include "usrp_spi_defs.h"
+
+void init_spi (void); // one time call to init
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_read (unsigned char header_hi, unsigned char header_lo,
+ unsigned char enables, unsigned char format,
+ xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_write (unsigned char header_hi, unsigned char header_lo,
+ unsigned char enables, unsigned char format,
+ const xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_transact (unsigned char data0, unsigned char data1,
+ unsigned char data2, unsigned char data3,
+ unsigned char enables, xdata unsigned char *buf,
+ unsigned char len);
+
+
+#endif /* INCLUDED_SPI_H */
diff --git a/firmware/fx2/common/syncdelay.h b/firmware/fx2/common/syncdelay.h
new file mode 100644
index 000000000..0af7d099f
--- /dev/null
+++ b/firmware/fx2/common/syncdelay.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef _SYNCDELAY_H_
+#define _SYNCDELAY_H_
+
+/*
+ * Magic delay required between access to certain xdata registers (TRM page 15-106).
+ * For our configuration, 48 MHz FX2 / 48 MHz IFCLK, we need three cycles. Each
+ * NOP is a single cycle....
+ *
+ * From TRM page 15-105:
+ *
+ * Under certain conditions, some read and write access to the FX2 registers must
+ * be separated by a "synchronization delay". The delay is necessary only under the
+ * following conditions:
+ *
+ * - between a write to any register in the 0xE600 - 0xE6FF range and a write to one
+ * of the registers listed below.
+ *
+ * - between a write to one of the registers listed below and a read from any register
+ * in the 0xE600 - 0xE6FF range.
+ *
+ * Registers which require a synchronization delay:
+ *
+ * FIFORESET FIFOPINPOLAR
+ * INPKTEND EPxBCH:L
+ * EPxFIFOPFH:L EPxAUTOINLENH:L
+ * EPxFIFOCFG EPxGPIFFLGSEL
+ * PINFLAGSAB PINFLAGSCD
+ * EPxFIFOIE EPxFIFOIRQ
+ * GPIFIE GPIFIRQ
+ * UDMACRCH:L GPIFADRH:L
+ * GPIFTRIG EPxGPIFTRIG
+ * OUTPKTEND REVCTL
+ * GPIFTCB3 GPIFTCB2
+ * GPIFTCB1 GPIFTCB0
+ */
+
+/*
+ * FIXME ensure that the peep hole optimizer isn't screwing us
+ */
+#define SYNCDELAY _asm nop; nop; nop; _endasm
+#define NOP _asm nop; _endasm
+
+
+#endif /* _SYNCDELAY_H_ */
diff --git a/firmware/fx2/common/timer.c b/firmware/fx2/common/timer.c
new file mode 100644
index 000000000..97e2f7cf9
--- /dev/null
+++ b/firmware/fx2/common/timer.c
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include "timer.h"
+#include "fx2regs.h"
+#include "isr.h"
+
+/*
+ * Arrange to have isr_tick_handler called at 100 Hz.
+ *
+ * The cpu clock is running at 48e6. The input to the timer
+ * is 48e6 / 12 = 4e6.
+ *
+ * We arrange to have the timer overflow every 40000 clocks == 100 Hz
+ */
+
+#define RELOAD_VALUE ((unsigned short) -40000)
+
+void
+hook_timer_tick (unsigned short isr_tick_handler)
+{
+ ET2 = 0; // disable timer 2 interrupts
+ hook_sv (SV_TIMER_2, isr_tick_handler);
+
+ RCAP2H = RELOAD_VALUE >> 8; // setup the auto reload value
+ RCAP2L = RELOAD_VALUE;
+
+ T2CON = 0x04; // interrupt on overflow; reload; run
+ ET2 = 1; // enable timer 2 interrupts
+}
diff --git a/firmware/fx2/common/timer.h b/firmware/fx2/common/timer.h
new file mode 100644
index 000000000..3181874d5
--- /dev/null
+++ b/firmware/fx2/common/timer.h
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+/*
+ * Arrange to have isr_tick_handler called at 100 Hz
+ */
+void hook_timer_tick (unsigned short isr_tick_handler);
+
+#define clear_timer_irq() \
+ TF2 = 0 /* clear overflow flag */
+
+
+#endif /* _TIMER_H_ */
diff --git a/firmware/fx2/common/usb_common.c b/firmware/fx2/common/usb_common.c
new file mode 100644
index 000000000..3b0547b2f
--- /dev/null
+++ b/firmware/fx2/common/usb_common.c
@@ -0,0 +1,386 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include "usb_common.h"
+#include "fx2regs.h"
+#include "syncdelay.h"
+#include "fx2utils.h"
+#include "isr.h"
+#include "usb_descriptors.h"
+#include "usb_requests.h"
+
+extern xdata char str0[];
+extern xdata char str1[];
+extern xdata char str2[];
+extern xdata char str3[];
+extern xdata char str4[];
+extern xdata char str5[];
+
+
+#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]
+
+#define MSB(x) (((unsigned short) x) >> 8)
+#define LSB(x) (((unsigned short) x) & 0xff)
+
+volatile bit _usb_got_SUDAV;
+
+unsigned char _usb_config = 0;
+unsigned char _usb_alt_setting = 0; // FIXME really 1/interface
+
+xdata unsigned char *current_device_descr;
+xdata unsigned char *current_devqual_descr;
+xdata unsigned char *current_config_descr;
+xdata unsigned char *other_config_descr;
+
+static void
+setup_descriptors (void)
+{
+ if (USBCS & bmHSM){ // high speed mode
+ current_device_descr = high_speed_device_descr;
+ current_devqual_descr = high_speed_devqual_descr;
+ current_config_descr = high_speed_config_descr;
+ other_config_descr = full_speed_config_descr;
+ }
+ else {
+ current_device_descr = full_speed_device_descr;
+ current_devqual_descr = full_speed_devqual_descr;
+ current_config_descr = full_speed_config_descr;
+ other_config_descr = high_speed_config_descr;
+ }
+
+ // whack the type fields
+ // FIXME, may not be required.
+ // current_config_descr[1] = DT_CONFIG;
+ // other_config_descr[1] = DT_OTHER_SPEED;
+}
+
+static void
+isr_SUDAV (void) interrupt
+{
+ clear_usb_irq ();
+ _usb_got_SUDAV = 1;
+}
+
+static void
+isr_USBRESET (void) interrupt
+{
+ clear_usb_irq ();
+ setup_descriptors ();
+}
+
+static void
+isr_HIGHSPEED (void) interrupt
+{
+ clear_usb_irq ();
+ setup_descriptors ();
+}
+
+void
+usb_install_handlers (void)
+{
+ setup_descriptors (); // ensure that they're set before use
+
+ hook_uv (UV_SUDAV, (unsigned short) isr_SUDAV);
+ hook_uv (UV_USBRESET, (unsigned short) isr_USBRESET);
+ hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
+
+ USBIE = bmSUDAV | bmURES | bmHSGRANT;
+}
+
+// On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8
+// This doesn't check to see that they're enabled
+
+unsigned char
+plausible_endpoint (unsigned char ep)
+{
+ ep &= ~0x80; // ignore direction bit
+
+ if (ep > 8)
+ return 0;
+
+ if (ep == 1)
+ return 1;
+
+ return (ep & 0x1) == 0; // must be even
+}
+
+// return pointer to control and status register for endpoint.
+// only called with plausible_endpoints
+
+xdata volatile unsigned char *
+epcs (unsigned char ep)
+{
+ if (ep == 0x01) // ep1 has different in and out CS regs
+ return EP1OUTCS;
+
+ if (ep == 0x81)
+ return EP1INCS;
+
+ ep &= ~0x80; // ignore direction bit
+
+ if (ep == 0x00) // ep0
+ return EP0CS;
+
+ return EP2CS + (ep >> 1); // 2, 4, 6, 8 are consecutive
+}
+
+void
+usb_handle_setup_packet (void)
+{
+ _usb_got_SUDAV = 0;
+
+ // handle the standard requests...
+
+ switch (bRequestType & bmRT_TYPE_MASK){
+
+ case bmRT_TYPE_CLASS:
+ case bmRT_TYPE_RESERVED:
+ fx2_stall_ep0 (); // we don't handle these. indicate error
+ break;
+
+ case bmRT_TYPE_VENDOR:
+ // call the application code.
+ // If it handles the command it returns non-zero
+
+ if (!app_vendor_cmd ())
+ fx2_stall_ep0 ();
+ break;
+
+ case bmRT_TYPE_STD:
+ // these are the standard requests...
+
+ if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
+
+ ////////////////////////////////////
+ // handle the IN requests
+ ////////////////////////////////////
+
+ switch (bRequest){
+
+ case RQ_GET_CONFIG:
+ EP0BUF[0] = _usb_config; // FIXME app should handle
+ EP0BCH = 0;
+ EP0BCL = 1;
+ break;
+
+ // --------------------------------
+
+ case RQ_GET_INTERFACE:
+ EP0BUF[0] = _usb_alt_setting; // FIXME app should handle
+ EP0BCH = 0;
+ EP0BCL = 1;
+ break;
+
+ // --------------------------------
+
+ case RQ_GET_DESCR:
+ switch (wValueH){
+
+ case DT_DEVICE:
+ SUDPTRH = MSB (current_device_descr);
+ SUDPTRL = LSB (current_device_descr);
+ break;
+
+ case DT_DEVQUAL:
+ SUDPTRH = MSB (current_devqual_descr);
+ SUDPTRL = LSB (current_devqual_descr);
+ break;
+
+ case DT_CONFIG:
+ if (0 && wValueL != 1) // FIXME only a single configuration
+ fx2_stall_ep0 ();
+ else {
+ SUDPTRH = MSB (current_config_descr);
+ SUDPTRL = LSB (current_config_descr);
+ }
+ break;
+
+ case DT_OTHER_SPEED:
+ if (0 && wValueL != 1) // FIXME only a single configuration
+ fx2_stall_ep0 ();
+ else {
+ SUDPTRH = MSB (other_config_descr);
+ SUDPTRL = LSB (other_config_descr);
+ }
+ break;
+
+ case DT_STRING:
+ if (wValueL >= nstring_descriptors)
+ fx2_stall_ep0 ();
+ else {
+ xdata char *p = string_descriptors[wValueL];
+ SUDPTRH = MSB (p);
+ SUDPTRL = LSB (p);
+ }
+ break;
+
+ default:
+ fx2_stall_ep0 (); // invalid request
+ break;
+ }
+ break;
+
+ // --------------------------------
+
+ case RQ_GET_STATUS:
+ switch (bRequestType & bmRT_RECIP_MASK){
+ case bmRT_RECIP_DEVICE:
+ EP0BUF[0] = bmGSDA_SELF_POWERED; // FIXME app should handle
+ EP0BUF[1] = 0;
+ EP0BCH = 0;
+ EP0BCL = 2;
+ break;
+
+ case bmRT_RECIP_INTERFACE:
+ EP0BUF[0] = 0;
+ EP0BUF[1] = 0;
+ EP0BCH = 0;
+ EP0BCL = 2;
+ break;
+
+ case bmRT_RECIP_ENDPOINT:
+ if (plausible_endpoint (wIndexL)){
+ EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;
+ EP0BUF[1] = 0;
+ EP0BCH = 0;
+ EP0BCL = 2;
+ }
+ else
+ fx2_stall_ep0 ();
+ break;
+
+ default:
+ fx2_stall_ep0 ();
+ break;
+ }
+ break;
+
+ // --------------------------------
+
+ case RQ_SYNCH_FRAME: // not implemented
+ default:
+ fx2_stall_ep0 ();
+ break;
+ }
+ }
+
+ else {
+
+ ////////////////////////////////////
+ // handle the OUT requests
+ ////////////////////////////////////
+
+ switch (bRequest){
+
+ case RQ_SET_CONFIG:
+ _usb_config = wValueL; // FIXME app should handle
+ break;
+
+ case RQ_SET_INTERFACE:
+ _usb_alt_setting = wValueL; // FIXME app should handle
+ break;
+
+ // --------------------------------
+
+ case RQ_CLEAR_FEATURE:
+ switch (bRequestType & bmRT_RECIP_MASK){
+
+ case bmRT_RECIP_DEVICE:
+ switch (wValueL){
+ case FS_DEV_REMOTE_WAKEUP:
+ default:
+ fx2_stall_ep0 ();
+ }
+ break;
+
+ case bmRT_RECIP_ENDPOINT:
+ if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){
+ *epcs (wIndexL) &= ~bmEPSTALL;
+ fx2_reset_data_toggle (wIndexL);
+ }
+ else
+ fx2_stall_ep0 ();
+ break;
+
+ default:
+ fx2_stall_ep0 ();
+ break;
+ }
+ break;
+
+ // --------------------------------
+
+ case RQ_SET_FEATURE:
+ switch (bRequestType & bmRT_RECIP_MASK){
+
+ case bmRT_RECIP_DEVICE:
+ switch (wValueL){
+ case FS_TEST_MODE:
+ // hardware handles this after we complete SETUP phase handshake
+ break;
+
+ case FS_DEV_REMOTE_WAKEUP:
+ default:
+ fx2_stall_ep0 ();
+ break;
+ }
+ }
+ break;
+
+ case bmRT_RECIP_ENDPOINT:
+ switch (wValueL){
+ case FS_ENDPOINT_HALT:
+ if (plausible_endpoint (wIndexL))
+ *epcs (wIndexL) |= bmEPSTALL;
+ else
+ fx2_stall_ep0 ();
+ break;
+
+ default:
+ fx2_stall_ep0 ();
+ break;
+ }
+ break;
+
+ // --------------------------------
+
+ case RQ_SET_ADDRESS: // handled by fx2 hardware
+ case RQ_SET_DESCR: // not implemented
+ default:
+ fx2_stall_ep0 ();
+ }
+
+ }
+ break;
+
+ } // bmRT_TYPE_MASK
+
+ // ack handshake phase of device request
+ EP0CS |= bmHSNAK;
+}
diff --git a/firmware/fx2/common/usb_common.h b/firmware/fx2/common/usb_common.h
new file mode 100644
index 000000000..ae07b236c
--- /dev/null
+++ b/firmware/fx2/common/usb_common.h
@@ -0,0 +1,37 @@
+/* -*- c -*- */
+/*
+ * 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.
+ */
+
+#ifndef _USB_COMMON_H_
+#define _USB_COMMON_H_
+
+extern volatile bit _usb_got_SUDAV;
+
+// Provided by user application to handle VENDOR commands.
+// returns non-zero if it handled the command.
+unsigned char app_vendor_cmd (void);
+
+void usb_install_handlers (void);
+void usb_handle_setup_packet (void);
+
+#define usb_setup_packet_avail() _usb_got_SUDAV
+
+#endif /* _USB_COMMON_H_ */
diff --git a/firmware/fx2/common/usb_descriptors.h b/firmware/fx2/common/usb_descriptors.h
new file mode 100644
index 000000000..0b8c6212f
--- /dev/null
+++ b/firmware/fx2/common/usb_descriptors.h
@@ -0,0 +1,40 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+extern xdata const char high_speed_device_descr[];
+extern xdata const char high_speed_devqual_descr[];
+extern xdata const char high_speed_config_descr[];
+
+extern xdata const char full_speed_device_descr[];
+extern xdata const char full_speed_devqual_descr[];
+extern xdata const char full_speed_config_descr[];
+
+extern xdata unsigned char nstring_descriptors;
+extern xdata char * xdata string_descriptors[];
+
+/*
+ * We patch these locations with info read from the usrp config eeprom
+ */
+extern xdata char usb_desc_hw_rev_binary_patch_location_0[];
+extern xdata char usb_desc_hw_rev_binary_patch_location_1[];
+extern xdata char usb_desc_hw_rev_ascii_patch_location_0[];
+extern xdata char usb_desc_serial_number_ascii[];
diff --git a/firmware/fx2/common/usb_requests.h b/firmware/fx2/common/usb_requests.h
new file mode 100644
index 000000000..7a543abb0
--- /dev/null
+++ b/firmware/fx2/common/usb_requests.h
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+// Standard USB requests.
+// These are contained in end point 0 setup packets
+
+
+#ifndef _USB_REQUESTS_H_
+#define _USB_REQUESTS_H_
+
+// format of bmRequestType byte
+
+#define bmRT_DIR_MASK (0x1 << 7)
+#define bmRT_DIR_IN (1 << 7)
+#define bmRT_DIR_OUT (0 << 7)
+
+#define bmRT_TYPE_MASK (0x3 << 5)
+#define bmRT_TYPE_STD (0 << 5)
+#define bmRT_TYPE_CLASS (1 << 5)
+#define bmRT_TYPE_VENDOR (2 << 5)
+#define bmRT_TYPE_RESERVED (3 << 5)
+
+#define bmRT_RECIP_MASK (0x1f << 0)
+#define bmRT_RECIP_DEVICE (0 << 0)
+#define bmRT_RECIP_INTERFACE (1 << 0)
+#define bmRT_RECIP_ENDPOINT (2 << 0)
+#define bmRT_RECIP_OTHER (3 << 0)
+
+
+// standard request codes (bRequest)
+
+#define RQ_GET_STATUS 0
+#define RQ_CLEAR_FEATURE 1
+#define RQ_RESERVED_2 2
+#define RQ_SET_FEATURE 3
+#define RQ_RESERVED_4 4
+#define RQ_SET_ADDRESS 5
+#define RQ_GET_DESCR 6
+#define RQ_SET_DESCR 7
+#define RQ_GET_CONFIG 8
+#define RQ_SET_CONFIG 9
+#define RQ_GET_INTERFACE 10
+#define RQ_SET_INTERFACE 11
+#define RQ_SYNCH_FRAME 12
+
+// standard descriptor types
+
+#define DT_DEVICE 1
+#define DT_CONFIG 2
+#define DT_STRING 3
+#define DT_INTERFACE 4
+#define DT_ENDPOINT 5
+#define DT_DEVQUAL 6
+#define DT_OTHER_SPEED 7
+#define DT_INTERFACE_POWER 8
+
+// standard feature selectors
+
+#define FS_ENDPOINT_HALT 0 // recip: endpoint
+#define FS_DEV_REMOTE_WAKEUP 1 // recip: device
+#define FS_TEST_MODE 2 // recip: device
+
+// Get Status device attributes
+
+#define bmGSDA_SELF_POWERED 0x01
+#define bmGSDA_REM_WAKEUP 0x02
+
+
+#endif /* _USB_REQUESTS_H_ */
diff --git a/firmware/fx2/common/usrp_commands.h b/firmware/fx2/common/usrp_commands.h
new file mode 100644
index 000000000..02778c7e3
--- /dev/null
+++ b/firmware/fx2/common/usrp_commands.h
@@ -0,0 +1,106 @@
+/*
+ * 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 _USRP_COMMANDS_H_
+#define _USRP_COMMANDS_H_
+
+#include <usrp_interfaces.h>
+#include <usrp_spi_defs.h>
+
+#define MAX_EP0_PKTSIZE 64 // max size of EP0 packet on FX2
+
+// ----------------------------------------------------------------
+// Vendor bmRequestType's
+// ----------------------------------------------------------------
+
+#define VRT_VENDOR_IN 0xC0
+#define VRT_VENDOR_OUT 0x40
+
+// ----------------------------------------------------------------
+// USRP Vendor Requests
+//
+// Note that Cypress reserves [0xA0,0xAF].
+// 0xA0 is the firmware load function.
+// ----------------------------------------------------------------
+
+
+// IN commands
+
+#define VRQ_GET_STATUS 0x80
+#define GS_TX_UNDERRUN 0 // wIndexL // returns 1 byte
+#define GS_RX_OVERRUN 1 // wIndexL // returns 1 byte
+
+#define VRQ_I2C_READ 0x81 // wValueL: i2c address; length: how much to read
+
+#define VRQ_SPI_READ 0x82 // wValue: optional header bytes
+ // wIndexH: enables
+ // wIndexL: format
+ // len: how much to read
+
+#define VRQ_SPI_TRANSACT 0x83 // wValueH: OUT byte 0
+ // wValueL: OUT byte 1
+ // wIndexH: OUT byte 2
+ // wIndexL: OUT byte 3
+ // wLengthH: enables
+ // wLengthL: transaction length
+
+// OUT commands
+
+#define VRQ_SET_LED 0x01 // wValueL off/on {0,1}; wIndexL: which {0,1}
+
+#define VRQ_FPGA_LOAD 0x02
+# define FL_BEGIN 0 // wIndexL: begin fpga programming cycle. stalls if trouble.
+# define FL_XFER 1 // wIndexL: xfer up to 64 bytes of data
+# define FL_END 2 // wIndexL: end programming cycle, check for success.
+ // stalls endpoint if trouble.
+
+#define VRQ_FPGA_WRITE_REG 0x03 // wIndexL: regno; data: 32-bit regval MSB first
+#define VRQ_FPGA_SET_RESET 0x04 // wValueL: {0,1}
+#define VRQ_FPGA_SET_TX_ENABLE 0x05 // wValueL: {0,1}
+#define VRQ_FPGA_SET_RX_ENABLE 0x06 // wValueL: {0,1}
+// see below VRQ_FPGA_SET_{TX,RX}_RESET
+
+#define VRQ_SET_SLEEP_BITS 0x07 // wValueH: mask; wValueL: bits. set bits given by mask to bits
+
+# define SLEEP_ADC0 0x01
+# define SLEEP_ADC1 0x02
+# define SLEEP_DAC0 0x04
+# define SLEEP_DAC1 0x08
+
+#define VRQ_I2C_WRITE 0x08 // wValueL: i2c address; data: data
+
+#define VRQ_SPI_WRITE 0x09 // wValue: optional header bytes
+ // wIndexH: enables
+ // wIndexL: format
+ // len: how much to write
+
+#define VRQ_FPGA_SET_TX_RESET 0x0a // wValueL: {0, 1}
+#define VRQ_FPGA_SET_RX_RESET 0x0b // wValueL: {0, 1}
+
+
+// -------------------------------------------------------------------
+// we store the hashes at fixed addresses in the FX2 internal memory
+
+#define USRP_HASH_SLOT_0_ADDR 0xe1e0
+#define USRP_HASH_SLOT_1_ADDR 0xe1f0
+
+
+
+#endif /* _USRP_COMMANDS_H_ */
diff --git a/firmware/fx2/common/usrp_common.h b/firmware/fx2/common/usrp_common.h
new file mode 100644
index 000000000..fd203927f
--- /dev/null
+++ b/firmware/fx2/common/usrp_common.h
@@ -0,0 +1,77 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2006 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 defines and prototypes for USRP
+ *
+ * In comments below "TRM" refers to the EZ-USB FX2 Technical Reference Manual
+ */
+
+#ifndef _USRPCOMMON_H_
+#define _USRPCOMMON_H_
+
+#include "usrp_config.h"
+#include "usrp_regs.h"
+#include "syncdelay.h"
+
+/*
+ * From TRM page 15-105:
+ *
+ * Under certain conditions, some read and write access to the FX2
+ * registers must be separated by a "synchronization delay". The
+ * delay is necessary only under the following conditions:
+ *
+ * - between a write to any register in the 0xE600 - 0xE6FF range
+ * and a write to one of the registers listed below.
+ *
+ * - between a write to one of the registers listed below and a read
+ * from any register in the 0xE600 - 0xE6FF range.
+ *
+ * Registers which require a synchronization delay:
+ *
+ * FIFORESET FIFOPINPOLAR
+ * INPKTEND EPxBCH:L
+ * EPxFIFOPFH:L EPxAUTOINLENH:L
+ * EPxFIFOCFG EPxGPIFFLGSEL
+ * PINFLAGSAB PINFLAGSCD
+ * EPxFIFOIE EPxFIFOIRQ
+ * GPIFIE GPIFIRQ
+ * UDMACRCH:L GPIFADRH:L
+ * GPIFTRIG EPxGPIFTRIG
+ * OUTPKTEND REVCTL
+ * GPIFTCB3 GPIFTCB2
+ * GPIFTCB1 GPIFTCB0
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+
+void init_usrp (void);
+void init_gpif (void);
+
+void set_led_0 (unsigned char on);
+void set_led_1 (unsigned char on);
+void toggle_led_0 (void);
+void toggle_led_1 (void);
+
+#define la_trace(v)
+
+#endif /* _USRPCOMMON_H_ */
diff --git a/firmware/fx2/common/usrp_config.h b/firmware/fx2/common/usrp_config.h
new file mode 100644
index 000000000..e77f8e4c5
--- /dev/null
+++ b/firmware/fx2/common/usrp_config.h
@@ -0,0 +1,44 @@
+/*
+ * 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
+ */
+
+/*
+ * configuration stuff for debugging
+ */
+
+/*
+ * Define to 0 for normal use of port A, i.e., FPGA control bus.
+ * Define to 1 to write trace to port A for scoping with logic analyzer.
+ */
+#define UC_TRACE_USING_PORT_A 0
+
+
+/*
+ * Define to 0 for normal use of low 3 bits of port E, i.e., A/D, D/A SLEEP bits.
+ * Define to 1 to enable by default driving the GPIF state to the
+ * low three bits of port E.
+ */
+#define UC_START_WITH_GSTATE_OUTPUT_ENABLED 0
+
+
+/*
+ * Define to 1 for normal use (the board really has an FPGA on it).
+ * Define to 0 for debug use on board without FPGA.
+ */
+#define UC_BOARD_HAS_FPGA 1
diff --git a/firmware/fx2/common/usrp_globals.h b/firmware/fx2/common/usrp_globals.h
new file mode 100644
index 000000000..445e9e6b4
--- /dev/null
+++ b/firmware/fx2/common/usrp_globals.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef _USRP_GLOBALS_H_
+#define _USRP_GLOBALS_H_
+
+extern unsigned char g_tx_enable;
+extern unsigned char g_rx_enable;
+extern unsigned char g_fpga_reset;
+extern unsigned char g_rx_overrun;
+extern unsigned char g_tx_underrun;
+
+
+#endif /* _USRP_GLOBALS_H_ */
diff --git a/firmware/fx2/common/usrp_i2c_addr.h b/firmware/fx2/common/usrp_i2c_addr.h
new file mode 100644
index 000000000..0a4f3ea59
--- /dev/null
+++ b/firmware/fx2/common/usrp_i2c_addr.h
@@ -0,0 +1,78 @@
+/* -*- 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.
+ */
+#ifndef INCLUDED_USRP_I2C_ADDR_H
+#define INCLUDED_USRP_I2C_ADDR_H
+
+// I2C addresses
+
+#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx
+
+#define I2C_ADDR_BOOT (I2C_DEV_EEPROM | 0x0)
+#define I2C_ADDR_TX_A (I2C_DEV_EEPROM | 0x4)
+#define I2C_ADDR_RX_A (I2C_DEV_EEPROM | 0x5)
+#define I2C_ADDR_TX_B (I2C_DEV_EEPROM | 0x6)
+#define I2C_ADDR_RX_B (I2C_DEV_EEPROM | 0x7)
+
+
+// format of FX2 BOOT EEPROM
+// 00: 0xC0 code for ``Read IDs from EEPROM''
+// 01: 0xFE USB Vendor ID (LSB)
+// 02: 0xFF USB Vendor ID (MSB)
+// 03: 0x02 USB Product ID (LSB)
+// 04: 0x00 USB Product ID (MSB)
+// 05: 0x01 USB Device ID (LSB) // rev1
+// 06: 0x00 USB Device ID (MSB) // 0 = unconfig'd (no firmware)
+// 07: 0x00 option byte
+
+
+// format of daughterboard EEPROM
+// 00: 0xDB code for ``I'm a daughterboard''
+// 01: .. Daughterboard ID (LSB)
+// 02: .. Daughterboard ID (MSB)
+// 03: .. io bits 7-0 direction (bit set if it's an output from m'board)
+// 04: .. io bits 15-8 direction (bit set if it's an output from m'board)
+// 05: .. ADC0 DC offset correction (LSB)
+// 06: .. ADC0 DC offset correction (MSB)
+// 07: .. ADC1 DC offset correction (LSB)
+// 08: .. ADC1 DC offset correction (MSB)
+// ...
+// 1f: .. negative of the sum of bytes [0x00, 0x1e]
+
+#define DB_EEPROM_MAGIC 0x00
+#define DB_EEPROM_MAGIC_VALUE 0xDB
+#define DB_EEPROM_ID_LSB 0x01
+#define DB_EEPROM_ID_MSB 0x02
+#define DB_EEPROM_OE_LSB 0x03
+#define DB_EEPROM_OE_MSB 0x04
+#define DB_EEPROM_OFFSET_0_LSB 0x05 // offset correction for ADC or DAC 0
+#define DB_EEPROM_OFFSET_0_MSB 0x06
+#define DB_EEPROM_OFFSET_1_LSB 0x07 // offset correction for ADC or DAC 1
+#define DB_EEPROM_OFFSET_1_MSB 0x08
+#define DB_EEPROM_CHKSUM 0x1f
+
+#define DB_EEPROM_CLEN 0x20 // length of common portion of eeprom
+
+#define DB_EEPROM_CUSTOM_BASE DB_EEPROM_CLEN // first avail offset for
+ // daughterboard specific use
+
+#endif /* INCLUDED_USRP_I2C_ADDR_H */
+
diff --git a/firmware/fx2/common/usrp_ids.h b/firmware/fx2/common/usrp_ids.h
new file mode 100644
index 000000000..ffeb47f3c
--- /dev/null
+++ b/firmware/fx2/common/usrp_ids.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2006,2007 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 Vendor and Product IDs that we use
+ *
+ * (keep in sync with usb_descriptors.a51)
+ */
+
+#ifndef _USRP_IDS_H_
+#define _USRP_IDS_H_
+
+#define USB_VID_CYPRESS 0x04b4
+#define USB_PID_CYPRESS_FX2 0x8613
+
+
+#define USB_VID_FSF 0xfffe // Free Software Folks
+#define USB_PID_FSF_EXP_0 0x0000 // Experimental 0
+#define USB_PID_FSF_EXP_1 0x0001 // Experimental 1
+#define USB_PID_FSF_USRP 0x0002 // Universal Software Radio Peripheral
+#define USB_PID_FSF_USRP1P 0x0003 // USRP1P
+#define USB_PID_FSF_SSRP 0x0004 // Simple Software Radio Peripheral
+#define USB_PID_FSF_SSRP_reserved 0x0005 // Simple Software Radio Peripheral
+#define USB_PID_FSF_HPSDR 0x0006 // High Performance Software Defined Radio (Internal Boot)
+#define USB_PID_FSF_HPSDR_HA 0x0007 // High Performance Software Defined Radio (Host Assisted Boot)
+#define USB_PID_FSF_QS1R 0x0008 // QS1R HF receiver
+#define USB_PID_FSF_EZDOP 0x0009 // ezdop <jcorgan@aeinet.com>
+#define USB_PID_FSF_BDALE_0 0x000a // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_1 0x000b // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_2 0x000c // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_3 0x000d // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_4 0x000e // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_5 0x000f // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_6 0x0010 // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_7 0x0011 // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_8 0x0012 // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_BDALE_9 0x0013 // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_HPSDR_HERMES 0x0014 // HPSDR Hermes
+#define USB_PID_FSF_THINKRF 0x0015 // Catalin Patulea <catalin.patulea@thinkrf.com>
+#define USB_PID_FSF_MSA 0x0016 // Hans de Bok <hdbok@dionaea.demon.nl> Scotty's Modular Spectrum Analyzer
+
+#define USB_PID_FSF_LBNL_UXO 0x0018 // http://recycle.lbl.gov/~ldoolitt/uxo/
+
+
+#define USB_DID_USRP_0 0x0000 // unconfigured rev 0 USRP
+#define USB_DID_USRP_1 0x0001 // unconfigured rev 1 USRP
+#define USB_DID_USRP_2 0x0002 // unconfigured rev 2 USRP
+
+#endif /* _USRP_IDS_H_ */
diff --git a/firmware/fx2/common/usrp_interfaces.h b/firmware/fx2/common/usrp_interfaces.h
new file mode 100644
index 000000000..8666e0490
--- /dev/null
+++ b/firmware/fx2/common/usrp_interfaces.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef _USRP_INTERFACES_H_
+#define _USRP_INTERFACES_H_
+
+/*
+ * We've now split the USRP into 3 separate interfaces.
+ *
+ * Interface 0 contains only ep0 and is used for command and status.
+ * Interface 1 is the Tx path and it uses ep2 OUT BULK.
+ * Interface 2 is the Rx path and it uses ep6 IN BULK.
+ */
+
+#define USRP_CMD_INTERFACE 0
+#define USRP_CMD_ALTINTERFACE 0
+#define USRP_CMD_ENDPOINT 0
+
+#define USRP_TX_INTERFACE 1
+#define USRP_TX_ALTINTERFACE 0
+#define USRP_TX_ENDPOINT 2 // streaming data from host to FPGA
+
+#define USRP_RX_INTERFACE 2
+#define USRP_RX_ALTINTERFACE 0
+#define USRP_RX_ENDPOINT 6 // streaming data from FPGA to host
+
+
+#endif /* _USRP_INTERFACES_H_ */
diff --git a/firmware/fx2/common/usrp_spi_defs.h b/firmware/fx2/common/usrp_spi_defs.h
new file mode 100644
index 000000000..963463ef2
--- /dev/null
+++ b/firmware/fx2/common/usrp_spi_defs.h
@@ -0,0 +1,86 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_USRP_SPI_DEFS_H
+#define INCLUDED_USRP_SPI_DEFS_H
+
+/*
+ * defines for the VRQ_SPI_READ and VRQ_SPI_WRITE commands
+ *
+ * SPI == "Serial Port Interface". SPI is a 3 wire bus plus a
+ * separate enable for each peripheral. The common lines are SCLK,
+ * SDI and SDO. The FX2 always drives SCLK and SDI, the clock and
+ * data lines from the FX2 to the peripheral. When enabled, a
+ * peripheral may drive SDO, the data line from the peripheral to the
+ * FX2.
+ *
+ * The SPI_READ and SPI_WRITE commands are formatted identically.
+ * Each specifies which peripherals to enable, whether the bits should
+ * be transmistted Most Significant Bit first or Least Significant Bit
+ * first, the number of bytes in the optional header, and the number
+ * of bytes to read or write in the body.
+ *
+ * The body is limited to 64 bytes. The optional header may contain
+ * 0, 1 or 2 bytes. For an SPI_WRITE, the header bytes are
+ * transmitted to the peripheral followed by the the body bytes. For
+ * an SPI_READ, the header bytes are transmitted to the peripheral,
+ * then len bytes are read back from the peripheral.
+ */
+
+/*
+ * SPI_FMT_* goes in wIndexL
+ */
+#define SPI_FMT_xSB_MASK (1 << 7)
+# define SPI_FMT_LSB (1 << 7) // least signficant bit first
+# define SPI_FMT_MSB (0 << 7) // most significant bit first
+#define SPI_FMT_HDR_MASK (3 << 5)
+# define SPI_FMT_HDR_0 (0 << 5) // 0 header bytes
+# define SPI_FMT_HDR_1 (1 << 5) // 1 header byte
+# define SPI_FMT_HDR_2 (2 << 5) // 2 header bytes
+
+/*
+ * SPI_ENABLE_* goes in wIndexH
+ *
+ * For the software interface, the enables are active high.
+ * For reads, it's an error to have more than one enable set.
+ *
+ * [FWIW, the hardware implements them as active low. Don't change the
+ * definitions of these. They are related to usrp_rev1_regs.h]
+ */
+#define SPI_ENABLE_FPGA 0x01 // select FPGA
+#define SPI_ENABLE_CODEC_A 0x02 // select AD9862 A
+#define SPI_ENABLE_CODEC_B 0x04 // select AD9862 B
+#define SPI_ENABLE_reserved 0x08
+#define SPI_ENABLE_TX_A 0x10 // select d'board TX A
+#define SPI_ENABLE_RX_A 0x20 // select d'board RX A
+#define SPI_ENABLE_TX_B 0x40 // select d'board TX B
+#define SPI_ENABLE_RX_B 0x80 // select d'board RX B
+
+/*
+ * If there's one header byte, it goes in wValueL.
+ *
+ * If there are two header bytes, they go in wValueH | wValueL.
+ * The transmit order of the bytes (and bits within them) is
+ * determined by SPI_FMT_*SB
+ */
+
+#endif /* INCLUDED_USRP_SPI_DEFS_H */
diff --git a/firmware/fx2/common/vectors.a51 b/firmware/fx2/common/vectors.a51
new file mode 100644
index 000000000..4eec9fdbf
--- /dev/null
+++ b/firmware/fx2/common/vectors.a51
@@ -0,0 +1,179 @@
+;;; -*- 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.
+;;;
+
+;;; Interrupt vectors.
+
+;;; N.B. This object module must come first in the list of modules
+
+ .module vectors
+
+;;; ----------------------------------------------------------------
+;;; standard FX2 interrupt vectors
+;;; ----------------------------------------------------------------
+ .area CSEG (CODE)
+ .area GSINIT (CODE)
+ .area CSEG (CODE)
+__standard_interrupt_vector::
+__reset_vector::
+ ljmp s_GSINIT
+
+ ;; 13 8-byte entries. We point them all at __isr_nop
+ ljmp __isr_nop ; 3 bytes
+ .ds 5 ; + 5 = 8 bytes for vector slot
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+ ljmp __isr_nop
+ .ds 5
+
+__isr_nop::
+ reti
+
+;;; ----------------------------------------------------------------
+;;; the FIFO/GPIF autovector. 14 4-byte entries.
+;;; must start on a 128 byte boundary.
+;;; ----------------------------------------------------------------
+
+ . = __reset_vector + 0x0080
+
+__fifo_gpif_autovector::
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+
+
+;;; ----------------------------------------------------------------
+;;; the USB autovector. 32 4-byte entries.
+;;; must start on a 256 byte boundary.
+;;; ----------------------------------------------------------------
+
+ . = __reset_vector + 0x0100
+
+__usb_autovector::
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
+ ljmp __isr_nop
+ nop
diff --git a/firmware/fx2/config/CMakeASM_SDCCInformation.cmake b/firmware/fx2/config/CMakeASM_SDCCInformation.cmake
new file mode 100644
index 000000000..d9f28b8d3
--- /dev/null
+++ b/firmware/fx2/config/CMakeASM_SDCCInformation.cmake
@@ -0,0 +1,28 @@
+#
+# 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/>.
+#
+
+# support for the SDCC assembler, asx8051
+SET( ASM_DIALECT "_SDCC" )
+SET( CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS a51 )
+
+#i don't want to talk about it. i had such high hopes for CMake.
+SET( CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> -plosgff <SOURCE>" "${CMAKE_COMMAND} -DFILE=<OBJECT> -DSOURCE=<SOURCE> -P ${CMAKE_SOURCE_DIR}/config/Rename.cmake")
+
+INCLUDE( CMakeASMInformation )
+SET( CMAKE_ASM${ASM_DIALECT}_OUTPUT_EXTENSION ".rel" ) #must go here because the include appears to overwrite it, although it shouldn't
+# for future use
+SET( ASM_DIALECT )
diff --git a/firmware/fx2/config/CMakeDetermineASM_SDCCCompiler.cmake b/firmware/fx2/config/CMakeDetermineASM_SDCCCompiler.cmake
new file mode 100644
index 000000000..ab301b9f3
--- /dev/null
+++ b/firmware/fx2/config/CMakeDetermineASM_SDCCCompiler.cmake
@@ -0,0 +1,22 @@
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Find the MS assembler (masm or masm64)
+
+SET(ASM_DIALECT "_SDCC")
+
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT asx8051)
+
+INCLUDE(CMakeDetermineASMCompiler)
+SET(ASM_DIALECT)
diff --git a/firmware/fx2/config/CMakeTestASM_SDCCCompiler.cmake b/firmware/fx2/config/CMakeTestASM_SDCCCompiler.cmake
new file mode 100644
index 000000000..1cb71cd9d
--- /dev/null
+++ b/firmware/fx2/config/CMakeTestASM_SDCCCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected ASM-ATT compiler can actually compile
+# and link the most basic of programs. If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+
+SET(ASM_DIALECT "_SDCC")
+INCLUDE(CMakeTestASMCompiler)
+SET(ASM_DIALECT)
diff --git a/firmware/fx2/config/Rename.cmake b/firmware/fx2/config/Rename.cmake
new file mode 100644
index 000000000..36cd33527
--- /dev/null
+++ b/firmware/fx2/config/Rename.cmake
@@ -0,0 +1,37 @@
+#
+# 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/>.
+#
+
+#go and fetch the real compiler outputs because the compiler does things wrong and CMake is too damn brittle to cope
+#just incidentally, why the heck does aslink look for a .lst input? why should it care?
+
+#first the .rel
+get_filename_component(source_noext ${SOURCE} NAME_WE)
+get_filename_component(source_path ${SOURCE} PATH)
+set(compiled_ext .rel)
+list(APPEND compiled_filepath ${source_path}/${source_noext}${compiled_ext})
+#EXECUTE_PROCESS(COMMAND echo Moving ${compiled_filepath} to ${FILE})
+EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E rename ${compiled_filepath} ${FILE})
+
+#now do the same for the .lst
+set(compiled_lst .lst)
+get_filename_component(src_ext ${SOURCE} EXT)
+get_filename_component(lst_noext ${FILE} NAME_WE)
+get_filename_component(lst_path ${FILE} PATH)
+list(APPEND compiled_lstpath ${source_path}/${source_noext}${compiled_lst})
+list(APPEND compiled_outputlstpath ${lst_path}/${lst_noext}${src_ext}${compiled_lst})
+#EXECUTE_PROCESS(COMMAND echo Moving ${compiled_lstpath} to ${compiled_outputlstpath})
+EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E rename ${compiled_lstpath} ${compiled_outputlstpath})
diff --git a/firmware/fx2/config/Toolchain-sdcc.cmake b/firmware/fx2/config/Toolchain-sdcc.cmake
new file mode 100644
index 000000000..733d8f563
--- /dev/null
+++ b/firmware/fx2/config/Toolchain-sdcc.cmake
@@ -0,0 +1,32 @@
+#
+# 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/>.
+#
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Generic)
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER sdcc)
+
+# here is where the target environment is located
+SET(CMAKE_FIND_ROOT_PATH /usr/bin /usr/share/sdcc)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
diff --git a/firmware/fx2/usrp1/CMakeLists.txt b/firmware/fx2/usrp1/CMakeLists.txt
new file mode 100644
index 000000000..6607bc7f2
--- /dev/null
+++ b/firmware/fx2/usrp1/CMakeLists.txt
@@ -0,0 +1,84 @@
+#
+# 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(libusrp1_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
+# ${CMAKE_SOURCE_DIR}/common/vectors.a51
+)
+
+#file(GLOB libusrp1_c_sources ${CMAKE_SOURCE_DIR}/common/*.c)
+#file(GLOB libusrp1_a51_sources ${CMAKE_SOURCE_DIR}/common/*.a51)
+#list(APPEND libusrp1_sources ${libusrp1_c_sources} ${libusrp1_a51_sources})
+
+add_library(libusrp1 STATIC ${libusrp1_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_USRP1}
+ COMMAND ${PYTHON_EXECUTABLE} ${EDIT_GPIF_USRP1} ${GPIF_SOURCE} ${GPIF_SOURCE_OUTPUT} ${GPIF_HEADER_OUTPUT}
+ COMMENT "Generating ${GPIF_SOURCE_OUTPUT}"
+)
+
+#file(GLOB usrp1_sources *.c)
+set(usrp1_sources
+ ${CMAKE_SOURCE_DIR}/common/vectors.a51
+ board_specific.c
+ eeprom_io.c
+ fpga_load.c
+ fpga_rev2.c
+ usrp_common.c
+ usrp_gpif.c
+ usrp_main.c
+ usb_descriptors.a51
+ ${CMAKE_SOURCE_DIR}/common/spi.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+add_executable(usrp1_fw ${usrp1_sources})
+target_link_libraries(usrp1_fw libusrp1)
+
+set(eeprom1_sources
+ ${CMAKE_SOURCE_DIR}/common/eeprom_boot.a51
+ ${CMAKE_SOURCE_DIR}/common/eeprom_init.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+
+add_custom_target(usrp1_eeprom ALL
+ DEPENDS usrp1_boot
+ COMMAND objcopy -I ihex -O binary usrp1_boot.ihx usrp1_boot.bin
+ COMMAND ${PYTHON_EXECUTABLE} ${BUILD_EEPROM} -r1 usrp1_boot.bin usrp1_eeprom.bin
+)
+
+add_executable(usrp1_boot ${eeprom1_sources})
+target_link_libraries(usrp1_boot libusrp1)
diff --git a/firmware/fx2/usrp1/board_specific.c b/firmware/fx2/usrp1/board_specific.c
new file mode 100644
index 000000000..ef0081d84
--- /dev/null
+++ b/firmware/fx2/usrp1/board_specific.c
@@ -0,0 +1,113 @@
+/* -*- 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"
+#include "spi.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
+la_trace_init (void)
+{
+}
+
+void
+set_sleep_bits (unsigned char bits, unsigned char mask)
+{
+ // NOP on usrp1
+}
+
+static xdata unsigned char xbuf[1];
+
+void
+write_9862 (unsigned char which, unsigned char regno, unsigned char value)
+{
+ xbuf[0] = value;
+
+ spi_write (0, regno & 0x3f,
+ which == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+ SPI_FMT_MSB | SPI_FMT_HDR_1,
+ xbuf, 1);
+}
+
+void
+write_both_9862s (unsigned char regno, unsigned char value)
+{
+ xbuf[0] = value;
+
+ spi_write (0, regno & 0x3f,
+ SPI_ENABLE_CODEC_A | SPI_ENABLE_CODEC_B,
+ SPI_FMT_MSB | SPI_FMT_HDR_1,
+ xbuf, 1);
+}
+
+#define REG_RX_PWR_DN 1
+#define REG_TX_PWR_DN 8
+#define REG_TX_MODULATOR 20
+
+static void
+power_down_9862s (void)
+{
+ write_both_9862s (REG_RX_PWR_DN, 0x01);
+ write_both_9862s (REG_TX_PWR_DN, 0x0f); // pwr dn digital and analog_both
+ write_both_9862s (REG_TX_MODULATOR, 0x00); // coarse & fine modulators disabled
+}
+
+void
+init_board (void)
+{
+ la_trace_init ();
+ init_spi ();
+
+ USRP_PC &= ~bmPC_nRESET; // active low reset
+ USRP_PC |= bmPC_nRESET;
+
+ power_down_9862s ();
+}
diff --git a/firmware/fx2/usrp1/eeprom_io.c b/firmware/fx2/usrp1/eeprom_io.c
new file mode 100644
index 000000000..9eeb53636
--- /dev/null
+++ b/firmware/fx2/usrp1/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/usrp1/eeprom_io.h b/firmware/fx2/usrp1/eeprom_io.h
new file mode 100644
index 000000000..558017b12
--- /dev/null
+++ b/firmware/fx2/usrp1/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/usrp1/fpga_load.c b/firmware/fx2/usrp1/fpga_load.c
new file mode 100644
index 000000000..c3ae9e707
--- /dev/null
+++ b/firmware/fx2/usrp1/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
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rrc 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/usrp1/fpga_rev2.c b/firmware/fx2/usrp1/fpga_rev2.c
new file mode 100644
index 000000000..cca961dc4
--- /dev/null
+++ b/firmware/fx2/usrp1/fpga_rev2.c
@@ -0,0 +1,122 @@
+/* -*- 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"
+#include "spi.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)
+{
+ spi_write (0, 0x00 | (regno & 0x7f),
+ SPI_ENABLE_FPGA,
+ SPI_FMT_MSB | SPI_FMT_HDR_1,
+ regval, 4);
+}
+
+
+static xdata unsigned char regval[4] = {0, 0, 0, 0};
+
+static void
+write_fpga_master_ctrl (void)
+{
+ unsigned char v = 0;
+ if (g_tx_enable)
+ v |= bmFR_MC_ENABLE_TX;
+ if (g_rx_enable)
+ v |= bmFR_MC_ENABLE_RX;
+ if (g_tx_reset)
+ v |= bmFR_MC_RESET_TX;
+ if (g_rx_reset)
+ v |= bmFR_MC_RESET_RX;
+ regval[3] = v;
+
+ fpga_write_reg (FR_MASTER_CTRL, regval);
+}
+
+// Resets both AD9862's and the FPGA serial bus interface.
+
+void
+fpga_set_reset (unsigned char on)
+{
+ on &= 0x1;
+
+ if (on){
+ USRP_PC &= ~bmPC_nRESET; // active low
+ g_tx_enable = 0;
+ g_rx_enable = 0;
+ g_tx_reset = 0;
+ g_rx_reset = 0;
+ }
+ else
+ USRP_PC |= bmPC_nRESET;
+}
+
+void
+fpga_set_tx_enable (unsigned char on)
+{
+ on &= 0x1;
+ g_tx_enable = on;
+
+ write_fpga_master_ctrl ();
+
+ if (on){
+ g_tx_underrun = 0;
+ fpga_clear_flags ();
+ }
+}
+
+void
+fpga_set_rx_enable (unsigned char on)
+{
+ on &= 0x1;
+ g_rx_enable = on;
+
+ write_fpga_master_ctrl ();
+ if (on){
+ g_rx_overrun = 0;
+ fpga_clear_flags ();
+ }
+}
+
+void
+fpga_set_tx_reset (unsigned char on)
+{
+ on &= 0x1;
+ g_tx_reset = on;
+
+ write_fpga_master_ctrl ();
+}
+
+void
+fpga_set_rx_reset (unsigned char on)
+{
+ on &= 0x1;
+ g_rx_reset = on;
+
+ write_fpga_master_ctrl ();
+}
diff --git a/firmware/fx2/usrp1/fpga_rev2.h b/firmware/fx2/usrp1/fpga_rev2.h
new file mode 100644
index 000000000..54ec3f9fa
--- /dev/null
+++ b/firmware/fx2/usrp1/fpga_rev2.h
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+void fpga_set_reset (unsigned char v);
+void fpga_set_tx_enable (unsigned char v);
+void fpga_set_rx_enable (unsigned char v);
+void fpga_set_tx_reset (unsigned char v);
+void fpga_set_rx_reset (unsigned char v);
+
+unsigned char fpga_has_room_for_packet (void);
+unsigned char fpga_has_packet_avail (void);
+
+#if (UC_BOARD_HAS_FPGA)
+/*
+ * return TRUE iff FPGA internal fifo has room for 512 bytes.
+ */
+#define fpga_has_room_for_packet() (GPIFREADYSTAT & bmFPGA_HAS_SPACE)
+
+/*
+ * return TRUE iff FPGA internal fifo has at least 512 bytes available.
+ */
+#define fpga_has_packet_avail() (GPIFREADYSTAT & bmFPGA_PKT_AVAIL)
+
+#else /* no FPGA on board. fake it. */
+
+#define fpga_has_room_for_packet() TRUE
+#define fpga_has_packet_avail() TRUE
+
+#endif
+
+#define fpga_clear_flags() \
+ do { \
+ USRP_PE |= bmPE_FPGA_CLR_STATUS; \
+ USRP_PE &= ~bmPE_FPGA_CLR_STATUS; \
+ } while (0)
+
+
+#endif /* INCLUDED_FPGA_REV1_H */
diff --git a/firmware/fx2/usrp1/gpif.c b/firmware/fx2/usrp1/gpif.c
new file mode 100644
index 000000000..f6745a43b
--- /dev/null
+++ b/firmware/fx2/usrp1/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 = CLRST CMOS
+// CTL 4 = unused CMOS
+// CTL 5 = BOGUS CMOS
+
+// GPIF Rdy Inputs
+// RDY0 = EF#
+// RDY1 = FF#
+// RDY2 = unused
+// RDY3 = unused
+// 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 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x26,0x00,0x04,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x21,0x00,0x04,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/usrp1/gpif.gpf b/firmware/fx2/usrp1/gpif.gpf
new file mode 100755
index 000000000..854e25399
--- /dev/null
+++ b/firmware/fx2/usrp1/gpif.gpf
Binary files differ
diff --git a/firmware/fx2/usrp1/usb_descriptors.a51 b/firmware/fx2/usrp1/usb_descriptors.a51
new file mode 100644
index 000000000..a60adbef8
--- /dev/null
+++ b/firmware/fx2/usrp1/usb_descriptors.a51
@@ -0,0 +1,404 @@
+;;; -*- 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 USRP
+;;;
+;;; We're a high-speed only device (480 Mb/sec) with 1 configuration
+;;; and 3 interfaces.
+;;;
+;;; interface 0: command and status (ep0 COMMAND)
+;;; interface 1: Transmit path (ep2 OUT BULK)
+;;; interface 2: Receive path (ep6 IN BULK)
+
+ .module usb_descriptors
+
+ VID_FREE = 0xfffe ; Free Software Folks
+ PID_USRP = 0x0002 ; USRP
+
+ ;; 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
+
+_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 3 ; 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)
+
+_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
+_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 ' , 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:
+
diff --git a/firmware/fx2/usrp1/usrp_common.c b/firmware/fx2/usrp1/usrp_common.c
new file mode 100644
index 000000000..0998653c2
--- /dev/null
+++ b/firmware/fx2/usrp1/usrp_common.c
@@ -0,0 +1,109 @@
+/*
+ * 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 | bmQUADBUF; SYNCDELAY; // 512 quad bulk OUT
+ EP4CFG = 0; SYNCDELAY; // disabled
+ EP6CFG = bmVALID | bmBULK | bmQUADBUF | bmIN; SYNCDELAY; // 512 quad bulk IN
+ EP8CFG = 0; SYNCDELAY; // disabled
+
+ // 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 = bmAUTOIN | bmWORDWIDE; SYNCDELAY;
+
+
+ // prime the pump
+
+#if 0
+ EP2BCL = 0x80; SYNCDELAY;
+ EP2BCL = 0x80; SYNCDELAY;
+ EP2BCL = 0x80; SYNCDELAY;
+ EP2BCL = 0x80; SYNCDELAY;
+#endif
+
+ EP0BCH = 0; SYNCDELAY;
+
+ // arm EP1OUT so we can receive "out" packets (TRM pg 8-8)
+
+ EP1OUTBC = 0; SYNCDELAY;
+
+ EP2GPIFFLGSEL = 0x01; SYNCDELAY; // For EP2OUT, GPIF uses EF flag
+ EP6GPIFFLGSEL = 0x02; SYNCDELAY; // For EP6IN, GPIF uses FF flag
+
+ // 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;
+
+ init_board ();
+}
+
diff --git a/firmware/fx2/usrp1/usrp_gpif.c b/firmware/fx2/usrp1/usrp_gpif.c
new file mode 100644
index 000000000..1191c8b28
--- /dev/null
+++ b/firmware/fx2/usrp1/usrp_gpif.c
@@ -0,0 +1,206 @@
+/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+// 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 = CLRST CMOS
+// CTL 4 = unused CMOS
+// CTL 5 = BOGUS CMOS
+
+// GPIF Rdy Inputs
+// RDY0 = EF#
+// RDY1 = FF#
+// RDY2 = unused
+// RDY3 = unused
+// 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 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 FlowStates[36] =
+{
+/* Wave 0 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x26,0x00,0x04,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x21,0x00,0x04,0x04,0x03,0x02,0x00,
+};
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char InitData[7] =
+{
+/* Regs */ 0xA0,0x00,0x00,0x00,0xEE,0x4E,0x00
+};
+// END DO NOT EDIT
+
+// TO DO: You may add additional code below.
+
diff --git a/firmware/fx2/usrp1/usrp_gpif_inline.h b/firmware/fx2/usrp1/usrp_gpif_inline.h
new file mode 100644
index 000000000..77a741a8b
--- /dev/null
+++ b/firmware/fx2/usrp1/usrp_gpif_inline.h
@@ -0,0 +1,27 @@
+/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+#define setup_flowstate_common() \
+do { \
+ FLOWSTATE = 0x81; \
+ FLOWLOGIC = 0x2d; \
+ FLOWEQ0CTL = 0x26; \
+ FLOWEQ1CTL = 0x00; \
+ FLOWHOLDOFF = 0x04; \
+ FLOWSTB = 0x04; \
+ FLOWSTBEDGE = 0x03; \
+FLOWSTBHPERIOD = 0x02; \
+GPIFHOLDAMOUNT = 0x00; \
+} while (0)
+
+#define setup_flowstate_read() \
+do { \
+ FLOWEQ0CTL = 0x26; \
+} while (0)
+
+#define setup_flowstate_write() \
+do { \
+ FLOWEQ0CTL = 0x21; \
+} while (0)
+
diff --git a/firmware/fx2/usrp1/usrp_main.c b/firmware/fx2/usrp1/usrp_main.c
new file mode 100644
index 000000000..3eb8c001f
--- /dev/null
+++ b/firmware/fx2/usrp1/usrp_main.c
@@ -0,0 +1,389 @@
+/*
+ * 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_regs.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 "spi.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;
+
+/*
+ * 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];
+
+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
+ ;
+}
+
+/*
+ * 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:
+ switch (wIndexL){
+
+ case GS_TX_UNDERRUN:
+ EP0BUF[0] = g_tx_underrun;
+ g_tx_underrun = 0;
+ EP0BCH = 0;
+ EP0BCL = 1;
+ break;
+
+ case GS_RX_OVERRUN:
+ EP0BUF[0] = g_rx_overrun;
+ g_rx_overrun = 0;
+ EP0BCH = 0;
+ EP0BCL = 1;
+ break;
+
+ default:
+ return 0;
+ }
+ break;
+
+ case VRQ_I2C_READ:
+ if (!i2c_read (wValueL, EP0BUF, wLengthL))
+ return 0;
+
+ EP0BCH = 0;
+ EP0BCL = wLengthL;
+ break;
+
+ case VRQ_SPI_READ:
+ if (!spi_read (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, wLengthL))
+ return 0;
+
+ EP0BCH = 0;
+ EP0BCL = wLengthL;
+ break;
+
+ case VRQ_SPI_TRANSACT:
+ if (!spi_transact (wValueH, wValueL, wIndexH, wIndexL, wLengthH, EP0BUF, wLengthL))
+ return 0;
+
+ EP0BCH = 0;
+ EP0BCL = wLengthL;
+ 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_FPGA_SET_TX_ENABLE:
+ fpga_set_tx_enable (wValueL);
+ break;
+
+ case VRQ_FPGA_SET_RX_ENABLE:
+ fpga_set_rx_enable (wValueL);
+ break;
+
+ case VRQ_FPGA_SET_TX_RESET:
+ fpga_set_tx_reset (wValueL);
+ break;
+
+ case VRQ_FPGA_SET_RX_RESET:
+ fpga_set_rx_reset (wValueL);
+ break;
+
+ case VRQ_I2C_WRITE:
+ get_ep0_data ();
+ if (!i2c_write (wValueL, EP0BUF, EP0BCL))
+ return 0;
+ break;
+
+ case VRQ_SPI_WRITE:
+ get_ep0_data ();
+ if (!spi_write (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, EP0BCL))
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ }
+ else
+ return 0; // invalid bRequestType
+
+ return 1;
+}
+
+
+
+static void
+main_loop (void)
+{
+ setup_flowstate_common ();
+
+ while (1){
+
+ if (usb_setup_packet_avail ())
+ usb_handle_setup_packet ();
+
+
+ if (GPIFTRIG & bmGPIF_IDLE){
+
+ // OK, GPIF is idle. Let's try to give it some work.
+
+ // First check for underruns and overruns
+
+ if (UC_BOARD_HAS_FPGA && (USRP_PA & (bmPA_TX_UNDERRUN | bmPA_RX_OVERRUN))){
+
+ // record the under/over run
+ if (USRP_PA & bmPA_TX_UNDERRUN)
+ g_tx_underrun = 1;
+
+ if (USRP_PA & bmPA_RX_OVERRUN)
+ g_rx_overrun = 1;
+
+ // tell the FPGA to clear the flags
+ fpga_clear_flags ();
+ }
+
+ // Next see if there are any "OUT" packets waiting for our attention,
+ // and if so, if there's room in the FPGA's FIFO for them.
+
+ if (g_tx_enable && !(EP24FIFOFLGS & 0x02)){ // USB end point fifo is not empty...
+
+ if (fpga_has_room_for_packet ()){ // ... and FPGA has room for packet
+
+ GPIFTCB1 = 0x01; SYNCDELAY;
+ GPIFTCB0 = 0x00; SYNCDELAY;
+
+ setup_flowstate_write ();
+
+ SYNCDELAY;
+ GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer
+ SYNCDELAY;
+
+ while (!(GPIFTRIG & bmGPIF_IDLE)){
+ // wait for the transaction to complete
+ }
+ }
+ }
+
+ // See if there are any requests for "IN" packets, and if so
+ // whether the FPGA's got any packets for us.
+
+ if (g_rx_enable && !(EP6CS & bmEPFULL)){ // USB end point fifo is not full...
+
+ if (fpga_has_packet_avail ()){ // ... and FPGA has packet available
+
+ GPIFTCB1 = 0x01; SYNCDELAY;
+ GPIFTCB0 = 0x00; SYNCDELAY;
+
+ setup_flowstate_read ();
+
+ SYNCDELAY;
+ GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+
+ while (!(GPIFTRIG & bmGPIF_IDLE)){
+ // wait for the transaction to complete
+ }
+
+ SYNCDELAY;
+ INPKTEND = 6; // tell USB we filled buffer (6 is our endpoint num)
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * 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)
+{
+#if 0
+ g_rx_enable = 0; // FIXME (work around initialization bug)
+ g_tx_enable = 0;
+ g_rx_overrun = 0;
+ g_tx_underrun = 0;
+#endif
+
+ 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
+
+ main_loop ();
+}
diff --git a/firmware/fx2/usrp1/usrp_regs.h b/firmware/fx2/usrp1/usrp_regs.h
new file mode 100644
index 000000000..a4f1d9896
--- /dev/null
+++ b/firmware/fx2/usrp1/usrp_regs.h
@@ -0,0 +1,163 @@
+/*
+ * 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 _USRP_REV1_REGS_H_
+#define _USRP_REV1_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 bmPA_S_CLK bmBIT0 // SPI serial clock
+#define bmPA_S_DATA_TO_PERIPH bmBIT1 // SPI SDI (peripheral rel name)
+#define bmPA_S_DATA_FROM_PERIPH bmBIT2 // SPI SDO (peripheral rel name)
+#define bmPA_SEN_FPGA bmBIT3 // serial enable for FPGA (active low)
+#define bmPA_SEN_CODEC_A bmBIT4 // serial enable AD9862 A (active low)
+#define bmPA_SEN_CODEC_B bmBIT5 // serial enable AD9862 B (active low)
+//#define bmPA_FX2_2 bmBIT6 // misc pin to FPGA (overflow)
+//#define bmPA_FX2_3 bmBIT7 // misc pin to FPGA (underflow)
+#define bmPA_RX_OVERRUN bmBIT6 // misc pin to FPGA (overflow)
+#define bmPA_TX_UNDERRUN bmBIT7 // misc pin to FPGA (underflow)
+
+
+sbit at 0x80+0 bitS_CLK; // 0x80 is the bit address of PORT A
+sbit at 0x80+1 bitS_OUT; // out from FX2 point of view
+sbit at 0x80+2 bitS_IN; // in from FX2 point of view
+
+
+/* all outputs except S_DATA_FROM_PERIPH, FX2_2, FX2_3 */
+
+#define bmPORT_A_OUTPUTS (bmPA_S_CLK \
+ | bmPA_S_DATA_TO_PERIPH \
+ | bmPA_SEN_FPGA \
+ | bmPA_SEN_CODEC_A \
+ | bmPA_SEN_CODEC_B \
+ )
+
+#define bmPORT_A_INITIAL (bmPA_SEN_FPGA | bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+
+
+/* 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 USRP_ALTERA_CONFIG USRP_PC
+
+#define bmPC_nRESET bmBIT0 // reset line to codecs (active low)
+#define bmALTERA_DATA0 bmBIT1
+#define bmALTERA_NCONFIG bmBIT2
+#define bmALTERA_DCLK bmBIT3
+#define bmALTERA_CONF_DONE bmBIT4
+#define bmALTERA_NSTATUS bmBIT5
+#define bmPC_LED0 bmBIT6 // active low
+#define bmPC_LED1 bmBIT7 // active low
+
+sbit at 0xA0+1 bitALTERA_DATA0; // 0xA0 is the bit address of PORT C
+sbit at 0xA0+3 bitALTERA_DCLK;
+
+
+#define bmALTERA_BITS (bmALTERA_DATA0 \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DCLK \
+ | bmALTERA_CONF_DONE \
+ | bmALTERA_NSTATUS)
+
+#define bmPORT_C_OUTPUTS (bmPC_nRESET \
+ | bmALTERA_DATA0 \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DCLK \
+ | 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 bmPE_PE0 bmBIT0 // GPIF debug output
+#define bmPE_PE1 bmBIT1 // GPIF debug output
+#define bmPE_PE2 bmBIT2 // GPIF debug output
+#define bmPE_FPGA_CLR_STATUS bmBIT3 // misc pin to FPGA (clear status)
+#define bmPE_SEN_TX_A bmBIT4 // serial enable d'board TX A (active low)
+#define bmPE_SEN_RX_A bmBIT5 // serial enable d'board RX A (active low)
+#define bmPE_SEN_TX_B bmBIT6 // serial enable d'board TX B (active low)
+#define bmPE_SEN_RX_B bmBIT7 // serial enable d'board RX B (active low)
+
+
+#define bmPORT_E_OUTPUTS (bmPE_FPGA_CLR_STATUS \
+ | bmPE_SEN_TX_A \
+ | bmPE_SEN_RX_A \
+ | bmPE_SEN_TX_B \
+ | bmPE_SEN_RX_B \
+ )
+
+
+#define bmPORT_E_INITIAL (bmPE_SEN_TX_A \
+ | bmPE_SEN_RX_A \
+ | bmPE_SEN_TX_B \
+ | bmPE_SEN_RX_B \
+ )
+
+/*
+ * 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 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...
+ */
+// WR bmBIT0 // usbctl[0]
+// RD bmBIT1 // usbctl[1]
+// OE bmBIT2 // usbctl[2]
+
+#endif /* _USRP_REV1_REGS_H_ */
diff --git a/firmware/fx2/utils/build_eeprom.py b/firmware/fx2/utils/build_eeprom.py
new file mode 100755
index 000000000..298ccc00c
--- /dev/null
+++ b/firmware/fx2/utils/build_eeprom.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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.
+#
+
+import re
+import sys
+import os, os.path
+from optparse import OptionParser
+
+# USB Vendor and Product ID's
+
+VID = 0xfffe # Free Software Folks
+
+
+def msb (x):
+ return (x >> 8) & 0xff
+
+def lsb (x):
+ return x & 0xff
+
+def build_eeprom_image (filename, rev):
+ """Build a ``C2 Load'' EEPROM image.
+
+ For details on this format, see section 3.4.3 of
+ the EZ-USB FX2 Technical Reference Manual
+ """
+ # get the code we want to run
+ f = open(filename, 'rb')
+ bytes = f.read()
+
+ devid = 4 #for compatibility
+ start_addr = 0 #prove me wrong
+
+ if(rev == 1):
+ PID = 0x0002 #USRP1
+ else:
+ PID = 0x0003 #USRP1P
+
+ rom_header = [
+ 0xC2, # boot from EEPROM
+ lsb (VID),
+ msb (VID),
+ lsb (PID),
+ msb (PID),
+ lsb (devid),
+ msb (devid),
+ 0 # configuration byte
+ ]
+
+ # 4 byte header that indicates where to load
+ # the immediately follow code bytes.
+ code_header = [
+ msb (len (bytes)),
+ lsb (len (bytes)),
+ msb (start_addr),
+ lsb (start_addr)
+ ]
+
+ # writes 0 to CPUCS reg (brings FX2 out of reset)
+ trailer = [
+ 0x80,
+ 0x01,
+ 0xe6,
+ 0x00,
+ 0x00
+ ]
+
+ image = rom_header + code_header + [ord(c) for c in bytes] + trailer
+
+ assert (len (image) <= 256)
+ return image
+
+if __name__ == '__main__':
+ usage = "usage: %prog -r REV [options] bootfile.bin outfile.bin"
+ parser = OptionParser (usage=usage)
+ parser.add_option ("-r", "--rev", type="int", default=-1,
+ help="Specify USRP revision, 1 for USRP1, 2 for USRP1P")
+ (options, args) = parser.parse_args ()
+ if len (args) != 2:
+ parser.print_help ()
+ sys.exit (1)
+ if options.rev < 0:
+ sys.stderr.write (
+ "You must specify the USRP revision number (2 or 4) with -r REV\n")
+ sys.exit (1)
+
+ infile = args[0]
+ outfile = args[1]
+
+ image = "".join(chr(c) for c in build_eeprom_image(infile, options.rev))
+
+ f = open(outfile, 'wb')
+ f.write(str(image))
+ f.close()
diff --git a/firmware/fx2/utils/edit-gpif.py b/firmware/fx2/utils/edit-gpif.py
new file mode 100755
index 000000000..5367b75a5
--- /dev/null
+++ b/firmware/fx2/utils/edit-gpif.py
@@ -0,0 +1,114 @@
+#!/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_FLOW_STATE = 2
+ WRITE_FLOW_STATE = 3
+
+ read_info = zip (regs, dict[READ_FLOW_STATE])
+ write_info = zip (regs, dict[WRITE_FLOW_STATE])
+
+ output.write ('''/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+''')
+ write_define (output, 'setup_flowstate_common', read_info)
+ write_define (output, 'setup_flowstate_read', delta (read_info, write_info))
+ write_define (output, 'setup_flowstate_write', delta (write_info, read_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])
diff --git a/firmware/fx2/utils/generate_regs.py b/firmware/fx2/utils/generate_regs.py
new file mode 100755
index 000000000..656cd5e81
--- /dev/null
+++ b/firmware/fx2/utils/generate_regs.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+
+import os, os.path
+import re
+import sys
+
+
+# set srcdir to the directory that contains Makefile.am
+try:
+ srcdir = os.environ['srcdir']
+except KeyError, e:
+ srcdir = "."
+srcdir = srcdir + '/'
+
+def open_src (name, mode):
+ global srcdir
+ return open (os.path.join (srcdir, name), mode)
+
+
+def generate_fpga_regs (h_filename, v_filename):
+ const_width = 7 # bit width of constants
+
+ h_file = open_src (h_filename, 'r')
+ v_file = open (v_filename, 'w')
+ v_file.write (
+ '''//
+// This file is machine generated from %s
+// Do not edit by hand; your edits will be overwritten.
+//
+''' % (h_filename,))
+
+ pat = re.compile (r'^#define\s*(FR_\w*)\s*(\w*)(.*)$')
+ pat_bitno = re.compile (r'^#define\s*(bitno\w*)\s*(\w*)(.*)$')
+ pat_bm = re.compile (r'^#define\s*(bm\w*)\s*(\w*)(.*)$')
+ for line in h_file:
+ if re.match ('//|\s*$', line): # comment or blank line
+ v_file.write (line)
+ mo = pat.search (line)
+ mo_bitno =pat_bitno.search (line)
+ mo_bm =pat_bm.search (line)
+ if mo:
+ v_file.write ('`define %-25s %d\'d%s%s\n' % (
+ mo.group (1), const_width, mo.group (2), mo.group (3)))
+ elif mo_bitno:
+ v_file.write ('`define %-25s %s%s\n' % (
+ mo_bitno.group (1), mo_bitno.group (2), mo_bitno.group (3)))
+ elif mo_bm:
+ v_file.write ('`define %-25s %s%s\n' % (
+ mo_bm.group (1), mo_bm.group (2), mo_bm.group (3)))
+
+
+if __name__ == '__main__':
+ if len (sys.argv) != 3:
+ sys.stderr.write ('usage: %s file.h file.v\n' % (sys.argv[0]))
+ sys.exit (1)
+ generate_fpga_regs (sys.argv[1], sys.argv[2])
+