Respond to Vendor Request on a different Endpoint?

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

cross mob
dmickels
Level 1
Level 1
10 sign-ins 5 replies posted 5 sign-ins

Hello,

I am trying to integrate some custom vendor requests and I am looking for a method to respond to these requests, but on a separate endpoint from EP0. I know that CyU3PUsbSendEP0Data() exists for responding on the EP0 endpoint, but I am looking for the ability to send a response to a different endpoint in addition. For instance,  sending data to an interrupt endpoint I have defined, or potentially even over GPIF? 

 

Is there anything put in place for this already, or is there a recommended approach for doing this?

Thanks in advance.

0 Likes
7 Replies
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi,

Could you elaborate your requirement so that we can understand more and suggest the best possible solution for you?

Best Regards,
AliAsgar

0 Likes

Hi,

I am working with two back to back FX3's using a modified version of the AutoMaster/Slave configuration from the GPIF II Master interface example. I am looking to add some custom vendor commands to integrate USBTMC on one FX3, and a custom implementation on the other FX3. Since these are connected back to back over GPIF, I am looking for a way to still send specific requests over the GPIF connection, by making use of an Interrupt endpoint to forward a request that would come through on the USBTMC side as a Vendor Request. For instance, if one of the FX3's receives a command, I might need to forward that command over GPIF to the second FX3, or even push the response onto an Interrupt endpoint.

0 Likes
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi,

One of the FX3 (A) will receive vendor commands. These vendor commands need to be pushed to the other FX3 (B) and the response must be sent from FX3 (B) to FX3 (A) over GPIF, back to host through interrupt IN endpoint. Is my understanding correct?

Why are vendor commands needed?

What are the types of DMA channels used?

Best Regards,
AliAsgar

0 Likes

Hi,

Yes, essentially I am just looking for a method like CyU3PUsbSendEP0Data(), but can work for any EP so that I could forward data to an interrupt endpoint I have defined.

I am using vendor commands as both FX3's are acting as essentially a bridge between two devices, and both the FX3's are interfacing with their own drivers. So sometimes, FX3(A) might have a request from the device attached to FX3(B) and I would like to forward that request across the GPIF and onto an Interrupt Endpoint so that the host running FX3(B) can then respond and send appropriate data, etc.

Currently using Auto DMA Channels like so:

/* Create a DMA Auto Channel between four sockets of the U port.
     * DMA size is set based on the USB speed. */
    dmaCfg.prodSckId = CY_FX_PRODUCER_USB_SOCKET;
    dmaCfg.consSckId = CY_FX_CONSUMER_PPORT_SOCKET;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_CONS_SUSP | CY_U3P_DMA_CB_PROD_SUSP | CY_U3P_DMA_CB_ERROR | CY_U3P_DMA_CB_ABORTED | CY_U3P_DMA_CB_XFER_CPLT | CY_U3P_DMA_CB_SEND_CPLT | CY_U3P_DMA_CB_RECV_CPLT | CY_U3P_DMA_CB_PROD_EVENT |CY_U3P_DMA_CB_CONS_EVENT;
    dmaCfg.cb = CyFxBulkDMATransferCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleBulkLpUtoP,
            CY_U3P_DMA_TYPE_AUTO_SIGNAL, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Create a DMA Auto Channel between four sockets of the P port.
     * DMA size is set based on the USB speed. */
    dmaCfg.prodSckId = CY_FX_PRODUCER_PPORT_SOCKET;
    dmaCfg.consSckId = CY_FX_CONSUMER_USB_SOCKET;
    dmaCfg.notification = CY_U3P_DMA_CB_CONS_SUSP | CY_U3P_DMA_CB_PROD_SUSP | CY_U3P_DMA_CB_ERROR | CY_U3P_DMA_CB_ABORTED | CY_U3P_DMA_CB_XFER_CPLT | CY_U3P_DMA_CB_SEND_CPLT | CY_U3P_DMA_CB_RECV_CPLT | CY_U3P_DMA_CB_PROD_EVENT |CY_U3P_DMA_CB_CONS_EVENT;
    dmaCfg.cb = CyFxBulkDMATransferCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;
    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleBulkLpPtoU,
    CY_U3P_DMA_TYPE_AUTO_SIGNAL, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
         CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
         CyFxAppErrorHandler(apiRetStatus);
    }

    /* Create a DMA Auto Channel between two sockets of the U port.
     * DMA size is set based on the USB speed.
     */
    /*
    dmaCfg.prodSckId = CY_FX_INTERRUPT_PRODUCER_PPORT_SOCKET;
    dmaCfg.consSckId = CY_FX_INTERRUPT_USB_SOCKET;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = 0;
    dmaCfg.cb = CyFxBulkDMATransferCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleInterruptLpUtoP,
            CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
       CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
       CyFxAppErrorHandler(apiRetStatus);
    }
    */

(The DMA callback is just a debug print so that I see a message every time I transfer over the endpoints)

Is there a way that I can manually write a message and send it to an endpoint? Like essentially construct a new USB Packet and some how send it to an endpoint?

0 Likes
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi,

In your previous response, you have mentioned "device attached to FX3(B)" and "host running FX3(B)". But the FX3's are connected back-to-back. Could you give more clarity on your application?

Also if you want to manually write a message and send it to an endpoint, you could use a MANUAL OUT channel.

Best Regards,
AliAsgar

 

 

0 Likes

Hi,

I have the FX3's hooked up back to back, with a host on each side like described in the Designing a Master Interface AN87216 example. Both sides are running a different driver to communicate with the FX3 on their side, but some times will need to communicate with the host on the opposite side (I should add, that I am currently just testing this in Control Center to ensure everything works). So Host A, will want to forward requests to Host B sometimes, and vice versa.

The desired result is that both hosts communicate to the FX3 on their side using Vendor requests, and some Vendor requests will need to send a notice over GPIF and to the attached FX3's Interrupt In endpoint so that the driver on the other side can read it.

Capture.PNG

Additionally, I have tried using a Manual Out DMA, but I am not seeing the expected results.

On each side, I have a DMA set up to send and receive over GPIF like so:

 

    //Send DMA
    dmaCfg.size  = 16384;
    dmaCfg.count = 3;
    dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaCfg.consSckId = CY_FX_INTERRUPT_CONSUMER_PPORT_SOCKET;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_CONS_SUSP | CY_U3P_DMA_CB_PROD_EVENT;
    dmaCfg.cb = CyFxSlFifoUtoPDmaCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleInterruptLpUtoP,
    		CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
       CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
       CyFxAppErrorHandler(apiRetStatus);
    }

    //Receive DMA
    dmaCfg.prodSckId = CY_FX_INTERRUPT_PRODUCER_PPORT_SOCKET;
    dmaCfg.consSckId = CY_FX_INTERRUPT_USB_SOCKET;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
    dmaCfg.cb = CyFxSlFifoPtoUDmaCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleInterruptLpPtoU,
    		CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
       CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
       CyFxAppErrorHandler(apiRetStatus);
    }

 

 

Then, when I want to send data, I use something like that is called on a Vendor request (0xC7).

 

        stat = CyU3PDmaChannelGetBuffer (&glChHandleInterruptLpUtoP, &buf_p, CYU3P_NO_WAIT);
        if (stat != CY_U3P_SUCCESS)
        {

            CyU3PDebugPrint (4, "FILLBUF-CyU3PDmaChannelGetBuffer failed, Error code = %d\n", stat);
            CyFxAppErrorHandler(stat);

        }

        CyU3PMemSet (buf_p.buffer, 0xAA, buf_p.size);
        stat = CyU3PDmaChannelCommitBuffer (&glChHandleInterruptLpUtoP, buf_p.size, 0);

        if (stat != CY_U3P_SUCCESS)
        {

            CyU3PDebugPrint (4, "CyU3PDmaChannelCommitBuffer failed, Error code = %d\n", stat);
            CyFxAppErrorHandler(stat);

        }

 

 

The Vendor request gets called, but I don't see the data (0xAA just for testing) showing up on the Interrupt In endpoint however. Is there more that would have to be done to make this work? Or am I using this in the wrong way?

0 Likes
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi,

Could you share the debug prints with us for both the FX3?

Count the number of PROD and CONS events for both the FX3 and print it.

Best Regards,
AliAsgar

 

0 Likes