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