diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/README | 6 | ||||
-rw-r--r-- | firmware/README.txt | 31 | ||||
-rw-r--r-- | firmware/fx2/b100/usrp_common.c | 57 | ||||
-rw-r--r-- | firmware/fx2/b100/usrp_main.c | 153 | ||||
-rw-r--r-- | firmware/fx2/b100/usrp_regs.h | 28 | ||||
-rw-r--r-- | firmware/fx2/common/fx2regs.h | 17 |
6 files changed, 102 insertions, 190 deletions
diff --git a/firmware/README b/firmware/README deleted file mode 100644 index 251486955..000000000 --- a/firmware/README +++ /dev/null @@ -1,6 +0,0 @@ -######################################################################## -# Firmware for USRP devices -######################################################################## - -fx2 - firmware for USRP1 -zpu - firmware for USRP2 and N Series diff --git a/firmware/README.txt b/firmware/README.txt new file mode 100644 index 000000000..1c233de1d --- /dev/null +++ b/firmware/README.txt @@ -0,0 +1,31 @@ +######################################################################## +# Firmware for USRP devices +######################################################################## + +fx2/ + + Description: firmware for FX2 device + + Devices: USRP1 and B100 + + Tools: sdcc, cmake + + Build Instructions: + 1) mkdir <build directory> + 2) cd <build directory> + 3) cmake <source directory> + 4) make + +zpu/ + + Description: firmware for soft CPU in FPGA + + Devices: USRP2 and N Series + + Tools: zpu-gcc, cmake + + Build Instructions: + 1) mkdir <build directory> + 2) cd <build directory> + 3) cmake <source directory> + 4) make diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c index 4b6dde881..a21353688 100644 --- a/firmware/fx2/b100/usrp_common.c +++ b/firmware/fx2/b100/usrp_common.c @@ -32,13 +32,11 @@ 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; + // IFCLK is generated internally and runs at 48 MHz, external clk en + IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE; SYNCDELAY; - // configure IO ports (B and D are used by GPIF) - + // configure IO ports (B and D are used by slave FIFO) IOA = bmPORT_A_INITIAL; // Port A initial state OEA = bmPORT_A_OUTPUTS; // Port A direction register @@ -53,7 +51,6 @@ init_usrp (void) // SYNCDELAY; // configure end points - EP1OUTCFG = bmVALID | bmBULK; SYNCDELAY; EP1INCFG = bmVALID | bmBULK | bmIN; SYNCDELAY; @@ -63,7 +60,6 @@ init_usrp (void) EP8CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN // reset FIFOs - FIFORESET = bmNAKALL; SYNCDELAY; FIFORESET = 2; SYNCDELAY; FIFORESET = 4; SYNCDELAY; @@ -72,37 +68,50 @@ init_usrp (void) FIFORESET = 0; SYNCDELAY; // configure end point FIFOs - - // let core see 0 to 1 transistion of autoout bit - + // let core see 0 to 1 transistion of autoin/out bit EP2FIFOCFG = bmWORDWIDE; SYNCDELAY; EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; - EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; - //EP6FIFOCFG = bmWORDWIDE; SYNCDELAY; + EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; + EP6FIFOCFG = bmZEROLENIN | bmAUTOIN | bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmWORDWIDE; SYNCDELAY; EP4FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; - EP8FIFOCFG = bmAUTOIN | bmWORDWIDE; SYNCDELAY; + EP8FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY; + EP8FIFOCFG = bmZEROLENIN | 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) - + // set autoin length for EP6/EP8 EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed EP6AUTOINLENL = (512) & 0xff; SYNCDELAY; - EP8AUTOINLENH = (32) >> 8; SYNCDELAY; EP8AUTOINLENL = (32) & 0xff; SYNCDELAY; + //set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF + PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4); + PINFLAGSCD = (bmEP6PF) | (bmEP8PF << 4); + + //ok as far as i can tell, DECIS is reversed compared to the FX2 TRM. + //p15.34 says DECIS high implements [assert when (fill > level)], observed opposite + EP6FIFOPFH = 0x09; + SYNCDELAY; + EP6FIFOPFL = 0xFD; + SYNCDELAY; + +// EP2FIFOPFH = 0x08; +// SYNCDELAY; +// EP2FIFOPFL = 0x00; +// SYNCDELAY; + + //assert FIFOEMPTY one cycle sooner so we get it in time at the FPGA + EP2FIFOCFG |= bmBIT5; + + //set FIFOPINPOLAR to normal (active low) mode + FIFOPINPOLAR = 0x00; + SYNCDELAY; + PORTACFG = 0x80; + init_board (); } diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c index 391a6d94f..7c4dd479d 100644 --- a/firmware/fx2/b100/usrp_main.c +++ b/firmware/fx2/b100/usrp_main.c @@ -21,7 +21,6 @@ #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" @@ -64,7 +63,12 @@ bit enable_gpif = 0; #define USRP_HASH_SIZE 16 xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE]; -void clear_fpga_data_fifo(void); +//void clear_fpga_data_fifo(void); + +//use the B100 fpga_config_cclk/ext_reset line to reset the FPGA +void fpga_reset(int level) { + bitALTERA_DCLK = level; +} static void get_ep0_data (void) @@ -75,13 +79,21 @@ get_ep0_data (void) ; } -static void initialize_gpif_buffer(int ep) { - //clear the GPIF buffers on startup to keep crap out of the data path +static void clear_fifo(int ep) { FIFORESET = 0x80; SYNCDELAY; //activate NAKALL FIFORESET = ep; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; } +void enable_xfers(int enable) { + if(enable) { + IFCONFIG |= bmIFSLAVE; + } else { + IFCONFIG &= ~bmIFSLAVE; + } + set_led_0(enable); +} + /* * Handle our "Vendor Extension" commands on endpoint 0. * If we handle this one, return non-zero. @@ -112,7 +124,7 @@ app_vendor_cmd (void) case VRQ_FW_COMPAT: EP0BCH = 0; - EP0BCL = 2; + EP0BCL = 3; break; default: @@ -161,7 +173,7 @@ app_vendor_cmd (void) break; case VRQ_FPGA_SET_RESET: - //fpga_set_reset (wValueL); + fpga_reset(wValueL); break; case VRQ_I2C_WRITE: @@ -171,16 +183,15 @@ app_vendor_cmd (void) break; case VRQ_RESET_GPIF: - initialize_gpif_buffer(wValueL); + clear_fifo(wValueL); break; case VRQ_ENABLE_GPIF: - enable_gpif = (wValueL != 0) ? 1 : 0; - set_led_1(enable_gpif); + enable_xfers(wValueL); break; case VRQ_CLEAR_FPGA_FIFO: - clear_fpga_data_fifo(); + //clear_fpga_data_fifo(); break; default: @@ -194,125 +205,12 @@ app_vendor_cmd (void) 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(); - } } } @@ -363,15 +261,9 @@ patch_usb_descriptors(void) 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); @@ -388,7 +280,6 @@ main (void) 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 index f6695d9f9..3d65337f5 100644 --- a/firmware/fx2/b100/usrp_regs.h +++ b/firmware/fx2/b100/usrp_regs.h @@ -41,8 +41,6 @@ #define bmALTERA_NCONFIG bmBIT1 #define bmALTERA_DATA0 bmBIT3 #define bmALTERA_NSTATUS bmBIT4 -#define bmRESET_FPGA_FIFOS bmBIT7 - #define bmALTERA_BITS (bmALTERA_DCLK \ | bmALTERA_NCONFIG \ @@ -64,7 +62,6 @@ sbit at PORT_A_ADDR+0 bitALTERA_DCLK; // 0x80 is the bit address of PORT A sbit at PORT_A_ADDR+1 bitALTERA_NCONFIG; sbit at PORT_A_ADDR+3 bitALTERA_DATA0; -sbit at PORT_A_ADDR+6 bitSHORT_PACKET_SIGNAL; sbit at PORT_C_ADDR+7 bitALTERA_CONF_DONE; @@ -102,29 +99,4 @@ sbit at PORT_C_ADDR+7 bitALTERA_CONF_DONE; #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 aa44791d0..acbc0b89e 100644 --- a/firmware/fx2/common/fx2regs.h +++ b/firmware/fx2/common/fx2regs.h @@ -91,7 +91,6 @@ EXTERN xdata _AT_(0xE60A) volatile BYTE REVID ; // Chip Revision EXTERN xdata _AT_(0xE60B) volatile BYTE REVCTL ; // Chip Revision Control // Endpoint Configuration - EXTERN xdata _AT_(0xE610) volatile BYTE EP1OUTCFG ; // Endpoint 1-OUT Configuration EXTERN xdata _AT_(0xE611) volatile BYTE EP1INCFG ; // Endpoint 1-IN Configuration EXTERN xdata _AT_(0xE612) volatile BYTE EP2CFG ; // Endpoint 2 Configuration @@ -654,6 +653,22 @@ sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320 #define bmIFCFG0 bmBIT0 #define bmIFCFGMASK (bmIFCFG0 | bmIFCFG1) #define bmIFGPIF bmIFCFG1 +#define bmIFSLAVE (bmIFCFG0 | bmIFCFG1) + +/* Slave FIFO pin flags configuration bits (PINFLAGS) */ +#define bmINDEXED 0x0 //which fifo selected by FIFOADR +#define bmEP2PF 0x4 +#define bmEP4PF 0x5 +#define bmEP6PF 0x6 +#define bmEP8PF 0x7 +#define bmEP2EF 0x8 +#define bmEP4EF 0x9 +#define bmEP6EF 0xA +#define bmEP8EF 0xB +#define bmEP2FF 0xC +#define bmEP4FF 0xD +#define bmEP6FF 0xE +#define bmEP8FF 0xF /* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */ #define bmINFM bmBIT6 |