|
Hi,
I was able to modify the UVC firmware example so that vendor requests could be handled. The UVC example makes use of class requests to control operation of the FX3 and this very similar to how vendor requests are handled. I’ve described below the steps necessary to implement a simple vendor request for the FX3. The vendor request out transfer sends data to the FX3 while the vendor request in transfer reads this data back but multiplied by 2. In some case code comments have been removed to allow easier reading.The steps to implement vendor requests in the FX3 are:
Add separate thread in the CyFxApplicationDefine function to deal with the vendor requests
ptr2 = CyU3PMemAlloc (VndReq_EP0_THREAD_STACK);
retThrdCreate = CyU3PThreadCreate (&vndAppEP0Thread,
"31:Vendor EP0 Thread",
VndReqEP0Thread_Entry,
0,
ptr2,
VndReq_EP0_THREAD_STACK,
VndReq_EP0_THREAD_PRIORITY,
VndReq_EP0_THREAD_PRIORITY,
CYU3P_NO_TIME_SLICE,
CYU3P_AUTO_START
);
/* Check the return code */
if (retThrdCreate != 0)
{
/* Application cannot continue */
/* Loop indefinitely */
while(1);
}
Create thread handling function called in this case VndReqEP0Thread_Entry. This function will carry out the vendor request actions.
void
VndReqEP0Thread_Entry (
uint32_t input)
{
uint32_t flag;
uint16_t readcount;
uint8_t i;
CyU3PReturnStatus_t apiRetStatus;
for (;;)
{
/* Check for Vendor request event */
if (CyU3PEventGet (&glFxVREQEvent, (CY_FX_VREQ_RD | CY_FX_VREQ_WR) ,
CYU3P_EVENT_OR_CLEAR, &flag,
CYU3P_WAIT_FOREVER) == CY_U3P_SUCCESS)
{
/* Check for Vendor request upload event */
if (flag & CY_FX_VREQ_RD)
{
// multiply download data by 2
for (i = 0; i < 16; i++)
Ep0_OutData[i] = Ep0_InData[i] * 2;
apiRetStatus = CyU3PUsbSendEP0Data(16, Ep0_OutData);
if (apiRetStatus != CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "EP0 Send Data Failed, Error Code = %d\n",apiRetStatus);
}
}
/* Check for Vendor request download event */
else if (flag & CY_FX_VREQ_WR)
apiRetStatus = CyU3PUsbGetEP0Data(16, Ep0_InData, &readcount);
if (apiRetStatus != CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "EP0 Get Data Failed, Error Code = %d\n",apiRetStatus);
}
}
/* Relinguish the thread */
CyU3PThreadRelinquish ();
}
}
Modify the USB setup call back function (CyFxBulkLpApplnUSBSetupCB) to get the vendor requests and create the event flags
/* Callback to handle the USB Setup Requests */
CyBool_t
CyFxBulkLpApplnUSBSetupCB (
uint32_t setupdat0, /* SETUP Data 0 */
uint32_t setupdat1 /* SETUP Data 1 */
)
{
uint8_t setupReqType, setupReq;
CyU3PReturnStatus_t apiRetStatus;
CyBool_t vndHandleReq = CyFalse;
/* Obtain Request Type and Request */
setupReqType = (uint8_t)(setupdat0 & CY_FX_USB_SETUP_REQ_TYPE_MASK);
setupReq = (uint8_t)((setupdat0 & CY_FX_USB_SETUP_REQ_MASK) >> 8);
/* Check for user vendor request */
if (setupReq == CY_FX_VND_REQ1)
{
/* Vendor requests are handled in the application */
vndHandleReq = CyTrue;
/* Check for vendor request upload */
if (setupReqType == CY_FX_USB_VND_GET_REQ_TYPE)
{
apiRetStatus = CyU3PEventSet(&glFxVREQEvent,CY_FX_VREQ_RD,CYU3P_EVENT_OR);
if (apiRetStatus != CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "Get Vendor Request Event Failed, Error Code = %d\n",apiRetStatus);
}
}
/* Check for vendor request download */
else if (setupReqType == CY_FX_USB_VND_SET_REQ_TYPE)
apiRetStatus = CyU3PEventSet(&glFxVREQEvent,CY_FX_VREQ_WR,CYU3P_EVENT_OR);
if (apiRetStatus != CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "Set Vendor Request Event Failed, Error Code = %d\n",apiRetStatus);
}
Rest of user code follows on from here
Update the main .h file to include the user vendor requests; event flags variables and variables associated with the new thread.
#define VndReq_EP0_THREAD_STACK (0x0800) /* Thread stack size */
#define VndReq_EP0_THREAD_PRIORITY (8) /* Thread priority */
#define CY_FX_VREQ_RD (1 << 0) /* rd event flag */
#define CY_FX_VREQ_WR (1 << 1) /* wr event flag */
#define CY_FX_VND_REQ1 (uint8_t)(0xB1) /* Vendor request */
#define CY_FX_USB_VND_SET_REQ_TYPE (uint8_t)(0x40) /* Download */
#define CY_FX_USB_VND_GET_REQ_TYPE (uint8_t)(0xC0) /* Upload */
Add memory buffers to store Ep0 vendor in and out data and event and flag variables.
These are added to the main source code file
static CyU3PThread BulkLpAppThread, vndAppEP0Thread;
static CyU3PEvent glFxVREQEvent; // vendor request event flags
static uint8_t Ep0_InData[16]; // ep0 in data buffer
static uint8_t Ep0_OutData[16]; // ep0 out data buffer
void VndReqEP0Thread_Entry (uint32_t); /* Declaration for the thread entry function */
That’s it.
Sodafarl
|