How to let the control endpoint XferData function return true for FX3 device

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

cross mob
MaXi_1246331
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

I develop my FX3 firmare based on AN65974 "Designing with the EZ-USB FX3 Slave FIFO Interface".

The following code in CyFxSlFifoApplnUSBSetupCB is to clear the data in endpoint.

if ((bTarget == CY_U3P_USB_TARGET_ENDPT) && (bRequest == CY_U3P_USB_SC_CLEAR_FEATURE)

                && (wValue == CY_U3P_USBX_FS_EP_HALT))

{

if (glIsApplnActive)

        {

                if (wIndex == CY_FX_COMMAND_PRODUCER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoCommandUtoP);

                    CyU3PUsbFlushEp(CY_FX_COMMAND_PRODUCER);

                    CyU3PUsbResetEp (CY_FX_COMMAND_PRODUCER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoCommandUtoP, CY_FX_SLFIFO_DMA_TX_SIZE);

                }

                else if (wIndex == CY_FX_RESPONSE_CONSUMER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoResponsePtoU);

                    CyU3PUsbFlushEp(CY_FX_RESPONSE_CONSUMER);

                    CyU3PUsbResetEp (CY_FX_RESPONSE_CONSUMER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoResponsePtoU, CY_FX_SLFIFO_DMA_RX_SIZE);

                }

  CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                isHandled = CyTrue;

        }

}

The corresponding C++ code running in the host computer is as follows:

pCtrlEndpt->Target = TGT_ENDPT;

pCtrlEndpt->ReqType = REQ_STD;

pCtrlEndpt->Direction = DIR_TO_DEVICE;

pCtrlEndpt->ReqCode = 0x01;

pCtrlEndpt->Value = 0;

pCtrlEndpt->Index = WORD(address);

long len = 0;

UCHAR buf;

result = pCtrlEndpt->XferData(&buf,len);

I debug the firmware and see the code can run into the desired if and else branch. But the C++ application waits for a few seconds and return false. How to let pCtrlEndpt->XferData(&buf,len) return true. Thank you.

0 Likes
1 Solution

If you want to clear the CY_FX_RESPONSE_CONSUMER and CY_FX_COMMAND_PRODUCER endpoint.

Send a vendor command to handle the clearing the endpoint and DMA channel instead standard requests.

In side the vendor command, look for the endoint and do the following. Please refer USB Bulk Source Sink example firmware for handling the vendor request. In the host application, you have to frame a setup command so that it sends a VENDOR REQUEST (NOT STANDARD REQUEST ) w.r.t the endpoint that you want to reset(clear).

                    if(wIndex == CY_FX_EP_PRODUCER)

               {

                    CyU3PUsbSetEpNak (CY_FX_EP_PRODUCER, CyTrue);

                    CyU3PBusyWait (125);

                    CyU3PDmaChannelReset (&glChHandleBulkSink);

                    CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);

                    CyU3PUsbResetEp (CY_FX_EP_PRODUCER);

                    CyU3PUsbSetEpNak (CY_FX_EP_PRODUCER, CyFalse);

                    CyU3PDmaChannelSetXfer (&glChHandleBulkSink, CY_FX_BULKSRCSINK_DMA_TX_SIZE);

                    CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                    isHandled = CyTrue;

                    CyU3PUsbAckSetup ();

                    }

               else if(wIndex == CY_FX_EP_CONSUMER)

              {

               

                CyU3PUsbSetEpNak (CY_FX_EP_CONSUMER, CyTrue);

                    CyU3PBusyWait (125);

                    CyU3PDmaChannelReset (&glChHandleBulkSrc);

                    CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);

                    CyU3PUsbResetEp (CY_FX_EP_CONSUMER);

                    CyU3PUsbSetEpNak (CY_FX_EP_CONSUMER, CyFalse);

                    CyU3PDmaChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE);

                    CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                    isHandled = CyTrue;

                    CyU3PUsbAckSetup ();

                    CyFxBulkSrcSinkFillInBuffers ();

                    }

               }

The snippet that you posted in the first response is used to remove the USB STALL on endpoint along with clear endpoint and DMA channel.

Note that when the endpoint is can't handle the received request from the host, it can STALL the endpoint. When the host sees the STALL, it should send Clear feature request to remove the STALL. If you can't understand this, you may ignore this context for time being.

View solution in original post

0 Likes
18 Replies
KandlaguntaR_36
Moderator
Moderator
Moderator
25 solutions authored 10 solutions authored 5 solutions authored

The above mentioned FX3 code executes when the host sees that the endpoint is STALLed and send a clear feature over that endpoint.

The corresponding host application code is as follows:

if (!pCtrlEndpt->XferData(&buf,len)) {

  if (pCtrlEndpt->UsbdStatus == USBD_STATUS_STALL_PID) {

  std::cout << "stall detected, resetting endpoint" << std::endl;

  if (!pCtrlEndpt->Reset()) {

  std::cerr << "Reset() failed" << std::endl;

  }

  }

}

If you want to clear the endpoint and reset the dma channel before start of data transfer, you can call RESET function before the  start of a tranfser.

0 Likes

Does these codes should precede your code?

pCtrlEndpt->Target = TGT_ENDPT;

pCtrlEndpt->ReqType = REQ_STD;

pCtrlEndpt->Direction = DIR_TO_DEVICE;

pCtrlEndpt->ReqCode = 0x01;

pCtrlEndpt->Value = 0;

pCtrlEndpt->Index = WORD(address);

long len = 0;

UCHAR buf;

My experience is pCtrlEndpt->XferData(&buf,len) takes too much time and return a false.How to let it return a true? thank you.

0 Likes

After debugging, I find the endpoint can be reset by the above codes. But XferData will wait for a few seconds and return a false, or immediately return a false, depending on the firmware.I hope it returns a true immediately.

I think CyU3PUsbStall in the firmware decides the return of XferData in the host software. But I have tried many combinations of input parameters of CyU3PUsbStall.Only CyU3PUsbStall

(0, CyTrue, CyFalse) will immediately return false. Other combination will return false after a few seconds. What should be the first parameter of CyU3PUsbStall

0 Likes

What should be the first parameter of CyU3PUsbStall? In AN65974, it is wIndex which is the endpoint to be cleared. But I think it may be constant 0 instead, because XferData here is run by control endpoint. Anyway putting wIndex here will not return a true either.

0 Likes

Edited:

Please refer the following description regarding CyU3PUsbStall API. The first parameter is endpoint. When you call Reset function from one endpoint in host application, the same endpoint need to be pass to the first parameter of this. This endpoint is copied to wIndex and passed to the API. In case of control endpoint, wIndex will be 0.

CyU3PReturnStatus_t CyU3PUsbStall ( uint8_t ep, CyBool_t stall, CyBool_t toggle )

Set or clear the stall status of an endpoint.

Description

This function is to set or clear the stall status of a given endpoint. This function is to be used in response to SET_ -

FEATURE and CLEAR_FEATURE requests from the host as well as for interface specific error handling. When the

stall condition is being cleared, the data toggles for the endpoint can also be cleared. While an option is provided to

leave the data toggles unmodified, this should only be used under specific conditions as recommended by Cypress.

Return value

CY_U3P_SUCCESS - when the call is successful.

CY_U3P_ERROR_NOT_STARTED - when the USB driver has not been started.

CY_U3P_ERROR_BAD_ARGUMENT - when the endpoint is invalid.

Parameters

ep                          Endpoint number to be modified.

stall CyTrue:          Set the stall condition, CyFalse: Clear the stall

toggle CyTrue:      Clear the data toggles in a Clear Stall call. Note that the toggle parameter is ignored when

                              the stall parameter is set to CyTrue.

Please let me know why do you want to do this before every transfer?

0 Likes

I do not clear date before every transfer, but before the first transfer to eleminate the residual data of the last run of the host computer in the hardware remain powered all the time.

I do not understand the meaning of "stall". Does it mean stop or delay?

What should be the exact code of CyU3PUsbStall in order that the XferData return true immediately?

Thank you.

0 Likes

Looks like we are not in the same page.

Can you please let us know what is application and where you got stuck?

Which endpoint data that you want to clear before first transfer: Control Endpoint or Bulk endpoint?

0 Likes

If you want to clear the residual data on control endpoint, you have to filtered out in the application firmware and give the handle to library. Please try with the following snippet.

if ((bTarget == CY_U3P_USB_TARGET_ENDPT) && (bRequest == CY_U3P_USB_SC_CLEAR_FEATURE)

                && (wValue == CY_U3P_USBX_FS_EP_HALT))

{

if (glIsApplnActive)

        {

                if (wIndex == CY_FX_COMMAND_PRODUCER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoCommandUtoP);

                    CyU3PUsbFlushEp(CY_FX_COMMAND_PRODUCER);

                    CyU3PUsbResetEp (CY_FX_COMMAND_PRODUCER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoCommandUtoP, CY_FX_SLFIFO_DMA_TX_SIZE);

                 CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                     isHandled = CyTrue;

                }

                else if (wIndex == CY_FX_RESPONSE_CONSUMER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoResponsePtoU);

                    CyU3PUsbFlushEp(CY_FX_RESPONSE_CONSUMER);

                    CyU3PUsbResetEp (CY_FX_RESPONSE_CONSUMER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoResponsePtoU, CY_FX_SLFIFO_DMA_RX_SIZE);

                      CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                isHandled = CyTrue;

                }

        }

}

0 Likes

I do not want to clear control endpoint, but rather out and in endpoint before the first transfer.  The FX3 is used for host PC and FPGA communication. CY_FX_RESPONSE_CONSUMER is for FPGA to host computer transfer. CY_FX_COMMAND_PRODUCER is for host to FPGA transfer.As to my understanding, your latest code snippet is not for the control point. Your code is actually the same as the original question at the top. My question is my host computer function result = pCtrlEndpt->XferData(&buf,len) does not return true, no mater how I change the parameter of CyU3PUsbStall.But  the clear operation actually succeed acording to the empty flag.

I hope we are in the same page.

Thank you for your help.

0 Likes

If you want to clear the CY_FX_RESPONSE_CONSUMER and CY_FX_COMMAND_PRODUCER endpoint.

Send a vendor command to handle the clearing the endpoint and DMA channel instead standard requests.

In side the vendor command, look for the endoint and do the following. Please refer USB Bulk Source Sink example firmware for handling the vendor request. In the host application, you have to frame a setup command so that it sends a VENDOR REQUEST (NOT STANDARD REQUEST ) w.r.t the endpoint that you want to reset(clear).

                    if(wIndex == CY_FX_EP_PRODUCER)

               {

                    CyU3PUsbSetEpNak (CY_FX_EP_PRODUCER, CyTrue);

                    CyU3PBusyWait (125);

                    CyU3PDmaChannelReset (&glChHandleBulkSink);

                    CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);

                    CyU3PUsbResetEp (CY_FX_EP_PRODUCER);

                    CyU3PUsbSetEpNak (CY_FX_EP_PRODUCER, CyFalse);

                    CyU3PDmaChannelSetXfer (&glChHandleBulkSink, CY_FX_BULKSRCSINK_DMA_TX_SIZE);

                    CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                    isHandled = CyTrue;

                    CyU3PUsbAckSetup ();

                    }

               else if(wIndex == CY_FX_EP_CONSUMER)

              {

               

                CyU3PUsbSetEpNak (CY_FX_EP_CONSUMER, CyTrue);

                    CyU3PBusyWait (125);

                    CyU3PDmaChannelReset (&glChHandleBulkSrc);

                    CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);

                    CyU3PUsbResetEp (CY_FX_EP_CONSUMER);

                    CyU3PUsbSetEpNak (CY_FX_EP_CONSUMER, CyFalse);

                    CyU3PDmaChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE);

                    CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                    isHandled = CyTrue;

                    CyU3PUsbAckSetup ();

                    CyFxBulkSrcSinkFillInBuffers ();

                    }

               }

The snippet that you posted in the first response is used to remove the USB STALL on endpoint along with clear endpoint and DMA channel.

Note that when the endpoint is can't handle the received request from the host, it can STALL the endpoint. When the host sees the STALL, it should send Clear feature request to remove the STALL. If you can't understand this, you may ignore this context for time being.

0 Likes

I think the problem is nearly solved by your latest instruction. Tomorow I will try your solution. But why can't I use standard request? Why does the flag tell me the endpoint is cleared. If the standard request is not for clear ordinary endpoint. Whar is the following code used for?

if ((bTarget == CY_U3P_USB_TARGET_ENDPT) && (bRequest == CY_U3P_USB_SC_CLEAR_FEATURE)

                && (wValue == CY_U3P_USBX_FS_EP_HALT))

{

if (glIsApplnActive)

        {

                if (wIndex == CY_FX_COMMAND_PRODUCER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoCommandUtoP);

                    CyU3PUsbFlushEp(CY_FX_COMMAND_PRODUCER);

                    CyU3PUsbResetEp (CY_FX_COMMAND_PRODUCER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoCommandUtoP, CY_FX_SLFIFO_DMA_TX_SIZE);

                 CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                     isHandled = CyTrue;

                }

                else if (wIndex == CY_FX_RESPONSE_CONSUMER)

                {

                    CyU3PDmaChannelReset (&glChHandleSlFifoResponsePtoU);

                    CyU3PUsbFlushEp(CY_FX_RESPONSE_CONSUMER);

                    CyU3PUsbResetEp (CY_FX_RESPONSE_CONSUMER);

                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoResponsePtoU, CY_FX_SLFIFO_DMA_RX_SIZE);

                      CyU3PUsbStall (wIndex, CyFalse, CyTrue);

                isHandled = CyTrue;

                }

        }

}

What is the meaning of stall?

Thank you

0 Likes

Hi,

In response to the query asked in response 11 of this thread, this code is used to handle the CLEAR FEATURE request send by host when EP gets stalled. In that case host will send the CLEAR FEATURE request along with wValue = CY_U3P_USBX_FS_EP_HALT which tells that EP is halted.

-- CyU3PUsbStall (wIndex, CyFalse, CyTrue) should not be called otherwise the host can not successfully send a packet after clear operation.

This API is used to remove the stall form the EP(when second argument is CyFALSE). Could you please mention how you came across such conclusion? What error you are facing if you are trying to send data after executing this command?

Is your issue resolved? Are you able to clear the producer and consumer EP using Vendor commands?

Thanks & Regards
Abhinav

0 Likes

srdr​ told me to use vendor command to clear endpoint instead of the standard request. He provides the code in this thread. CyU3PUsbStall (wIndex, CyFalse, CyTrue) is called in the provided code. I test the code. After clear operation. I try to send a new packet previously cleared. The result is the host fuction pEndpoint->FinishXfer return false. If I remove CyU3PUsbStall (wIndex, CyFalse, CyTrue), the host can send data to FX3 and then host can send vendor command  to clear the data. This two steps can repeated without any error to be found and the nEmpty flag responds the these action as expected. I also found CyU3PUsbFlushEp is unnecessary for this clear vendor command.

"In response to the query asked in response 11 of this thread, this code is used to handle the CLEAR FEATURE request send by host when EP gets stalled. In that case host will send the CLEAR FEATURE request along with wValue = CY_U3P_USBX_FS_EP_HALT which tells that EP is halted." I think your remarks is on the standard request, Not the vendor request. To clear in and out endpoint I do not succeed in using standard request, but succeed in using vendor request.

Thank you. Please confirm my understanding.

0 Likes

My Final codes is orgnaised as follows.A few difference from your suggested code exists.Please confirm whether the difference from your suggestion is OK.

1) CyU3PUsbAckSetup is used for the clearing of each endpoint, no matter it is an in or out endpoint. If it is removed, the host pControlEnd->XferData() would wait for a few seconds and return a false.

2) CyFxBulkSrcSinkFillInBuffers() is removed, because I do not know the necessity of it and it can not be found in the Firmware API Guide.

I have a further question CyU3PBusyWait(125); 125ms is a constant and the delay required may depends on the clock frequency. Is the delay of 125ms OK for all of the frequency range?

Thank you for your effort. My problem is nearly solved.

  else if (bType == CY_U3P_USB_VENDOR_RQT)

  {

  if ((bTarget == CY_U3P_USB_TARGET_ENDPT) && (bRequest == 0xB3))

  {

  uint8_t EndPoint = (uint8_t)wValue;

  CyU3PDmaChannel* pChannel;

  uint32_t size;

  switch(EndPoint)

  {

  case CY_FX_COMMAND_PRODUCER:

  pChannel = &glChHandleSlFifoCommandUtoP;

  size = CY_FX_SLFIFO_DMA_TX_SIZE;

  break;

  case CY_FX_RESPONSE_CONSUMER:

  pChannel = &glChHandleSlFifoResponsePtoU;

  size = CY_FX_SLFIFO_DMA_RX_SIZE;

  break;

  case CY_FX_DATA_PRODUCER:

  pChannel = &glChHandleSlFifoDataPtoU;

  size = CY_FX_SLFIFO_DMA_RX_SIZE;

  break;

  case CY_FX_DATA_CONSUMER:

  pChannel = &glChHandleSlFifoDataUtoP;

  size = CY_FX_SLFIFO_DMA_TX_SIZE;

  break;

  }

  if (EndPoint==CY_FX_COMMAND_PRODUCER || EndPoint==CY_FX_RESPONSE_CONSUMER

  || EndPoint==CY_FX_DATA_PRODUCER || EndPoint==CY_FX_DATA_CONSUMER)

  {

  CyU3PUsbSetEpNak(EndPoint, CyTrue);

  CyU3PBusyWait(125);

  CyU3PDmaChannelReset (pChannel);

  CyU3PUsbFlushEp(EndPoint);

  CyU3PUsbResetEp (EndPoint);

  CyU3PUsbSetEpNak(EndPoint, CyFalse);

  CyU3PDmaChannelSetXfer (pChannel, size);

  CyU3PUsbStall (EndPoint, CyFalse, CyTrue);

  CyU3PUsbAckSetup();

  isHandled = CyTrue;

  }

  }

  }

0 Likes

My recent experience told me 1) CyU3PUsbStall (wIndex, CyFalse, CyTrue) should not be called otherwise the host can not successfully send a packet after clear operation. 2) CyU3PUsbFlushEp is not required to be called.

Please confirm my remarks. Thank you.

In the vendor request, remove CyU3PUsbStall (wIndex, CyFalse, CyTrue) and you may keep CyU3PUsbFlushEp.

Are you facing any issue if you keep CyU3PUsbFlushEp.

Yes, remove CyFxBulkSrcSinkFillInBuffers this is unrelated to your application.

Till now your understanding is correct.

0 Likes

I can not tell any difference whether the flush operation is called. But I am inclined to delete it so long as I do not know its necessity.

Thank you.

0 Likes