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