forked from stm/stm32-mw-usb-device
505 lines
14 KiB
C
505 lines
14 KiB
C
/**
|
|
******************************************************************************
|
|
* @file usbd_billboard.c
|
|
* @author MCD Application Team
|
|
* @brief This file provides the high layer firmware functions to manage the
|
|
* following functionalities of the USB BillBoard Class:
|
|
* - Initialization and Configuration of high and low layer
|
|
* - Enumeration as BillBoard Device
|
|
* - Error management
|
|
* @verbatim
|
|
*
|
|
* ===================================================================
|
|
* BillBoard Class Description
|
|
* ===================================================================
|
|
* This module manages the BillBoard class V1.2.1 following the "Device Class Definition
|
|
* for BillBoard Devices (BB) Version R1.2.1 Sept 08, 2016".
|
|
* This driver implements the following aspects of the specification:
|
|
* - Device descriptor management
|
|
* - Configuration descriptor management
|
|
* - Enumeration as an USB BillBoard device
|
|
* - Enumeration & management of BillBoard device supported alternate modes
|
|
*
|
|
* @endverbatim
|
|
*
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* This software component is licensed by ST under Ultimate Liberty license
|
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at:
|
|
* www.st.com/SLA0044
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "usbd_billboard.h"
|
|
#include "usbd_ctlreq.h"
|
|
|
|
|
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|
* @{
|
|
*/
|
|
|
|
|
|
/** @defgroup USBD_BB
|
|
* @brief usbd core module
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup USBD_BB_Private_TypesDefinitions
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup USBD_BB_Private_Defines
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup USBD_BB_Private_Macros
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup USBD_BB_Private_FunctionPrototypes
|
|
* @{
|
|
*/
|
|
|
|
static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
|
static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
|
static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
|
static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
|
static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
|
static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev);
|
|
|
|
static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length);
|
|
static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length);
|
|
static uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length);
|
|
|
|
#if (USBD_CLASS_BOS_ENABLED == 1)
|
|
USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup USBD_BB_Private_Variables
|
|
* @{
|
|
*/
|
|
USBD_ClassTypeDef USBD_BB =
|
|
{
|
|
USBD_BB_Init, /* Init */
|
|
USBD_BB_DeInit, /* DeInit */
|
|
USBD_BB_Setup, /* Setup */
|
|
NULL, /* EP0_TxSent */
|
|
USBD_BB_EP0_RxReady, /* EP0_RxReady */
|
|
USBD_BB_DataIn, /* DataIn */
|
|
USBD_BB_DataOut, /* DataOut */
|
|
NULL, /* SOF */
|
|
NULL,
|
|
NULL,
|
|
USBD_BB_GetCfgDesc,
|
|
USBD_BB_GetCfgDesc,
|
|
USBD_BB_GetOtherSpeedCfgDesc,
|
|
USBD_BB_GetDeviceQualifierDesc,
|
|
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
|
NULL,
|
|
#endif
|
|
};
|
|
|
|
/* USB Standard Device Qualifier Descriptor */
|
|
__ALIGN_BEGIN static uint8_t USBD_BB_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
|
{
|
|
USB_LEN_DEV_QUALIFIER_DESC, /* bLength */
|
|
USB_DESC_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */
|
|
0x01, /* bcdUSB */
|
|
0x20,
|
|
0x11, /* bDeviceClass */
|
|
0x00, /* bDeviceSubClass */
|
|
0x00, /* bDeviceProtocol */
|
|
0x40, /* bMaxPacketSize0 */
|
|
0x01, /* bNumConfigurations */
|
|
0x00, /* bReserved */
|
|
};
|
|
|
|
/* USB device Configuration Descriptor */
|
|
__ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END =
|
|
{
|
|
0x09, /* bLength: Configuration Descriptor size */
|
|
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
|
USB_BB_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
|
|
0x00,
|
|
0x01, /* bNumInterfaces: 1 interface */
|
|
0x01, /* bConfigurationValue: Configuration value */
|
|
USBD_IDX_CONFIG_STR, /* iConfiguration: Index of string descriptor describing the configuration */
|
|
#if (USBD_SELF_POWERED == 1U)
|
|
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
|
#else
|
|
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
|
#endif
|
|
USBD_MAX_POWER, /* MaxPower (mA) */
|
|
/* 09 */
|
|
|
|
/************** Descriptor of BillBoard interface ****************/
|
|
/* 09 */
|
|
0x09, /* bLength: Interface Descriptor size */
|
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
|
0x00, /* bInterfaceNumber: Number of Interface */
|
|
0x00, /* bAlternateSetting: Alternate setting */
|
|
0x00, /* bNumEndpoints */
|
|
0x11, /* bInterfaceClass: billboard */
|
|
0x00, /* bInterfaceSubClass */
|
|
0x00, /* nInterfaceProtocol */
|
|
USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */
|
|
};
|
|
|
|
/* USB device Other Speed Configuration Descriptor */
|
|
__ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END =
|
|
{
|
|
0x09, /* bLength: Configuration Descriptor size */
|
|
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
|
|
USB_BB_CONFIG_DESC_SIZ,
|
|
0x00,
|
|
0x01, /* bNumInterfaces: 1 interface */
|
|
0x01, /* bConfigurationValue */
|
|
USBD_IDX_CONFIG_STR, /* iConfiguration */
|
|
#if (USBD_SELF_POWERED == 1U)
|
|
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
|
#else
|
|
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
|
#endif
|
|
USBD_MAX_POWER, /* MaxPower (mA) */
|
|
|
|
/************** Descriptor of BillBoard interface ****************/
|
|
/* 09 */
|
|
0x09, /* bLength: Interface Descriptor size */
|
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
|
0x00, /* bInterfaceNumber: Number of Interface */
|
|
0x00, /* bAlternateSetting: Alternate setting */
|
|
0x00, /* bNumEndpoints*/
|
|
0x11, /* bInterfaceClass: billboard */
|
|
0x00, /* bInterfaceSubClass */
|
|
0x00, /* nInterfaceProtocol */
|
|
USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */
|
|
} ;
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup USBD_BB_Private_Functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief USBD_BB_Init
|
|
* Initialize the BB interface
|
|
* @param pdev: device instance
|
|
* @param cfgidx: Configuration index
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
|
{
|
|
/* Prevent unused argument compilation warning */
|
|
UNUSED(pdev);
|
|
UNUSED(cfgidx);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_Init
|
|
* DeInitialize the BB layer
|
|
* @param pdev: device instance
|
|
* @param cfgidx: Configuration index
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
|
{
|
|
/* Prevent unused argument compilation warning */
|
|
UNUSED(pdev);
|
|
UNUSED(cfgidx);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_Setup
|
|
* Handle the BB specific requests
|
|
* @param pdev: instance
|
|
* @param req: usb requests
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
|
{
|
|
USBD_StatusTypeDef ret = USBD_OK;
|
|
uint16_t status_info = 0U;
|
|
uint16_t AltSetting = 0U;
|
|
|
|
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
|
{
|
|
case USB_REQ_TYPE_CLASS:
|
|
break;
|
|
case USB_REQ_TYPE_STANDARD:
|
|
switch (req->bRequest)
|
|
{
|
|
case USB_REQ_GET_STATUS:
|
|
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
|
{
|
|
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
|
}
|
|
else
|
|
{
|
|
USBD_CtlError(pdev, req);
|
|
ret = USBD_FAIL;
|
|
}
|
|
break;
|
|
|
|
case USB_REQ_GET_INTERFACE:
|
|
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
|
{
|
|
(void)USBD_CtlSendData(pdev, (uint8_t *)&AltSetting, 1U);
|
|
}
|
|
else
|
|
{
|
|
USBD_CtlError(pdev, req);
|
|
ret = USBD_FAIL;
|
|
}
|
|
break;
|
|
|
|
case USB_REQ_SET_INTERFACE:
|
|
case USB_REQ_CLEAR_FEATURE:
|
|
break;
|
|
|
|
default:
|
|
USBD_CtlError(pdev, req);
|
|
ret = USBD_FAIL;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
USBD_CtlError(pdev, req);
|
|
ret = USBD_FAIL;
|
|
break;
|
|
}
|
|
|
|
return (uint8_t)ret;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_DataIn
|
|
* Data sent on non-control IN endpoint
|
|
* @param pdev: device instance
|
|
* @param epnum: endpoint number
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
|
{
|
|
/* Prevent unused argument compilation warning */
|
|
UNUSED(pdev);
|
|
UNUSED(epnum);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_DataOut
|
|
* Data received on non-control Out endpoint
|
|
* @param pdev: device instance
|
|
* @param epnum: endpoint number
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
|
{
|
|
/* Prevent unused argument compilation warning */
|
|
UNUSED(pdev);
|
|
UNUSED(epnum);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_EP0_RxReady
|
|
* Handle EP0 Rx Ready event
|
|
* @param pdev: device instance
|
|
* @retval status
|
|
*/
|
|
static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev)
|
|
{
|
|
/* Prevent unused argument compilation warning */
|
|
UNUSED(pdev);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_GetCfgDesc
|
|
* return configuration descriptor
|
|
* @param speed : current device speed
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)sizeof(USBD_BB_CfgDesc);
|
|
return USBD_BB_CfgDesc;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_BB_GetOtherSpeedCfgDesc
|
|
* return other speed configuration descriptor
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)sizeof(USBD_BB_OtherSpeedCfgDesc);
|
|
return USBD_BB_OtherSpeedCfgDesc;
|
|
}
|
|
|
|
/**
|
|
* @brief DeviceQualifierDescriptor
|
|
* return Device Qualifier descriptor
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)sizeof(USBD_BB_DeviceQualifierDesc);
|
|
return USBD_BB_DeviceQualifierDesc;
|
|
}
|
|
|
|
|
|
#if (USBD_CLASS_BOS_ENABLED == 1U)
|
|
/**
|
|
* @brief USBD_BB_GetNextDesc
|
|
* This function return the next descriptor header
|
|
* @param buf: Buffer where the descriptor is available
|
|
* @param ptr: data pointer inside the descriptor
|
|
* @retval next header
|
|
*/
|
|
USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
|
|
{
|
|
USBD_BB_DescHeader_t *pnext = (USBD_BB_DescHeader_t *)(void *)pbuf;
|
|
|
|
*ptr += pnext->bLength;
|
|
pnext = (USBD_BB_DescHeader_t *)(void *)(pbuf + pnext->bLength);
|
|
|
|
return (pnext);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief USBD_BB_GetCapDesc
|
|
* This function return the Billboard Capability descriptor
|
|
* @param pdev: device instance
|
|
* @param pBosDesc: pointer to Bos descriptor
|
|
* @retval pointer to Billboard Capability descriptor
|
|
*/
|
|
void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc)
|
|
{
|
|
UNUSED(pdev);
|
|
|
|
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
|
|
USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc;
|
|
USBD_BosBBCapDescTypedef *pCapDesc = NULL;
|
|
uint16_t ptr;
|
|
|
|
if (desc->wTotalLength > desc->bLength)
|
|
{
|
|
ptr = desc->bLength;
|
|
|
|
while (ptr < desc->wTotalLength)
|
|
{
|
|
pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr);
|
|
|
|
if (pdesc->bDevCapabilityType == USBD_BILLBOARD_CAPABILITY)
|
|
{
|
|
pCapDesc = (USBD_BosBBCapDescTypedef *)(void *)pdesc;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return (void *)pCapDesc;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief USBD_BB_GetAltModeDesc
|
|
* This function return the Billboard Alternate Mode descriptor
|
|
* @param pdev: device instance
|
|
* @param pBosDesc: pointer to Bos descriptor
|
|
* @param idx: Index of requested Alternate Mode descriptor
|
|
* @retval pointer to Alternate Mode descriptor
|
|
*/
|
|
void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_t idx)
|
|
{
|
|
UNUSED(pdev);
|
|
|
|
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
|
|
USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc;
|
|
USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL;
|
|
uint8_t cnt = 0U;
|
|
uint16_t ptr;
|
|
|
|
if (desc->wTotalLength > desc->bLength)
|
|
{
|
|
ptr = desc->bLength;
|
|
|
|
while (ptr < desc->wTotalLength)
|
|
{
|
|
pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr);
|
|
|
|
if (pdesc->bDevCapabilityType == USBD_BILLBOARD_ALTMODE_CAPABILITY)
|
|
{
|
|
if (cnt == idx)
|
|
{
|
|
pAltModDesc = (USBD_BB_AltModeCapDescTypeDef *)(void *)pdesc;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
cnt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (void *)pAltModDesc;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|