Beispiel #1
0
static void UartBridgeStart(void)
{
    uint16_t size = 0;
    CyU3PEpConfig_t epCfg;
    CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();

    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PUartConfig_t uartConfig;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;


    /* Initialize the UART for printing debug messages */
    apiRetStatus = CyU3PUartInit();
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Set UART configuration */
    CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
    uartConfig.baudRate = CY_U3P_UART_BAUDRATE_4M; // CY_U3P_UART_BAUDRATE_115200;
    uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;
    uartConfig.parity = CY_U3P_UART_NO_PARITY;
    uartConfig.txEnable = CyTrue;
    uartConfig.rxEnable = CyTrue;
    uartConfig.flowCtrl = CyFalse;
    uartConfig.isDma = CyTrue;

    apiRetStatus = CyU3PUartSetConfig (&uartConfig, NULL);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Set UART Tx and Rx transfer Size to infinite */
    apiRetStatus = CyU3PUartTxSetBlockXfer(0xFFFFFFFF);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyFxAppErrorHandler(apiRetStatus);
    }

    apiRetStatus = CyU3PUartRxSetBlockXfer(0xFFFFFFFF);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyFxAppErrorHandler(apiRetStatus);
    }


    /* Determine max packet size based on USB speed */
    switch (usbSpeed)
    {
        case CY_U3P_FULL_SPEED:
            size = 64;
            break;

        case CY_U3P_HIGH_SPEED:
            size = 512;
            break;

        case CY_U3P_SUPER_SPEED:
            size = 1024;
            break;

        default:
            CyU3PDebugPrint (4, "Error! Invalid USB speed.\n");
            CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE);
            break;
    }

    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
    epCfg.enable = CyTrue;
    epCfg.epType = CY_U3P_USB_EP_BULK;
    epCfg.burstLen = 1;
    epCfg.streams = 0;
    epCfg.pcktSize = size;

    /* Producer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_UART_EP_PRODUCER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    /* Consumer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_UART_EP_CONSUMER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size  = 16;
    dmaCfg.count = 10;
    dmaCfg.prodSckId = CY_U3P_UIB_SOCKET_PROD_2;
    dmaCfg.consSckId = CY_U3P_LPP_SOCKET_UART_CONS;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = 0;
    dmaCfg.cb = 0;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

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

    dmaCfg.prodSckId = CY_U3P_LPP_SOCKET_UART_PROD;
    dmaCfg.consSckId = CY_U3P_UIB_SOCKET_CONS_2;
    apiRetStatus = CyU3PDmaChannelCreate(&glChHandlebladeRFUARTtoU,
            CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Flush the endpoint memory */
    CyU3PUsbFlushEp(BLADE_UART_EP_PRODUCER);
    CyU3PUsbFlushEp(BLADE_UART_EP_CONSUMER);

    /* Set DMA channel transfer size */
    apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandlebladeRFUtoUART, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandlebladeRFUARTtoU, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

     /* Set UART Tx and Rx transfer Size to infinite */
     apiRetStatus = CyU3PUartTxSetBlockXfer(0xFFFFFFFF);
     if (apiRetStatus != CY_U3P_SUCCESS) {
         CyFxAppErrorHandler(apiRetStatus);
     }

     apiRetStatus = CyU3PUartRxSetBlockXfer(0xFFFFFFFF);
     if (apiRetStatus != CY_U3P_SUCCESS) {
         CyFxAppErrorHandler(apiRetStatus);
     }
}
void
CyFxGpifAppRqtHandler (
        void)
{
    CyU3PReturnStatus_t status;
    CyU3PMbox rspMbox;
    uint8_t rqtCode;
    uint8_t params[7];

    /* Break the request data into bytes. */
    rqtCode   = CY_U3P_DWORD_GET_BYTE3 (fxAppMbox.w0);  /* The request code is the MSB of w0. */
    params[0] = CY_U3P_DWORD_GET_BYTE2 (fxAppMbox.w0);
    params[1] = CY_U3P_DWORD_GET_BYTE1 (fxAppMbox.w0);
    params[2] = CY_U3P_DWORD_GET_BYTE0 (fxAppMbox.w0);
    params[3] = CY_U3P_DWORD_GET_BYTE3 (fxAppMbox.w1);
    params[4] = CY_U3P_DWORD_GET_BYTE2 (fxAppMbox.w1);
    params[5] = CY_U3P_DWORD_GET_BYTE1 (fxAppMbox.w1);
    params[6] = CY_U3P_DWORD_GET_BYTE0 (fxAppMbox.w1);

    switch (rqtCode)
    {
    case CYFXSTORRQT_INIT:
        {
            /* SIB start request. No parameters are used for this request. */
            status = CyU3PSibStart ();

            /* SIB start has succeeded. We can create the DMA channels for data transfer at this stage. */
            if (status == CY_U3P_SUCCESS)
            {
                status = CyFxGpifAppCreateDmaChannels ();

                /* Register a callback for SIB events. */
                CyU3PSibRegisterCbk (CyFxGpifAppSibCallback);
            }

            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_DEINIT:
        {
            /* SIB start request. No parameters are used for this request. */
            CyU3PSibStop ();

            /* SIB stop is complete. We can tear down the DMA channels at this stage. */
            CyFxGpifAppDestroyDmaChannels ();

            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24);
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_PORTCFG:
        {
            CyU3PSibIntfParams_t intfCfg;

            /* Populate the structure with data from the mailbox request. */
            intfCfg.rstActHigh      = ((params[1] & 0x01) == 0x01) ? 1 : 0;
            intfCfg.writeProtEnable = ((params[1] & 0x02) == 0x02) ? 1 : 0;
            intfCfg.lowVoltage      = ((params[1] & 0x04) == 0x04) ? 1 : 0;
            intfCfg.useDdr          = ((params[1] & 0x08) == 0x08) ? 1 : 0;
            intfCfg.resetGpio       = params[2];
            intfCfg.cardDetType     = params[3];
            intfCfg.voltageSwGpio   = params[4];
            intfCfg.lvGpioState     = CyFalse;
            intfCfg.maxFreq         = CY_U3P_SIB_FREQ_104MHZ;        /* No S port clock limitation. */
            intfCfg.cardInitDelay   = 0;                             /* No SD/MMC initialization delay. */

            status = CyU3PSibSetIntfParams (params[0], &intfCfg);

            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_QUERYDEV:
        {
            CyU3PSibDevInfo_t devInfo;

            status = CyU3PSibQueryDevice (params[0], &devInfo);
            if (status == CY_U3P_SUCCESS)
            {
                /* Only some of the device info fields are being returned here, so as to restrict the
                   response to 8 bytes. This can be expanded by breaking up the response into multiple
                   messages.
                   */
                rspMbox.w0 = CY_U3P_MAKEDWORD (CYFXSTORRESP_DEVDATA, (uint8_t)devInfo.cardType,
                        (uint8_t)devInfo.numUnits, (uint8_t)devInfo.writeable);
                rspMbox.w1 = (uint32_t)devInfo.blkLen;

                fxAppDevBlkSize = devInfo.blkLen;
            }
            else
            {
                rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
                rspMbox.w1 = 0;
            }

            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_QUERYUNIT:
        {
            CyU3PSibLunInfo_t unitInfo;

            status = CyU3PSibQueryUnit (params[0], params[1], &unitInfo);
            if (status == CY_U3P_SUCCESS)
            {
                /* Only some of the device info fields are being returned here, so as to restrict the
                   response to 8 bytes. This can be expanded by breaking up the response into multiple
                   messages.
                   */
                rspMbox.w0 = CY_U3P_MAKEDWORD (CYFXSTORRESP_UNITDATA, (uint8_t)unitInfo.valid,
                        (uint8_t)unitInfo.location, (uint8_t)unitInfo.type);
                rspMbox.w1 = unitInfo.numBlocks;
            }
            else
            {
                rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
                rspMbox.w1 = 0;
            }

            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_READ:
        {
            uint32_t flag;

            status = CyU3PDmaChannelSetXfer (&fxAppReadChannel, params[3] * fxAppDevBlkSize);
            if (status == CY_U3P_SUCCESS)
            {
                status = CyU3PSibReadWriteRequest (CyTrue, params[0], params[1], params[2],
                        fxAppMbox.w1, CYFXSTORAPP_SIB_RDSOCK);
                if (status == CY_U3P_SUCCESS)
                {
                    status = CyU3PEventGet (&fxAppEvent, CYFXAPP_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR,
                            &flag, CYFXSTORAPP_XFER_TIMEOUT);
                    if (status == CY_U3P_SUCCESS)
                    {
                        if (fxAppXferStatus == CY_U3P_SUCCESS)
                        {
                            status = CyU3PDmaChannelWaitForCompletion (&fxAppReadChannel, CYFXSTORAPP_XFER_TIMEOUT);
                        }
                        else
                            status = fxAppXferStatus;
                    }

                    if (status != CY_U3P_SUCCESS)
                    {
                        CyU3PSibAbortRequest (params[0]);
                        CyU3PDmaChannelReset (&fxAppReadChannel);
                    }
                }
            }

            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_WRITE:
        {
            uint32_t flag;

            status = CyU3PDmaChannelSetXfer (&fxAppWriteChannel, params[3] * fxAppDevBlkSize);
            if (status == CY_U3P_SUCCESS)
            {
                status = CyU3PSibReadWriteRequest (CyFalse, params[0], params[1], params[2],
                        fxAppMbox.w1, CYFXSTORAPP_SIB_WRSOCK);
                if (status == CY_U3P_SUCCESS)
                {
                    status = CyU3PEventGet (&fxAppEvent, CYFXAPP_SIB_DONE_EVENT, CYU3P_EVENT_OR_CLEAR,
                            &flag, CYFXSTORAPP_XFER_TIMEOUT);
                    if (status == CY_U3P_SUCCESS)
                    {
                        if (fxAppXferStatus == CY_U3P_SUCCESS)
                        {
                            status = CyU3PDmaChannelWaitForCompletion (&fxAppWriteChannel, CYFXSTORAPP_XFER_TIMEOUT);
                        }
                        else
                            status = fxAppXferStatus;
                    }

                    if (status != CY_U3P_SUCCESS)
                    {
                        CyU3PSibAbortRequest (params[0]);
                        CyU3PDmaChannelReset (&fxAppWriteChannel);
                    }
                }
            }

            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | status;
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    case CYFXSTORRQT_ECHO:
        {
            rspMbox.w0 = (CYFXSTORRESP_ECHO << 24) | (fxAppMbox.w0 & 0xFFFFFF);
            rspMbox.w1 = fxAppMbox.w1;
            CyU3PMboxWrite (&rspMbox);
        }
        break;

    default:
        {
            /* Unsupported command. */
            rspMbox.w0 = (CYFXSTORRESP_STATUS << 24) | CY_U3P_ERROR_CMD_NOT_SUPPORTED;
            rspMbox.w1 = 0;
            CyU3PMboxWrite (&rspMbox);
        }
        break;
    }
}
Beispiel #3
0
/* This function starts the RF data transport mechanism. This is the second
 * interface of the first and only descriptor. */
static void NuandRFLinkStart(void)
{
    uint16_t size = 0;
    CyU3PEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PDmaMultiChannelConfig_t dmaMultiConfig;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();

    NuandAllowSuspend(CyFalse);
    NuandGPIOReconfigure(CyTrue, CyTrue);

    /* Restart the PIB block, due to a bug where 16-bit to 32-bit GPIF transitions
       mess up the first DMA transaction.  Restarting the PIB wipes all of the GPIF
       configurations */
    CyU3PPibClock_t pibClock;

    apiRetStatus = CyU3PPibDeInit();
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "P-Port DeInitialization failed, Error Code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Initialize the P-Port here */
    pibClock.clkDiv = 4;
    pibClock.clkSrc = CY_U3P_SYS_CLK;
    pibClock.isHalfDiv = CyFalse;

    /* Enable DLL for async GPIF */
    pibClock.isDllEnable = CyFalse;
    apiRetStatus = CyU3PPibInit(CyTrue, &pibClock);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "P-Port Initialization failed, Error Code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    CyU3PGpioSetValue(GPIO_SYS_RST, CyTrue);
    CyU3PGpioSetValue(GPIO_RX_EN, CyFalse);
    CyU3PGpioSetValue(GPIO_TX_EN, CyFalse);
    CyU3PGpioSetValue(GPIO_SYS_RST, CyFalse);

    /* Load the GPIF configuration for loading the RF transceiver */
    apiRetStatus = CyU3PGpifLoad(&Rflink_CyFxGpifConfig);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PGpifLoad failed, Error Code = %d\n",apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Start the state machine. */
    apiRetStatus = CyU3PGpifSMStart(RFLINK_START, RFLINK_ALPHA_START);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PGpifSMStart failed, Error Code = %d\n",apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Determine max packet size based on USB speed */
    switch (usbSpeed)
    {
        case CY_U3P_FULL_SPEED:
            size = 64;
            break;

        case CY_U3P_HIGH_SPEED:
            size = 512;
            break;

        case CY_U3P_SUPER_SPEED:
            size = 1024;
            break;

        default:
            CyU3PDebugPrint (4, "Error! Invalid USB speed.\n");
            CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE);
            break;
    }

    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
    epCfg.enable = CyTrue;
    epCfg.epType = CY_U3P_USB_EP_BULK;
    epCfg.burstLen = (usbSpeed == CY_U3P_SUPER_SPEED ? 15 : 1);
    epCfg.streams = 0;
    epCfg.pcktSize = size;

    /* Producer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_RF_SAMPLE_EP_PRODUCER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    /* Consumer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_RF_SAMPLE_EP_CONSUMER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    // multi variant
    dmaMultiConfig.size = size * 2;
    dmaMultiConfig.count = 22;
    dmaMultiConfig.validSckCount = 2;
    dmaMultiConfig.prodSckId[0] = BLADE_RF_SAMPLE_EP_PRODUCER_USB_SOCKET;
    dmaMultiConfig.consSckId[0] = CY_U3P_PIB_SOCKET_2;
    dmaMultiConfig.consSckId[1] = CY_U3P_PIB_SOCKET_3;
    dmaMultiConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaMultiConfig.notification = 0;
    dmaMultiConfig.cb = 0;
    dmaMultiConfig.prodHeader = 0;
    dmaMultiConfig.prodFooter = 0;
    dmaMultiConfig.consHeader = 0;
    dmaMultiConfig.prodAvailCount = 0;

    // non multi variant
    CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size  = size * 2;
    dmaCfg.count = 22;
    dmaCfg.prodSckId = BLADE_RF_SAMPLE_EP_PRODUCER_USB_SOCKET;
    dmaCfg.consSckId = CY_U3P_PIB_SOCKET_3;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = 0;
    dmaCfg.cb = 0;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate(&glChHandleUtoP, CY_U3P_DMA_TYPE_AUTO, &dmaCfg);

    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaMultiChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    dmaCfg.prodSckId = CY_U3P_PIB_SOCKET_0;
    dmaCfg.consSckId = BLADE_RF_SAMPLE_EP_CONSUMER_USB_SOCKET;
    apiRetStatus = CyU3PDmaChannelCreate(&glChHandlePtoU, CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaMultiChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Flush the Endpoint memory */
    CyU3PUsbFlushEp(BLADE_RF_SAMPLE_EP_PRODUCER);
    CyU3PUsbFlushEp(BLADE_RF_SAMPLE_EP_CONSUMER);

    /* Set DMA channel transfer size. */

    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUtoP, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandlePtoU, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    UartBridgeStart();
    glAppMode = MODE_RF_CONFIG;

}
Beispiel #4
0
/* This function starts the RF data transport mechanism. This is the second
 * interface of the first and only descriptor. */
static void NuandRFLinkStart(void)
{
    uint16_t size = 0;
    CyU3PEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PDmaMultiChannelConfig_t dmaMultiConfig;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();

    NuandAllowSuspend(CyFalse);
    NuandGPIOReconfigure(CyTrue, CyTrue);

    CyU3PGpioSetValue(GPIO_SYS_RST, CyTrue);
    CyU3PGpioSetValue(GPIO_RX_EN, CyFalse);
    CyU3PGpioSetValue(GPIO_TX_EN, CyFalse);
    CyU3PGpioSetValue(GPIO_SYS_RST, CyFalse);

    apiRetStatus = NuandConfigureGpif(GPIF_CONFIG_RF_LINK);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "Failed to configure GPIF, Error code = %d\n",
                        apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Determine max packet size based on USB speed */
    switch (usbSpeed)
    {
        case CY_U3P_FULL_SPEED:
            size = 64;
            break;

        case CY_U3P_HIGH_SPEED:
            size = 512;
            break;

        case CY_U3P_SUPER_SPEED:
            size = 1024;
            break;

        default:
            CyU3PDebugPrint (4, "Error! Invalid USB speed.\n");
            CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE);
            break;
    }

    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
    epCfg.enable = CyTrue;
    epCfg.epType = CY_U3P_USB_EP_BULK;
    epCfg.burstLen = (usbSpeed == CY_U3P_SUPER_SPEED ? 15 : 1);
    epCfg.streams = 0;
    epCfg.pcktSize = size;

    /* Producer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_RF_SAMPLE_EP_PRODUCER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    /* Consumer endpoint configuration */
    apiRetStatus = CyU3PSetEpConfig(BLADE_RF_SAMPLE_EP_CONSUMER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    // multi variant
    dmaMultiConfig.size = size * 2;
    dmaMultiConfig.count = 22;
    dmaMultiConfig.validSckCount = 2;
    dmaMultiConfig.prodSckId[0] = BLADE_RF_SAMPLE_EP_PRODUCER_USB_SOCKET;
    dmaMultiConfig.consSckId[0] = CY_U3P_PIB_SOCKET_2;
    dmaMultiConfig.consSckId[1] = CY_U3P_PIB_SOCKET_3;
    dmaMultiConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaMultiConfig.notification = 0;
    dmaMultiConfig.cb = 0;
    dmaMultiConfig.prodHeader = 0;
    dmaMultiConfig.prodFooter = 0;
    dmaMultiConfig.consHeader = 0;
    dmaMultiConfig.prodAvailCount = 0;

    // non multi variant
    CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size  = size * 2;
    dmaCfg.count = 22;
    dmaCfg.prodSckId = BLADE_RF_SAMPLE_EP_PRODUCER_USB_SOCKET;
    dmaCfg.consSckId = CY_U3P_PIB_SOCKET_3;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = 0;
    dmaCfg.cb = 0;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    loopback_when_created = loopback;

    if (loopback) {
        dmaCfg.prodSckId = BLADE_RF_SAMPLE_EP_PRODUCER_USB_SOCKET;
        dmaCfg.consSckId = BLADE_RF_SAMPLE_EP_CONSUMER_USB_SOCKET;
    }

    apiRetStatus = CyU3PDmaChannelCreate(&glChHandleUtoP, CY_U3P_DMA_TYPE_AUTO, &dmaCfg);

    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaMultiChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    if (!loopback) {
        dmaCfg.prodSckId = CY_U3P_PIB_SOCKET_0;
        dmaCfg.consSckId = BLADE_RF_SAMPLE_EP_CONSUMER_USB_SOCKET;
        apiRetStatus = CyU3PDmaChannelCreate(&glChHandlePtoU, CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
        if (apiRetStatus != CY_U3P_SUCCESS) {
            CyU3PDebugPrint(4, "CyU3PDmaMultiChannelCreate failed, Error code = %d\n", apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }
    }

    /* Flush the Endpoint memory */
    CyU3PUsbFlushEp(BLADE_RF_SAMPLE_EP_PRODUCER);
    CyU3PUsbFlushEp(BLADE_RF_SAMPLE_EP_CONSUMER);

    /* Set DMA channel transfer size. */

    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUtoP, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        CyU3PDebugPrint(4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    if (!loopback) {
        apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandlePtoU, BLADE_DMA_TX_SIZE);
        if (apiRetStatus != CY_U3P_SUCCESS) {
            CyU3PDebugPrint(4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }
    }

    UartBridgeStart();
    glAppMode = MODE_RF_CONFIG;

}
/* Initalizes the mouse driver. */
CyU3PReturnStatus_t
CyFxMouseDriverInit ()
{
    uint16_t length, size, interval;
    CyU3PReturnStatus_t status;
    CyU3PUsbHostEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;

    /* Read first four bytes of configuration descriptor to determine
     * the total length. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, 4, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the length of the data received. */
    length = CY_U3P_MAKEWORD(glEp0Buffer[3], glEp0Buffer[2]);
    if (length > CY_FX_HOST_EP0_BUFFER_SIZE)
    {
        goto enum_error;
    }

    /* Read the full configuration descriptor. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, length, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Save the required information. */
    glHostMouseEp = glEp0Buffer[29];
    size = CY_U3P_MAKEWORD(glEp0Buffer[32], glEp0Buffer[31]);
    interval = glEp0Buffer[33];

    /* Set the new configuration. */
    status = CyFxSendSetupRqt (0x00, CY_U3P_USB_SC_SET_CONFIGURATION, 1, 0, 0, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Set the report mode to idle so that report is sent only
     * when there is active data. */
    status = CyFxSendSetupRqt (0x21, 0x0A, 0, 0, 0, glEp0Buffer);
#if 0 /* It does not matter even if the request gets stalled. */
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
#endif

    /* Initialize the HID mouse. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_INTR;
    epCfg.mult = 1;
    epCfg.maxPktSize = size;
    interval = (1 << (interval - 1)) / 8;
    if (interval > 255)
    {
        interval = 255;
    }
    epCfg.pollingRate = interval;
    /* Since DMA buffer sizes can only be multiple of 16 bytes and
     * also since this is an interrupt endpoint where the max data
     * packet size is same as the maxPktSize field, the fullPktSize
     * has to be a multiple of 16 bytes. */
    size = ((size + 0x0F) & ~0x0F);
    epCfg.fullPktSize = size;
    /* Since the IN token has to be sent out continously, it
     * is easier to enable the stream mode. Otherwise we will
     * have to maintain the timing. */
    epCfg.isStreamMode = CyTrue;
    status = CyU3PUsbHostEpAdd (glHostMouseEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Create a DMA channel for this EP. */
    CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size = size;
    dmaCfg.count = CY_FX_HOST_DMA_BUF_COUNT;
    dmaCfg.prodSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_PROD_0 + (0x0F & glHostMouseEp));
    dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
    dmaCfg.cb = CyFxMouseDmaCb;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;
    status = CyU3PDmaChannelCreate (&glHostMouseCh, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Enable EP transfer. In stream mode, the transfer size should be zero. */
    status = CyU3PUsbHostEpSetXfer (glHostMouseEp, CY_U3P_USB_HOST_EPXFER_NORMAL, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Set for infinite transfer. */
    status = CyU3PDmaChannelSetXfer (&glHostMouseCh, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    CyU3PDebugPrint (4, "USB HID Mouse driver initialized successfully.\r\n");
    return CY_U3P_SUCCESS;

app_error:
    CyU3PDmaChannelDestroy (&glHostMouseCh);
    if (glHostMouseEp != 0)
    {
        CyU3PUsbHostEpRemove (glHostMouseEp);
        glHostMouseEp = 0;
    }

enum_error:
    return CY_U3P_ERROR_FAILURE;
}
Beispiel #6
0
static void NuandFpgaConfigStart(void)
{
    uint16_t size = 0;
    CyU3PEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();
    static int first_call = 1;

    NuandAllowSuspend(CyFalse);

    NuandGPIOReconfigure(CyFalse, !first_call);
    first_call = 0;

    apiRetStatus = NuandConfigureGpif(GPIF_CONFIG_FPGA_LOAD);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        LOG_ERROR(apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Determine max packet size based on USB speed */
    switch (usbSpeed)
    {
        case CY_U3P_FULL_SPEED:
            size = 64;
            break;

        case CY_U3P_HIGH_SPEED:
            size = 512;
            break;

        case CY_U3P_SUPER_SPEED:
            size = 1024;
            break;

        default:
            LOG_ERROR(usbSpeed);
            CyFxAppErrorHandler(CY_U3P_ERROR_FAILURE);
            break;
    }

    CyU3PMemSet((uint8_t *)&epCfg, 0, sizeof (epCfg));
    epCfg.enable = CyTrue;
    epCfg.epType = CY_U3P_USB_EP_BULK;
    epCfg.burstLen = 1;
    epCfg.streams = 0;
    epCfg.pcktSize = size;

    apiRetStatus = CyU3PSetEpConfig(BLADE_FPGA_EP_PRODUCER, &epCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        LOG_ERROR(apiRetStatus);
        CyFxAppErrorHandler (apiRetStatus);
    }

    dmaCfg.size  = size * 4;
    dmaCfg.count = BLADE_DMA_BUF_COUNT;
    dmaCfg.prodSckId = BLADE_FPGA_CONFIG_SOCKET;
    dmaCfg.consSckId = CY_U3P_PIB_SOCKET_3;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    /* Enable the callback for produce event, this is where the bits will get flipped */
    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;

    dmaCfg.cb = bladeRFConfigUtoPDmaCallback;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = size * 3;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate(&glChHandlebladeRFUtoP,
            CY_U3P_DMA_TYPE_MANUAL, &dmaCfg);

    if (apiRetStatus != CY_U3P_SUCCESS) {
        LOG_ERROR(apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Flush the endpoint memory */
    CyU3PUsbFlushEp(BLADE_FPGA_EP_PRODUCER);

    /* Set DMA channel transfer size. */
    apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandlebladeRFUtoP, BLADE_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        LOG_ERROR(apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    glAppMode = MODE_FPGA_CONFIG;
}
/* This function initializes the mouse driver application. */
static void
CyFxApplnStart ()
{
    uint16_t length, size, offset;
    CyU3PDmaBuffer_t buf_p;
    CyU3PReturnStatus_t status;
    CyU3PUsbHostEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PUsbHostEpStatus_t epStatus;

    /* Add EP0 to the scheduler. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_CONTROL;
    epCfg.mult = 1;
    /* Start off with 8 byte EP0 packet size. */
    epCfg.maxPktSize = 8;
    epCfg.pollingRate = 0;
    epCfg.fullPktSize = 8;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (0, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    CyU3PThreadSleep (100);
    /* Get the device descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_DEVICE_DESCR << 8), 0, 8);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the EP0 packet size and update the scheduler. */
    if (glEp0Buffer[7] != 8)
    {
        status = CyU3PUsbHostEpRemove (0);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
        /* Update the correct size. */
        epCfg.maxPktSize = glEp0Buffer[7];
        epCfg.fullPktSize = glEp0Buffer[7];
        status = CyU3PUsbHostEpAdd (0, &epCfg);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
    }

    /* Read the full device descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_DEVICE_DESCR << 8), 0, 18);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Check for the VID and PID of the attached peripheral. */
    if ((CY_U3P_MAKEWORD(glEp0Buffer[9], glEp0Buffer[8]) != CY_FX_HOST_PERIPHERAL_VID) ||
            (CY_U3P_MAKEWORD(glEp0Buffer[11], glEp0Buffer[10]) != CY_FX_HOST_PERIPHERAL_PID))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Check for device class, sub-class and protocol all of which has to be zero. */
    if ((glEp0Buffer[4] != 0) || (glEp0Buffer[5] != 0) || (glEp0Buffer[6] != 0))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Set the peripheral device address. */
    CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_ADDRESS,
            CY_FX_HOST_PERIPHERAL_ADDRESS, 0, 0);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostSetDeviceAddress (CY_FX_HOST_PERIPHERAL_ADDRESS);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Read the OTG descriptor to identify its characteristics.
     * Do this only if we are not already in role change. */
    glIsHnpSupported = CyFalse;
    if (!CyU3POtgIsHnpEnabled ())
    {
        CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                (CY_U3P_USB_OTG_DESCR << 8), 0, 5);
        status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
        status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
                CY_FX_HOST_EP0_WAIT_TIMEOUT);
        /* If the device does not support OTG, the request will be stalled. */
        if ((status == CY_U3P_SUCCESS) && (glEp0Buffer[2] & 0x02))
        {
            /* Let the device know that the host is HNP capable. */
            CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_FEATURE,
                    CY_U3P_USB2_OTG_A_HNP_SUPPORT, 0, 0);
            status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
            if (status != CY_U3P_SUCCESS)
            {
                goto enum_error;
            }
            status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
                    CY_FX_HOST_EP0_WAIT_TIMEOUT);

        }
        if (status == CY_U3P_SUCCESS)
        {
            glIsHnpSupported = CyTrue;
        }
    }

    /* Read first four bytes of configuration descriptor to determine
     * the total length. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, 4);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the length of the data received. */
    length = CY_U3P_MAKEWORD(glEp0Buffer[3], glEp0Buffer[2]);
    if (length > CY_FX_HOST_EP0_BUFFER_SIZE)
    {
        goto enum_error;
    }

    /* Read the full configuration descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, length);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Check if the device can be supported. Number of interfaces should be 1,
     * the intreface class must be vendor (0xFF) and the subclass and protocol
     * must be zero. The number of endpoints must be two. Also the endpoints
     * should be bulk. */
    if ((glEp0Buffer[5] != 1) || (glEp0Buffer[14] != 0xFF) ||
            (glEp0Buffer[15] != 0x00) || (glEp0Buffer[16] != 0x00) ||
            (glEp0Buffer[13] != 2))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Identify the EP characteristics. */
    offset = 0;
    while (offset < length)
    {
        if (glEp0Buffer[offset + 1] == CY_U3P_USB_ENDPNT_DESCR)
        {
            if (glEp0Buffer[offset + 3] != CY_U3P_USB_EP_BULK)
            {
                status = CY_U3P_ERROR_NOT_SUPPORTED;
                goto enum_error;
            }

            /* Retreive the information. */
            glHostEpSize = CY_U3P_MAKEWORD(glEp0Buffer[offset + 5],
                    glEp0Buffer[offset + 4]);
            if (glEp0Buffer[offset + 2] & 0x80)
            {
                glHostInEp = glEp0Buffer[offset + 2];
            }
            else
            {
                glHostOutEp = glEp0Buffer[offset + 2];
            }
        }

        /* Advance to next descriptor. */
        offset += glEp0Buffer[offset];
    }

    /* If there is any error in the configuration abort. */
    if ((glHostOutEp == 0) || (glHostInEp == 0))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Set the new configuration. */
    CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_CONFIGURATION, 1, 0, 0);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Initialize the loopback application. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_BULK;
    epCfg.mult = 1;
    epCfg.maxPktSize = glHostEpSize;
    epCfg.pollingRate = 0;
    size = ((glHostEpSize + 0x0F) & ~0x0F);
    epCfg.fullPktSize = glHostEpSize;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (glHostOutEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpAdd (glHostInEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        glHostInEp = 0;
        goto app_error;
    }

    /* Reset counter to zero. */
    glDMARxCount = 0;
    glDMATxCount = 0;

    /* Create a DMA channels for IN and OUT directions. */
    CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size = size;
    dmaCfg.count = CY_FX_HOST_DMA_BUF_COUNT;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    dmaCfg.prodSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_PROD_0 + (0x0F & glHostInEp));
    dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
    dmaCfg.cb = CyFxHostDmaCb;
    status = CyU3PDmaChannelCreate (&glHostInCh, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaCfg.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 + (0x0F & glHostOutEp));
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
    dmaCfg.cb = CyFxHostDmaCb;
    status = CyU3PDmaChannelCreate (&glHostOutCh, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Set infinite transfer on both the channels. */
    status = CyU3PDmaChannelSetXfer (&glHostInCh, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }
    status = CyU3PDmaChannelSetXfer (&glHostOutCh, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Pre-load all OUT buffers with fixed data. */
    for (offset = 0; offset < CY_FX_HOST_DMA_BUF_COUNT; offset++)
    {
        status = CyU3PDmaChannelGetBuffer (&glHostOutCh, &buf_p, CYU3P_NO_WAIT);
        if (status != CY_U3P_SUCCESS)
        {
            goto app_error;
        }
        CyU3PMemSet (buf_p.buffer, (uint8_t)CY_FX_HOST_DATA_BYTE, glHostEpSize);
        status = CyU3PDmaChannelCommitBuffer (&glHostOutCh, glHostEpSize, 0);
        if (status != CY_U3P_SUCCESS)
        {
            goto app_error;
        }
    }

    /* Queue a single read and single write request. */
    status = CyU3PUsbHostEpSetXfer (glHostInEp, CY_U3P_USB_HOST_EPXFER_NORMAL, glHostEpSize);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }
    status = CyU3PUsbHostEpSetXfer (glHostOutEp, CY_U3P_USB_HOST_EPXFER_NORMAL, glHostEpSize);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    glTimerCount = 0;
    glIsApplnActive = CyTrue;
    glIsHnp = CyFalse;
    glDoHnp = CyFalse;

    if (glIsHnpSupported)
    {
        CyU3PDebugPrint (4, "USB bulk loopback host mode operation started with HNP enabled.\r\n");
    }
    else
    {
        CyU3PDebugPrint (4, "USB bulk loopback host mode operation started with HNP disabled.\r\n");
    }

    return;

app_error:
    CyU3PDmaChannelDestroy (&glHostInCh);
    if (glHostInEp != 0)
    {
        CyU3PUsbHostEpRemove (glHostInEp);
        glHostInEp = 0;
    }
    CyU3PDmaChannelDestroy (&glHostOutCh);
    if (glHostOutEp != 0)
    {
        CyU3PUsbHostEpRemove (glHostOutEp);
        glHostOutEp = 0;
    }

enum_error:
    /* Remove EP0. and disable the port. */
    CyU3PUsbHostEpRemove (0);
    glHostEpSize = 0;
    CyU3PUsbHostPortDisable ();
    CyU3PDebugPrint (4, "Host mode application start failed with error: %d.\r\n", status);
}