Brian Meyrick

USB on the MCF54455

Discussion created by Brian Meyrick on Jun 11, 2009
Latest reply on Jul 8, 2009 by Brian Meyrick

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

Outcomes