fx2lp out endpoint not arming (AUTOOUT mode)

In older fx2 firmware code I'm leaving the REVCTL register alone but due to some (other) EP problems I'm having, I figured I should set REVCTL's DYN_OUT and ENH_PKT bits. With these bits set (according to the fx2 technical reference manual) one doesn't need to induce a 0->1 transition on EPnFIFOCFG to arm the endpoint (fx2 trm 15-24). However, endpoints are now armed by writing to OUTPKTEND. I'm using quad- buffering on EP2 and writing OUTPKTEND=0x82 four times. Even after doing this the endpoint never gets armed. Any ideas?

When I say it doesn't get armed, I mean that I can't write to the thing with my PC _and_ the EP2CS register says the EP2 FIFO is full after a fresh reset (when DYN_OUT bit is not set the EP2 FIFO is _not_ full after a fresh reset).

The code below produces the error: (the code below still induces the 0->1 transition on EP2FIFOCFG, the code operates the same with or without this transition)

CPUCS = bmCLKSPD1; // CPU runs @ 48 MHz CKCON = 0; // MOVX takes 2 cycles

// Slave FIFO, sync mode, 48MHz clock IFCONFIG = bmIFCFGMASK|bmIFCLKSRC|bmIFCLKOE|bmIFCLKPOL|bm3048MHZ; SYNCDELAY;

WAKEUPCS=0; REVCTL = bmDYN_OUT | bmENH_PKT; // highly recommended by docs

EP1OUTCFG = bmVALID | bmBULK; SYNCDELAY; EP1INCFG = bmVALID | bmBULK | bmIN; SYNCDELAY;

EP2CFG = bmVALID | bmBULK | bmQUADBUF; SYNCDELAY; // 512 quad bulk OUT EP4CFG = 0; SYNCDELAY; // disabled EP6CFG = bmVALID | bmBULK | bmQUADBUF | bmIN; SYNCDELAY; // 512 quad bulk IN EP8CFG = 0; SYNCDELAY; // disabled

// reset FIFOs

FIFORESET = bmNAKALL; SYNCDELAY; FIFORESET = 2; SYNCDELAY; FIFORESET = 6; SYNCDELAY; FIFORESET = 0; SYNCDELAY;

OUTPKTEND=0x82; OUTPKTEND=0x82; OUTPKTEND=0x82; OUTPKTEND=0x82;

// configure end point FIFOs // let core see 0 to 1 transistion of autoout bit EP2FIFOCFG = bmWORDWIDE; SYNCDELAY; EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY; EP6FIFOCFG = bmAUTOIN | bmWORDWIDE; SYNCDELAY;

EP0BCH = 0; SYNCDELAY;

// arm EP1OUT so we can receive "out" packets (TRM pg 8-8) EP1OUTBC = 0; SYNCDELAY;

EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed EP6AUTOINLENL = (512) & 0xff; SYNCDELAY;

Reply to
esterhui
Loading thread data ...

We're not doing the same, but for what it's worth, we use the following.

void TD_Init(void) // Called once at startup { // set the CPU clock to 48MHz CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ; SYNCDELAY;

// // 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

EP1OUTCFG = 0xA0; SYNCDELAY; EP1INCFG = 0xA0; SYNCDELAY;

#define VALID (1

Reply to
Bill Davy

Thanks - I tried rearranging my code so it looks more like the 'Husky' code but EP2CS still reports the FIFO is full after a FIFO reset (which I assume means it didn't arm correctly). I noticed I forgot the SYNCDELAY after my OUTPKTEND=0x82 statements in the original code, I fixed that but still no luck. I'll keep digging...

Reply to
esterhui

OK, I figured out why it doesn't arm: The fx2 loads firmware from an eeprom (firmware I didn't write), then I just nuke it by uploading my own firmware directly to RAM. I overwrote the eeprom to do a simple C0 load (just vid/pid) then upload my own firmware on a 'fresh' fx2 via USB. With this done the EP2CS comes up as 'empty' (which is correct, recall in previous instances it came up as 'full' after a FIFO reset). It appears that the problem still persists: when I tell my new firmware to reset EP2 FIFO it resets and comes up with the FULL flag set. Even uploading the exact same firmware again causes the EP2 full flag to be set.

To summarize, when I set REVCTL=0x03 and do a FIFORESET of EP2 and arm it using OUTPKTEND the _very first time_ after a powercycle it works. Any 2nd attempt to reset the FIFO causes it to come up in the full state.

Reply to
esterhui

Well spotted. I think I found something similar which is why I put off doing this initialisation until the external clock has arrived, as doing it twice (once when USB supplies power and once when the rest of the machine gets power) did not work in some way. It was a major time-waster as I recall, though the tech support folk did their best. When I was testing the code on the SDK using software loop-back, there was never going to be any external clock so it had different initialisation. I must put your note in my code for next time (and any poor maintenance programmer who passes this way again).

In fact, we still carry the overhead of optoisolating the Cypress from the rest of the board as it really cannot do much without the rest of the machine.

Incidentally, if you do softwaare loop-back the following neat wheeeze may help. It's not something to be proud of (though I would be) but the Keil compiler (at least) gets it right.

if ( Count ) { // // Use Tom Duff's (May 7, 1984) method for fast copying. // Count > 0 assumed // As the maximum bulk buffer size is 512 (even isochronous is only

1024), // we can count cycles in a byte. // BYTE n = (Count + 7) / 8;

switch (Count % 8) { case 0: do { EXTAUTODAT2 = EXTAUTODAT1; case 7: EXTAUTODAT2 = EXTAUTODAT1; case 6: EXTAUTODAT2 = EXTAUTODAT1; case 5: EXTAUTODAT2 = EXTAUTODAT1; case 4: EXTAUTODAT2 = EXTAUTODAT1; case 3: EXTAUTODAT2 = EXTAUTODAT1; case 2: EXTAUTODAT2 = EXTAUTODAT1; case 1: EXTAUTODAT2 = EXTAUTODAT1; } while (--n > 0); } }

Reply to
Bill Davy

Hi All, I found that the only way I could get the AUTOOUT function to reliabl start regardless of whether it was a cold boot or a warm boot of the 8051 was to turn off AUTOOUT, reset the fifo's, "Prime the pump", an transition AUTOOUT from 0->1

Here is a rough code snippet. REVCTL=0x03; // See TRM... SYNCDELAY; EP6CFG=0xe2; // 1110 0010 (bulk IN, 512 bytes, double-buffered) SYNCDELAY; EP2CFG=0xa2; // 1010 0010 (bulk OUT, 512 bytes, double-buffered) SYNCDELAY;

//EP2FIFOCFG = 0x00; // Make sure AUTOOUT=0. EP2FIFOCFG = (bmZEROLENIN) & ~(bmWORDWIDE) ; // Turn on Zero length IN, 8bit FIFO SYNCDELAY;

FIFORESET = 0x80; SYNCDELAY; // NAK all requests from host. FIFORESET = 0x02; SYNCDELAY; // Reset individual EP (2,4,6,8) FIFORESET = 0x04; SYNCDELAY; FIFORESET = 0x06; SYNCDELAY; FIFORESET = 0x08; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; // Resume normal operation.

#if (1) // Be sure to clear the 2 buffers (double-buffered) (required!). OUTPKTEND = 0x82; SYNCDELAY; OUTPKTEND = 0x82; SYNCDELAY; #endif EP2FIFOCFG = (bmAUTOOUT | bmZEROLENIN) & ~(bmWORDWIDE) ; // Turn on Zero length IN, 8bit FIFO, AUTOOUT SYNCDELAY;

It seems some other combinations start from cold-boot but not from warm for me aleast, ymmv!

Cheers, David

'Husky'

the

it

the

in

this

the

may

Reply to
cureton

Hi.

I just saw this thread and initially didn't notice that it's aged.

My experience is that the FIFORESET only works when EPxFIFOCFG is 0x00 (manual mode). So in my code I clear it to 0x00, do the FIFORESET stuff, do OUTPKTEND for each buffer and eventually program EPxFIFOCFG to the desired value.

The GP doesn't seem to do this and if he still suffers problems with his FX2 it might be worth trying. It would explain the reset/no-reset symtoms, too.

Regards, Marc

Reply to
jetmarc

The source of the problem is actually the DYN_OUT bit in REVCTL. All examples given in FX2 TRM tell us to set the bits in REVCTL(REVCTL=0x03). The DYN_out bit when set disables the auto-arming(TRM 15.5.9). But configuration of FIFO registers require DYN_OUT to be set. The REVCTL=0x03 is actually only required before we reset the FIFO buffers. Hence the trick is to reset the REVCTL(REVCTL=0x00) after resetting the FIFO, and EPxFIFOCFG must be done after resetting REVCTL. Try this sequence and see if it works.

  1. IFCONFIG=??; //Your choice of configuration
  2. REVCTL=0x03; SYNCDELAY
  3. Configure endpoints EP2CFG=0xA2; //endpoint2 as outendpoint EP6CFG=0xE2; //endpoint6 an inendpoint
  4. Fifo reset FIFORESET=0x80; FIFORESET=0x02; FIFORESET=0x06; FIFORESET=0X00;
  5. Prime outendpoints OUTPKTEND=0x82; OUTPKTEND=0x82; //2 times for double buffer SYNCDELAY;
  6. Now that fifo has been reset we can revert the REVCTL bits for autoarm REVCTL=0x00; SYNCDELAY;
  7. Configure FIFO EP2FIFOCFG=bmAUTOOUT; //set the commit EP6FIFOCFG=bmAUTOIN; //you can also set WORDWIDE here
  8. Set autoinlen for inendpoints EP6AUTOINLENH=??; EP6AUTOINLENL=??; SYNCDELAY; We are done. The example given above use endpoint2 as out endpoint and endpoint6 as in endpoint. With 8 bit FIFO access.

--------------------------------------- This message was sent using the comp.arch.embedded web interface on

formatting link

Reply to
eruan

REVCTL=0x03

trick

I've been looking for solution for the FIFO-reset problem, and found this post via Google. I've tested the suggestions, and here go my conclusions:

Actually, You need to combine both suggestions given above. :) So:

- SET IFCONFIG as required

- SET REVCTL=3

- configure endpoints (here: 2, 4 - OUT, 6, 8 - IN, all in bulk mode, double buffered):

EP2CFG = 0xA2; EP4CFG = 0xa0; EP6CFG = 0xe2; EP8CFG = 0xe0; SYNCDELAY;

- zero EPxFIFOCFG: EP2FIFOCFG=0; SYNCDELAY; EP4FIFOCFG=0; SYNCDELAY; EP6FIFOCFG=0; SYNCDELAY; EP8FIFOCFG=0; SYNCDELAY;

- reset FIFO, YES, You can reset all fifos at once :) FIFORESET = 0x80; SYNCDELAY; FIFORESET = 0x8f; SYNCDELAY; /* FIFORESET = 0x84; SYNCDELAY; FIFORESET = 0x86; SYNCDELAY; FIFORESET = 0x88; SYNCDELAY;

*/ FIFORESET = 0x00; SYNCDELAY;

- deal with the end of out packets....REVCTL.0 MUST NOT be 0 here... OUTPKTEND = 0x8f; SYNCDELAY; OUTPKTEND = 0x8f; SYNCDELAY; /* OUTPKTEND = 0x84; SYNCDELAY; OUTPKTEND = 0x84; SYNCDELAY; INPKTEND = 0x86; SYNCDELAY; INPKTEND = 0x86; SYNCDELAY; INPKTEND = 0x88; SYNCDELAY; INPKTEND = 0x88; SYNCDELAY;

*/

- zero REVCTL REVCTL=0; SYNCDELAY;

- configure fifos as required... EP2FIFOCFG = ...; SYNCDELAY; EP2FIFOPFH = ...; SYNCDELAY; EP2FIFOPFL = ...; SYNCDELAY;

EP4FIFOCFG = ...; SYNCDELAY; EP4FIFOPFH = ...; SYNCDELAY; EP4FIFOPFL = ...; SYNCDELAY;

EP6FIFOCFG = ...; SYNCDELAY; EP6FIFOPFH = ...; SYNCDELAY; EP6FIFOPFL = ...; SYNCDELAY;

EP8FIFOCFG = ...; SYNCDELAY; EP8FIFOPFH = ...; SYNCDELAY; EP8FIFOPFL = ...; SYNCDELAY;

EP6AUTOINLENH = ...; SYNCDELAY; EP6AUTOINLENL = ...; SYNCDELAY; EP8AUTOINLENH = ...; SYNCDELAY; EP8AUTOINLENL = ...; SYNCDELAY;

- and ...

You're done :)

Regards.

--------------------------------------- This message was sent using the comp.arch.embedded web interface on

formatting link

Reply to
__grzegorz__

Replying to dead thread for the benefit of future Googlers: leaving bit 7 (NAKALL) set when resetting the individual FIFOs seems to fail in at least some cases, such as when you try to switch back and forth between double- and quad-buffered FIFOs.

It's true that most (but not all) of the code snippets in the FX2LP TRM leave the high bit set.

-- john, KE5FX

Reply to
jmiles

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.