I am trying to download a file at full speed and except for the first, every 64 byte packet is Nak'd and then Ack'd on resend. Thus I am sending twice as many packets as I need to.
Has anyone come across anything similar?
The init function is:
static void init_ep1( void )
/*
Function to initialise endpoint 1
Initialises OUT endpoint queue head for EP1
*/
{
memset( ep1_buf, 0, MAX_USB_BUFFER_SIZE );
usb_ep_qh_init( ep_list_addr,
EP_QH1_OUT,
0,
EP1_MAX_PKT,
FALSE,
1 );
// Enable Rx on EP1
WRITE32( EPCR1, EPCR_TXT_BULK | EPCR_TXS | EPCR_RXE | EPCR_RXT_BULK | EPCR_RXR);
// Initialise DTD for receiving data
usb_dtd_ep1 = usb_dtd_init( EP1_MAX_PKT, TRUE, 0, (uint32*)ep1_buf );
// Point the endpoint OUT QH to the dTD
((USB_EP_QH*)((uint32)ep_list_addr + EP_QH_OUT(1)))->next_dtd = (uint32)usb_dtd_ep1;
// Prime Rx buffer for EP1
WRITE32( EPPRIME, READ32( EPPRIME ) | EPPRIME_PERB(1<<1));
// Wait for prime to complete
while ( READ32( EPPRIME ) & EPPRIME_PERB(1<<1))
;
}
whilst the recieve function is:
static void usb_rx_data( void )
/*
Function called in response to OUT event (on EP1 in our case).
See 21.5.3.6.4
Needs modifying for the general case of print files, by using
linked list of buffer pointers rather than reusing the first one.
Get away with this for status requests etc as all non-print data
always fits in a single buffer.
*/
{
uint32 len;
if(( len = ep1_transfer_complete( usb_dtd_ep1 )) != 0 ) // STCU
{
msg_manager_process_packet( ep1_buf, len, NULL );
memset( ep1_buf, 0, MAX_USB_BUFFER_SIZE );
}
// else error has occurred - just go again?
// Reinitialise dTD tokens
usb_dtd_ep1->dtd_token &= ~DTD_NUM_BYTES; // clear num_bytes
usb_dtd_ep1->dtd_token |=
(USB_DTD_TOKEN_TOTAL_BYTES(EP1_MAX_PKT) | USB_DTD_TOKEN_STAT_ACTIVE);
// Reinitialise dTD buffer pointers
usb_dtd_ep1->dtd_buf0 = (uint32)ep1_buf;
/*
usb_dtd_ep1->dtd_buf1 = (uint32)ep1_buf+0x1000;
usb_dtd_ep1->dtd_buf2 = (uint32)ep1_buf+0x2000;
usb_dtd_ep1->dtd_buf3 = (uint32)ep1_buf+0x3000;
usb_dtd_ep1->dtd_buf4 = 0;
*/
// Point QH to new dTDs
((USB_EP_QH*)((uint32)ep_list_addr + EP_QH_OUT(1)))->next_dtd = (uint32)usb_dtd_ep1;
// Prime Rx buffer for EP1
WRITE32( EPPRIME, READ32( EPPRIME ) | EPPRIME_PERB(1<<1));
// Wait for prime to complete
while ( READ32( EPPRIME ) & EPPRIME_PERB(1<<1))
;
}
regards
Stalis
Just a thought: can you back off on the speed any? It sounds like you're overrunning something that can't handle the throughput. Does the transfer work reliably at lower speeds?
---Tom
Not sure how we can hold off. The PC host is sending the packets according to the USB spec ... 64 bytes every 0.00006 secs say. At low speeds the same Nak'n is said to occur. A co worker however has reported that the transfers are ok if the packet size is less than a particular value .. but that remains to be confirmed.
It seems hard to believe that a linux EVB exists for the MFC54455 and that the USB so problematic. There must be some trick that I have missed.
Hi folks,
I downloaded the USB demo from the smx site and ran it up on the EVB.
The throughput was rather poor at HS, most every packet resulting in a NYET response necessitating a Ping.
Different symptoms for sure.
Has anyone managed to get decent USB throughput at FS and HS for this board ?
Yes.. You should be able to get decent throughput. Its been awhile since we dug into this, but cross-bar priorities have an effect on throughput. Have you done anything to configure the cross-bar?
Hi JWW,
The crosbar priorities are the defaults as set by reset.