This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C5505 USB Questions on USB_postTransaction - I/O flags

I have some questions concerning the CSL 3.03/C5505 USB. Yes, I am using a revised csl_usbAux.h in addition to the CSL-as built to deal with data length>64 bytes.

 I am using USB_postTransaction to receive OUT transfers (Set feature report) and send IN transfers (Get feature report) to Ep0. These are 80-byte transfers with a PC host and are working correctly except for the C5505 receive. I am setting an EOT event in the transfer complete callback routine but there is no data changed in the buffer when the Ep0 handler tries to process it.  

I use the CSL_USB_IOFLAG_SWAP I/O flag to request a byte-order swap of (little endian) received data by USB_postTransaction as in previous versions (5509A). It is likewise used to request a swap of data bytes before sending to host with IN transfers. The USB analyzer shows the first word coming in as 0x0055  (HostCmd=ReadMemory) with correct data following it. The analyzer is set for displaying little endian in this case. The analyzer shows C5505 correctly responding to host (IN transfer) when I swap the bytes instead of relying on USB_postTransaction to do it (swap flag).

I am using the existing PC host (code updater) application to exercise this on our C5505 target.

 

Does CSL v3.03 handle these I/O flags correctly? Are there subtle differences in the way these need to be addressed with C5505/CSL?

Can you explain the missing data problem with the OUT transfer?

Thanks,

 

Stephen

 

 

Our application uses a standard Windows HID driver on the PC host.


//code snippet from my HIDSetReport request handler

case 3: // Set Feature report

{

ii = 80;

// select the smaller of the two

ii = (ii < USB_Setup->wLength) ? ii : USB_Setup->wLength;

// hUsbDev->ep0State = CSL_USB_EP0_RX;

if(USB_isTransactionDone(hOutEp,&status))

{

status = USB_postTransaction(hOutEp, ii, (void*)&featureReport.reportData[1], CSL_USB_IOFLAG_NOSHORT/*|CSL_USB_IOFLAG_SWAP*/);

for (j=1; j<41; j++) //swap high/low bytes

{

/* temp = (featureReport.reportData[j] & 0xFF)<<8;

temp |= ((featureReport.reportData[j]>>8) & 0xFF);

featureReport.reportData[j] = temp; */

}

receivingFeatureReport = 1;

// Service the RXPKTRDY after reading the FIFO

// USB_clearEpRxPktRdy(CSL_USB_EP0);

}

break;

}

///this is the structure of the commands and replies transported by Set/Get feature report

typedef union

{

       Uint16 reportData[41];

       struct

       {

              Uint16 reportID;

              Uint16 hostCmd;

              Uint32 startAddress;

              Uint16 count;

              Uint16 key[4];

              Uint16 flashData[32];

       } report;

} FeatureReport;

 

  • Hi,

    We will get back to you as soon as we have update on this request.

    Thanks & regards,

    Sivaraj K

  • Sivaraj,

    It looks like USB_processEP0Out does not read the FIFO, which might explain the missing data on the OUT transfer.

    The only CSL routine I see that does read it (other than Setup) is USB_readEP0Buf. Where (in the code) should it be placed? It appears that USB_readEP0Buf will fail if COUNT0 > 64. Our host application is sending 80 bytes, which may require a different read routine.

    Any ideas?

    Stephen

  • The CSL_USB_IOFLAG_SWAP ioFlag is being collected in USB_postTransaction but isn't being utilized anywhere thereafter. Will check if the same should be included in a newer CSL version.

    For transferring >64bytes, could you please check if the following Forum post addresses your concern?

    http://e2e.ti.com/support/dsp/c5000/f/109/p/341349/1193437.aspx#1193437

    Thanks,

    Best Regards.

  • KRavis,

    I rearranged the code for better state handling and using USB_readEP0Buf to read data from the FIFO. I have seen valid data in dwOutEP0Buf, but the USB_processEP0Out does not copy it to my buffer. When the minimum function (macro) produces a zero count (i.e. pTransfer->cbTransferred gets a 0), the memcpy that should copy the data to the user buffer does nothing.

    Am I missing something?

    Thanks,

    Stephen

    //code snippets
    //in ISR...
    if(pContext->ep0State == CSL_USB_EP0_RX)
    {
       if((usbRegisters->PERI_CSR0_INDX & CSL_USB_PERI_CSR0_INDX_RXPKTRDY_MASK) ==
            CSL_USB_PERI_CSR0_INDX_RXPKTRDY_MASK)
       {
           USB_readEP0Buf(pContext, pContext->dwOutEP0Buf);

           //pContext->fOutPhaseCmd = TRUE;
           USB_processEP0Out(pContext);

           /* check if data end bit is set */
           if((usbRegisters->PERI_CSR0_INDX & CSL_USB_PERI_CSR0_INDX_DATAEND_MASK) ==
               CSL_USB_PERI_CSR0_INDX_DATAEND_MASK)
          {      
                pContext->ep0State = CSL_USB_EP0_IDLE;
          }
          /* else remain in rx state */
         }
    }
    ...
    // In CSL
    static inline CSL_Status USB_processEP0Out(CSL_UsbDevHandle hUsbDev)
    {
    ...
      /* move data from ep0 fifo to ep buffer */
      pTransfer->cbTransferred = CSL_USB_MIN(hUsbDev->cbOutEP0Buf,
      pTransfer->cbBuffer);

      memcpy(pwBuffer, (PVOID)hUsbDev->dwOutEP0Buf,
       (pTransfer->cbTransferred+1)/2);

       hUsbDev->fOutPhaseCmd = FALSE;
       pTransfer->fComplete = TRUE;
       pTransfer->prevTxferLen = pTransfer->cbTransferred;

       #if ((defined(CSL_MSC_TEST)) || (defined(CSL_AC_TEST)))
       /* This transfer is completed */
       *(PWORD)pTransfer->pvBuffer = pTransfer->cbTransferred;
       #endif
      

       status = hUsbDev->completeTransferCallback(hUsbDev, peps);
    ...
    }

     

  • Hi,

    Just to update: I made a new version of USB_processEp0Out to use with USB_readEp0Buf to meet our more than 64 byte transfer (multiple packet) requirement and I am now receiving the correct data. I had to use USB_swapWords after the reads for the correct ordering of the data. At the site of the USB_postTransaction call, I manually swap bytes for correct Endianess and the data is right. I still have a problem where the control endpoint handler attempts to handle the EOT event (the next step) and finds the data unswapped again.

    Any ideas?

    Stephen

  • Hi,

    Could it be possible to share the CCS project  / additonal appcode src (-preferably, the CCS proj) where you've inflicted the changes: the definition of the completeTransfer Callback function where you indicated the EOT event, the section where you swapped the bytes to take care of the Endianness, the new version of  USB_processEp0Out() using USB_readEp0Buf() (as the one in the above post is exactly the same as in the csl). Having the CCS proj will also help to understand better where exactly in the src the changes were made.

    Also, would you've checked the USB POLL, INTC examples provided in the CSL3.04? The USB examples have a config descriptor 74bytes in length which do get transferred properly.

    Best Regards.

  • Also, in addition to the CCS project, could you please share why you intend to swap the words for the transaction?

    The swap is required in case DMA is involved and that too is taken care of by the CSL, one needn't swap explicitly. Are you using DMA?

    Best Regards.

  • Hi Kravis,

    I can zip up the CCSv5.4 project so you can take a look. There is no descriptor length problem, enumeration works fine. I am using CSL v3.03 with some mods made only to csl_usbAux.h. None of the CSL source.c files are changed. The CSL is built for C5505 DSP. See later comments.

    Thanks,

    Stephen 

  • Hi Kravis,

    I noticed that following USB_readEp0Buf with USB_processEp0Out results in alternate words out of order. The data  also comes across as Little Endian which is not the best way to deal with it in our DSP application. The PC host (we call CodeUpdater) expects data in a certain order. We are able to change the PC side but it doesn't make sense to spend a lot of time there because this is an interim solution. There is a more elaborate scheme for the actual product that will require the USB handling and code updating to be packaged somewhat differently, as it not strictly a code updating or secondary bootloader function.

    I am not using DMA, this is more like the Intc example approach.I am able to handle the OUT transfers (Rx data) correctly at this point. I did modify some of the ISR Rx handling so that it is similar to the MSC example.

    The problem I tried to describe earlier seems to be related to the EOT event and my usb_ctl handler calls. The ISR calls usb_ctl (which reads the setup packet and takes care of decoding and processing the request) setting the SETUP event flag first. If the EOT flag happens to be set, it will be processed first. The ISR assumes that SETUP is what it received if the Ep0 state is IDLE when the Ep0 interrupt occurs 

    I will send the CCS project to Mark Damian (at Arrow) who will get it to you.

    Thanks.

    Stephen

  • Hi Kravis,

    I seem to have resolved the EOT/usb_ctl handler issue. Moving the byte swap code to precede the processing in usb_ctl prevents the race to byte swap the received data from USB_postTransaction (which already set EOT via the TransferComplete Callback routine). I need to confirm that this works for various commands from Host but this will allow me to check out the Interrupt Endpoint transfers that are used to transport the code load in chunks to the DSP.

    We would like to stay engaged as much as possible with the USB support group.

    Thanks

    Stephen