diff options
Diffstat (limited to 'firmware/fx2/usrp1')
-rw-r--r-- | firmware/fx2/usrp1/CMakeLists.txt | 84 | ||||
-rw-r--r-- | firmware/fx2/usrp1/board_specific.c | 113 | ||||
-rw-r--r-- | firmware/fx2/usrp1/eeprom_io.c | 65 | ||||
-rw-r--r-- | firmware/fx2/usrp1/eeprom_io.h | 38 | ||||
-rw-r--r-- | firmware/fx2/usrp1/fpga_load.c | 193 | ||||
-rw-r--r-- | firmware/fx2/usrp1/fpga_rev2.c | 122 | ||||
-rw-r--r-- | firmware/fx2/usrp1/fpga_rev2.h | 58 | ||||
-rw-r--r-- | firmware/fx2/usrp1/gpif.c | 292 | ||||
-rwxr-xr-x | firmware/fx2/usrp1/gpif.gpf | bin | 0 -> 5341 bytes | |||
-rw-r--r-- | firmware/fx2/usrp1/usb_descriptors.a51 | 404 | ||||
-rw-r--r-- | firmware/fx2/usrp1/usrp_common.c | 109 | ||||
-rw-r--r-- | firmware/fx2/usrp1/usrp_gpif.c | 206 | ||||
-rw-r--r-- | firmware/fx2/usrp1/usrp_gpif_inline.h | 27 | ||||
-rw-r--r-- | firmware/fx2/usrp1/usrp_main.c | 389 | ||||
-rw-r--r-- | firmware/fx2/usrp1/usrp_regs.h | 163 |
15 files changed, 2263 insertions, 0 deletions
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 Binary files differnew file mode 100755 index 000000000..854e25399 --- /dev/null +++ b/firmware/fx2/usrp1/gpif.gpf 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_ */ |