//----------------------------------------------------------------------------- // Copyright 2007, Piero Giubilato, Lawrence Berkely National Laboratory //----------------------------------------------------------------------------- //______________________________________________________________________________ // {Trace} // [File name] "FX2SlaveFIFOMode.c" // [Language] "C Standard" // [Last revision] "06 Dec 2007" // [Author] "Piero Giubilato" // [Member of] "FX2 Firmware" // [Description] "This file is the program that has to be loaded into the 8051" // "microprocessor embedded into the Cypress FX2LP chip, in order to get it" // "interfacing correctly with the FPGA firmware and the PARROT framework." // [Compiler] "Keil uVision 3.53" // [Key documentation] "Cypress EZ-USB Technical Reference Manual" // {Trace} //______________________________________________________________________________ //______________________________________________________________________________ // {Description} // // // // // // // {Description} //______________________________________________________________________________ // Using this setting for the TD_Init function will result into putting the // Cypress device into a FIFO Slave mode, actually putting out of the game the // integrated A851 microcrontroller. The FPGA is instead used as a master, while // the Cypress chips acts like a with FIFO USB // FX2LP inclusions (necessary just to avoid excessive 0x style programming) #include "fx2.h" // macros, datatypes, globals & function prototypes #include "fx2regs.h" // FX2 registers & reference masks definition #include "syncdly.h" // Cypress macro used to addres some FX2 issues //______________________________________________________________________________ void SlaveFIFOMode (void) { // Pay attention: the register initialization procedure MUST follow the // present order. Do NOT rearrange it! // ** Step 1: set the device IFCONFIG register to define the behaviour of // the interface between the slave FIFOs and the external master, and // set the SLAVE mode also. // Interface configuration register description: // Bit 7: IFCLKSRC (0 = external on IFGCLK pin, 1 = internal) // Bit 6: 3048MHZ (0 = 30 MHz, 1 = 48 MHz) // Bit 5: IFCLKOE (0 = disabled (tri-state), 1 = put IFCLK on IFCLK pin) // Bit 4: IFCLKPOL (0 = normal, 1 = inverted) // Bit 3: ASYNC (0 = synchronous mode, 1 = asynchronous mode) // Bit 2: GSTATE (0 = disabled, 1 = drive GPIF state on PORTE[0:2]) // Bit 1: IFCFG1 (00 = PORTS, 01 = reserved, 10 = GPIF, 11 = SLAVE) // Bit 0: IFCFG0 IFCONFIG = 0x43; // Ext Clk, 48MHz, No OE, No Inv, SYNCH, No GPIF, SLAVE //IFCONFIG = 0xE3; // Int Clk, 48MHz, OE, No Inv, SYNCH, No GPIF, SLAVE //IFCONFIG = 0xA3; // Int Clk, 32MHz, OE, No Inv, SYNCH, No GPIF, SLAVE SYNCDELAY; // ** Step 2: set the SLCS pin to allow enabling/disbling the chip // by an external command PORTACFG = 0x40; // Set pin # 74 as a SLCS input (active low) SYNCDELAY; // ** Step 3: set up the correct connection for the FIFO's flags, fixed mode. // Bits [7:4] FlagB / Flag D // Bits [3:0] FlagA / Flag C // // FLAGx[3:0] () // 1000 EP2 Empty {0x8} // 1110 EP6 Full {0xE} // 1100 EP2 Full {0xC} // 1010 EP6 Empty {0xA} PINFLAGSAB = 0x8E; // EP6 Full -> FlagA, EP2 Empty -> FlagB SYNCDELAY; //PINFLAGSAB = 0xE8; SYNCDELAY; // EP6 Full -> FlagB, EP2 Empty -> FlagA PINFLAGSCD = 0xDC; SYNCDELAY; // EP2 Full -> FlagC, EP6 Empty -> FlagD // ** Step 4: Set FIFO's flags pins asserted level (0 = active low, 1 = active high) // Bit 7: 0 // Bit 6: 0 // Bit 5: PKTEND // Bit 4: SLOE // Bit 3: SLRD // Bit 2: SLWR // Bit 1: EF // Bit 0: FF FIFOPINPOLAR = 0x00; // Set Empty and Full flag with active high pin! SYNCDELAY; // ** Step 5: set the auto-arming of endpoints when switching from Auto to // Manual mode. REVCTL = 0x03; SYNCDELAY; // ** Step 6: configure the Endpoints. // Endpoint configuration register description: // Bit 7: Active (0 = disable, 1 = active) // Bit 6: Direction (0 = OUT, 1 = IN) // Bit 5: Type1 (00 = illegal, 01 = ISO, 10 = BULK, 11 = INT) // Bit 4: Type0 // Bit 3: Size (0 = 512 bytes, 1 = 1024 bytes) // Bit 2: Not used // Bit 1: Buf1 (00 = quad, 01 = illegal, 10 = double, 11 = triple) // Bit 0: Buf0 // Pay attention: endpoints MUST be set starting from the active once // in order to avoid the chip messing up the buffer assignement! //EP2CFG = 0xA0; SYNCDELAY; // ON, OUT, BULK, 512, Buffer 4X EP2CFG = 0xA2; SYNCDELAY; // ON, OUT, BULK, 512, Buffer 2X EP6CFG = 0xE0; SYNCDELAY; // ON, IN, BULK, 512, Buffer 4X //EP6CFG = 0xE2; SYNCDELAY; // ON, IN, BULK, 512, Buffer 2X EP4CFG = 0x20; SYNCDELAY; // OFF, OUT, BULK, 512, Buffer 2X EP8CFG = 0x20; SYNCDELAY; // OFF, OUT, BULK, 512, Buffer 2X // ** Step 7: reset the FIFOs FIFORESET = 0x80; SYNCDELAY; // Send a NAK to all Host transfers FIFORESET = 0x02; SYNCDELAY; // Reset Endpoint 2 FIFO FIFORESET = 0x08; SYNCDELAY; // Reset Endpoint 6 FIFO FIFORESET = 0x00; SYNCDELAY; // Restore normal operation // ** Step 8: arm both Endpoint 2 buffers to "prime the pump" OUTPKTEND = 0x82; SYNCDELAY; OUTPKTEND = 0x82; SYNCDELAY; // ** Step 9: put both Endpoints in AUTO mode, so actually taking // away the CPU from managing the packets transfer. Set also the // packet width to 16 bits (one WORD wide). // Endpoint fifo register description: // Bit 7: Not used // Bit 6: INFM1 (0 = NORMAL, 1 = FLAG active 1 byte early) // Bit 5: OEP1 (0 = NORMAL, 1 = FLAG active 1 byte early) // Bit 4: AUTOOUT (0 = FALSE, 1 = TRUE) // Bit 3: AUTOIN (0 = FALSE, 1 = TRUE) // Bit 2: ZEROLENIN (0 = disable, 1 = send 0 length pkt on PKTEND) // Bit 1: Not used // Bit 0: WORDWIDE (0 = byte wide, 1 = word wide) EP2FIFOCFG = 0x11; SYNCDELAY; // AUTOOUT, ZEROLEN = 0, WORDWIDE = 1 EP6FIFOCFG = 0x0D; SYNCDELAY; // AUTOIN, ZEROLEN = 1, WORDWIDE = 1 // ** Step 10: set packet autocommissioning size for the IN endpoint EP6AUTOINLENH = 0x02; SYNCDELAY; // Auto-commit 512-bytes packets EP6AUTOINLENL = 0x00; SYNCDELAY; // Minimal packet is 0 bytes }