1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 04:15:44 +03:00

STM32F4: Libraries

This commit is contained in:
blckmn 2016-06-08 05:32:31 +10:00
parent 55d8eb57be
commit d4e96ba8e7
206 changed files with 141406 additions and 0 deletions

View file

@ -0,0 +1,158 @@
/**
******************************************************************************
* @file usbd_audio_core.h
* @author MCD Application Team
* @version V1.0.0
* @date 22-July-2011
* @brief header file for the usbd_audio_core.c file.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_AUDIO_CORE_H_
#define __USB_AUDIO_CORE_H_
#include "usbd_ioreq.h"
#include "usbd_req.h"
#include "usbd_desc.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio
* @brief This file is the Header file for USBD_audio.c
* @{
*/
/** @defgroup usbd_audio_Exported_Defines
* @{
*/
/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000))
/* 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 OUT_PACKET_NUM 4
/* Total size of the audio transfer buffer */
#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM))
#define AUDIO_CONFIG_DESC_SIZE 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 USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define AUDIO_ENDPOINT_GENERAL 0x01
#define AUDIO_REQ_GET_CUR 0x81
#define AUDIO_REQ_SET_CUR 0x01
#define AUDIO_OUT_STREAMING_CTRL 0x02
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef struct _Audio_Fops
{
uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
uint8_t (*DeInit) (uint32_t options);
uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd);
uint8_t (*VolumeCtl) (uint8_t vol);
uint8_t (*MuteCtl) (uint8_t cmd);
uint8_t (*PeriodicTC) (uint8_t cmd);
uint8_t (*GetState) (void);
}AUDIO_FOPS_TypeDef;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \
(uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF)
#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_Class_cb_TypeDef AUDIO_cb;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif // __USB_AUDIO_CORE_H_
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,117 @@
/**
******************************************************************************
* @file usbd_audio_out_if.h
* @author MCD Application Team
* @version V1.0.0
* @date 22-July-2011
* @brief header file for the usbd_audio_out_if.c file.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_AUDIO_OUT_IF_H_
#define __USB_AUDIO_OUT_IF_H_
#ifdef STM32F2XX
#include "stm322xg_usb_audio_codec.h"
#elif defined(STM32F10X_CL)
#include "stm3210c_usb_audio_codec.h"
#endif /* STM32F2XX */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio
* @brief This file is the Header file for USBD_audio.c
* @{
*/
/** @defgroup usbd_audio_Exported_Defines
* @{
*/
/* Audio Commands enmueration */
typedef enum
{
AUDIO_CMD_PLAY = 1,
AUDIO_CMD_PAUSE,
AUDIO_CMD_STOP,
}AUDIO_CMD_TypeDef;
/* Mute commands */
#define AUDIO_MUTE 0x01
#define AUDIO_UNMUTE 0x00
/* Functions return value */
#define AUDIO_OK 0x00
#define AUDIO_FAIL 0xFF
/* Audio Machine States */
#define AUDIO_STATE_INACTIVE 0x00
#define AUDIO_STATE_ACTIVE 0x01
#define AUDIO_STATE_PLAYING 0x02
#define AUDIO_STATE_PAUSED 0x03
#define AUDIO_STATE_STOPPED 0x04
#define AUDIO_STATE_ERROR 0x05
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif /* __USB_AUDIO_OUT_IF_H_ */
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,665 @@
/**
******************************************************************************
* @file usbd_audio_core.c
* @author MCD Application Team
* @version V1.0.0
* @date 22-July-2011
* @brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB Audio Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as Audio Streaming Device
* - Audio Streaming data transfer
* - AudioControl requests management
* - Error management
*
* @verbatim
*
* ===================================================================
* Audio Class Driver Description
* ===================================================================
* This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
* Audio Devices V1.0 Mar 18, 98".
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Standard AC Interface Descriptor management
* - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
* - 1 Audio Streaming Endpoint
* - 1 Audio Terminal Input (1 channel)
* - Audio Class-Specific AC Interfaces
* - Audio Class-Specific AS Interfaces
* - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
* - Audio Feature Unit (limited to Mute control)
* - Audio Synchronization type: Asynchronous
* - Single fixed audio sampling rate (configurable in usbd_conf.h file)
*
* @note
* The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only
* Low and Full speed modes and does not allow High Speed transfers.
* Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98"
* for more details.
*
* These aspects may be enriched or modified for a specific user application.
*
* This driver doesn't implement the following aspects of the specification
* (but it is possible to manage these features with some modifications on this driver):
* - AudioControl Endpoint management
* - AudioControl requsests other than SET_CUR and GET_CUR
* - Abstraction layer for AudioControl requests (only Mute functionality is managed)
* - Audio Synchronization type: Adaptive
* - Audio Compression modules and interfaces
* - MIDI interfaces and modules
* - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control)
* - Any other application-specific modules
* - Multiple and Variable audio sampling rates
* - Out Streaming Endpoint/Interface (microphone)
*
* @endverbatim
*
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_audio_core.h"
#include "usbd_audio_out_if.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
* @{
*/
/*********************************************
AUDIO Device library callbacks
*********************************************/
static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx);
static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx);
static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req);
static uint8_t usbd_audio_EP0_RxReady(void *pdev);
static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum);
static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum);
static uint8_t usbd_audio_SOF (void *pdev);
static uint8_t usbd_audio_OUT_Incplt (void *pdev);
/*********************************************
AUDIO Requests management functions
*********************************************/
static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req);
static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req);
static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length);
/**
* @}
*/
/** @defgroup usbd_audio_Private_Variables
* @{
*/
/* Main Buffer for Audio Data Out transfers and its relative pointers */
uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2];
uint8_t* IsocOutWrPtr = IsocOutBuff;
uint8_t* IsocOutRdPtr = IsocOutBuff;
/* Main Buffer for Audio Control Rrequests transfers and its relative variables */
uint8_t AudioCtl[64];
uint8_t AudioCtlCmd = 0;
uint32_t AudioCtlLen = 0;
uint8_t AudioCtlUnit = 0;
static uint32_t PlayFlag = 0;
static __IO uint32_t usbd_audio_AltSet = 0;
static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE];
/* AUDIO interface class callbacks structure */
USBD_Class_cb_TypeDef AUDIO_cb =
{
usbd_audio_Init,
usbd_audio_DeInit,
usbd_audio_Setup,
NULL, /* EP0_TxSent */
usbd_audio_EP0_RxReady,
usbd_audio_DataIn,
usbd_audio_DataOut,
usbd_audio_SOF,
NULL,
usbd_audio_OUT_Incplt,
USBD_audio_GetCfgDesc,
#ifdef USB_OTG_HS_CORE
USBD_audio_GetCfgDesc, /* use same config as per FS */
#endif
};
/* USB AUDIO device Configuration Descriptor */
static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] =
{
/* Configuration 1 */
0x09, /* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/
HIBYTE(AUDIO_CONFIG_DESC_SIZE),
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_INTERFACE_DESCRIPTOR_TYPE, /* 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, /* bmaControls(0) */
0x00, /* 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_INTERFACE_DESCRIPTOR_TYPE, /* 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_INTERFACE_DESCRIPTOR_TYPE, /* 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 */
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_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/
USB_ENDPOINT_TYPE_ISOCHRONOUS, /* 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*/
} ;
/**
* @}
*/
/** @defgroup usbd_audio_Private_Functions
* @{
*/
/**
* @brief usbd_audio_Init
* Initilaizes the AUDIO interface.
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_audio_Init (void *pdev,
uint8_t cfgidx)
{
/* Open EP OUT */
DCD_EP_Open(pdev,
AUDIO_OUT_EP,
AUDIO_OUT_PACKET,
USB_OTG_EP_ISOC);
/* Initialize the Audio output Hardware layer */
if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK)
{
return USBD_FAIL;
}
/* Prepare Out endpoint to receive audio data */
DCD_EP_PrepareRx(pdev,
AUDIO_OUT_EP,
(uint8_t*)IsocOutBuff,
AUDIO_OUT_PACKET);
return USBD_OK;
}
/**
* @brief usbd_audio_Init
* DeInitializes the AUDIO layer.
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_audio_DeInit (void *pdev,
uint8_t cfgidx)
{
DCD_EP_Close (pdev , AUDIO_OUT_EP);
/* DeInitialize the Audio output Hardware layer */
if (AUDIO_OUT_fops.DeInit(0) != USBD_OK)
{
return USBD_FAIL;
}
return USBD_OK;
}
/**
* @brief usbd_audio_Setup
* Handles the Audio control request parsing.
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t usbd_audio_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len;
uint8_t *pbuf;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* AUDIO Class Requests -------------------------------*/
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);
return USBD_FAIL;
}
break;
/* Standard Requests -------------------------------*/
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
pbuf = usbd_audio_Desc;
#else
pbuf = usbd_audio_CfgDesc + 18;
#endif
len = MIN(USB_AUDIO_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev,
pbuf,
len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&usbd_audio_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM)
{
usbd_audio_AltSet = (uint8_t)(req->wValue);
}
else
{
/* Call the error management function (command will be nacked */
USBD_CtlError (pdev, req);
}
break;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_EP0_RxReady
* Handles audio control requests data.
* @param pdev: device device instance
* @retval status
*/
static uint8_t usbd_audio_EP0_RxReady (void *pdev)
{
/* Check if an AudioControl request has been issued */
if (AudioCtlCmd == AUDIO_REQ_SET_CUR)
{/* In this driver, to simplify code, only SET_CUR request is managed */
/* Check for which addressed unit the AudioControl request has been issued */
if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL)
{/* In this driver, to simplify code, only one unit is manage */
/* Call the audio interface mute function */
AUDIO_OUT_fops.MuteCtl(AudioCtl[0]);
/* Reset the AudioCtlCmd variable to prevent re-entering this function */
AudioCtlCmd = 0;
AudioCtlLen = 0;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_DataIn
* Handles the audio IN data stage.
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum)
{
return USBD_OK;
}
/**
* @brief usbd_audio_DataOut
* Handles the Audio Out data stage.
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum)
{
if (epnum == AUDIO_OUT_EP)
{
/* Increment the Buffer pointer or roll it back when all buffers are full */
if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
{/* All buffers are full: roll back */
IsocOutWrPtr = IsocOutBuff;
}
else
{/* Increment the buffer pointer */
IsocOutWrPtr += AUDIO_OUT_PACKET;
}
/* Toggle the frame index */
((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame =
(((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1;
/* Prepare Out endpoint to receive next audio packet */
DCD_EP_PrepareRx(pdev,
AUDIO_OUT_EP,
(uint8_t*)(IsocOutWrPtr),
AUDIO_OUT_PACKET);
/* Trigger the start of streaming only when half buffer is full */
if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2))))
{
/* Enable start of Streaming */
PlayFlag = 1;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_SOF
* Handles the SOF event (data buffer update and synchronization).
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_SOF (void *pdev)
{
/* Check if there are available data in stream buffer.
In this function, a single variable (PlayFlag) is used to avoid software delays.
The play operation must be executed as soon as possible after the SOF detection. */
if (PlayFlag)
{
/* Start playing received packet */
AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */
AUDIO_OUT_PACKET, /* Number of samples in Bytes */
AUDIO_CMD_PLAY); /* Command to be processed */
/* Increment the Buffer pointer or roll it back when all buffers all full */
if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
{/* Roll back to the start of buffer */
IsocOutRdPtr = IsocOutBuff;
}
else
{/* Increment to the next sub-buffer */
IsocOutRdPtr += AUDIO_OUT_PACKET;
}
/* If all available buffers have been consumed, stop playing */
if (IsocOutRdPtr == IsocOutWrPtr)
{
/* Pause the audio stream */
AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */
AUDIO_OUT_PACKET, /* Number of samples in Bytes */
AUDIO_CMD_PAUSE); /* Command to be processed */
/* Stop entering play loop */
PlayFlag = 0;
/* Reset buffer pointers */
IsocOutRdPtr = IsocOutBuff;
IsocOutWrPtr = IsocOutBuff;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_OUT_Incplt
* Handles the iso out incomplete event.
* @param pdev: instance
* @retval status
*/
static uint8_t usbd_audio_OUT_Incplt (void *pdev)
{
return USBD_OK;
}
/******************************************************************************
AUDIO Class requests management
******************************************************************************/
/**
* @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(void *pdev, USB_SETUP_REQ *req)
{
/* Send the current mute state */
USBD_CtlSendData (pdev,
AudioCtl,
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(void *pdev, USB_SETUP_REQ *req)
{
if (req->wLength)
{
/* Prepare the reception of the buffer over EP0 */
USBD_CtlPrepareRx (pdev,
AudioCtl,
req->wLength);
/* Set the global variables indicating current request and its length
to the function usbd_audio_EP0_RxReady() which will process the request */
AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */
AudioCtlLen = req->wLength; /* Set the request data length */
AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */
}
}
/**
* @brief USBD_audio_GetCfgDesc
* Returns configuration descriptor.
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (usbd_audio_CfgDesc);
return usbd_audio_CfgDesc;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,318 @@
/**
******************************************************************************
* @file usbd_audio_out_if.c
* @author MCD Application Team
* @version V1.0.0
* @date 22-July-2011
* @brief This file provides the Audio Out (palyback) interface API.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_audio_core.h"
#include "usbd_audio_out_if.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio_out_if
* @brief usbd out interface module
* @{
*/
/** @defgroup usbd_audio_out_if_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes
* @{
*/
static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
static uint8_t DeInit (uint32_t options);
static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd);
static uint8_t VolumeCtl (uint8_t vol);
static uint8_t MuteCtl (uint8_t cmd);
static uint8_t PeriodicTC (uint8_t cmd);
static uint8_t GetState (void);
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Variables
* @{
*/
AUDIO_FOPS_TypeDef AUDIO_OUT_fops =
{
Init,
DeInit,
AudioCmd,
VolumeCtl,
MuteCtl,
PeriodicTC,
GetState
};
static uint8_t AudioState = AUDIO_STATE_INACTIVE;
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Functions
* @{
*/
/**
* @brief Init
* Initialize and configures all required resources for audio play function.
* @param AudioFreq: Statrtup audio frequency.
* @param Volume: Startup volume to be set.
* @param options: specific options passed to low layer function.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t Init (uint32_t AudioFreq,
uint32_t Volume,
uint32_t options)
{
static uint32_t Initialized = 0;
/* Check if the low layer has already been initialized */
if (Initialized == 0)
{
/* Call low layer function */
if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
/* Set the Initialization flag to prevent reinitializing the interface again */
Initialized = 1;
}
/* Update the Audio state machine */
AudioState = AUDIO_STATE_ACTIVE;
return AUDIO_OK;
}
/**
* @brief DeInit
* Free all resources used by low layer and stops audio-play function.
* @param options: options passed to low layer function.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t DeInit (uint32_t options)
{
/* Update the Audio state machine */
AudioState = AUDIO_STATE_INACTIVE;
return AUDIO_OK;
}
/**
* @brief AudioCmd
* Play, Stop, Pause or Resume current file.
* @param pbuf: address from which file shoud be played.
* @param size: size of the current buffer/file.
* @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE,
* AUDIO_CMD_RESUME or AUDIO_CMD_STOP.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t AudioCmd(uint8_t* pbuf,
uint32_t size,
uint8_t cmd)
{
/* Check the current state */
if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR))
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
switch (cmd)
{
/* Process the PLAY command ----------------------------*/
case AUDIO_CMD_PLAY:
/* If current state is Active or Stopped */
if ((AudioState == AUDIO_STATE_ACTIVE) || \
(AudioState == AUDIO_STATE_STOPPED) || \
(AudioState == AUDIO_STATE_PLAYING))
{
Audio_MAL_Play((uint32_t)pbuf, (size/2));
AudioState = AUDIO_STATE_PLAYING;
return AUDIO_OK;
}
/* If current state is Paused */
else if (AudioState == AUDIO_STATE_PAUSED)
{
if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_PLAYING;
return AUDIO_OK;
}
}
else /* Not allowed command */
{
return AUDIO_FAIL;
}
/* Process the STOP command ----------------------------*/
case AUDIO_CMD_STOP:
if (AudioState != AUDIO_STATE_PLAYING)
{
/* Unsupported command */
return AUDIO_FAIL;
}
else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_STOPPED;
return AUDIO_OK;
}
/* Process the PAUSE command ---------------------------*/
case AUDIO_CMD_PAUSE:
if (AudioState != AUDIO_STATE_PLAYING)
{
/* Unsupported command */
return AUDIO_FAIL;
}
else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_PAUSED;
return AUDIO_OK;
}
/* Unsupported command ---------------------------------*/
default:
return AUDIO_FAIL;
}
}
/**
* @brief VolumeCtl
* Set the volume level in %
* @param vol: volume level to be set in % (from 0% to 100%)
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t VolumeCtl (uint8_t vol)
{
/* Call low layer volume setting function */
if (EVAL_AUDIO_VolumeCtl(vol) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
return AUDIO_OK;
}
/**
* @brief MuteCtl
* Mute or Unmute the audio current output
* @param cmd: can be 0 to unmute, or 1 to mute.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t MuteCtl (uint8_t cmd)
{
/* Call low layer mute setting function */
if (EVAL_AUDIO_Mute(cmd) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
return AUDIO_OK;
}
/**
* @brief
*
* @param
* @param
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t PeriodicTC (uint8_t cmd)
{
return AUDIO_OK;
}
/**
* @brief GetState
* Return the current state of the audio machine
* @param None
* @retval Current State.
*/
static uint8_t GetState (void)
{
return AudioState;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/