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