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
|