Re: [Fx2lib-devel] Arming bulk end points early
Status: Beta
Brought to you by:
mulicheng
From: Eric W. <er...@wi...> - 2009-03-12 22:30:54
|
Dennis Muhlestein wrote: > If you find something, let us know! > I earned my cheese! Here is how to arm packets shorter than the host is asking for. First, read all about IN-BULK-NAK in the EZ-USB technical reference manual. There is a USB interrupt vector and registers that can be triggered on and watched to catch that the host has asked for an IN packet and the SIE is NAK'ing it. In code built from the Cypress firmware frameworks model here is code for periph.c to commit a short packet. // global variables, add this BYTE IbnFlag; // Flag to track which interrupt bulk nak happened. ... void TD_Init(void) // Called once at startup { ... // After the FIFORESET commands insert this // The following code initializes the interrupt bulk nak registers which enable getting short packets NAKIRQ = bmBIT0; // clear the global IBN IRQ NAKIE |= bmBIT0; // enable the global IBN IRQ IbnFlag = 0x00; // clear our IBN flag IBNIRQ = 0xFF; // clear any pending IBN IRQ IBNIE |= bmEP4IBN; // enable the IBN interrupt for EP6 and EP8 ... } void TD_Poll(void) // Called repeatedly while the device is idle { ... // Add this type of code to manually arm your packets. Note: my EP4IN is double buffered. // I'm indexing the EP4FIFOBUF with IRi as I fill it with data above, i.e. EP4FIFOBUF[IRi++] = data; if(IRi == 512) // When IRi = 512 we have filled one of the EP 512 byte buffers { IRi = 0; // Reset the counter so we can fill the next buffer SYNCDELAY; // see TRM section 15.15, pg 315. We are writing/reading a register within 0xE600-0xE6FF EP4BCH = 0x02; // Prepare to ARM the EP for an IN transaction (High byte must be first) SYNCDELAY; // see TRM section 15.15, pg 315. We are writing/reading a register within 0xE600-0xE6FF EP4BCL = 0x00; // Now arm the EP for transfer by loading the low byte of the byte count (512 bytes) } // Now commit any short packet on EP4IN if the host asks for it if(IbnFlag & bmEP4IBN) // Check our flag for interrupt bulk nak and see if EP4IN was requested { EP4BCH = MSB(IRi); // Prepare to ARM the EP for an IN transaction using the high byte of the IR FIFO buffer index (High byte must be first) SYNCDELAY; // see TRM section 15.15, pg 315. We are writing/reading a register within 0xE600-0xE6FF EP4BCL = LSB(IRi); // arm EP4IN for an IN transaction using the low byte of the IR FIFO buffer index. The bulk packet will be < 512 IRi = 0; // Reset the IR index variable IbnFlag &= ~bmEP4IBN; // clear the IBN flag for the bit representing EP4IN IBNIRQ = bmEP4IBN; // clear the IBN IRQ for the bit representing EP4IN IBNIE |= bmEP4IBN; // enable the IBN IRQ for the bit representing EP4IN so that we are ready for next time } ... } // Then fill out the IBN interrupt vector code like so: void ISR_Ibn(void) interrupt 0 { //This code taken from the FX2LP example code IBN.C int i; // disable IBN for all endpoints IBNIE = 0x00; EZUSB_IRQ_CLEAR(); // clear the global USB IRQ // Find the EP with its IBN bit set for (i=0;i<8;i++) // Incrementally check each bit to see which EP we're NAK'ing { if (IBNIRQ & (1 << i)) // If this bit is the NAK'ing EP then set our flag for it and clear the IRQ for it { IbnFlag |= (1 << i); // set the appropriate IBN flag bit IBNIRQ |= (1 << i); // clear the IBN IRQ for this endpoint } } NAKIRQ |= bmBIT0; // clear the global IBN IRQ // re-enable IBN interrupt for any endpoints that don't already have // an IBN pending in IbnFlag IBNIE = (bmEP4IBN) & ~IbnFlag; } I took most of this code from the IBN example code in the FX2LP development kit. The result of this is that I can have the host ask for a bulk IN of 512 bytes and get either, the full 512 if my FIFO was full and the CPU is filling the other 512, or a short packet < 512 for what ever the CPU has filled to the FIFO to that moment. This is cool because my data is very intermittent and may go days before happening. I can have the host poll regularly and get zero length packets back for no data. Also if there were a burst of data I could get a full 512 packet and then ask immediately for another to see if the data overflowed into the second FIFO. Eric |