MCUXpresso_MKS22FN256xxx12/boards/mapsks22/usb_examples/usb_device_audio_speaker_lite/bm/audio_speaker.c
2022-06-18 14:53:46 +08:00

1829 lines
70 KiB
C

/*
* The Clear BSD License
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_audio.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "audio_speaker.h"
#include "fsl_device_registers.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include <stdio.h>
#include <stdlib.h>
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
#include "usb_phy.h"
#endif
#include "fsl_wm8960.h"
#include "fsl_common.h"
#include "pin_mux.h"
#include "fsl_gpio.h"
#include "fsl_port.h"
#include "fsl_sai.h"
#include "fsl_dmamux.h"
#include "fsl_sai_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define OVER_SAMPLE_RATE (256U)
#define DEMO_SAI_BITWIDTH (kSAI_WordWidth16bits)
#define SAI_IRQ_CHANNEL (0U)
#define SAI_UserTxIRQHandler I2S0_Tx_IRQHandler
#define DEMO_SAI_IRQ_TX I2S0_Tx_IRQn
#define BOARD_DEMO_SAI I2S0
#define BOARD_DEMO_I2C LPI2C0
#define BOARD_DEMO_SAI_CLKSRC kCLOCK_CoreSysClk
#define BOARD_DEMO_I2C_CLKSRC kCLOCK_McgIrc48MClk
#define BOARD_DEMO_I2C_CLK_FREQ CLOCK_GetFreq(kCLOCK_McgIrc48MClk)
#define DEMO_SAI_CLK_FREQ CLOCK_GetFreq(kCLOCK_CoreSysClk)
#define EXAMPLE_DMA DMA0
#define EXAMPLE_DMAMUX DMAMUX
#define EXAMPLE_TX_CHANNEL (0U)
#define EXAMPLE_SAI_TX_SOURCE kDmaRequestMux0I2S0Tx
#define I2C_RELEASE_SDA_PORT PORTB
#define I2C_RELEASE_SCL_PORT PORTB
#define I2C_RELEASE_SDA_GPIO GPIOB
#define I2C_RELEASE_SDA_PIN 1U
#define I2C_RELEASE_SCL_GPIO GPIOB
#define I2C_RELEASE_SCL_PIN 0U
#define I2C_RELEASE_BUS_COUNT 100U
#define AUDIO_SAMPLING_RATE_TO_10_14 (AUDIO_SAMPLING_RATE_KHZ << 14)
#define AUDIO_SAMPLING_RATE_TO_16_16 (AUDIO_SAMPLING_RATE_KHZ << 20)
#define AUDIO_UPDATE_FEEDBACK_DATA(m, n) \
{ \
m[0] = (n & 0xFFU); \
m[1] = ((n >> 8U) & 0xFFU); \
m[2] = ((n >> 16U) & 0xFFU); \
}
#define USB_AUDIO_ENTER_CRITICAL() \
\
USB_OSA_SR_ALLOC(); \
\
USB_OSA_ENTER_CRITICAL()
#define USB_AUDIO_EXIT_CRITICAL() USB_OSA_EXIT_CRITICAL()
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_I2C_ReleaseBus(void);
void APPInit(void);
usb_status_t USB_DeviceAudioProcessTerminalRequest(uint32_t audioCommand, uint32_t *length, uint8_t **buffer);
void BOARD_InitHardware(void);
void USB_DeviceClockInit(void);
void USB_DeviceIsrEnable(void);
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle);
#endif
extern void BOARD_USB_Audio_TxInit(uint32_t samplingRate);
extern void BOARD_Codec_Init(void);
extern void BOARD_DMA_EDMA_Config(void);
extern void BOARD_Create_Audio_DMA_EDMA_Handle(void);
extern void BOARD_DMA_EDMA_Set_AudioFormat(void);
extern void BOARD_DMA_EDMA_Enable_Audio_Interrupts(void);
extern void BOARD_DMA_EDMA_Start(void);
/*******************************************************************************
* Variables
******************************************************************************/
extern usb_audio_speaker_struct_t g_UsbDeviceAudioSpeaker;
extern uint8_t audioPlayDataBuff[AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE];
sai_config_t saiTxConfig;
sai_transfer_format_t audioFormat;
sai_edma_handle_t txHandle = {0};
edma_handle_t dmaTxHandle = {0};
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t audioPlayDMATempBuff[FS_ISO_OUT_ENDP_PACKET_SIZE];
codec_handle_t codecHandle = {0};
extern codec_config_t boardCodecConfig;
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t audioPlayDataBuff[AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE];
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t audioPlayPacket[(FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE)];
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t audioFeedBackBuffer[3];
extern uint8_t
g_UsbDeviceInterface[USB_AUDIO_SPEAKER_INTERFACE_COUNT]; /* Default value of audio speaker device struct */
usb_audio_speaker_struct_t g_UsbDeviceAudioSpeaker = {
.deviceHandle = NULL,
.currentStreamOutMaxPacketSize = (FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE),
.currentFeedbackMaxPacketSize = FS_ISO_FEEDBACK_ENDP_PACKET_SIZE,
.attach = 0U,
.currentStreamInterfaceAlternateSetting = 0U,
.copyProtect = 0x01U,
.curMute = 0x00U,
.curVolume = {0x00U, 0x1fU},
.minVolume = {0x00U, 0x00U},
.maxVolume = {0x00U, 0x43U},
.resVolume = {0x01U, 0x00U},
.curBass = 0x00U,
.minBass = 0x80U,
.maxBass = 0x7FU,
.resBass = 0x01U,
.curMid = 0x00U,
.minMid = 0x80U,
.maxMid = 0x7FU,
.resMid = 0x01U,
.curTreble = 0x01U,
.minTreble = 0x80U,
.maxTreble = 0x7FU,
.resTreble = 0x01U,
.curAutomaticGain = 0x01U,
.curDelay = {0x00U, 0x40U},
.minDelay = {0x00U, 0x00U},
.maxDelay = {0xFFU, 0xFFU},
.resDelay = {0x00U, 0x01U},
.curLoudness = 0x01U,
.curSamplingFrequency = {0x00U, 0x00U, 0x01U},
.minSamplingFrequency = {0x00U, 0x00U, 0x01U},
.maxSamplingFrequency = {0x00U, 0x00U, 0x01U},
.resSamplingFrequency = {0x00U, 0x00U, 0x01U},
#if USBCFG_AUDIO_CLASS_2_0
.curSampleFrequency = 48000U, /* This should be changed to 48000 if sampling rate is 48k */
.curClockValid = 1U,
.controlRange = {1U, 48000U, 48000U, 0U},
#endif
.speed = USB_SPEED_FULL,
.tdReadNumberPlay = 0,
.tdWriteNumberPlay = 0,
.audioSendCount = 0,
.lastAudioSendCount = 0,
.usbRecvCount = 0,
.audioSendTimes = 0,
.usbRecvTimes = 0,
.startPlay = 0,
.startPlayHalfFull = 0,
.speakerIntervalCount = 0,
.speakerReservedSpace = 0,
.timesFeedbackCalculate = 0,
.speakerDetachOrNoInput = 0,
};
/*******************************************************************************
* Code
******************************************************************************/
extern void WM8960_USB_Audio_Init(void *I2CBase, void *i2cHandle);
extern void WM8960_Config_Audio_Formats(uint32_t samplingRate);
/*******************************************************************************
* Code
******************************************************************************/
static void i2c_release_bus_delay(void)
{
uint32_t i = 0;
for (i = 0; i < I2C_RELEASE_BUS_COUNT; i++)
{
__NOP();
}
}
void BOARD_I2C_ReleaseBus(void)
{
uint8_t i = 0;
gpio_pin_config_t pin_config;
port_pin_config_t i2c_pin_config = {0};
CLOCK_EnableClock(kCLOCK_PortB); /* Port B Clock Gate Control: Clock enabled */
/* Config pin mux as gpio */
i2c_pin_config.pullSelect = kPORT_PullUp;
i2c_pin_config.mux = kPORT_MuxAsGpio;
pin_config.pinDirection = kGPIO_DigitalOutput;
pin_config.outputLogic = 1U;
CLOCK_EnableClock(kCLOCK_PortB);
PORT_SetPinConfig(I2C_RELEASE_SCL_PORT, I2C_RELEASE_SCL_PIN, &i2c_pin_config);
PORT_SetPinConfig(I2C_RELEASE_SCL_PORT, I2C_RELEASE_SDA_PIN, &i2c_pin_config);
GPIO_PinInit(I2C_RELEASE_SCL_GPIO, I2C_RELEASE_SCL_PIN, &pin_config);
GPIO_PinInit(I2C_RELEASE_SDA_GPIO, I2C_RELEASE_SDA_PIN, &pin_config);
/* Drive SDA low first to simulate a start */
GPIO_PinWrite(I2C_RELEASE_SDA_GPIO, I2C_RELEASE_SDA_PIN, 0U);
i2c_release_bus_delay();
/* Send 9 pulses on SCL and keep SDA high */
for (i = 0; i < 9; i++)
{
GPIO_PinWrite(I2C_RELEASE_SCL_GPIO, I2C_RELEASE_SCL_PIN, 0U);
i2c_release_bus_delay();
GPIO_PinWrite(I2C_RELEASE_SDA_GPIO, I2C_RELEASE_SDA_PIN, 1U);
i2c_release_bus_delay();
GPIO_PinWrite(I2C_RELEASE_SCL_GPIO, I2C_RELEASE_SCL_PIN, 1U);
i2c_release_bus_delay();
i2c_release_bus_delay();
}
/* Send stop */
GPIO_PinWrite(I2C_RELEASE_SCL_GPIO, I2C_RELEASE_SCL_PIN, 0U);
i2c_release_bus_delay();
GPIO_PinWrite(I2C_RELEASE_SDA_GPIO, I2C_RELEASE_SDA_PIN, 0U);
i2c_release_bus_delay();
GPIO_PinWrite(I2C_RELEASE_SCL_GPIO, I2C_RELEASE_SCL_PIN, 1U);
i2c_release_bus_delay();
GPIO_PinWrite(I2C_RELEASE_SDA_GPIO, I2C_RELEASE_SDA_PIN, 1U);
i2c_release_bus_delay();
}
void BOARD_Codec_Init()
{
CODEC_Init(&codecHandle, &boardCodecConfig);
CODEC_SetFormat(&codecHandle, audioFormat.masterClockHz, audioFormat.sampleRate_Hz, audioFormat.bitWidth);
}
void SAI_USB_Audio_TxInit(I2S_Type *SAIBase)
{
SAI_TxGetDefaultConfig(&saiTxConfig);
SAI_TxInit(SAIBase, &saiTxConfig);
}
void WM8960_Config_Audio_Formats(uint32_t samplingRate)
{
/* Configure the audio audioFormat */
audioFormat.bitWidth = kSAI_WordWidth16bits;
audioFormat.channel = 0U;
audioFormat.sampleRate_Hz = samplingRate;
audioFormat.masterClockHz = OVER_SAMPLE_RATE * audioFormat.sampleRate_Hz;
audioFormat.protocol = saiTxConfig.protocol;
audioFormat.stereo = kSAI_Stereo;
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
audioFormat.watermark = FSL_FEATURE_SAI_FIFO_COUNT / 2U;
#endif
}
void BOARD_USB_Audio_TxInit(uint32_t samplingRate)
{
SAI_USB_Audio_TxInit(BOARD_DEMO_SAI);
WM8960_Config_Audio_Formats(samplingRate);
}
static void txCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
{
sai_transfer_t xfer = {0};
if ((g_UsbDeviceAudioSpeaker.audioSendTimes >= g_UsbDeviceAudioSpeaker.usbRecvTimes) &&
(g_UsbDeviceAudioSpeaker.startPlayHalfFull == 1))
{
g_UsbDeviceAudioSpeaker.startPlayHalfFull = 0;
g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput = 1;
}
if (g_UsbDeviceAudioSpeaker.startPlayHalfFull)
{
xfer.dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE;
xfer.data = audioPlayDataBuff + g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
g_UsbDeviceAudioSpeaker.audioSendCount += FS_ISO_OUT_ENDP_PACKET_SIZE;
g_UsbDeviceAudioSpeaker.audioSendTimes++;
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay += FS_ISO_OUT_ENDP_PACKET_SIZE;
if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >=
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE)
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
}
else
{
xfer.dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE;
xfer.data = audioPlayDMATempBuff;
}
SAI_TransferSendEDMA(base, handle, &xfer);
}
void BOARD_DMA_EDMA_Config()
{
edma_config_t dmaConfig = {0};
EDMA_GetDefaultConfig(&dmaConfig);
EDMA_Init(EXAMPLE_DMA, &dmaConfig);
EDMA_CreateHandle(&dmaTxHandle, EXAMPLE_DMA, EXAMPLE_TX_CHANNEL);
DMAMUX_Init(EXAMPLE_DMAMUX);
DMAMUX_SetSource(EXAMPLE_DMAMUX, EXAMPLE_TX_CHANNEL, (uint8_t)EXAMPLE_SAI_TX_SOURCE);
DMAMUX_EnableChannel(EXAMPLE_DMAMUX, EXAMPLE_TX_CHANNEL);
}
void BOARD_Create_Audio_DMA_EDMA_Handle()
{
SAI_TransferTxCreateHandleEDMA(BOARD_DEMO_SAI, &txHandle, txCallback, NULL, &dmaTxHandle);
}
void BOARD_DMA_EDMA_Set_AudioFormat()
{
uint32_t mclkSourceClockHz = 0U;
mclkSourceClockHz = CLOCK_GetFreq(BOARD_DEMO_SAI_CLKSRC);
SAI_TransferTxSetFormatEDMA(BOARD_DEMO_SAI, &txHandle, &audioFormat, mclkSourceClockHz, audioFormat.masterClockHz);
}
void BOARD_DMA_EDMA_Enable_Audio_Interrupts()
{
/* Enable interrupt to handle FIFO error */
SAI_TxEnableInterrupts(BOARD_DEMO_SAI, kSAI_FIFOErrorInterruptEnable);
EnableIRQ(DEMO_SAI_IRQ_TX);
}
void BOARD_DMA_EDMA_Start()
{
sai_transfer_t xfer = {0};
memset(audioPlayDMATempBuff, 0, FS_ISO_OUT_ENDP_PACKET_SIZE);
xfer.dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE;
xfer.data = audioPlayDMATempBuff;
SAI_TransferSendEDMA(BOARD_DEMO_SAI, &txHandle, &xfer);
}
void SAI_UserTxIRQHandler(void)
{
/* Clear the FEF flag */
SAI_TxClearStatusFlags(BOARD_DEMO_SAI, kSAI_FIFOErrorFlag);
SAI_TxSoftwareReset(BOARD_DEMO_SAI, kSAI_ResetTypeFIFO);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
__DSB();
}
#if (defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U))
void USB0_IRQHandler(void)
{
USB_DeviceKhciIsrFunction(g_UsbDeviceAudioSpeaker.deviceHandle);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
__DSB();
}
#endif
void USB_DeviceClockInit(void)
{
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
SystemCoreClockUpdate();
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
/*
* If the SOC has USB KHCI dedicated RAM, the RAM memory needs to be clear after
* the KHCI clock is enabled. When the demo uses USB EHCI IP, the USB KHCI dedicated
* RAM can not be used and the memory can't be accessed.
*/
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U))
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS) && (FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS > 0U))
for (int i = 0; i < FSL_FEATURE_USB_KHCI_USB_RAM; i++)
{
((uint8_t *)FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
}
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS */
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM */
#endif
}
void USB_DeviceIsrEnable(void)
{
uint8_t irqNumber;
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
uint8_t usbDeviceKhciIrq[] = USB_IRQS;
irqNumber = usbDeviceKhciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];
#endif
/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type)irqNumber);
}
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle)
{
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
USB_DeviceKhciTaskFunction(deviceHandle);
#endif
}
#endif
/* Initialize the structure information for sai. */
void Init_Board_Sai_Codec(void)
{
usb_echo("Init Audio SAI and CODEC\r\n");
BOARD_USB_Audio_TxInit(AUDIO_SAMPLING_RATE);
BOARD_Codec_I2C_Init();
BOARD_Codec_Init();
BOARD_DMA_EDMA_Config();
BOARD_Create_Audio_DMA_EDMA_Handle();
BOARD_DMA_EDMA_Set_AudioFormat();
BOARD_DMA_EDMA_Enable_Audio_Interrupts();
BOARD_DMA_EDMA_Start();
}
usb_status_t USB_DeviceAudioGetControlTerminal(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint32_t audioCommand = 0U;
switch (setup->bRequest)
{
/* Copy Protect Control only supports the CUR attribute!*/
case USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST:
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_MUTE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL;
break;
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_AUTOMATIC_GAIN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_AUTOMATIC_GAIN_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_DELAY_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_BOOST_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_BASS_BOOST_CONTROL;
break;
case USB_DEVICE_AUDIO_LOUDNESS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_LOUDNESS_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetResAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
switch (controlSelector)
{
case USB_DEVICE_AUDIO_MUTE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL;
break;
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_AUTOMATIC_GAIN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_AUTOMATIC_GAIN_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_DELAY_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_BOOST_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_BASS_BOOST_CONTROL;
break;
case USB_DEVICE_AUDIO_LOUDNESS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_LOUDNESS_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioSetResAudioFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
switch (controlSelector)
{
case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST:
error = USB_DeviceAudioGetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_MIN_VOLUME_REQUEST:
error = USB_DeviceAudioGetMinAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_MAX_VOLUME_REQUEST:
error = USB_DeviceAudioGetMaxAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_RES_VOLUME_REQUEST:
error = USB_DeviceAudioGetResAudioFeatureUnit(handle, setup, length, buffer);
break;
default:
break;
}
return error;
}
usb_status_t USB_DeviceAudioSetFeatureUnit(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST:
error = USB_DeviceAudioSetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_MIN_VOLUME_REQUEST:
error = USB_DeviceAudioSetMinAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_MAX_VOLUME_REQUEST:
error = USB_DeviceAudioSetMaxAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_RES_VOLUME_REQUEST:
error = USB_DeviceAudioSetResAudioFeatureUnit(handle, setup, length, buffer);
break;
default:
break;
}
return error;
}
usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint32_t audioCommand = 0U;
switch (setup->bRequest)
{
/* Copy Protect Control only supports the CUR attribute!*/
case USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST:
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioSetRequestInterface(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t entity_id = (uint8_t)(setup->wIndex >> 0x08);
if (USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entity_id)
{
error = USB_DeviceAudioSetControlTerminal(handle, setup, length, buffer);
}
else if (USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID == entity_id)
{
error = USB_DeviceAudioSetFeatureUnit(handle, setup, length, buffer);
}
else
{
}
return error;
}
usb_status_t USB_DeviceAudioGetRequestInterface(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t entity_id = (uint8_t)(setup->wIndex >> 0x08);
if (USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entity_id)
{
error = USB_DeviceAudioGetControlTerminal(handle, setup, length, buffer);
}
else if (USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID == entity_id)
{
error = USB_DeviceAudioGetFeatureUnit(handle, setup, length, buffer);
}
else
{
}
return error;
}
usb_status_t USB_DeviceAudioSetRequestEndpoint(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_SAMPLING_FREQ_CONTROL;
break;
case USB_DEVICE_AUDIO_PITCH_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_PITCH_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_SET_MIN_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MIN_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_SET_MAX_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_MAX_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_SET_RES_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_SET_RES_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceAudioGetRequestEndpoint(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
uint32_t audioCommand = 0U;
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_GET_MIN_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MIN_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_GET_MAX_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_MAX_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
case USB_DEVICE_AUDIO_GET_RES_VOLUME_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_GET_RES_SAMPLING_FREQ_CONTROL;
break;
default:
break;
}
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
return error;
}
usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
usb_status_t error = kStatus_USB_InvalidRequest;
#if USBCFG_AUDIO_CLASS_2_0
/* Handle the audio class specific request. */
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
uint32_t audioCommand = 0;
switch (entityId)
{
case USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID:
break;
case USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID:
break;
case USB_AUDIO_CONTROL_CLOCK_SOURCE_UNIT_ID:
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN))
{
switch (setup->wValue >> 8)
{
case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL:
if (setup->bRequest == USB_DEVICE_AUDIO_REQUEST_CUR)
{
audioCommand = USB_DEVICE_AUDIO_GET_CUR_SAM_FREQ_CONTROL;
}
else if (setup->bRequest == USB_DEVICE_AUDIO_REQUEST_RANGE)
{
audioCommand = USB_DEVICE_AUDIO_GET_RANGE_SAM_FREQ_CONTROL;
}
else
{
}
break;
case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL:
audioCommand = USB_DEVICE_AUDIO_GET_CUR_CLOCK_VALID_CONTROL;
break;
default:
break;
}
}
else if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
{
switch (setup->wValue >> 8)
{
case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_SAM_FREQ_CONTROL;
break;
case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL:
audioCommand = USB_DEVICE_AUDIO_SET_CUR_CLOCK_VALID_CONTROL;
break;
default:
break;
}
}
else
{
}
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer);
#else
switch (setup->bmRequestType)
{
case USB_DEVICE_AUDIO_SET_REQUEST_INTERFACE:
error = USB_DeviceAudioSetRequestInterface(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_REQUEST_INTERFACE:
error = USB_DeviceAudioGetRequestInterface(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_REQUEST_ENDPOINT:
error = USB_DeviceAudioSetRequestEndpoint(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_REQUEST_ENDPOINT:
error = USB_DeviceAudioGetRequestEndpoint(handle, setup, length, buffer);
break;
default:
break;
}
#endif
return error;
}
usb_status_t USB_DeviceAudioProcessTerminalRequest(uint32_t audioCommand, uint32_t *length, uint8_t **buffer)
{
usb_status_t error = kStatus_USB_Success;
static uint16_t volume = 0;
uint8_t *volBuffAddr;
switch (audioCommand)
{
case USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curMute;
*length = sizeof(g_UsbDeviceAudioSpeaker.curMute);
break;
case USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.curVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.curVolume);
break;
case USB_DEVICE_AUDIO_GET_CUR_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.curBass);
break;
case USB_DEVICE_AUDIO_GET_CUR_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.curMid);
break;
case USB_DEVICE_AUDIO_GET_CUR_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.curTreble);
break;
case USB_DEVICE_AUDIO_GET_CUR_AUTOMATIC_GAIN_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curAutomaticGain;
*length = sizeof(g_UsbDeviceAudioSpeaker.curAutomaticGain);
break;
case USB_DEVICE_AUDIO_GET_CUR_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.curDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.curDelay);
break;
case USB_DEVICE_AUDIO_GET_CUR_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.curSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.curSamplingFrequency);
break;
case USB_DEVICE_AUDIO_GET_MIN_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.minVolume);
break;
case USB_DEVICE_AUDIO_GET_MIN_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.minBass);
break;
case USB_DEVICE_AUDIO_GET_MIN_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.minMid);
break;
case USB_DEVICE_AUDIO_GET_MIN_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.minTreble);
break;
case USB_DEVICE_AUDIO_GET_MIN_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.minDelay);
break;
case USB_DEVICE_AUDIO_GET_MIN_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.minSamplingFrequency);
break;
case USB_DEVICE_AUDIO_GET_MAX_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxVolume);
break;
case USB_DEVICE_AUDIO_GET_MAX_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxBass);
break;
case USB_DEVICE_AUDIO_GET_MAX_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxMid);
break;
case USB_DEVICE_AUDIO_GET_MAX_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxTreble);
break;
case USB_DEVICE_AUDIO_GET_MAX_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxDelay);
break;
case USB_DEVICE_AUDIO_GET_MAX_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxSamplingFrequency);
break;
case USB_DEVICE_AUDIO_GET_RES_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.resVolume);
break;
case USB_DEVICE_AUDIO_GET_RES_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.resBass);
break;
case USB_DEVICE_AUDIO_GET_RES_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.resMid);
break;
case USB_DEVICE_AUDIO_GET_RES_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.resTreble);
break;
case USB_DEVICE_AUDIO_GET_RES_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.resDelay);
break;
case USB_DEVICE_AUDIO_GET_RES_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.resSamplingFrequency);
break;
#if USBCFG_AUDIO_CLASS_2_0
case USB_DEVICE_AUDIO_GET_CUR_SAM_FREQ_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.curSampleFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.curSampleFrequency);
break;
case USB_DEVICE_AUDIO_GET_RANGE_SAM_FREQ_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.controlRange;
*length = sizeof(g_UsbDeviceAudioSpeaker.controlRange);
break;
case USB_DEVICE_AUDIO_GET_CUR_CLOCK_VALID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curClockValid;
*length = sizeof(g_UsbDeviceAudioSpeaker.curClockValid);
break;
#endif
case USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL:
volBuffAddr = *buffer;
g_UsbDeviceAudioSpeaker.curVolume[0] = *volBuffAddr;
g_UsbDeviceAudioSpeaker.curVolume[1] = *(volBuffAddr + 1);
volume = (uint16_t)((uint16_t)g_UsbDeviceAudioSpeaker.curVolume[1] << 8U);
volume |= (uint8_t)(g_UsbDeviceAudioSpeaker.curVolume[0]);
/* If needs print information while adjusting the volume, please enable the following sentence. */
/* usb_echo("Set Cur Volume : %x\r\n", volume); */
break;
case USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL:
g_UsbDeviceAudioSpeaker.curMute = **(buffer);
/* If needs print information while adjusting the volume, please enable the following sentence. */
/* usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute); */
break;
case USB_DEVICE_AUDIO_SET_CUR_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.curBass = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_CUR_MID_CONTROL:
g_UsbDeviceAudioSpeaker.curMid = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_CUR_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.curTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_CUR_AUTOMATIC_GAIN_CONTROL:
g_UsbDeviceAudioSpeaker.curAutomaticGain = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_CUR_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.curDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.curDelay[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_CUR_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.curSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.curSamplingFrequency[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MIN_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.minVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minVolume[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MIN_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.minBass = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MIN_MID_CONTROL:
g_UsbDeviceAudioSpeaker.minMid = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MIN_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.minTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MIN_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.minDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minDelay[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MIN_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.minSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minSamplingFrequency[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MAX_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.maxVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxVolume[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MAX_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.maxBass = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MAX_MID_CONTROL:
g_UsbDeviceAudioSpeaker.maxMid = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MAX_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.maxTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_MAX_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.maxDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxDelay[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_MAX_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.maxSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxSamplingFrequency[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_RES_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.resVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resVolume[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_RES_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.resBass = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_RES_MID_CONTROL:
g_UsbDeviceAudioSpeaker.resMid = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_RES_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.resTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_RES_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.resDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resDelay[1] = **(buffer + 1);
break;
case USB_DEVICE_AUDIO_SET_RES_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.resSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resSamplingFrequency[1] = **(buffer + 1);
break;
#if USBCFG_AUDIO_CLASS_2_0
case USB_DEVICE_AUDIO_SET_CUR_SAM_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.curSampleFrequency = **(buffer);
break;
case USB_DEVICE_AUDIO_SET_CUR_CLOCK_VALID_CONTROL:
g_UsbDeviceAudioSpeaker.curClockValid = **(buffer);
break;
#endif
default:
error = kStatus_USB_InvalidRequest;
break;
}
return error;
}
/* The AudioSpeakerBufferSpaceUsed() function gets the reserved speaker ringbuffer size */
uint32_t AudioSpeakerBufferSpaceUsed(void)
{
if (g_UsbDeviceAudioSpeaker.tdReadNumberPlay > g_UsbDeviceAudioSpeaker.tdWriteNumberPlay)
{
g_UsbDeviceAudioSpeaker.speakerReservedSpace =
g_UsbDeviceAudioSpeaker.tdReadNumberPlay - g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
}
else
{
g_UsbDeviceAudioSpeaker.speakerReservedSpace =
g_UsbDeviceAudioSpeaker.tdReadNumberPlay +
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE -
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
}
return g_UsbDeviceAudioSpeaker.speakerReservedSpace;
}
/* The USB_AudioFeedbackDataUpdate() function calculates the feedback data */
void USB_AudioFeedbackDataUpdate()
{
static uint32_t feedbackValue = 0x0, originFeedbackValue = 0x0;
uint32_t usedSpace = 0;
if (g_UsbDeviceAudioSpeaker.speakerIntervalCount != AUDIO_CALCULATE_Ff_INTERVAL)
{
g_UsbDeviceAudioSpeaker.speakerIntervalCount++;
return;
}
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 1;
g_UsbDeviceAudioSpeaker.timesFeedbackCalculate++;
if (g_UsbDeviceAudioSpeaker.timesFeedbackCalculate == 2)
{
originFeedbackValue =
((g_UsbDeviceAudioSpeaker.audioSendCount - g_UsbDeviceAudioSpeaker.lastAudioSendCount) << 4) /
(AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
feedbackValue = originFeedbackValue;
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, originFeedbackValue);
}
else if (g_UsbDeviceAudioSpeaker.timesFeedbackCalculate > 2)
{
usedSpace = AudioSpeakerBufferSpaceUsed();
if (usedSpace >=
AUDIO_BUFFER_UPPER_LIMIT(AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE))
{
feedbackValue -= (AUDIO_SAMPLING_RATE_KHZ / AUDIO_SAMPLING_RATE_16KHZ) * (AUDIO_ADJUST_MIN_STEP);
}
else if (usedSpace <
AUDIO_BUFFER_LOWER_LIMIT(AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE))
{
feedbackValue += (AUDIO_SAMPLING_RATE_KHZ / AUDIO_SAMPLING_RATE_16KHZ) * (AUDIO_ADJUST_MIN_STEP);
}
else
{
}
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, feedbackValue);
}
else
{
}
g_UsbDeviceAudioSpeaker.lastAudioSendCount = g_UsbDeviceAudioSpeaker.audioSendCount;
}
/* The USB_AudioSpeakerPutBuffer() function fills the audioRecDataBuff with audioPlayPacket in every callback*/
void USB_AudioSpeakerPutBuffer(uint8_t *buffer, uint32_t size)
{
while (size)
{
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdReadNumberPlay] = *buffer;
g_UsbDeviceAudioSpeaker.tdReadNumberPlay++;
buffer++;
size--;
if (g_UsbDeviceAudioSpeaker.tdReadNumberPlay >=
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE)
{
g_UsbDeviceAudioSpeaker.tdReadNumberPlay = 0;
}
}
}
usb_status_t USB_DeviceAudioIsoIn(usb_device_handle deviceHandle,
usb_device_endpoint_callback_message_struct_t *event,
void *arg)
{
usb_status_t error = kStatus_USB_InvalidRequest;
usb_device_endpoint_callback_message_struct_t *ep_cb_param;
ep_cb_param = (usb_device_endpoint_callback_message_struct_t *)event;
if ((g_UsbDeviceAudioSpeaker.attach) && (ep_cb_param->length != (USB_UNINITIALIZED_VAL_32)))
{
error = USB_DeviceSendRequest(deviceHandle, USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT, audioFeedBackBuffer,
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize);
}
return error;
}
/* USB device audio ISO IN endpoint callback */
usb_status_t USB_DeviceAudioIsoOut(usb_device_handle deviceHandle,
usb_device_endpoint_callback_message_struct_t *event,
void *arg)
{
usb_status_t error = kStatus_USB_InvalidRequest;
usb_device_endpoint_callback_message_struct_t *ep_cb_param;
ep_cb_param = (usb_device_endpoint_callback_message_struct_t *)event;
if ((g_UsbDeviceAudioSpeaker.attach) && (ep_cb_param->length != (USB_UNINITIALIZED_VAL_32)))
{
if (g_UsbDeviceAudioSpeaker.startPlay == 0)
{
g_UsbDeviceAudioSpeaker.startPlay = 1;
}
if ((g_UsbDeviceAudioSpeaker.tdReadNumberPlay >=
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE / 2) &&
(g_UsbDeviceAudioSpeaker.startPlayHalfFull == 0))
{
g_UsbDeviceAudioSpeaker.startPlayHalfFull = 1;
}
USB_AudioSpeakerPutBuffer(audioPlayPacket, ep_cb_param->length);
g_UsbDeviceAudioSpeaker.usbRecvCount += ep_cb_param->length;
g_UsbDeviceAudioSpeaker.usbRecvTimes++;
USB_AUDIO_ENTER_CRITICAL();
USB_AudioFeedbackDataUpdate();
USB_AUDIO_EXIT_CRITICAL();
error = USB_DeviceRecvRequest(deviceHandle, USB_AUDIO_SPEAKER_STREAM_ENDPOINT, &audioPlayPacket[0],
g_UsbDeviceAudioSpeaker.currentStreamOutMaxPacketSize);
}
return error;
}
/*!
* @brief Get the setup packet buffer.
*
* This function provides the buffer for setup packet.
*
* @param handle The USB device handle.
* @param setupBuffer The pointer to the address of setup packet buffer.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
{
static uint32_t audioSpeakerSetup[2];
if (NULL == setupBuffer)
{
return kStatus_USB_InvalidParameter;
}
*setupBuffer = (usb_setup_struct_t *)&audioSpeakerSetup;
return kStatus_USB_Success;
}
/*!
* @brief Get the setup packet data buffer.
*
* This function gets the data buffer for setup packet.
*
* @param handle The USB device handle.
* @param setup The pointer to the setup packet.
* @param length The pointer to the length of the data buffer.
* @param buffer The pointer to the address of setup packet data buffer.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
usb_setup_struct_t *setup,
uint32_t *length,
uint8_t **buffer)
{
static uint8_t setupOut[8];
if ((NULL == buffer) || ((*length) > sizeof(setupOut)))
{
return kStatus_USB_InvalidRequest;
}
*buffer = setupOut;
return kStatus_USB_Success;
}
/*!
* @brief Configure remote wakeup feature.
*
* This function configures the remote wakeup feature.
*
* @param handle The USB device handle.
* @param enable 1: enable, 0: disable.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
{
return kStatus_USB_InvalidRequest;
}
/*!
* @brief USB configure endpoint function.
*
* This function configure endpoint status.
*
* @param handle The USB device handle.
* @param ep Endpoint address.
* @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
{
if (status)
{
if ((USB_AUDIO_SPEAKER_STREAM_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
return USB_DeviceStallEndpoint(handle, ep);
}
else if ((USB_AUDIO_CONTROL_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
return USB_DeviceStallEndpoint(handle, ep);
}
else
{
}
}
else
{
if ((USB_AUDIO_SPEAKER_STREAM_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
return USB_DeviceUnstallEndpoint(handle, ep);
}
else if ((USB_AUDIO_CONTROL_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
return USB_DeviceUnstallEndpoint(handle, ep);
}
else
{
}
}
return kStatus_USB_InvalidRequest;
}
/* The USB_DeviceAudioSpeakerStatusReset() function resets the audio speaker status to the initialized status */
void USB_DeviceAudioSpeakerStatusReset(void)
{
g_UsbDeviceAudioSpeaker.startPlay = 0;
g_UsbDeviceAudioSpeaker.startPlayHalfFull = 0;
g_UsbDeviceAudioSpeaker.tdReadNumberPlay = 0;
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
g_UsbDeviceAudioSpeaker.audioSendCount = 0;
g_UsbDeviceAudioSpeaker.usbRecvCount = 0;
g_UsbDeviceAudioSpeaker.lastAudioSendCount = 0;
g_UsbDeviceAudioSpeaker.audioSendTimes = 0;
g_UsbDeviceAudioSpeaker.usbRecvTimes = 0;
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 0;
g_UsbDeviceAudioSpeaker.speakerReservedSpace = 0;
g_UsbDeviceAudioSpeaker.timesFeedbackCalculate = 0;
g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput = 0;
}
/*!
* @brief USB device callback function.
*
* This function handles the usb device specific requests.
*
* @param handle The USB device handle.
* @param event The USB device event type.
* @param param The parameter of the device specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_Error;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
g_UsbDeviceAudioSpeaker.attach = 0U;
error = kStatus_USB_Success;
USB_DeviceControlPipeInit(g_UsbDeviceAudioSpeaker.deviceHandle);
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
if (kStatus_USB_Success == USB_DeviceGetStatus(g_UsbDeviceAudioSpeaker.deviceHandle, kUSB_DeviceStatusSpeed,
&g_UsbDeviceAudioSpeaker.speed))
{
USB_DeviceSetSpeed(g_UsbDeviceAudioSpeaker.speed);
}
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
g_UsbDeviceAudioSpeaker.currentStreamOutMaxPacketSize =
(HS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize = HS_ISO_FEEDBACK_ENDP_PACKET_SIZE;
}
#endif
}
break;
case kUSB_DeviceEventSetConfiguration:
if (USB_AUDIO_SPEAKER_CONFIGURE_INDEX == (*temp8))
{
g_UsbDeviceAudioSpeaker.attach = 1U;
g_UsbDeviceAudioSpeaker.currentStreamInterfaceAlternateSetting = 0U;
}
break;
case kUSB_DeviceEventSetInterface:
if (g_UsbDeviceAudioSpeaker.attach)
{
uint8_t interface = (*temp8) & 0xFF;
uint8_t alternateSetting = g_UsbDeviceInterface[interface];
if (g_UsbDeviceAudioSpeaker.currentStreamInterfaceAlternateSetting != alternateSetting)
{
if (g_UsbDeviceAudioSpeaker.currentStreamInterfaceAlternateSetting)
{
USB_DeviceDeinitEndpoint(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_STREAM_ENDPOINT | (USB_OUT << 7U));
}
else
{
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
epCallback.callbackFn = USB_DeviceAudioIsoOut;
epCallback.callbackParam = handle;
epInitStruct.zlt = 0U;
epInitStruct.transferType = USB_ENDPOINT_ISOCHRONOUS;
epInitStruct.endpointAddress = USB_AUDIO_SPEAKER_STREAM_ENDPOINT |
(USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
epInitStruct.maxPacketSize =
(HS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
}
else
{
epInitStruct.maxPacketSize =
(FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
}
USB_DeviceInitEndpoint(g_UsbDeviceAudioSpeaker.deviceHandle, &epInitStruct, &epCallback);
error = USB_DeviceRecvRequest(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_STREAM_ENDPOINT, &audioPlayPacket[0],
g_UsbDeviceAudioSpeaker.currentStreamOutMaxPacketSize);
epCallback.callbackFn = USB_DeviceAudioIsoIn;
epCallback.callbackParam = handle;
epInitStruct.zlt = 0U;
epInitStruct.transferType = USB_ENDPOINT_ISOCHRONOUS;
epInitStruct.endpointAddress = USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT |
(USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
epInitStruct.maxPacketSize = HS_ISO_FEEDBACK_ENDP_PACKET_SIZE;
}
else
{
epInitStruct.maxPacketSize = FS_ISO_FEEDBACK_ENDP_PACKET_SIZE;
}
USB_DeviceInitEndpoint(g_UsbDeviceAudioSpeaker.deviceHandle, &epInitStruct, &epCallback);
error = USB_DeviceSendRequest(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT, audioFeedBackBuffer,
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize);
}
g_UsbDeviceAudioSpeaker.currentStreamInterfaceAlternateSetting = alternateSetting;
}
}
break;
default:
break;
}
return error;
}
/*!
* @brief Application initialization function.
*
* This function initializes the application.
*
* @return None.
*/
void APPInit(void)
{
USB_DeviceClockInit();
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
SYSMPU_Enable(SYSMPU, 0);
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
Init_Board_Sai_Codec();
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_10_14);
if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_UsbDeviceAudioSpeaker.deviceHandle))
{
usb_echo("USB device failed\r\n");
return;
}
else
{
usb_echo("USB device audio speaker demo\r\n");
}
/* Install isr, set priority, and enable IRQ. */
USB_DeviceIsrEnable();
USB_DeviceRun(g_UsbDeviceAudioSpeaker.deviceHandle);
}
void USB_AudioCodecTask(void)
{
if (g_UsbDeviceAudioSpeaker.codecTask & MUTE_CODEC_TASK)
{
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute);
g_UsbDeviceAudioSpeaker.codecTask &= ~MUTE_CODEC_TASK;
}
if (g_UsbDeviceAudioSpeaker.codecTask & UNMUTE_CODEC_TASK)
{
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute);
g_UsbDeviceAudioSpeaker.codecTask &= ~UNMUTE_CODEC_TASK;
}
if (g_UsbDeviceAudioSpeaker.codecTask & VOLUME_CHANGE_TASK)
{
usb_echo("Set Cur Volume : %x\r\n",
(uint16_t)(g_UsbDeviceAudioSpeaker.curVolume[1] << 8U) | g_UsbDeviceAudioSpeaker.curVolume[0]);
g_UsbDeviceAudioSpeaker.codecTask &= ~VOLUME_CHANGE_TASK;
}
}
void USB_AudioSpeakerResetTask(void)
{
if (g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput)
{
USB_DeviceAudioSpeakerStatusReset();
}
}
/*!
* @brief Application task function.
*
* This function runs the task for application.
*
* @return None.
*/
#if defined(__CC_ARM) || defined(__GNUC__)
int main(void)
#else
void main(void)
#endif
{
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_I2C_ReleaseBus();
BOARD_I2C_ConfigurePins();
BOARD_InitDebugConsole();
CLOCK_SetPllFllSelClock(3U); /* IRC48 MHz clock. */
CLOCK_SetLpi2c0Clock(1);
APPInit();
while (1)
{
USB_AudioCodecTask();
USB_AudioSpeakerResetTask();
#if USB_DEVICE_CONFIG_USE_TASK
USB_DeviceTaskFn(g_UsbDeviceAudioSpeaker.deviceHandle);
#endif
}
}