/* Entry function for the AppThread. */ void ApplnThread_Entry ( uint32_t input) { CyBool_t isPresent = CyFalse; CyU3PReturnStatus_t status = CY_U3P_SUCCESS; /* Initialize the debug logger. */ CyFxApplnDebugInit (); /* Initialize the example application. */ status = CyFxApplnInit(); if (status != CY_U3P_SUCCESS) { CyU3PDebugPrint (2, "Application initialization failed. Aborting.\r\n"); CyFxAppErrorHandler (status); } for (;;) { CyU3PThreadSleep (100); if (isPresent != glIsPeripheralPresent) { /* Stop previously started application. */ if (glIsApplnActive) { CyFxApplnStop (); } /* If a peripheral got connected, then enumerate * and start the application. */ if (glIsPeripheralPresent) { status = CyU3PUsbHostPortEnable (); if (status == CY_U3P_SUCCESS) { CyFxApplnStart (); } } /* Update the state variable. */ isPresent = glIsPeripheralPresent; } /* Since the test needs to be done from a thread, * this function is called at fixed interval. */ if (glHostOwner == CY_FX_HOST_OWNER_MSC_DRIVER) { CyFxMscDriverDoWork (); } } }
/* This function will be called periodically from * the application thread. If there is a change in * the peripheral status, this function will start * or stop the application accordingly. */ void CyFxUsbHostDoWork () { uint32_t upTime = 0, epStatus = 0; static CyBool_t isPresent = CyFalse; CyU3PReturnStatus_t status = CY_U3P_SUCCESS; static uint32_t rxCount = 0; static uint32_t txCount = 0; if (isPresent != glIsPeripheralPresent) { if (glDoHnp) { /* Complete the HNP. */ CyFxHostHnp (); glDoHnp = CyFalse; } else { /* Stop previously started application. */ if (glIsApplnActive) { CyFxApplnStop (); } /* If a peripheral got connected, then enumerate * and start the application. */ if (glIsPeripheralPresent) { status = CyU3PUsbHostPortEnable (); if (status == CY_U3P_SUCCESS) { CyFxApplnStart (); } } } /* Update the state variable. */ isPresent = glIsPeripheralPresent; } if (glIsApplnActive) { if ((rxCount != glDMARxCount) || (txCount != glDMATxCount)) { CyU3PDebugPrint (4, "Host mode: transferred %d buffers, received %d buffers.\r\n", glDMATxCount, glDMARxCount); rxCount = glDMARxCount; txCount = glDMATxCount; } /* OTG status polling. */ upTime = glTimerCount * CY_FX_OTG_POLL_INTERVAL; glTimerCount++; if ((glIsHnpSupported) && ((upTime % CY_FX_OTG_STATUS_POLL_INTERVAL) == 0) && (!CyU3POtgIsHnpEnabled ()) && (!glIsHnp) && (!glDoHnp)) { /* Get the OTG status. */ CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_STATUS, 0, CY_U3P_USB_OTG_STATUS_SELECTOR, 1); status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer); if (status == CY_U3P_SUCCESS) { status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus, CY_FX_HOST_EP0_WAIT_TIMEOUT); } /* Check if the session request flag is set. */ if ((status == CY_U3P_SUCCESS) && (glEp0Buffer[0] & 0x01)) { /* Initiate the HNP process. */ CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_FEATURE, CY_U3P_USB2_OTG_B_HNP_ENABLE, 0, 0); status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer); if (status == CY_U3P_SUCCESS) { status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus, CY_FX_HOST_EP0_WAIT_TIMEOUT); } if (status == CY_U3P_SUCCESS) { glIsHnp = CyTrue; /* Stop all active transfers. */ CyU3PDmaChannelDestroy (&glHostInCh); if (glHostInEp != 0) { CyU3PUsbHostEpRemove (glHostInEp); glHostInEp = 0; } CyU3PDmaChannelDestroy (&glHostOutCh); if (glHostOutEp != 0) { CyU3PUsbHostEpRemove (glHostOutEp); glHostOutEp = 0; } /* Remove EP0. and disable the port. */ CyU3PUsbHostEpRemove (0); glHostEpSize = 0; /* Suspend the USB bus and wait for the device to disconnect. */ status = CyU3PUsbHostPortSuspend (); } } if (status != CY_U3P_SUCCESS) { glIsHnp = CyFalse; glIsHnpSupported = CyFalse; CyU3PUsbHostEpAbort (0); CyU3PDebugPrint (4, "HNP disabled due to GET_STATUS failure.\r\n"); } } } }