972 lines
43 KiB
C
972 lines
43 KiB
C
/*
|
|
*********************************************************************************************************
|
|
* EXAMPLE CODE
|
|
*
|
|
* This file is provided as an example on how to use Micrium products.
|
|
*
|
|
* Please feel free to use any application code labeled as 'EXAMPLE CODE' in
|
|
* your application products. Example code may be used as is, in whole or in
|
|
* part, or may be used as a reference only. This file can be modified as
|
|
* required to meet the end-product requirements.
|
|
*
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
*
|
|
* USB DEVICE VENDOR CLASS APPLICATION INITIALIZATION
|
|
*
|
|
* TEMPLATE
|
|
*
|
|
* Filename : app_usbd_vendor.c
|
|
* Version : V4.06.01
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* INCLUDE FILES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#include <app_usbd.h>
|
|
|
|
#if (APP_CFG_USBD_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_EN == DEF_ENABLED)
|
|
|
|
#include <Class/Vendor/usbd_vendor.h>
|
|
#include <Source/os.h>
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL DEFINES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#ifndef OS_VERSION
|
|
#error "OS_VERSION must be #define'd."
|
|
#endif
|
|
|
|
#if (OS_VERSION > 30000u)
|
|
#define APP_USBD_VENDOR_OS_III_EN DEF_ENABLED
|
|
#else
|
|
#define APP_USBD_VENDOR_OS_III_EN DEF_DISABLED
|
|
#endif
|
|
|
|
#define APP_RX_TIMEOUT_MS 5000u
|
|
#define APP_TX_TIMEOUT_MS 5000u
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL CONSTANTS
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (USBD_CFG_MS_OS_DESC_EN == DEF_ENABLED)
|
|
static const CPU_INT08U App_USBD_Vendor_MS_PropertyNameGUID[] = {
|
|
'D', 0u, 'e', 0u, 'v', 0u, 'i', 0u, 'c', 0u, 'e', 0u,
|
|
'I', 0u, 'n', 0u, 't', 0u, 'e', 0u, 'r', 0u, 'f', 0u, 'a', 0u, 'c', 0u, 'e', 0u,
|
|
'G', 0u, 'U', 0u, 'I', 0u, 'D', 0u, 0u, 0u
|
|
};
|
|
|
|
static const CPU_INT08U App_USBD_Vendor_MS_GUID[] = {
|
|
'{', 0u, '1', 0u, '4', 0u, '3', 0u, 'F', 0u, '2', 0u, '0', 0u, 'B', 0u, 'D', 0u,
|
|
'-', 0u, '7', 0u, 'B', 0u, 'D', 0u, '2', 0u, '-', 0u, '4', 0u, 'C', 0u, 'A', 0u, '6', 0u,
|
|
'-', 0u, '9', 0u, '4', 0u, '6', 0u, '5', 0u,
|
|
'-', 0u, '8', 0u, '8', 0u, '8', 0u, '2', 0u, 'F', 0u, '2', 0u, '1', 0u, '5', 0u, '6', 0u, 'B', 0u, 'D', 0u, '6', 0u, '}', 0u, 0u, 0u
|
|
};
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL DATA TYPES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL TABLES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL GLOBAL VARIABLES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED)
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
static OS_TCB App_USBD_Vendor_EchoSyncTaskTCB;
|
|
#endif
|
|
static CPU_STK App_USBD_Vendor_EchoSyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE];
|
|
static CPU_INT08U App_USBD_Vendor_Buf[512u];
|
|
#endif
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
static OS_TCB App_USBD_Vendor_EchoAsyncTaskTCB;
|
|
static OS_SEM App_USBD_Vendor_EchoAsyncSem;
|
|
#else
|
|
static OS_EVENT *App_USBD_Vendor_EchoAsyncSemPtr;
|
|
#endif
|
|
static CPU_STK App_USBD_Vendor_EchoAsyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE];
|
|
static CPU_INT08U App_USBD_Vendor_PayloadBuf[512u];
|
|
static CPU_INT08U App_USBD_Vendor_HeaderBuf[2u];
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static CPU_BOOLEAN App_USBD_Vendor_VendorReq ( CPU_INT08U class_nbr,
|
|
CPU_INT08U dev_nbr,
|
|
const USBD_SETUP_REQ *p_setup_req);
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_EchoSyncTask ( void *p_arg);
|
|
|
|
static CPU_BOOLEAN App_USBD_Vendor_Echo ( CPU_INT08U class_nbr);
|
|
#endif
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_EchoAsyncTask( void *p_arg);
|
|
|
|
static void App_USBD_Vendor_RxHeaderCmpl ( CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err);
|
|
|
|
static void App_USBD_Vendor_RxPayloadCmpl( CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err);
|
|
|
|
static void App_USBD_Vendor_TxPayloadCmpl( CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err);
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL CONFIGURATION ERRORS
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_Init()
|
|
*
|
|
* Description : Add a Vendor interface to the USB device stack.
|
|
*
|
|
* Argument(s) : dev_nbr Device number.
|
|
*
|
|
* cfg_hs Index of high-speed configuration to which this interface will be added to.
|
|
*
|
|
* cfg_fs Index of full-speed configuration to which this interface will be added to.
|
|
*
|
|
* Return(s) : DEF_OK, if Vendor interface successfully added.
|
|
*
|
|
* DEF_FAIL, otherwise.
|
|
*
|
|
* Note(s) : (1) The semaphore is initially available so that the Async task can initiate the first
|
|
* transfer to receive the header. Then the semaphore is used only when an error
|
|
* condition is detected during the test sequence execution. This allows to restart
|
|
* the test sequence in case of communication error.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
CPU_BOOLEAN App_USBD_Vendor_Init (CPU_INT08U dev_nbr,
|
|
CPU_INT08U cfg_hs,
|
|
CPU_INT08U cfg_fs)
|
|
{
|
|
USBD_ERR err;
|
|
USBD_ERR err_hs;
|
|
USBD_ERR err_fs;
|
|
CPU_INT08U class_nbr_0;
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) || \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
OS_ERR os_err;
|
|
#endif
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
CPU_INT08U class_nbr_1;
|
|
#endif
|
|
|
|
|
|
err_hs = USBD_ERR_NONE;
|
|
err_fs = USBD_ERR_NONE;
|
|
|
|
APP_TRACE_DBG((" Initializing Vendor class ... \r\n"));
|
|
|
|
USBD_Vendor_Init(&err); /* Init Vendor class. */
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not initialize Vendor class w/err = %d\r\n\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
/* Create a Vendor class instance. */
|
|
class_nbr_0 = USBD_Vendor_Add(DEF_FALSE, 0u, App_USBD_Vendor_VendorReq, &err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not instantiate a Vendor class w/err = %d\r\n\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
if (cfg_hs != USBD_CFG_NBR_NONE) {
|
|
/* Add vendor class to HS dflt cfg. */
|
|
USBD_Vendor_CfgAdd(class_nbr_0, dev_nbr, cfg_hs, &err_hs);
|
|
if (err_hs != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor class instance #%d to HS configuration w/err = %d\r\n\r\n", class_nbr_0, err_hs));
|
|
}
|
|
}
|
|
|
|
if (cfg_fs != USBD_CFG_NBR_NONE) {
|
|
/* Add vendor class to FS dflt cfg. */
|
|
USBD_Vendor_CfgAdd(class_nbr_0, dev_nbr, cfg_fs, &err_fs);
|
|
if (err_fs != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor class instance #%d to FS configuration w/err = %d\r\n\r\n", class_nbr_0, err_fs));
|
|
}
|
|
}
|
|
|
|
if ((err_hs != USBD_ERR_NONE) && /* If HS and FS cfg fail, stop class init. */
|
|
(err_fs != USBD_ERR_NONE)) {
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
/* Create a Vendor class instance. */
|
|
class_nbr_1 = USBD_Vendor_Add( DEF_FALSE,
|
|
0u,
|
|
(USBD_VENDOR_REQ_FNCT)0u,
|
|
&err);
|
|
|
|
if (cfg_hs != USBD_CFG_NBR_NONE) {
|
|
/* Add vendor class to HS dflt cfg. */
|
|
USBD_Vendor_CfgAdd(class_nbr_1, dev_nbr, cfg_hs, &err_hs);
|
|
if (err_hs != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor class instance #%d to HS configuration w/err = %d\r\n\r\n", class_nbr_1, err_hs));
|
|
}
|
|
}
|
|
|
|
if (cfg_fs != USBD_CFG_NBR_NONE) {
|
|
/* Add vendor class to FS dflt cfg. */
|
|
USBD_Vendor_CfgAdd(class_nbr_1, dev_nbr, cfg_fs, &err_fs);
|
|
if (err_fs != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor class instance #%d to FS configuration w/err = %d\r\n\r\n", class_nbr_1, err_fs));
|
|
}
|
|
}
|
|
|
|
if ((err_hs != USBD_ERR_NONE) && /* If HS and FS cfg fail, stop class init. */
|
|
(err_fs != USBD_ERR_NONE)) {
|
|
return (DEF_FAIL);
|
|
}
|
|
#endif
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED)
|
|
/* Create Echo Sync task. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSTaskCreate( &App_USBD_Vendor_EchoSyncTaskTCB,
|
|
"USB Device Vendor Echo Sync",
|
|
App_USBD_Vendor_EchoSyncTask,
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoSyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE / 10u,
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
0u,
|
|
0u,
|
|
(void *) 0,
|
|
OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
|
|
&os_err);
|
|
if (os_err != OS_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor echo sync task w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
#if (OS_STK_GROWTH == 1u)
|
|
os_err = OSTaskCreateExt( App_USBD_Vendor_EchoSyncTask,
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
&App_USBD_Vendor_EchoSyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE - 1],
|
|
APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO,
|
|
APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoSyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
(void *) 0,
|
|
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
|
|
#else
|
|
os_err = OSTaskCreateExt( App_USBD_Vendor_EchoSyncTask,
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
&App_USBD_Vendor_EchoSyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO,
|
|
APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoSyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE - 1],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
(void *) 0,
|
|
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
|
|
#endif
|
|
if (os_err != OS_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor echo sync task w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
#if (OS_TASK_NAME_EN > 0u)
|
|
OSTaskNameSet(APP_CFG_USBD_VENDOR_ECHO_SYNC_TASK_PRIO, (INT8U *)"USB Device Vendor Echo Sync", &os_err);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
/* Create sem to signal re(starting) of test sequence. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemCreate(&App_USBD_Vendor_EchoAsyncSem,
|
|
"Async task sem",
|
|
1u, /* Sem initially available (see Note #1). */
|
|
&os_err);
|
|
if (os_err != OS_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not create Vendor echo async semaphore w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
/* Create Echo Async task. */
|
|
OSTaskCreate( &App_USBD_Vendor_EchoAsyncTaskTCB,
|
|
"USB Device Vendor Echo Async",
|
|
App_USBD_Vendor_EchoAsyncTask,
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
(void *)(CPU_ADDR)class_nbr_1,
|
|
#else
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
#endif
|
|
APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoAsyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE / 10u,
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
0u,
|
|
0u,
|
|
(void *) 0,
|
|
OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
|
|
&os_err);
|
|
if (os_err != OS_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor echo async task w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
App_USBD_Vendor_EchoAsyncSemPtr = OSSemCreate(1u); /* Sem initially available (see Note #1). */
|
|
if (App_USBD_Vendor_EchoAsyncSemPtr == (OS_EVENT *)0) {
|
|
APP_TRACE_DBG((" ... could not create Vendor echo async semaphore w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
/* Create Echo Async task. */
|
|
#if (OS_STK_GROWTH == 1u)
|
|
os_err = OSTaskCreateExt( App_USBD_Vendor_EchoAsyncTask,
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
(void *)(CPU_ADDR)class_nbr_1,
|
|
#else
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
#endif
|
|
&App_USBD_Vendor_EchoAsyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE - 1],
|
|
APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO,
|
|
APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoAsyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
(void *) 0,
|
|
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
|
|
#else
|
|
os_err = OSTaskCreateExt( App_USBD_Vendor_EchoAsyncTask,
|
|
#if ((APP_CFG_USBD_VENDOR_TEST_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_TEST_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
(void *)(CPU_ADDR)class_nbr_1,
|
|
#else
|
|
(void *)(CPU_ADDR)class_nbr_0,
|
|
#endif
|
|
&App_USBD_Vendor_EchoAsyncTaskStk[0],
|
|
APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO,
|
|
APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO,
|
|
&App_USBD_Vendor_EchoAsyncTaskStk[APP_CFG_USBD_VENDOR_TASK_STK_SIZE - 1],
|
|
APP_CFG_USBD_VENDOR_TASK_STK_SIZE,
|
|
(void *) 0,
|
|
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
|
|
#endif
|
|
if (os_err != OS_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not add Vendor echo async task w/err = %d\r\n\r\n", os_err));
|
|
return (DEF_FAIL);
|
|
}
|
|
#if (OS_TASK_NAME_EN > 0u)
|
|
OSTaskNameSet(APP_CFG_USBD_VENDOR_ECHO_ASYNC_TASK_PRIO, (INT8U *)"USB Device Vendor Echo Async", &os_err);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#if (USBD_CFG_MS_OS_DESC_EN == DEF_ENABLED)
|
|
USBD_DevSetMS_VendorCode(dev_nbr, 1u, &err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not set MS vendor code w/err = %d\r\n\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
USBD_Vendor_MS_ExtPropertyAdd(class_nbr_0,
|
|
USBD_MS_OS_PROPERTY_TYPE_REG_SZ,
|
|
App_USBD_Vendor_MS_PropertyNameGUID,
|
|
sizeof(App_USBD_Vendor_MS_PropertyNameGUID),
|
|
App_USBD_Vendor_MS_GUID,
|
|
sizeof(App_USBD_Vendor_MS_GUID),
|
|
&err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not set MS vendor GUID w/err = %d\r\n\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
#if ((APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED) && \
|
|
(APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED))
|
|
USBD_Vendor_MS_ExtPropertyAdd(class_nbr_1,
|
|
USBD_MS_OS_PROPERTY_TYPE_REG_SZ,
|
|
App_USBD_Vendor_MS_PropertyNameGUID,
|
|
sizeof(App_USBD_Vendor_MS_PropertyNameGUID),
|
|
App_USBD_Vendor_MS_GUID,
|
|
sizeof(App_USBD_Vendor_MS_GUID),
|
|
&err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... could not set MS vendor GUID w/err = %d\r\n\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
return (DEF_OK);
|
|
}
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_VendorReq()
|
|
*
|
|
* Description : Process vendor-specific requests.
|
|
*
|
|
* Argument(s) : class_nbr Class instance number.
|
|
*
|
|
* dev_nbr Device number.
|
|
*
|
|
* p_setup_req Pointer to setup request structure.
|
|
*
|
|
* Return(s) : DEF_OK, if NO error(s) occurred and request is supported.
|
|
*
|
|
* DEF_FAIL, otherwise.
|
|
*
|
|
* Note(s) : (1) USB Spec 2.0, section 9.3 'USB Device Requests' specifies the Setup packet format.
|
|
*
|
|
* (2) The customer may process inside this callback his proprietary vendor-specific
|
|
* requests decoding.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static CPU_BOOLEAN App_USBD_Vendor_VendorReq ( CPU_INT08U class_nbr,
|
|
CPU_INT08U dev_nbr,
|
|
const USBD_SETUP_REQ *p_setup_req)
|
|
{
|
|
(void)class_nbr;
|
|
(void)dev_nbr;
|
|
(void)p_setup_req;
|
|
|
|
return (DEF_FAIL); /* Indicate request is not supported. */
|
|
}
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_EchoSyncTask()
|
|
*
|
|
* Description : Perform Echo demo with synchronous communication:
|
|
*
|
|
* (a) Read header.
|
|
* (b) Read payload of a certain size.
|
|
* (c) Write payload previously received.
|
|
*
|
|
* Argument(s) : p_arg Argument passed to the task.
|
|
*
|
|
* Return(s) : none.
|
|
*
|
|
* Note(s) : none.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_EchoSyncTask (void *p_arg)
|
|
{
|
|
CPU_INT08U class_nbr;
|
|
CPU_BOOLEAN conn;
|
|
CPU_BOOLEAN err;
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OS_ERR os_err;
|
|
#endif
|
|
|
|
|
|
class_nbr = (CPU_INT08U)(CPU_ADDR)p_arg;
|
|
err = DEF_OK;
|
|
|
|
APP_TRACE_DBG((" Executing Vendor Echo Sync demo...\r\n"));
|
|
|
|
while (DEF_TRUE) {
|
|
|
|
/* Wait for cfg activated by host. */
|
|
conn = USBD_Vendor_IsConn(class_nbr);
|
|
while (conn != DEF_YES) {
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u, OS_OPT_TIME_HMSM_NON_STRICT, &os_err);
|
|
#else
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u);
|
|
#endif
|
|
|
|
conn = USBD_Vendor_IsConn(class_nbr);
|
|
}
|
|
|
|
err = App_USBD_Vendor_Echo(class_nbr);
|
|
|
|
if (err != DEF_OK) {
|
|
/* Delay 250 ms if an error occurred. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u, OS_OPT_TIME_HMSM_NON_STRICT, &os_err);
|
|
#else
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_Echo()
|
|
*
|
|
* Description : Read and write transfers from different size.
|
|
*
|
|
* Argument(s) : class_nbr Vendor class instance number.
|
|
*
|
|
* Return(s) : DEF_OK, if NO error(s).
|
|
*
|
|
* DEF_FAIL, otherwise.
|
|
*
|
|
* Note(s) : none.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_SYNC_EN == DEF_ENABLED)
|
|
static CPU_BOOLEAN App_USBD_Vendor_Echo (CPU_INT08U class_nbr)
|
|
{
|
|
USBD_ERR err;
|
|
CPU_INT08U msg_hdr[2];
|
|
CPU_INT32U nbr_octets_recv;
|
|
CPU_INT32U payload_len;
|
|
CPU_INT32U rem_payload_len;
|
|
CPU_INT32U xfer_len;
|
|
|
|
/* ----------------- HEADER RECEPTION ----------------- */
|
|
nbr_octets_recv = USBD_Vendor_Rd( class_nbr,
|
|
(void *)&msg_hdr[0],
|
|
2,
|
|
0,
|
|
&err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... Echo Sync demo failed to receive message header w/err = %d\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
if (nbr_octets_recv != 2) { /* Verify that hdr is 2 octets. */
|
|
return (DEF_FAIL);
|
|
}
|
|
/* ---------------- PAYLOAD PROCESSING ---------------- */
|
|
payload_len = DEF_BIT_MASK(msg_hdr[0], 8); /* Get nbr of octets from the message header. */
|
|
payload_len |= msg_hdr[1];
|
|
rem_payload_len = payload_len;
|
|
|
|
while (rem_payload_len > 0) {
|
|
|
|
if (rem_payload_len >= 512) {
|
|
xfer_len = 512;
|
|
} else {
|
|
xfer_len = rem_payload_len;
|
|
}
|
|
/* Receive payload chunk from host. */
|
|
nbr_octets_recv = USBD_Vendor_Rd( class_nbr,
|
|
(void *)&App_USBD_Vendor_Buf[0],
|
|
xfer_len,
|
|
APP_RX_TIMEOUT_MS,
|
|
&err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... Echo Sync demo failed to read data from host w/err = %d\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
rem_payload_len -= nbr_octets_recv; /* Remaining nbr of octets to be received. */
|
|
|
|
/* Send back received payload chunk to host. */
|
|
(void)USBD_Vendor_Wr( class_nbr,
|
|
(void *)&App_USBD_Vendor_Buf[0],
|
|
nbr_octets_recv,
|
|
APP_TX_TIMEOUT_MS,
|
|
DEF_FALSE,
|
|
&err);
|
|
if (err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... Echo Sync demo failed to write data to host w/err = %d\r\n", err));
|
|
return (DEF_FAIL);
|
|
}
|
|
|
|
}
|
|
|
|
return (DEF_OK);
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_EchoAsyncTask()
|
|
*
|
|
* Description : Perform Echo demo with asynchronous communication (see Note #1):
|
|
*
|
|
* (a) Read header.
|
|
* (b) Read payload of a certain size.
|
|
* (c) Write payload previously received.
|
|
*
|
|
* Argument(s) : p_arg Argument passed to the task.
|
|
*
|
|
* Return(s) : none.
|
|
*
|
|
* Note(s) : (1) The Echo Async task will prepare the first read to initiate the test sequence with
|
|
* the host. The other steps of the test sequence will be managed in the different
|
|
* asynchronous callback.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_EchoAsyncTask (void *p_arg)
|
|
{
|
|
CPU_INT08U class_nbr;
|
|
CPU_BOOLEAN conn;
|
|
USBD_ERR usb_err;
|
|
OS_ERR os_err;
|
|
CPU_INT32U nbr_octets_expected;
|
|
|
|
|
|
class_nbr = (CPU_INT08U)(CPU_ADDR)p_arg;
|
|
|
|
APP_TRACE_DBG((" Executing Vendor Echo Async demo...\r\n"));
|
|
|
|
while (DEF_TRUE) {
|
|
/* Wait to (re)start the test sequence. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
(void)OSSemPend( &App_USBD_Vendor_EchoAsyncSem,
|
|
0,
|
|
OS_OPT_PEND_BLOCKING,
|
|
(CPU_TS *)0,
|
|
&os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
OSSemPend(App_USBD_Vendor_EchoAsyncSemPtr, 0, &os_err);
|
|
#endif
|
|
/* Wait for cfg activated by host. */
|
|
conn = USBD_Vendor_IsConn(class_nbr);
|
|
while (conn != DEF_YES) {
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u, OS_OPT_TIME_HMSM_NON_STRICT, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
OSTimeDlyHMSM(0u, 0u, 0u, 250u);
|
|
#endif
|
|
conn = USBD_Vendor_IsConn(class_nbr);
|
|
}
|
|
|
|
nbr_octets_expected = 0;
|
|
/* ----------------- HEADER RECEPTION ----------------- */
|
|
/* Prepare async Bulk OUT xfer. */
|
|
USBD_Vendor_RdAsync( class_nbr,
|
|
(void *)&App_USBD_Vendor_HeaderBuf[0],
|
|
2u,
|
|
App_USBD_Vendor_RxHeaderCmpl,
|
|
(void *)&nbr_octets_expected,
|
|
&usb_err);
|
|
|
|
if (usb_err != USBD_ERR_NONE) {
|
|
APP_TRACE_DBG((" ... Echo Async demo failed to prepare OUT transfer for header w/err = %d\r\n", usb_err));
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_RxHeaderCmpl()
|
|
*
|
|
* Description : Callback called upon Bulk OUT transfer completion.
|
|
*
|
|
* Argument(s) : p_buf Pointer to receive buffer.
|
|
*
|
|
* buf_len Receive buffer length.
|
|
*
|
|
* xfer_len Number of octets received.
|
|
*
|
|
* p_callback_arg Additional argument provided by application.
|
|
*
|
|
* err Transfer error status.
|
|
*
|
|
* Return(s) : none.
|
|
*
|
|
* Note(s) : none.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_RxHeaderCmpl (CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err)
|
|
{
|
|
CPU_INT08U *p_header_buf;
|
|
CPU_INT32U payload_len;
|
|
CPU_INT32U *p_nbr_octets_expected;
|
|
USBD_ERR usb_err;
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OS_ERR os_err;
|
|
#endif
|
|
|
|
|
|
(void)buf_len;
|
|
|
|
p_header_buf = (CPU_INT08U *)p_buf;
|
|
p_nbr_octets_expected = (CPU_INT32U *)p_callback_arg;
|
|
|
|
if (err == USBD_ERR_NONE) {
|
|
|
|
if (xfer_len != 2) { /* Verify that hdr is 2 octets. */
|
|
return;
|
|
}
|
|
/* ---------------- PAYLOAD PROCESSING ---------------- */
|
|
/* Get nbr of octets from the message header. */
|
|
payload_len = DEF_BIT_MASK(p_header_buf[0], 8);
|
|
payload_len |= p_header_buf[1];
|
|
*p_nbr_octets_expected = payload_len;
|
|
|
|
if (*p_nbr_octets_expected >= 512) {
|
|
xfer_len = 512;
|
|
} else {
|
|
xfer_len = *p_nbr_octets_expected;
|
|
}
|
|
|
|
/* Receive payload chunk from host. */
|
|
USBD_Vendor_RdAsync( class_nbr,
|
|
(void *)&App_USBD_Vendor_PayloadBuf[0],
|
|
xfer_len,
|
|
App_USBD_Vendor_RxPayloadCmpl,
|
|
(void *) p_nbr_octets_expected,
|
|
&usb_err);
|
|
if (usb_err != USBD_ERR_NONE) { /* Restart header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
} else { /* Restart header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_RxPayloadCmpl()
|
|
*
|
|
* Description : Callback called upon Bulk OUT transfer completion.
|
|
*
|
|
* Argument(s) : p_buf Pointer to receive buffer.
|
|
*
|
|
* buf_len Receive buffer length.
|
|
*
|
|
* xfer_len Number of octets received.
|
|
*
|
|
* p_callback_arg Additional argument provided by application.
|
|
*
|
|
* err Transfer error status.
|
|
*
|
|
* Return(s) : none.
|
|
*
|
|
* Note(s) : none.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_RxPayloadCmpl (CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err)
|
|
{
|
|
USBD_ERR usb_err;
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OS_ERR os_err;
|
|
#endif
|
|
|
|
|
|
(void)buf_len;
|
|
|
|
if (err == USBD_ERR_NONE) {
|
|
/* ---------------- PAYLOAD PROCESSING ---------------- */
|
|
USBD_Vendor_WrAsync( class_nbr,
|
|
p_buf, /* Rx buf becomes a Tx buf. */
|
|
xfer_len,
|
|
App_USBD_Vendor_TxPayloadCmpl,
|
|
p_callback_arg, /* Nbr of octets expected gotten from header msg. */
|
|
DEF_FALSE,
|
|
&usb_err);
|
|
if (usb_err != USBD_ERR_NONE) { /* Restart test sequence with header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
} else { /* Restart test sequence with header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* App_USBD_Vendor_TxPayloadCmpl()
|
|
*
|
|
* Description : Callback called upon Bulk IN transfer completion.
|
|
*
|
|
* Argument(s) : p_buf Pointer to transmit buffer.
|
|
*
|
|
* buf_len Transmit buffer length.
|
|
*
|
|
* xfer_len Number of octets transmitted.
|
|
*
|
|
* p_callback_arg Additional argument provided by application.
|
|
*
|
|
* err Transfer error status.
|
|
*
|
|
* Return(s) : none.
|
|
*
|
|
* Note(s) : none.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#if (APP_CFG_USBD_VENDOR_ECHO_ASYNC_EN == DEF_ENABLED)
|
|
static void App_USBD_Vendor_TxPayloadCmpl (CPU_INT08U class_nbr,
|
|
void *p_buf,
|
|
CPU_INT32U buf_len,
|
|
CPU_INT32U xfer_len,
|
|
void *p_callback_arg,
|
|
USBD_ERR err)
|
|
{
|
|
CPU_INT32U *p_nbr_octets_expected;
|
|
USBD_ERR usb_err;
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED)
|
|
OS_ERR os_err;
|
|
#endif
|
|
|
|
|
|
(void)p_buf;
|
|
(void)buf_len;
|
|
(void)xfer_len;
|
|
|
|
p_nbr_octets_expected = (CPU_INT32U *)p_callback_arg; /* Nbr of octets expected gotten from header msg. */
|
|
|
|
if (err == USBD_ERR_NONE) {
|
|
|
|
*p_nbr_octets_expected -= xfer_len; /* Update nbr of octets expected from host. */
|
|
|
|
if (*p_nbr_octets_expected == 0) { /* All the msg payload received from host. */
|
|
|
|
/* ----------------- HEADER RECEPTION ----------------- */
|
|
/* Prepare async Bulk OUT xfer. */
|
|
USBD_Vendor_RdAsync( class_nbr,
|
|
(void *)&App_USBD_Vendor_HeaderBuf[0],
|
|
2u,
|
|
App_USBD_Vendor_RxHeaderCmpl,
|
|
(void *) p_nbr_octets_expected,
|
|
&usb_err);
|
|
if (usb_err != USBD_ERR_NONE) { /* Restart test sequence with header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
} else {
|
|
/* ---------------- PAYLOAD PROCESSING ---------------- */
|
|
if (*p_nbr_octets_expected >= 512) {
|
|
xfer_len = 512;
|
|
} else {
|
|
xfer_len = *p_nbr_octets_expected;
|
|
}
|
|
/* Receive payload chunk from host. */
|
|
USBD_Vendor_RdAsync( class_nbr,
|
|
(void *)&App_USBD_Vendor_PayloadBuf[0],
|
|
xfer_len,
|
|
App_USBD_Vendor_RxPayloadCmpl,
|
|
(void *) p_nbr_octets_expected,
|
|
&usb_err);
|
|
if (usb_err != USBD_ERR_NONE) { /* Restart test sequence with header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
}
|
|
} else { /* Restart test sequence with header reception. */
|
|
#if (APP_USBD_VENDOR_OS_III_EN == DEF_ENABLED) /* ---------------------- OS-III ---------------------- */
|
|
OSSemPost(&App_USBD_Vendor_EchoAsyncSem, OS_OPT_POST_ALL, &os_err);
|
|
#else /* ---------------------- OS-II ----------------------- */
|
|
(void)OSSemPost(App_USBD_Vendor_EchoAsyncSemPtr);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* MODULE END
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#endif
|