USBFS - Generic 64-Byte HID problems with Out Endpoint?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hello,

I'm having some problems getting my 64-Byte HID interface working properly, and I'm stumped as to why.  I mostly used this as a reference: https://www.cypress.com/file/134411/download

https://www.cypress.com/file/134411/download

My code to process the endpoints, based on the code in Appendix A of AN82072 is as follows:

static uint8_t USB_InBuffer[64];

static uint8_t USB_OutBuffer[64];

#define CONFIG_STX 0x02

void Process_USB(void){

    /*IN Buffer is data going INTO PC*/

    if (USBFS_bGetEPState(1) == USBFS_IN_BUFFER_EMPTY){

        USBFS_LoadInEP(1, USB_InBuffer, 64);

        memset(USB_InBuffer, 0x00,64);

        USBFS_EnableOutEP(2);

    }

   

    /*OUT Buffer is data coming OUT OF PC*/

    if (USBFS_bGetEPState(2) == USBFS_OUT_BUFFER_FULL){

        USBFS_ReadOutEP(2,USB_OutBuffer,64);

       

        if (USB_OutBuffer[0] == CONFIG_STX){

            UART_PutString("RCVD\r\n");

            /*Process Data Here*/

           

        }

        memset(USB_OutBuffer,0x00,64);

        USBFS_EnableOutEP(2);

    }

       

}

I've been able to determine that using EP1 (IN) works fine as far as I can tell.  I drop my bytes into the USB_InBuffer and they show up on the host no problem.  What is giving me fits is EP2 (OUT).  What I'm seeing that that when I send a data to the PSoC from the host PC, I hit USBFS_ReadOutEP() just as I should, and when I put a breakpoint on USBFS_ReadOutEP() I notice that the USB_OutBuffer seems to already contain the data packet I sent via my .NET application:

pastedImage_5.png

Data at Beakpoint:

pastedImage_1.png

Then,  if I break on the next line (checking for my 0x02 STX byte) my contents of USB_OutBuffer are now completely different!

pastedImage_2.png

This leaves me with 2 questions:

1) Why does my USB_OutBuffer contain the data I sent before I've read the OUT endpoint

2) Why does reading the OUT endpoint overwrite USB_OutBuffer with (seemingly nonsensical) data?

I've been banging my head against the desk all morning, I can't figure out why this is occurring!

I've also attached the project, I'm running this on a CY8CKIT-050.  There's a bunch of other code in there related to RS232 and an attached keypad that shouldn't matter (I've commented out the calls for processing RS232 and Keypad in main).  If anyone could take a look and let me know if I'm missing (or misunderstanding) something it would be greatly appreciated!

1 Solution

I referred the AN82072, The problem may be due to the order in which the program executes.

  1.     if (USBFS_bGetEPState(1) == USBFS_IN_BUFFER_EMPTY){ 
  2.         USBFS_LoadInEP(1, USB_InBuffer, 64); 
  3.         memset(USB_InBuffer, 0x00,64); 
  4.         USBFS_EnableOutEP(2); 
  5.     } 
  6.      
  7.     /*OUT Buffer is data coming OUT OF PC*/ 
  8.     if (USBFS_bGetEPState(2) == USBFS_OUT_BUFFER_FULL){ 
  9.         USBFS_ReadOutEP(2,USB_OutBuffer,64); 
  10.          
  11.         if (USB_OutBuffer[0] == CONFIG_STX){ 
  12.             UART_PutString("RCVD\r\n"); 
  13.             /*Process Data Here*/ 
  14.              
  15.         } 
  16.         memset(USB_OutBuffer,0x00,64); 
  17.         USBFS_EnableOutEP(2); 
  18.     } 

a. USBFS_EnableOutEP(2)  must be called before OutBuffer read out.

void USBFS_EnableOutEP(uint8 epNumber)

{

    if ((epNumber > USBFS_EP0) && (epNumber < USBFS_MAX_EP))

    {

        USBFS_EP[epNumber].apiEpState = USBFS_NO_EVENT_PENDING;

        /* Enable OUT endpoint to be written by Host. */

        USBFS_SIE_EP_BASE.sieEp[epNumber].epCr0 = USBFS_EP[epNumber].epMode;

       

    }

}

b. USBFS_bGetEPState(2) return the the "apiEpState"

uint8 USBFS_GetEPState(uint8 epNumber)

{

    return (USBFS_EP[epNumber].apiEpState);

}

c. In the usb ISR, apiEpState is assigned USBFS_EVENT_PENDING which is the same as USBFS_OUT_BUFFER_FULL

     USBFS_EP[USBFS_EP2].apiEpState = USBFS_EVENT_PENDING;

So, the communication between HOST and PSOC is depended on the USBFS_EnableOutEP what caused the problem in AN82072.

View solution in original post

2 Replies
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Well I at least think I've got a hint now.  Of course it was in the code that I didn't put in my post, the initialization code:

while (!USBFS_bGetConfiguration());

    USBFS_LoadInEP(1, USB_InBuffer, 64);

    USBFS_EnableOutEP(2);

    USBFS_ReadOutEP(2, USB_OutBuffer, 64);  //This line here

Removing the USBFS_ReadOutEP() call looks like it was solves the issue, although I'm not entirely sure why that made it behave like it did.  When that first call of USBFS_ReadOutEP() occurs in my initialization code, I hadn't sent the data from the PC yet.

Looking at the USBFS_ReadOutEP() definition, I don't see how it would have the data already in the buffer when I call it after checking if the OUT Endpoint is full.  If anything I would think that first call of USBFS_ReadOutEP() would put all 0 into USB_OutBuffer.

I did on the other hand notice that I don't need to re-enable the Out EP manually in my main processing code, looks like USBFS_ReadOutEP() will do that for me.  I guess that AppNote I referenced is a little old.

0 Likes

I referred the AN82072, The problem may be due to the order in which the program executes.

  1.     if (USBFS_bGetEPState(1) == USBFS_IN_BUFFER_EMPTY){ 
  2.         USBFS_LoadInEP(1, USB_InBuffer, 64); 
  3.         memset(USB_InBuffer, 0x00,64); 
  4.         USBFS_EnableOutEP(2); 
  5.     } 
  6.      
  7.     /*OUT Buffer is data coming OUT OF PC*/ 
  8.     if (USBFS_bGetEPState(2) == USBFS_OUT_BUFFER_FULL){ 
  9.         USBFS_ReadOutEP(2,USB_OutBuffer,64); 
  10.          
  11.         if (USB_OutBuffer[0] == CONFIG_STX){ 
  12.             UART_PutString("RCVD\r\n"); 
  13.             /*Process Data Here*/ 
  14.              
  15.         } 
  16.         memset(USB_OutBuffer,0x00,64); 
  17.         USBFS_EnableOutEP(2); 
  18.     } 

a. USBFS_EnableOutEP(2)  must be called before OutBuffer read out.

void USBFS_EnableOutEP(uint8 epNumber)

{

    if ((epNumber > USBFS_EP0) && (epNumber < USBFS_MAX_EP))

    {

        USBFS_EP[epNumber].apiEpState = USBFS_NO_EVENT_PENDING;

        /* Enable OUT endpoint to be written by Host. */

        USBFS_SIE_EP_BASE.sieEp[epNumber].epCr0 = USBFS_EP[epNumber].epMode;

       

    }

}

b. USBFS_bGetEPState(2) return the the "apiEpState"

uint8 USBFS_GetEPState(uint8 epNumber)

{

    return (USBFS_EP[epNumber].apiEpState);

}

c. In the usb ISR, apiEpState is assigned USBFS_EVENT_PENDING which is the same as USBFS_OUT_BUFFER_FULL

     USBFS_EP[USBFS_EP2].apiEpState = USBFS_EVENT_PENDING;

So, the communication between HOST and PSOC is depended on the USBFS_EnableOutEP what caused the problem in AN82072.