From b30c02afa078f7713faa14087ae28433dee49027 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Mar 2014 00:30:37 +0000 Subject: stmhal: Get USB enumerating a CDC device. Enumerates CDC device over USB, but doesn't transmit/receive yet. --- stmhal/usbdev/class/AUDIO/Inc/usbd_audio.h | 201 ++++++ .../class/AUDIO/Inc/usbd_audio_if_template.h | 44 ++ stmhal/usbdev/class/AUDIO/Src/usbd_audio.c | 781 +++++++++++++++++++++ .../class/AUDIO/Src/usbd_audio_if_template.c | 190 +++++ 4 files changed, 1216 insertions(+) create mode 100644 stmhal/usbdev/class/AUDIO/Inc/usbd_audio.h create mode 100644 stmhal/usbdev/class/AUDIO/Inc/usbd_audio_if_template.h create mode 100644 stmhal/usbdev/class/AUDIO/Src/usbd_audio.c create mode 100644 stmhal/usbdev/class/AUDIO/Src/usbd_audio_if_template.c (limited to 'stmhal/usbdev/class/AUDIO') diff --git a/stmhal/usbdev/class/AUDIO/Inc/usbd_audio.h b/stmhal/usbdev/class/AUDIO/Inc/usbd_audio.h new file mode 100644 index 000000000..b9a225f20 --- /dev/null +++ b/stmhal/usbdev/class/AUDIO/Inc/usbd_audio.h @@ -0,0 +1,201 @@ +/** + ****************************************************************************** + * @file usbd_audio_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief header file for the usbd_audio_core.c file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_AUDIO_CORE_H_ +#define __USB_AUDIO_CORE_H_ + +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_AUDIO + * @brief This file is the Header file for USBD_msc.c + * @{ + */ + + +/** @defgroup USBD_AUDIO_Exported_Defines + * @{ + */ +#define AUDIO_OUT_EP 0x01 +#define USB_AUDIO_CONFIG_DESC_SIZ 109 +#define AUDIO_INTERFACE_DESC_SIZE 9 +#define USB_AUDIO_DESC_SIZ 0x09 +#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 +#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 + +#define AUDIO_DESCRIPTOR_TYPE 0x21 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_PROTOCOL_UNDEFINED 0x00 +#define AUDIO_STREAMING_GENERAL 0x01 +#define AUDIO_STREAMING_FORMAT_TYPE 0x02 + +/* Audio Descriptor Types */ +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + +/* Audio Control Interface Descriptor Subtypes */ +#define AUDIO_CONTROL_HEADER 0x01 +#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 +#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 +#define AUDIO_CONTROL_FEATURE_UNIT 0x06 + +#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C +#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 +#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 + +#define AUDIO_CONTROL_MUTE 0x0001 + +#define AUDIO_FORMAT_TYPE_I 0x01 +#define AUDIO_FORMAT_TYPE_III 0x03 + +#define AUDIO_ENDPOINT_GENERAL 0x01 + +#define AUDIO_REQ_GET_CUR 0x81 +#define AUDIO_REQ_SET_CUR 0x01 + +#define AUDIO_OUT_STREAMING_CTRL 0x02 + + +#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) +#define AUDIO_DEFAULT_VOLUME 70 + +/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure + that it is an even number and higher than 3 */ +#define AUDIO_OUT_PACKET_NUM 80 +/* Total size of the audio transfer buffer */ +#define AUDIO_TOTAL_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM)) + + /* Audio Commands enmueration */ +typedef enum +{ + AUDIO_CMD_START = 1, + AUDIO_CMD_PLAY, + AUDIO_CMD_STOP, +}AUDIO_CMD_TypeDef; + + +typedef enum +{ + AUDIO_OFFSET_NONE = 0, + AUDIO_OFFSET_HALF, + AUDIO_OFFSET_FULL, + AUDIO_OFFSET_UNKNOWN, +} +AUDIO_OffsetTypeDef; +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + typedef struct +{ + uint8_t cmd; + uint8_t data[USB_MAX_EP0_SIZE]; + uint8_t len; + uint8_t unit; +} +USBD_AUDIO_ControlTypeDef; + + + +typedef struct +{ + __IO uint32_t alt_setting; + uint8_t buffer[AUDIO_TOTAL_BUF_SIZE]; + AUDIO_OffsetTypeDef offset; + uint8_t rd_enable; + uint16_t rd_ptr; + uint16_t wr_ptr; + USBD_AUDIO_ControlTypeDef control; +} +USBD_AUDIO_HandleTypeDef; + + +typedef struct +{ + int8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options); + int8_t (*DeInit) (uint32_t options); + int8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); + int8_t (*VolumeCtl) (uint8_t vol); + int8_t (*MuteCtl) (uint8_t cmd); + int8_t (*PeriodicTC) (uint8_t cmd); + int8_t (*GetState) (void); +}USBD_AUDIO_ItfTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_AUDIO; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_AUDIO_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops); + +void USBD_AUDIO_Sync (USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); +/** + * @} + */ + +#endif // __USB_AUDIO_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/AUDIO/Inc/usbd_audio_if_template.h b/stmhal/usbdev/class/AUDIO/Inc/usbd_audio_if_template.h new file mode 100644 index 000000000..cf407a484 --- /dev/null +++ b/stmhal/usbdev/class/AUDIO/Inc/usbd_audio_if_template.h @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * @file usbd_audio_if_template.h + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief Header for dfu_mal.c file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_AUDIO_IF_TEMPLATE_H +#define __USBD_AUDIO_IF_TEMPLATE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +#endif /* __USBD_AUDIO_IF_TEMPLATE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/AUDIO/Src/usbd_audio.c b/stmhal/usbdev/class/AUDIO/Src/usbd_audio.c new file mode 100644 index 000000000..32565320a --- /dev/null +++ b/stmhal/usbdev/class/AUDIO/Src/usbd_audio.c @@ -0,0 +1,781 @@ +/** + ****************************************************************************** + * @file usbd_audio.c + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief This file provides the HID core functions. + * + * @verbatim + * + * =================================================================== + * AUDIO Class Description + * =================================================================== + * + * + * + * + * + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_AUDIO + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_AUDIO_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Macros + * @{ + */ +#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) + +#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ + (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) + +/** + * @} + */ + + + + +/** @defgroup USBD_AUDIO_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_AUDIO_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_AUDIO_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_AUDIO_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_AUDIO_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_AUDIO_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_EP0_RxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_EP0_TxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_SOF (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +/** + * @} + */ + +/** @defgroup USBD_AUDIO_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_AUDIO = +{ + USBD_AUDIO_Init, + USBD_AUDIO_DeInit, + USBD_AUDIO_Setup, + USBD_AUDIO_EP0_TxReady, + USBD_AUDIO_EP0_RxReady, + USBD_AUDIO_DataIn, + USBD_AUDIO_DataOut, + USBD_AUDIO_SOF, + USBD_AUDIO_IsoINIncomplete, + USBD_AUDIO_IsoOutIncomplete, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetDeviceQualifierDesc, +}; + +/* USB AUDIO device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /* Configuration 1 */ + 0x09, /* bLength */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */ + LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength 109 bytes*/ + HIBYTE(USB_AUDIO_CONFIG_DESC_SIZ), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xC0, /* bmAttributes BUS Powred*/ + 0x32, /* bMaxPower = 100 mA*/ + /* 09 byte*/ + + /* USB Speaker Standard interface descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Class-specific AC Interface Descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ + 0x00, /* 1.00 */ /* bcdADC */ + 0x01, + 0x27, /* wTotalLength = 39*/ + 0x00, + 0x01, /* bInCollection */ + 0x01, /* baInterfaceNr */ + /* 09 byte*/ + + /* USB Speaker Input Terminal Descriptor */ + AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalID */ + 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ + 0x01, + 0x00, /* bAssocTerminal */ + 0x01, /* bNrChannels */ + 0x00, /* wChannelConfig 0x0000 Mono */ + 0x00, + 0x00, /* iChannelNames */ + 0x00, /* iTerminal */ + /* 12 byte*/ + + /* USB Speaker Audio Feature Unit Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ + AUDIO_OUT_STREAMING_CTRL, /* bUnitID */ + 0x01, /* bSourceID */ + 0x01, /* bControlSize */ + AUDIO_CONTROL_MUTE,// |AUDIO_CONTROL_VOLUME, /* bmaControls(0) */ + 0, /* bmaControls(1) */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /*USB Speaker Output Terminal Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ + 0x03, /* bTerminalID */ + 0x01, /* wTerminalType 0x0301*/ + 0x03, + 0x00, /* bAssocTerminal */ + 0x02, /* bSourceID */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ + /* Interface 1, Alternate Setting 0 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ + /* Interface 1, Alternate Setting 1 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x01, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Audio Streaming Interface Descriptor */ + AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalLink */ + 0x01, /* bDelay */ + 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ + 0x00, + /* 07 byte*/ + + /* USB Speaker Audio Type III Format Interface Descriptor */ + 0x0B, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ + AUDIO_FORMAT_TYPE_III, /* bFormatType */ + 0x02, /* bNrChannels */ + 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ + 16, /* bBitResolution (16-bits per sample) */ + 0x01, /* bSamFreqType only one frequency supported */ + AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ + /* 11 byte*/ + + /* Endpoint 1 - Standard Descriptor */ + AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ + AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ + USBD_EP_TYPE_ISOC, /* bmAttributes */ + AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ + 0x01, /* bInterval */ + 0x00, /* bRefresh */ + 0x00, /* bSynchAddress */ + /* 09 byte*/ + + /* Endpoint - Audio Streaming Descriptor*/ + AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ + AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ + 0x00, /* bmAttributes */ + 0x00, /* bLockDelayUnits */ + 0x00, /* wLockDelay */ + 0x00, + /* 07 byte*/ +} ; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END= +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_AUDIO_Private_Functions + * @{ + */ + +/** + * @brief USBD_AUDIO_Init + * Initialize the AUDIO interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_AUDIO_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + USBD_AUDIO_HandleTypeDef *haudio; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + AUDIO_OUT_EP, + USBD_EP_TYPE_ISOC, + AUDIO_OUT_PACKET); + + /* Allocate Audio structure */ + pdev->pClassData = USBD_malloc(sizeof (USBD_AUDIO_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + return USBD_FAIL; + } + else + { + haudio = pdev->pClassData; + haudio->alt_setting = 0; + haudio->offset = AUDIO_OFFSET_UNKNOWN; + haudio->wr_ptr = 0; + haudio->rd_ptr = 0; + haudio->rd_enable = 0; + + /* Initialize the Audio output Hardware layer */ + if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ, AUDIO_DEFAULT_VOLUME, 0) != USBD_OK) + { + return USBD_FAIL; + } + + /* Prepare Out endpoint to receive 1st packet */ + USBD_LL_PrepareReceive(pdev, + AUDIO_OUT_EP, + haudio->buffer, + AUDIO_OUT_PACKET); + } + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_Init + * DeInitialize the AUDIO layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_AUDIO_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + + /* Open EP OUT */ + USBD_LL_CloseEP(pdev, + AUDIO_OUT_EP); + + /* DeInit physical Interface components */ + if(pdev->pClassData != NULL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->DeInit(0); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_Setup + * Handle the AUDIO specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_AUDIO_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + uint16_t len; + uint8_t *pbuf; + uint8_t ret = USBD_OK; + haudio = pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case AUDIO_REQ_GET_CUR: + AUDIO_REQ_GetCurrent(pdev, req); + break; + + case AUDIO_REQ_SET_CUR: + AUDIO_REQ_SetCurrent(pdev, req); + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) + { + pbuf = USBD_AUDIO_CfgDesc + 18; + len = MIN(USB_AUDIO_DESC_SIZ , req->wLength); + + + USBD_CtlSendData (pdev, + pbuf, + len); + } + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)haudio->alt_setting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) + { + haudio->alt_setting = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + } + return ret; +} + + +/** + * @brief USBD_AUDIO_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_AUDIO_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_AUDIO_CfgDesc); + return USBD_AUDIO_CfgDesc; +} + +/** + * @brief USBD_AUDIO_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + /* Only OUT data are processed */ + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_EP0_RxReady + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = pdev->pClassData; + + if (haudio->control.cmd == AUDIO_REQ_SET_CUR) + {/* In this driver, to simplify code, only SET_CUR request is managed */ + + if (haudio->control.unit == AUDIO_OUT_STREAMING_CTRL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->MuteCtl(haudio->control.data[0]); + haudio->control.cmd = 0; + haudio->control.len = 0; + } + } + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_EP0_TxReady + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_EP0_TxReady (USBD_HandleTypeDef *pdev) +{ + /* Only OUT control data are processed */ + return USBD_OK; +} +/** + * @brief USBD_AUDIO_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_SOF (USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +void USBD_AUDIO_Sync (USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) +{ + int8_t shift = 0; + USBD_AUDIO_HandleTypeDef *haudio; + haudio = pdev->pClassData; + + haudio->offset = offset; + + + if(haudio->rd_enable == 1) + { + haudio->rd_ptr += AUDIO_TOTAL_BUF_SIZE/2; + + if (haudio->rd_ptr == AUDIO_TOTAL_BUF_SIZE) + { + /* roll back */ + haudio->rd_ptr = 0; + } + } + + if(haudio->rd_ptr > haudio->wr_ptr) + { + if((haudio->rd_ptr - haudio->wr_ptr) < AUDIO_OUT_PACKET) + { + shift = -4; + } + else if((haudio->rd_ptr - haudio->wr_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) + { + shift = 4; + } + + } + else + { + if((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET) + { + shift = 4; + } + else if((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) + { + shift = -4; + } + } + + if(haudio->offset == AUDIO_OFFSET_FULL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], + AUDIO_TOTAL_BUF_SIZE/2 - shift, + AUDIO_CMD_PLAY); + haudio->offset = AUDIO_OFFSET_NONE; + } + else if (haudio->offset == AUDIO_OFFSET_HALF) + { + + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[AUDIO_TOTAL_BUF_SIZE/2], + AUDIO_TOTAL_BUF_SIZE/2 - shift, + AUDIO_CMD_PLAY); + haudio->offset = AUDIO_OFFSET_NONE; + + } +} +/** + * @brief USBD_AUDIO_IsoINIncomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_IsoOutIncomplete + * handle data ISO OUT Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = pdev->pClassData; + + if (epnum == AUDIO_OUT_EP) + { + /* Increment the Buffer pointer or roll it back when all buffers are full */ + + haudio->wr_ptr += AUDIO_OUT_PACKET; + + if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE) + {/* All buffers are full: roll back */ + haudio->wr_ptr = 0; + + if(haudio->offset == AUDIO_OFFSET_UNKNOWN) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], + AUDIO_TOTAL_BUF_SIZE/2, + AUDIO_CMD_START); + haudio->offset = AUDIO_OFFSET_NONE; + } + } + + if(haudio->rd_enable == 0) + { + if (haudio->wr_ptr == (AUDIO_TOTAL_BUF_SIZE / 2)) + { + haudio->rd_enable = 1; + } + } + + /* Prepare Out endpoint to receive next audio packet */ + USBD_LL_PrepareReceive(pdev, + AUDIO_OUT_EP, + &haudio->buffer[haudio->wr_ptr], + AUDIO_OUT_PACKET); + + } + + return USBD_OK; +} + +/** + * @brief AUDIO_Req_GetCurrent + * Handles the GET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = pdev->pClassData; + + memset(haudio->control.data, 0, 64); + /* Send the current mute state */ + USBD_CtlSendData (pdev, + haudio->control.data, + req->wLength); +} + +/** + * @brief AUDIO_Req_SetCurrent + * Handles the SET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = pdev->pClassData; + + if (req->wLength) + { + /* Prepare the reception of the buffer over EP0 */ + USBD_CtlPrepareRx (pdev, + haudio->control.data, + req->wLength); + + haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */ + haudio->control.len = req->wLength; /* Set the request data length */ + haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */ + } +} + + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_AUDIO_DeviceQualifierDesc); + return USBD_AUDIO_DeviceQualifierDesc; +} + +/** +* @brief USBD_AUDIO_RegisterInterface +* @param fops: Audio interface callback +* @retval status +*/ +uint8_t USBD_AUDIO_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops) +{ + if(fops != NULL) + { + pdev->pUserData= fops; + } + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/AUDIO/Src/usbd_audio_if_template.c b/stmhal/usbdev/class/AUDIO/Src/usbd_audio_if_template.c new file mode 100644 index 000000000..63ac8fed0 --- /dev/null +++ b/stmhal/usbdev/class/AUDIO/Src/usbd_audio_if_template.c @@ -0,0 +1,190 @@ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.c + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio_if_template.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_AUDIO + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_AUDIO_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_FunctionPrototypes + * @{ + */ + +static int8_t TEMPLATE_Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options); +static int8_t TEMPLATE_DeInit (uint32_t options); +static int8_t TEMPLATE_AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); +static int8_t TEMPLATE_VolumeCtl (uint8_t vol); +static int8_t TEMPLATE_MuteCtl (uint8_t cmd); +static int8_t TEMPLATE_PeriodicTC (uint8_t cmd); +static int8_t TEMPLATE_GetState (void); + +USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops = +{ + TEMPLATE_Init, + TEMPLATE_DeInit, + TEMPLATE_AudioCmd, + TEMPLATE_VolumeCtl, + TEMPLATE_MuteCtl, + TEMPLATE_PeriodicTC, + TEMPLATE_GetState, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_Init + * Initializes the AUDIO media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options) +{ + /* + Add your initialization code here + */ + return (0); +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the AUDIO media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_DeInit(uint32_t options) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_AudioCmd + * AUDIO command handler + * @param Buf: Buffer of data to be sent + * @param size: Number of data to be sent (in bytes) + * @param cmd: command opcode + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_VolumeCtl + * @param vol: volume level (0..100) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_VolumeCtl (uint8_t vol) +{ + + return (0); +} + +/** + * @brief TEMPLATE_MuteCtl + * @param cmd: vmute command + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_MuteCtl (uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_PeriodicTC + * @param cmd + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_PeriodicTC (uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_GetState + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_GetState (void) +{ + + return (0); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + -- cgit v1.2.3