summaryrefslogtreecommitdiffstats
path: root/firmware/fx2/src/usrp1
diff options
context:
space:
mode:
authorThomas Tsou <ttsou@vt.edu>2010-08-05 11:48:41 -0700
committerThomas Tsou <ttsou@vt.edu>2010-08-13 12:25:36 -0700
commit70eae1d242a9530cab4efa927bd1331b099fdd00 (patch)
treea0050754ec06f71e9b2dd4415e576c370143b429 /firmware/fx2/src/usrp1
parentef6953024f1075a729e85f2511c75de337879888 (diff)
downloaduhd-70eae1d242a9530cab4efa927bd1331b099fdd00.tar.gz
uhd-70eae1d242a9530cab4efa927bd1331b099fdd00.tar.bz2
uhd-70eae1d242a9530cab4efa927bd1331b099fdd00.zip
usrp1: Add FX2 firmware files
These firmware files for the usrp1 are imported from GNURadio.
Diffstat (limited to 'firmware/fx2/src/usrp1')
-rw-r--r--firmware/fx2/src/usrp1/.gitignore20
-rw-r--r--firmware/fx2/src/usrp1/Makefile.am171
-rw-r--r--firmware/fx2/src/usrp1/_startup.a511
-rw-r--r--firmware/fx2/src/usrp1/blink_leds.c1
-rw-r--r--firmware/fx2/src/usrp1/board_specific.c113
-rw-r--r--firmware/fx2/src/usrp1/check_mdelay.c1
-rw-r--r--firmware/fx2/src/usrp1/check_udelay.c1
-rwxr-xr-xfirmware/fx2/src/usrp1/edit-gpif114
-rw-r--r--firmware/fx2/src/usrp1/eeprom_boot.a51573
-rw-r--r--firmware/fx2/src/usrp1/eeprom_init.c116
-rw-r--r--firmware/fx2/src/usrp1/eeprom_io.c65
-rw-r--r--firmware/fx2/src/usrp1/eeprom_io.h38
-rw-r--r--firmware/fx2/src/usrp1/fpga_load.c1
-rw-r--r--firmware/fx2/src/usrp1/fpga_rev2.c122
-rw-r--r--firmware/fx2/src/usrp1/fpga_rev2.h58
-rw-r--r--firmware/fx2/src/usrp1/gpif.c292
-rwxr-xr-xfirmware/fx2/src/usrp1/gpif.gpfbin0 -> 5341 bytes
-rw-r--r--firmware/fx2/src/usrp1/init_gpif.c1
-rw-r--r--firmware/fx2/src/usrp1/spi.c381
-rw-r--r--firmware/fx2/src/usrp1/spi.h43
-rw-r--r--firmware/fx2/src/usrp1/usb_descriptors.a51404
-rw-r--r--firmware/fx2/src/usrp1/usrp_common.c1
-rw-r--r--firmware/fx2/src/usrp1/usrp_common.h77
-rw-r--r--firmware/fx2/src/usrp1/usrp_main.c380
-rw-r--r--firmware/fx2/src/usrp1/usrp_rev2_regs.h163
-rw-r--r--firmware/fx2/src/usrp1/vectors.a511
26 files changed, 3138 insertions, 0 deletions
diff --git a/firmware/fx2/src/usrp1/.gitignore b/firmware/fx2/src/usrp1/.gitignore
new file mode 100644
index 000000000..54a9e9415
--- /dev/null
+++ b/firmware/fx2/src/usrp1/.gitignore
@@ -0,0 +1,20 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/Makefile
+/Makefile.in
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile.in
+/burn-usrp2-eeprom
+/burn-usrp4-eeprom
diff --git a/firmware/fx2/src/usrp1/Makefile.am b/firmware/fx2/src/usrp1/Makefile.am
new file mode 100644
index 000000000..5586e83a3
--- /dev/null
+++ b/firmware/fx2/src/usrp1/Makefile.am
@@ -0,0 +1,171 @@
+#
+# Copyright 2003,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.
+#
+
+firmware2dir = $(prefix)/share/usrp/rev2
+firmware2_DATA = std.ihx
+
+# we put the same stuff in the rev4 directory
+firmware4dir = $(prefix)/share/usrp/rev4
+firmware4_DATA = std.ihx
+
+EXTRA_DIST = \
+ edit-gpif \
+ _startup.a51 \
+ blink_leds.c \
+ board_specific.c \
+ check_mdelay.c \
+ check_udelay.c \
+ eeprom_boot.a51 \
+ eeprom_init.c \
+ eeprom_io.c \
+ eeprom_io.h \
+ fpga_load.c \
+ fpga_rev2.c \
+ fpga_rev2.h \
+ gpif.c \
+ init_gpif.c \
+ spi.c \
+ spi.h \
+ usb_descriptors.a51 \
+ usrp_common.c \
+ usrp_common.h \
+ usrp_gpif.c \
+ usrp_main.c \
+ usrp_rev2_regs.h \
+ vectors.a51
+
+
+DEFINES=-DHAVE_USRP2
+FW_INCLUDES=-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/usrp1 \
+ -I$(top_srcdir)/src/common \
+ -I$(top_builddir)/src/common
+
+# with EA = 0, the FX2 implements a portion of the 8051 "external memory"
+# on chip. This memory is mapped like this:
+#
+# The bottom 8K of memory (0x0000 - 0x1fff) is used for both data and
+# code accesses. There's also 512 bytes for data only from 0xe000 - 0xe1ff.
+#
+# We tell the linker to start the xdata segment at 0x1800, 6K up from
+# the bottom.
+
+MEMOPTS = --code-loc 0x0000 --code-size 0x1800 --xram-loc 0x1800 --xram-size 0x0800 \
+ -Wl '-b USBDESCSEG = 0xE000'
+
+LIBOPTS = -L ../../lib libfx2.lib
+LIBDEP = ../../lib/libfx2.lib
+
+LINKOPTS = $(MEMOPTS) $(LIBOPTS)
+
+EXECUTABLES = \
+ std.ihx \
+ blink_leds.ihx \
+ check_mdelay.ihx \
+ check_udelay.ihx \
+ eeprom_boot.ihx
+
+STARTUP = _startup.rel
+
+noinst_SCRIPTS = \
+ burn-usrp2-eeprom \
+ burn-usrp4-eeprom
+
+
+.c.rel:
+ $(XCC) $(FW_INCLUDES) $(DEFINES) \
+ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+.a51.rel:
+ test -f `basename '$<'` || $(LN_S) '$<' .
+ test -f ../common/`basename '$<'` -o \
+ \! -f `dirname '$<'`/../common/`basename '$<'` \
+ || $(LN_S) `dirname '$<'`/../common/`basename '$<'` ../common/`basename '$<'`
+ $(XAS) `basename '$<'`
+
+
+EEPROM_BOOT_OBJS = eeprom_boot.rel eeprom_init.rel $(STARTUP)
+
+eeprom_boot.ihx: $(EEPROM_BOOT_OBJS) $(LIBDEP)
+ $(XCC) $(LINKOPTS) -o $@ $(EEPROM_BOOT_OBJS)
+
+burn-usrp2-eeprom: eeprom_boot.ihx
+ $(PYTHON) $(srcdir)/../common/build_eeprom.py -r2 eeprom_boot.ihx > $@
+ chmod +x $@
+
+burn-usrp4-eeprom: eeprom_boot.ihx
+ $(PYTHON) $(srcdir)/../common/build_eeprom.py -r4 eeprom_boot.ihx > $@
+ chmod +x $@
+
+
+BLINK_LEDS_OBJS = blink_leds.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+blink_leds.ihx: $(BLINK_LEDS_OBJS) $(LIBDEP)
+ $(XCC) $(LINKOPTS) -o $@ $(BLINK_LEDS_OBJS)
+
+
+CHECK_MDELAY_OBJS = check_mdelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+check_mdelay.ihx: $(CHECK_MDELAY_OBJS) $(LIBDEP)
+ $(XCC) $(LINKOPTS) -o $@ $(CHECK_MDELAY_OBJS)
+
+
+
+CHECK_UDELAY_OBJS = check_udelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+check_udelay.ihx: $(CHECK_UDELAY_OBJS) $(LIBDEP)
+ $(XCC) $(LINKOPTS) -o $@ $(CHECK_UDELAY_OBJS)
+
+
+
+USRP_OBJS = \
+ vectors.rel \
+ usrp_main.rel usrp_common.rel board_specific.rel \
+ fpga_load.rel fpga_rev2.rel init_gpif.rel usrp_gpif.rel \
+ usb_descriptors.rel spi.rel eeprom_io.rel $(STARTUP)
+
+std.ihx: $(USRP_OBJS) $(LIBDEP)
+ $(XCC) $(LINKOPTS) -o $@ $(USRP_OBJS)
+
+CLEANFILES = \
+ *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib \
+ usrp_gpif.c usrp_gpif_inline.h \
+ burn-usrp2-eeprom \
+ burn-usrp4-eeprom
+
+DISTCLEANFILES = \
+ *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib
+
+# build gpif stuff
+
+all: usrp_gpif.c
+
+usrp_gpif.c usrp_gpif_inline.h : gpif.c
+ srcdir=$(srcdir) $(PYTHON) $(srcdir)/edit-gpif $(srcdir)/gpif.c usrp_gpif.c usrp_gpif_inline.h
+
+
+# dependencies
+
+usrp_main.rel: usrp_gpif_inline.h
+#usrp_main.rel: fpga.h usrp_common.h ../../include/usrp_commands.h usrp_gpif_inline.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#usrp_common.rel: usrp_common.h ../../include/usrp_commands.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#fpga.rel: usrp_common.h ../../include/usrp_commands.h fpga.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#init_gpif.rel: usrp_common.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
diff --git a/firmware/fx2/src/usrp1/_startup.a51 b/firmware/fx2/src/usrp1/_startup.a51
new file mode 100644
index 000000000..4f5309922
--- /dev/null
+++ b/firmware/fx2/src/usrp1/_startup.a51
@@ -0,0 +1 @@
+ .include "../common/_startup.a51"
diff --git a/firmware/fx2/src/usrp1/blink_leds.c b/firmware/fx2/src/usrp1/blink_leds.c
new file mode 100644
index 000000000..c633d5d48
--- /dev/null
+++ b/firmware/fx2/src/usrp1/blink_leds.c
@@ -0,0 +1 @@
+#include "../common/blink_leds.c"
diff --git a/firmware/fx2/src/usrp1/board_specific.c b/firmware/fx2/src/usrp1/board_specific.c
new file mode 100644
index 000000000..ef0081d84
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/check_mdelay.c b/firmware/fx2/src/usrp1/check_mdelay.c
new file mode 100644
index 000000000..ea4ccdb14
--- /dev/null
+++ b/firmware/fx2/src/usrp1/check_mdelay.c
@@ -0,0 +1 @@
+#include "../common/check_mdelay.c"
diff --git a/firmware/fx2/src/usrp1/check_udelay.c b/firmware/fx2/src/usrp1/check_udelay.c
new file mode 100644
index 000000000..d01622e5e
--- /dev/null
+++ b/firmware/fx2/src/usrp1/check_udelay.c
@@ -0,0 +1 @@
+#include "../common/check_udelay.c"
diff --git a/firmware/fx2/src/usrp1/edit-gpif b/firmware/fx2/src/usrp1/edit-gpif
new file mode 100755
index 000000000..5367b75a5
--- /dev/null
+++ b/firmware/fx2/src/usrp1/edit-gpif
@@ -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/src/usrp1/eeprom_boot.a51 b/firmware/fx2/src/usrp1/eeprom_boot.a51
new file mode 100644
index 000000000..65e452668
--- /dev/null
+++ b/firmware/fx2/src/usrp1/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/src/usrp1/eeprom_init.c b/firmware/fx2/src/usrp1/eeprom_init.c
new file mode 100644
index 000000000..a6f6cbe2d
--- /dev/null
+++ b/firmware/fx2/src/usrp1/eeprom_init.c
@@ -0,0 +1,116 @@
+/* -*- 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"
+#include "spi.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 enable_codecs() USRP_PA &= ~(bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+#define disable_all() USRP_PA |= (bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+
+static void
+write_byte_msb (unsigned char v);
+
+void
+write_both_9862s (unsigned char header_lo, unsigned char v)
+{
+ enable_codecs ();
+
+ write_byte_msb (header_lo);
+ write_byte_msb (v);
+
+ disable_all ();
+}
+
+// ----------------------------------------------------------------
+
+static void
+write_byte_msb (unsigned char v)
+{
+ unsigned char n = 8;
+ do {
+ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit)
+ bitS_OUT = v & 0x1;
+ bitS_CLK = 1;
+ bitS_CLK = 0;
+ } while (--n != 0);
+}
+
+// ----------------------------------------------------------------
+
+#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;
+
+ // init_spi ();
+ bitS_OUT = 0; /* idle state has CLK = 0 */
+
+ 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
+
+ // 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/src/usrp1/eeprom_io.c b/firmware/fx2/src/usrp1/eeprom_io.c
new file mode 100644
index 000000000..9eeb53636
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/eeprom_io.h b/firmware/fx2/src/usrp1/eeprom_io.h
new file mode 100644
index 000000000..558017b12
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/fpga_load.c b/firmware/fx2/src/usrp1/fpga_load.c
new file mode 100644
index 000000000..b0256e925
--- /dev/null
+++ b/firmware/fx2/src/usrp1/fpga_load.c
@@ -0,0 +1 @@
+#include "../common/fpga_load.c"
diff --git a/firmware/fx2/src/usrp1/fpga_rev2.c b/firmware/fx2/src/usrp1/fpga_rev2.c
new file mode 100644
index 000000000..cca961dc4
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/fpga_rev2.h b/firmware/fx2/src/usrp1/fpga_rev2.h
new file mode 100644
index 000000000..54ec3f9fa
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/gpif.c b/firmware/fx2/src/usrp1/gpif.c
new file mode 100644
index 000000000..f6745a43b
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/gpif.gpf b/firmware/fx2/src/usrp1/gpif.gpf
new file mode 100755
index 000000000..854e25399
--- /dev/null
+++ b/firmware/fx2/src/usrp1/gpif.gpf
Binary files differ
diff --git a/firmware/fx2/src/usrp1/init_gpif.c b/firmware/fx2/src/usrp1/init_gpif.c
new file mode 100644
index 000000000..0f5944b3b
--- /dev/null
+++ b/firmware/fx2/src/usrp1/init_gpif.c
@@ -0,0 +1 @@
+#include "../common/init_gpif.c"
diff --git a/firmware/fx2/src/usrp1/spi.c b/firmware/fx2/src/usrp1/spi.c
new file mode 100644
index 000000000..f5803c55b
--- /dev/null
+++ b/firmware/fx2/src/usrp1/spi.c
@@ -0,0 +1,381 @@
+/* -*- 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_rev2_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);
+
+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);
+
+
+// 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
+}
+
+// ----------------------------------------------------------------
+
+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/src/usrp1/spi.h b/firmware/fx2/src/usrp1/spi.h
new file mode 100644
index 000000000..12bc5e544
--- /dev/null
+++ b/firmware/fx2/src/usrp1/spi.h
@@ -0,0 +1,43 @@
+/* -*- 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);
+
+
+#endif /* INCLUDED_SPI_H */
diff --git a/firmware/fx2/src/usrp1/usb_descriptors.a51 b/firmware/fx2/src/usrp1/usb_descriptors.a51
new file mode 100644
index 000000000..a60adbef8
--- /dev/null
+++ b/firmware/fx2/src/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/src/usrp1/usrp_common.c b/firmware/fx2/src/usrp1/usrp_common.c
new file mode 100644
index 000000000..f389d9253
--- /dev/null
+++ b/firmware/fx2/src/usrp1/usrp_common.c
@@ -0,0 +1 @@
+#include "../common/usrp_common.c"
diff --git a/firmware/fx2/src/usrp1/usrp_common.h b/firmware/fx2/src/usrp1/usrp_common.h
new file mode 100644
index 000000000..738ba6b37
--- /dev/null
+++ b/firmware/fx2/src/usrp1/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_rev2_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/src/usrp1/usrp_main.c b/firmware/fx2/src/usrp1/usrp_main.c
new file mode 100644
index 000000000..c7c09f8c5
--- /dev/null
+++ b/firmware/fx2/src/usrp1/usrp_main.c
@@ -0,0 +1,380 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#include "usrp_common.h"
+#include "usrp_commands.h"
+#include "fpga.h"
+#include "usrp_gpif_inline.h"
+#include "timer.h"
+#include "i2c.h"
+#include "isr.h"
+#include "usb_common.h"
+#include "fx2utils.h"
+#include "usrp_globals.h"
+#include "usrp_i2c_addr.h"
+#include <string.h>
+#include "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;
+
+ 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/src/usrp1/usrp_rev2_regs.h b/firmware/fx2/src/usrp1/usrp_rev2_regs.h
new file mode 100644
index 000000000..a4f1d9896
--- /dev/null
+++ b/firmware/fx2/src/usrp1/usrp_rev2_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/src/usrp1/vectors.a51 b/firmware/fx2/src/usrp1/vectors.a51
new file mode 100644
index 000000000..fa579ba8a
--- /dev/null
+++ b/firmware/fx2/src/usrp1/vectors.a51
@@ -0,0 +1 @@
+ .include "../common/vectors.a51"