MCUXpresso_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_device_audio_speaker_lite/bm/audio_speaker.c
Yilin Sun 75f32185d2
Updated to v2.14.0
Signed-off-by: Yilin Sun <imi415@imi.moe>
2023-11-30 20:55:00 +08:00

2953 lines
122 KiB
C

/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
/*${standard_header_anchor}*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_audio.h"
#include "usb_device_ch9.h"
#include "usb_audio_config.h"
#include "usb_device_descriptor.h"
#include "fsl_adapter_audio.h"
#include "audio_speaker.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.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 FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#include "fsl_ctimer.h"
#endif
#include "fsl_sai.h"
#include "fsl_dmamux.h"
#include "fsl_sai_edma.h"
#include "fsl_codec_common.h"
#include "fsl_wm8960.h"
#include "fsl_codec_adapter.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_SAI_INSTANCE_INDEX (1U)
#define DEMO_DMA_INDEX (0U)
#define DEMO_DMA_TX_CHANNEL (0U)
#define DEMO_DMAMUX_INDEX (0U)
#define DEMO_SAI_TX_SOURCE kDmaRequestMuxSai1Tx
#define DEMO_SAI SAI1
/* Select Audio/Video PLL (786.48 MHz) as sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_SELECT (2U)
/* Clock pre divider for sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER (3U)
/* Clock divider for sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_DIVIDER (15U)
/* Get frequency of sai1 clock */
#define DEMO_SAI_CLK_FREQ \
(CLOCK_GetFreq(kCLOCK_AudioPllClk) / (DEMO_SAI1_CLOCK_SOURCE_DIVIDER + 1U) / \
(DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER + 1U))
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define DEMO_LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define DEMO_LPI2C_CLOCK_SOURCE_DIVIDER (5U)
#define AUDIO_SAMPLING_RATE_TO_10_14 (AUDIO_SAMPLING_RATE_KHZ << 10)
#define AUDIO_SAMPLING_RATE_TO_16_16 \
((AUDIO_SAMPLING_RATE_KHZ / (AUDIO_OUT_TRANSFER_LENGTH_ONE_FRAME / HS_ISO_OUT_ENDP_PACKET_SIZE)) << 13)
/* audio 2.0 and high speed, use low latency, but IP3511HS controller do not have micro frame count */
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
volatile static uint8_t s_microFrameCountIp3511HS = 0;
#endif
#endif
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
extern volatile uint8_t feedbackValueUpdating;
#endif
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if defined(USB_DEVICE_WORKAROUND_AUDIO_20_WINDOWS) && (USB_DEVICE_WORKAROUND_AUDIO_20_WINDOWS > 0)
/* this is used for windows that supports usb audio 2.0 */
#define AUDIO_UPDATE_FEEDBACK_DATA(m, n) \
{ \
feedbackValueUpdating = 1; \
m[0] = ((n << 6U) & 0xFFu); \
m[1] = ((n >> 2U) & 0xFFu); \
m[2] = ((n >> 10U) & 0xFFu); \
m[3] = ((n >> 18U) & 0xFFu); \
feedbackValueUpdating = 0; \
}
#else
/* change 10.10 data to 10.14 or change 12.13 to 16.16 */
#define AUDIO_UPDATE_FEEDBACK_DATA(m, n) \
feedbackValueUpdating = 1; \
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed) \
{ \
m[0] = (((n & 0x00001FFFu) << 3) & 0xFFu); \
m[1] = ((((n & 0x00001FFFu) << 3) >> 8) & 0xFFu); \
m[2] = (((n & 0x01FFE000u) >> 13) & 0xFFu); \
m[3] = (((n & 0x01FFE000u) >> 21) & 0xFFu); \
} \
else \
{ \
m[0] = ((n << 4) & 0xFFU); \
m[1] = (((n << 4) >> 8U) & 0xFFU); \
m[2] = (((n << 4) >> 16U) & 0xFFU); \
} \
feedbackValueUpdating = 0;
#endif
#else
/* change 10.10 data to 10.14 */
#define AUDIO_UPDATE_FEEDBACK_DATA(m, n) \
{ \
feedbackValueUpdating = 1; \
m[0] = ((n << 4) & 0xFFU); \
m[1] = (((n << 4) >> 8U) & 0xFFU); \
m[2] = (((n << 4) >> 16U) & 0xFFU); \
feedbackValueUpdating = 0; \
}
#endif
#define USB_AUDIO_ENTER_CRITICAL() \
\
OSA_SR_ALLOC(); \
\
OSA_ENTER_CRITICAL()
#define USB_AUDIO_EXIT_CRITICAL() OSA_EXIT_CRITICAL()
/*******************************************************************************
* Prototypes
******************************************************************************/
void APPInit(void);
usb_status_t USB_DeviceAudioProcessTerminalRequest(uint32_t audioCommand,
uint32_t *length,
uint8_t **buffer,
uint8_t entityOrEndpoint);
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 AUDIO_DMA_EDMA_Start();
extern void BOARD_Codec_Init();
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
extern void CTIMER_CaptureInit(void);
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
(defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)))
extern void audio_fro_trim_up(void);
extern void audio_fro_trim_down(void);
#endif
extern void USB_AudioPllChange(void);
#endif
/*******************************************************************************
* Variables
******************************************************************************/
extern usb_audio_speaker_struct_t g_UsbDeviceAudioSpeaker;
extern uint8_t audioPlayDataBuff[AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT_NORMAL * AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME];
HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
hal_audio_config_t audioTxConfig;
hal_audio_dma_config_t dmaTxConfig;
hal_audio_ip_config_t ipTxConfig;
hal_audio_dma_mux_config_t dmaMuxTxConfig;
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t audioPlayDMATempBuff[AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME];
uint32_t masterClockHz = 0U;
codec_handle_t codecHandle;
wm8960_config_t wm8960Config = {
.i2cConfig = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = BOARD_CODEC_I2C_CLOCK_FREQ},
.route = kWM8960_RoutePlaybackandRecord,
.leftInputSource = kWM8960_InputDifferentialMicInput3,
.rightInputSource = kWM8960_InputDifferentialMicInput2,
.playSource = kWM8960_PlaySourceDAC,
.slaveAddress = WM8960_I2C_ADDR,
.bus = kWM8960_BusI2S,
.format = {.mclk_HZ = 12288000U,
.sampleRate = kWM8960_AudioSampleRate48KHz,
.bitWidth = kWM8960_AudioBitWidth16bit},
.master_slave = false,
};
codec_config_t boardCodecConfig = {.codecDevType = kCODEC_WM8960, .codecDevConfig = &wm8960Config};
/*
* AUDIO PLL setting: Frequency = Fref * (DIV_SELECT + NUM / DENOM)
* = 24 * (32 + 77/100)
* = 786.48 MHz
*/
const clock_audio_pll_config_t audioPllConfig = {
.loopDivider = 32, /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */
.postDivider = 1, /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */
.numerator = 77, /* 30 bit numerator of fractional loop divider. */
.denominator = 100, /* 30 bit denominator of fractional loop divider */
};
extern void WM8960_USB_Audio_Init(void *I2CBase, void *i2cHandle);
extern void WM8960_Config_Audio_Formats(uint32_t samplingRate);
extern uint32_t USB_AudioSpeakerBufferSpaceUsed(void);
extern void USB_DeviceCalculateFeedback(void);
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t audioPlayDataBuff[AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT_NORMAL * AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME];
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t audioPlayPacket[FS_ISO_OUT_ENDP_PACKET_SIZE];
#else
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 usbAudioFeedBackBuffer[4];
USB_RAM_ADDRESS_ALIGNMENT(4) uint8_t audioFeedBackBuffer[4];
volatile uint8_t feedbackValueUpdating;
#endif
extern hal_audio_config_t audioTxConfig;
extern HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
extern uint8_t
g_UsbDeviceInterface[USB_AUDIO_SPEAKER_INTERFACE_COUNT]; /* Default value of audio speaker device struct */
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_SetupOutBuffer[8];
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
usb_audio_speaker_struct_t g_UsbDeviceAudioSpeaker = {
.deviceHandle = NULL,
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
.currentStreamOutMaxPacketSize = (FS_ISO_OUT_ENDP_PACKET_SIZE),
#else
.currentStreamOutMaxPacketSize = (FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE),
.currentFeedbackMaxPacketSize = FS_ISO_FEEDBACK_ENDP_PACKET_SIZE,
#endif
.attach = 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 (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
.curMute20 = 0U,
.curClockValid = 1U,
.curVolume20 = {0x00U, 0x1FU},
.curSampleFrequency = 48000U, /* This should be changed to 48000 if sampling rate is 48k */
.freqControlRange = {1U, 48000U, 48000U, 0U},
.volumeControlRange = {1U, 0x8001U, 0x7FFFU, 1U},
#endif
.speed = USB_SPEED_FULL,
.tdWriteNumberPlay = 0,
.tdReadNumberPlay = 0,
.audioSendCount = {0, 0},
.audioSpeakerReadDataCount = {0, 0},
.audioSpeakerWriteDataCount = {0, 0},
.usbRecvCount = 0,
.audioSendTimes = 0,
.usbRecvTimes = 0,
.startPlayFlag = 0,
.speakerIntervalCount = 0,
.speakerReservedSpace = 0,
.speakerDetachOrNoInput = 0,
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
(defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)))
.froTrimIntervalCount = 0,
.usbFroTicksPrev = 0,
.usbFroTicksEma = AUDIO_FRO_USB_SOF_INTERVAL_TICK_COUNT,
.usbFroTickEmaFrac = 0,
.usbFroTickBasedPrecision = AUDIO_USB_FRO_TRIM_TICK_BASED_PRECISION,
#endif
.curAudioPllFrac = AUDIO_PLL_FRACTIONAL_DIVIDER,
.audioPllTicksPrev = 0,
.audioPllTicksEma = AUDIO_PLL_USB_SOF_INTERVAL_TICK_COUNT,
.audioPllTickEmaFrac = 0,
.audioPllTickBasedPrecision = AUDIO_PLL_FRACTION_TICK_BASED_PRECISION,
.stopDataLengthAudioAdjust = 0U,
#endif
};
/*******************************************************************************
* Code
******************************************************************************/
void BOARD_EnableSaiMclkOutput(bool enable)
{
if (enable)
{
IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK;
}
else
{
IOMUXC_GPR->GPR1 &= (~IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK);
}
}
void BOARD_Codec_Init()
{
if (CODEC_Init(&codecHandle, &boardCodecConfig) != kStatus_Success)
{
assert(false);
}
}
static void txCallback(hal_audio_handle_t handle, hal_audio_status_t completionStatus, void *callbackParam)
{
uint32_t audioSpeakerPreReadDataCount = 0U;
uint32_t preAudioSendCount = 0U;
hal_audio_transfer_t xfer = {0};
if ((USB_AudioSpeakerBufferSpaceUsed() < (g_UsbDeviceAudioSpeaker.audioPlayTransferSize)) &&
(g_UsbDeviceAudioSpeaker.startPlayFlag == 1U))
{
g_UsbDeviceAudioSpeaker.startPlayFlag = 0;
g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput = 1;
}
if (0U != g_UsbDeviceAudioSpeaker.startPlayFlag)
{
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
USB_DeviceCalculateFeedback();
#endif
xfer.dataSize = g_UsbDeviceAudioSpeaker.audioPlayTransferSize;
xfer.data = audioPlayDataBuff + g_UsbDeviceAudioSpeaker.tdReadNumberPlay;
preAudioSendCount = g_UsbDeviceAudioSpeaker.audioSendCount[0];
g_UsbDeviceAudioSpeaker.audioSendCount[0] += g_UsbDeviceAudioSpeaker.audioPlayTransferSize;
if (preAudioSendCount > g_UsbDeviceAudioSpeaker.audioSendCount[0])
{
g_UsbDeviceAudioSpeaker.audioSendCount[1] += 1U;
}
g_UsbDeviceAudioSpeaker.audioSendTimes++;
g_UsbDeviceAudioSpeaker.tdReadNumberPlay += g_UsbDeviceAudioSpeaker.audioPlayTransferSize;
if (g_UsbDeviceAudioSpeaker.tdReadNumberPlay >= g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
g_UsbDeviceAudioSpeaker.tdReadNumberPlay = 0;
}
audioSpeakerPreReadDataCount = g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[0];
g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[0] += g_UsbDeviceAudioSpeaker.audioPlayTransferSize;
if (audioSpeakerPreReadDataCount > g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[0])
{
g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[1] += 1U;
}
}
else
{
if (0U != g_UsbDeviceAudioSpeaker.audioPlayTransferSize)
{
xfer.dataSize = g_UsbDeviceAudioSpeaker.audioPlayTransferSize;
}
else
{
xfer.dataSize = AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME / 8U;
}
xfer.data = audioPlayDMATempBuff;
}
HAL_AudioTransferSendNonBlocking((hal_audio_handle_t)&audioTxHandle[0], &xfer);
}
void AUDIO_DMA_EDMA_Start()
{
usb_echo("Init Audio SAI and CODEC\r\n");
hal_audio_transfer_t xfer = {0};
memset(audioPlayDMATempBuff, 0, AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME);
xfer.dataSize = AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME / 8U;
xfer.data = audioPlayDMATempBuff;
HAL_AudioTxInstallCallback((hal_audio_handle_t)&audioTxHandle[0], txCallback, NULL);
HAL_AudioTransferSendNonBlocking((hal_audio_handle_t)&audioTxHandle[0], &xfer);
}
void USB_OTG1_IRQHandler(void)
{
USB_DeviceEhciIsrFunction(g_UsbDeviceAudioSpeaker.deviceHandle);
}
void USB_OTG2_IRQHandler(void)
{
USB_DeviceEhciIsrFunction(g_UsbDeviceAudioSpeaker.deviceHandle);
}
void USB_DeviceClockInit(void)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
if (CONTROLLER_ID == kUSB_ControllerEhci0)
{
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
}
else
{
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
}
void USB_DeviceIsrEnable(void)
{
uint8_t irqNumber;
uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
irqNumber = usbDeviceEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];
/* 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)
{
USB_DeviceEhciTaskFunction(deviceHandle);
}
#endif
usb_status_t USB_DeviceAudioGetControlTerminal(
usb_device_handle handle, usb_setup_struct_t *setup, uint32_t *length, uint8_t **buffer, uint8_t entityId)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint32_t audioCommand = 0U;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
switch (setup->bRequest)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
if (USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entityId)
{
audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_COPY_PROTECT_CONTROL;
}
else
{
/* Input Terminals only support the Get Terminal Copy Protect Control request */
}
break;
case USB_DEVICE_AUDIO_TE_CONNECTOR_CONTROL:
audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_CONNECTOR_CONTROL;
break;
case USB_DEVICE_AUDIO_TE_OVERLOAD_CONTROL:
audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_OVERLOAD_CONTROL;
break;
default:
/*no action*/
break;
}
#else
case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
if (USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entityId)
{
audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_COPY_PROTECT_CONTROL;
}
else
{
/* Input Terminals only support the Get Terminal Copy Protect Control request */
}
break;
default:
/*no action*/
break;
}
#endif
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
return error;
}
usb_status_t USB_DeviceAudioSetControlTerminal(
usb_device_handle handle, usb_setup_struct_t *setup, uint32_t *length, uint8_t **buffer, uint8_t entityId)
{
uint32_t audioCommand = 0U;
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t controlSelector = (setup->wValue >> 0x08) & 0xFFU;
switch (setup->bRequest)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
if (USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID == entityId)
{
audioCommand = USB_DEVICE_AUDIO_TE_SET_CUR_COPY_PROTECT_CONTROL;
}
else
{
/* Output Terminals only support the Set Terminal Copy Protect Control request */
}
break;
default:
/*no action*/
break;
}
#else
case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
if (USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID == entityId)
{
audioCommand = USB_DEVICE_AUDIO_TE_SET_CUR_COPY_PROTECT_CONTROL;
}
else
{
/* Output Terminals only support the Set Terminal Copy Protect Control request */
}
break;
default:
/*no action*/
break;
}
#endif
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_MUTE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_MUTE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_AUTOMATIC_GAIN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_AUTOMATIC_GAIN_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_DELAY_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_BOOST_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_BASS_BOOST_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_LOUDNESS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_LOUDNESS_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
return error;
}
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
usb_status_t USB_DeviceAudioGetRangeAudioFeatureUnit(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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
/* Select GET RANGE request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RANGE_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
break;
default:
/*no action*/
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
return error;
}
#endif
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_MUTE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_MUTE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_AUTOMATIC_GAIN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_AUTOMATIC_GAIN_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_DELAY_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_BOOST_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_BASS_BOOST_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_LOUDNESS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_LOUDNESS_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (controlSelector)
{
case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_VOLUME_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_BASS_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_MID_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_TREBLE_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_GRAPHIC_EQUALIZER_CONTROL;
break;
case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_DELAY_CONTROL;
break;
default:
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
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)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
error = USB_DeviceAudioGetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_RANGE_REQUEST:
error = USB_DeviceAudioGetRangeAudioFeatureUnit(handle, setup, length, buffer);
break;
default:
/*no action*/
break;
#else
case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
error = USB_DeviceAudioGetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_MIN_REQUEST:
error = USB_DeviceAudioGetMinAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_MAX_REQUEST:
error = USB_DeviceAudioGetMaxAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_GET_RES_REQUEST:
error = USB_DeviceAudioGetResAudioFeatureUnit(handle, setup, length, buffer);
break;
default:
break;
#endif
}
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)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
error = USB_DeviceAudioSetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_RANGE_REQUEST:
break;
default:
/*no action*/
break;
#else
case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
error = USB_DeviceAudioSetCurAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_MIN_REQUEST:
error = USB_DeviceAudioSetMinAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_MAX_REQUEST:
error = USB_DeviceAudioSetMaxAudioFeatureUnit(handle, setup, length, buffer);
break;
case USB_DEVICE_AUDIO_SET_RES_REQUEST:
error = USB_DeviceAudioSetResAudioFeatureUnit(handle, setup, length, buffer);
break;
default:
break;
#endif
}
return error;
}
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
usb_status_t USB_DeviceAudioSetClockSource(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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_CS_SET_CUR_SAMPLING_FREQ_CONTROL;
break;
case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_CS_SET_CUR_CLOCK_VALID_CONTROL;
break;
default:
/*no action*/
break;
}
case USB_DEVICE_AUDIO_RANGE_REQUEST:
break;
default:
/*no action*/
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
return error;
}
usb_status_t USB_DeviceAudioGetClockSource(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;
uint8_t entityId = (uint8_t)(setup->wIndex >> 0x08);
switch (setup->bRequest)
{
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_CS_GET_CUR_SAMPLING_FREQ_CONTROL;
break;
case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_CS_GET_CUR_CLOCK_VALID_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_RANGE_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_CS_GET_RANGE_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
default:
/*no action*/
break;
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, entityId);
return error;
}
#endif
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 entityId = (uint8_t)(setup->wIndex >> 0x08);
if ((USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entityId) ||
(USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID == entityId))
{
error = USB_DeviceAudioSetControlTerminal(handle, setup, length, buffer, entityId);
}
else if (USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID == entityId)
{
error = USB_DeviceAudioSetFeatureUnit(handle, setup, length, buffer);
}
else
{
}
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
if (USB_AUDIO_SPEAKER_CONTROL_CLOCK_SOURCE_ENTITY_ID == entityId)
{
error = USB_DeviceAudioSetClockSource(handle, setup, length, buffer);
}
#endif
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 entityId = (uint8_t)(setup->wIndex >> 0x08);
if ((USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID == entityId) ||
(USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID == entityId))
{
error = USB_DeviceAudioGetControlTerminal(handle, setup, length, buffer, entityId);
}
else if (USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID == entityId)
{
error = USB_DeviceAudioGetFeatureUnit(handle, setup, length, buffer);
}
else
{
}
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
if (USB_AUDIO_SPEAKER_CONTROL_CLOCK_SOURCE_ENTITY_ID == entityId)
{
error = USB_DeviceAudioGetClockSource(handle, setup, length, buffer);
}
#endif
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;
uint8_t endpoint = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_PITCH_CONTROL_SELECTOR_AUDIO20:
audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_PITCH_CONTROL_AUDIO20;
break;
default:
/*no action*/
break;
}
break;
default:
/*no action*/
break;
#else
case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_SAMPLING_FREQ_CONTROL;
break;
case USB_DEVICE_AUDIO_EP_PITCH_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_PITCH_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_SET_MIN_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_SET_MIN_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_SET_MAX_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_SET_MAX_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_SET_RES_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_SET_RES_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
default:
break;
#endif
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, endpoint); /* endpoint is not used */
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;
uint8_t endpoint = (uint8_t)(setup->wIndex >> 0x08);
/* Select SET request Control Feature Unit Module */
switch (setup->bRequest)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_DATA_OVERRUN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_DATA_OVERRUN_CONTROL;
break;
case USB_DEVICE_AUDIO_EP_DATA_UNDERRUN_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_DATA_UNDERRUN_CONTROL;
break;
default:
/*no action*/
break;
}
default:
/*no action*/
break;
#else
case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_GET_MIN_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_MIN_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_GET_MAX_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_MAX_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
case USB_DEVICE_AUDIO_GET_RES_REQUEST:
switch (controlSelector)
{
case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
audioCommand = USB_DEVICE_AUDIO_EP_GET_RES_SAMPLING_FREQ_CONTROL;
break;
default:
/*no action*/
break;
}
break;
default:
/*no action*/
break;
#endif
}
error = USB_DeviceAudioProcessTerminalRequest(audioCommand, length, buffer, endpoint); /* endpoint is not used */
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;
uint8_t interfaceOrEndpoint = (uint8_t)setup->wIndex;
if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
{
if ((interfaceOrEndpoint == USB_AUDIO_SPEAKER_STREAM_ENDPOINT) ||
(interfaceOrEndpoint == USB_AUDIO_CONTROL_ENDPOINT)
#if !(defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U))
|| (interfaceOrEndpoint == USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT)
#endif
)
{
switch (setup->bmRequestType)
{
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;
}
}
}
else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
{
if (USB_AUDIO_CONTROL_INTERFACE_INDEX == interfaceOrEndpoint)
{
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;
default:
break;
}
}
}
else
{
/* no action */
}
return error;
}
usb_status_t USB_DeviceAudioProcessTerminalRequest(uint32_t audioCommand,
uint32_t *length,
uint8_t **buffer,
uint8_t entityOrEndpoint)
{
usb_status_t error = kStatus_USB_Success;
uint8_t *volBuffAddr;
#if (!USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
uint16_t volume;
#endif
switch (audioCommand)
{
case USB_DEVICE_AUDIO_FU_GET_CUR_MUTE_CONTROL:
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.curMute20;
*length = sizeof(g_UsbDeviceAudioSpeaker.curMute20);
#else
*buffer = &g_UsbDeviceAudioSpeaker.curMute;
*length = sizeof(g_UsbDeviceAudioSpeaker.curMute);
#endif
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_VOLUME_CONTROL:
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.curVolume20;
*length = sizeof(g_UsbDeviceAudioSpeaker.curVolume20);
#else
*buffer = g_UsbDeviceAudioSpeaker.curVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.curVolume);
#endif
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.curBass);
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.curMid);
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.curTreble);
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_AUTOMATIC_GAIN_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.curAutomaticGain;
*length = sizeof(g_UsbDeviceAudioSpeaker.curAutomaticGain);
break;
case USB_DEVICE_AUDIO_FU_GET_CUR_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.curDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.curDelay);
break;
case USB_DEVICE_AUDIO_FU_GET_MIN_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.minVolume);
break;
case USB_DEVICE_AUDIO_FU_GET_MIN_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.minBass);
break;
case USB_DEVICE_AUDIO_FU_GET_MIN_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.minMid);
break;
case USB_DEVICE_AUDIO_FU_GET_MIN_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.minTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.minTreble);
break;
case USB_DEVICE_AUDIO_FU_GET_MIN_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.minDelay);
break;
case USB_DEVICE_AUDIO_FU_GET_MAX_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxVolume);
break;
case USB_DEVICE_AUDIO_FU_GET_MAX_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxBass);
break;
case USB_DEVICE_AUDIO_FU_GET_MAX_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxMid);
break;
case USB_DEVICE_AUDIO_FU_GET_MAX_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.maxTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxTreble);
break;
case USB_DEVICE_AUDIO_FU_GET_MAX_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxDelay);
break;
case USB_DEVICE_AUDIO_FU_GET_RES_VOLUME_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resVolume;
*length = sizeof(g_UsbDeviceAudioSpeaker.resVolume);
break;
case USB_DEVICE_AUDIO_FU_GET_RES_BASS_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resBass;
*length = sizeof(g_UsbDeviceAudioSpeaker.resBass);
break;
case USB_DEVICE_AUDIO_FU_GET_RES_MID_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resMid;
*length = sizeof(g_UsbDeviceAudioSpeaker.resMid);
break;
case USB_DEVICE_AUDIO_FU_GET_RES_TREBLE_CONTROL:
*buffer = &g_UsbDeviceAudioSpeaker.resTreble;
*length = sizeof(g_UsbDeviceAudioSpeaker.resTreble);
break;
case USB_DEVICE_AUDIO_FU_GET_RES_DELAY_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resDelay;
*length = sizeof(g_UsbDeviceAudioSpeaker.resDelay);
break;
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
case USB_DEVICE_AUDIO_CS_GET_CUR_SAMPLING_FREQ_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.curSampleFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.curSampleFrequency);
break;
case USB_DEVICE_AUDIO_CS_SET_CUR_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.curSampleFrequency = *(uint32_t *)(*buffer);
break;
case USB_DEVICE_AUDIO_CS_GET_CUR_CLOCK_VALID_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.curClockValid;
*length = sizeof(g_UsbDeviceAudioSpeaker.curClockValid);
break;
case USB_DEVICE_AUDIO_CS_SET_CUR_CLOCK_VALID_CONTROL:
g_UsbDeviceAudioSpeaker.curClockValid = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_GET_RANGE_VOLUME_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.volumeControlRange;
*length = sizeof(g_UsbDeviceAudioSpeaker.volumeControlRange);
break;
case USB_DEVICE_AUDIO_CS_GET_RANGE_SAMPLING_FREQ_CONTROL:
*buffer = (uint8_t *)&g_UsbDeviceAudioSpeaker.freqControlRange;
*length = sizeof(g_UsbDeviceAudioSpeaker.freqControlRange);
break;
#else
case USB_DEVICE_AUDIO_EP_GET_CUR_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.curSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.curSamplingFrequency);
break;
case USB_DEVICE_AUDIO_EP_GET_MIN_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.minSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.minSamplingFrequency);
break;
case USB_DEVICE_AUDIO_EP_GET_MAX_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.maxSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.maxSamplingFrequency);
break;
case USB_DEVICE_AUDIO_EP_GET_RES_SAMPLING_FREQ_CONTROL:
*buffer = g_UsbDeviceAudioSpeaker.resSamplingFrequency;
*length = sizeof(g_UsbDeviceAudioSpeaker.resSamplingFrequency);
break;
case USB_DEVICE_AUDIO_EP_SET_CUR_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.curSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.curSamplingFrequency[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_EP_SET_MIN_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.minSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minSamplingFrequency[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_EP_SET_MAX_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.maxSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxSamplingFrequency[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_EP_SET_RES_SAMPLING_FREQ_CONTROL:
g_UsbDeviceAudioSpeaker.resSamplingFrequency[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resSamplingFrequency[1] = *((*buffer) + 1);
break;
#endif
case USB_DEVICE_AUDIO_FU_SET_CUR_VOLUME_CONTROL:
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
volBuffAddr = *buffer;
g_UsbDeviceAudioSpeaker.curVolume20[0] = *(volBuffAddr);
g_UsbDeviceAudioSpeaker.curVolume20[1] = *(volBuffAddr + 1);
g_UsbDeviceAudioSpeaker.codecTask |= VOLUME_CHANGE_TASK;
#else
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]);
g_UsbDeviceAudioSpeaker.codecTask |= VOLUME_CHANGE_TASK;
/* If needs print information while adjusting the volume, please enable the following sentence. */
/* usb_echo("Set Cur Volume : %x\r\n", volume); */
#endif
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_MUTE_CONTROL:
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
g_UsbDeviceAudioSpeaker.curMute20 = **(buffer);
if (g_UsbDeviceAudioSpeaker.curMute20)
{
g_UsbDeviceAudioSpeaker.codecTask |= MUTE_CODEC_TASK;
}
else
{
g_UsbDeviceAudioSpeaker.codecTask |= UNMUTE_CODEC_TASK;
}
#else
g_UsbDeviceAudioSpeaker.curMute = **(buffer);
if (g_UsbDeviceAudioSpeaker.curMute)
{
g_UsbDeviceAudioSpeaker.codecTask |= MUTE_CODEC_TASK;
}
else
{
g_UsbDeviceAudioSpeaker.codecTask |= UNMUTE_CODEC_TASK;
}
/* If needs print information while adjusting the volume, please enable the following sentence. */
/* usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute); */
#endif
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.curBass = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_MID_CONTROL:
g_UsbDeviceAudioSpeaker.curMid = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.curTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_AUTOMATIC_GAIN_CONTROL:
g_UsbDeviceAudioSpeaker.curAutomaticGain = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_CUR_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.curDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.curDelay[1] = *((*buffer) + 1);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
g_UsbDeviceAudioSpeaker.curDelay[2] = *((*buffer) + 2);
g_UsbDeviceAudioSpeaker.curDelay[3] = *((*buffer) + 3);
#endif
break;
case USB_DEVICE_AUDIO_FU_SET_MIN_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.minVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minVolume[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_FU_SET_MIN_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.minBass = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MIN_MID_CONTROL:
g_UsbDeviceAudioSpeaker.minMid = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MIN_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.minTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MIN_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.minDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.minDelay[1] = *((*buffer) + 1);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
g_UsbDeviceAudioSpeaker.minDelay[2] = *((*buffer) + 2);
g_UsbDeviceAudioSpeaker.minDelay[3] = *((*buffer) + 3);
#endif
break;
case USB_DEVICE_AUDIO_FU_SET_MAX_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.maxVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxVolume[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_FU_SET_MAX_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.maxBass = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MAX_MID_CONTROL:
g_UsbDeviceAudioSpeaker.maxMid = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MAX_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.maxTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_MAX_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.maxDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.maxDelay[1] = *((*buffer) + 1);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
g_UsbDeviceAudioSpeaker.maxDelay[2] = *((*buffer) + 2);
g_UsbDeviceAudioSpeaker.maxDelay[3] = *((*buffer) + 3);
#endif
break;
case USB_DEVICE_AUDIO_FU_SET_RES_VOLUME_CONTROL:
g_UsbDeviceAudioSpeaker.resVolume[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resVolume[1] = *((*buffer) + 1);
break;
case USB_DEVICE_AUDIO_FU_SET_RES_BASS_CONTROL:
g_UsbDeviceAudioSpeaker.resBass = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_RES_MID_CONTROL:
g_UsbDeviceAudioSpeaker.resMid = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_RES_TREBLE_CONTROL:
g_UsbDeviceAudioSpeaker.resTreble = **(buffer);
break;
case USB_DEVICE_AUDIO_FU_SET_RES_DELAY_CONTROL:
g_UsbDeviceAudioSpeaker.resDelay[0] = **(buffer);
g_UsbDeviceAudioSpeaker.resDelay[1] = *((*buffer) + 1);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
g_UsbDeviceAudioSpeaker.resDelay[2] = *((*buffer) + 2);
g_UsbDeviceAudioSpeaker.resDelay[3] = *((*buffer) + 3);
#endif
break;
default:
error = kStatus_USB_InvalidRequest;
break;
}
return error;
}
/* The USB_AudioSpeakerBufferSpaceUsed() function gets the used speaker ringbuffer size */
uint32_t USB_AudioSpeakerBufferSpaceUsed(void)
{
uint64_t write_count = 0U;
uint64_t read_count = 0U;
write_count = (uint64_t)((((uint64_t)g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0]);
read_count = (uint64_t)((((uint64_t)g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[0]);
if (write_count >= read_count)
{
return (uint32_t)(write_count - read_count);
}
else
{
return 0;
}
}
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
void USB_DeviceCalculateFeedback(void)
{
volatile static uint64_t totalFrameValue = 0U;
volatile static uint32_t frameDistance = 0U;
volatile static uint32_t feedbackValue = 0U;
uint32_t audioSpeakerUsedSpace = 0U;
/* feedback interval is AUDIO_CALCULATE_Ff_INTERVAL */
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0) /* high speed, feedback interval is AUDIO_CALCULATE_Ff_INTERVAL ms */
if (g_UsbDeviceAudioSpeaker.speakerIntervalCount !=
AUDIO_CALCULATE_Ff_INTERVAL *
(AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME / g_UsbDeviceAudioSpeaker.audioPlayTransferSize))
#else
if (g_UsbDeviceAudioSpeaker.speakerIntervalCount != AUDIO_CALCULATE_Ff_INTERVAL)
#endif
{
g_UsbDeviceAudioSpeaker.speakerIntervalCount++;
return;
}
}
else /* full speed, feedback interval is AUDIO_CALCULATE_Ff_INTERVAL ms */
{
if (g_UsbDeviceAudioSpeaker.speakerIntervalCount != AUDIO_CALCULATE_Ff_INTERVAL)
{
g_UsbDeviceAudioSpeaker.speakerIntervalCount++;
return;
}
}
if (0U == g_UsbDeviceAudioSpeaker.firstCalculateFeedback)
{
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 0;
g_UsbDeviceAudioSpeaker.currentFrameCount = 0;
g_UsbDeviceAudioSpeaker.audioSendCount[0] = 0;
g_UsbDeviceAudioSpeaker.audioSendCount[1] = 0;
totalFrameValue = 0;
frameDistance = 0;
feedbackValue = 0;
USB_DeviceGetStatus(g_UsbDeviceAudioSpeaker.deviceHandle, kUSB_DeviceStatusGetCurrentFrameCount,
(uint32_t *)&g_UsbDeviceAudioSpeaker.lastFrameCount);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
g_UsbDeviceAudioSpeaker.lastFrameCount += s_microFrameCountIp3511HS;
}
#endif
#endif
g_UsbDeviceAudioSpeaker.firstCalculateFeedback = 1U;
return;
}
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 0;
USB_DeviceGetStatus(g_UsbDeviceAudioSpeaker.deviceHandle, kUSB_DeviceStatusGetCurrentFrameCount,
(uint32_t *)&g_UsbDeviceAudioSpeaker.currentFrameCount);
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
g_UsbDeviceAudioSpeaker.currentFrameCount += s_microFrameCountIp3511HS;
}
#endif
#endif
frameDistance = ((g_UsbDeviceAudioSpeaker.currentFrameCount + USB_DEVICE_MAX_FRAME_COUNT + 1U -
g_UsbDeviceAudioSpeaker.lastFrameCount) &
USB_DEVICE_MAX_FRAME_COUNT);
g_UsbDeviceAudioSpeaker.lastFrameCount = g_UsbDeviceAudioSpeaker.currentFrameCount;
totalFrameValue += frameDistance;
if (1U == g_UsbDeviceAudioSpeaker.stopFeedbackUpdate)
{
return;
}
if (1U == g_UsbDeviceAudioSpeaker.feedbackDiscardFlag)
{
if (0 != g_UsbDeviceAudioSpeaker.feedbackDiscardTimes)
{
g_UsbDeviceAudioSpeaker.feedbackDiscardTimes--;
if (0 != g_UsbDeviceAudioSpeaker.lastFeedbackValue)
{
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, g_UsbDeviceAudioSpeaker.lastFeedbackValue);
}
return;
}
else
{
g_UsbDeviceAudioSpeaker.feedbackDiscardFlag = 0;
}
}
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed)
{
#if ((defined(USB_AUDIO_CHANNEL7_1) && (USB_AUDIO_CHANNEL7_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL5_1) && (USB_AUDIO_CHANNEL5_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL3_1) && (USB_AUDIO_CHANNEL3_1 > 0U)))
#if (defined(AUDIO_SPEAKER_MULTI_CHANNEL_PLAY) && (AUDIO_SPEAKER_MULTI_CHANNEL_PLAY > 0U))
feedbackValue =
(uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL * 8UL / totalFrameValue / ((uint64_t)(DEMO_TDM_AUDIO_OUTPUT_CHANNEL_COUNT * 4U)));
#else
feedbackValue = (uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL * 8UL / totalFrameValue / ((uint64_t)(2U * AUDIO_FORMAT_SIZE)));
#endif
#else
feedbackValue =
(uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL * 8UL / totalFrameValue / ((uint64_t)(AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE)));
#endif
}
else
{
#if ((defined(USB_AUDIO_CHANNEL7_1) && (USB_AUDIO_CHANNEL7_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL5_1) && (USB_AUDIO_CHANNEL5_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL3_1) && (USB_AUDIO_CHANNEL3_1 > 0U)))
#if (defined(AUDIO_SPEAKER_MULTI_CHANNEL_PLAY) && (AUDIO_SPEAKER_MULTI_CHANNEL_PLAY > 0U))
feedbackValue = (uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL / totalFrameValue / ((uint64_t)(DEMO_TDM_AUDIO_OUTPUT_CHANNEL_COUNT * 4U)));
#else
feedbackValue = (uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL / totalFrameValue / ((uint64_t)(2U * AUDIO_FORMAT_SIZE)));
#endif
#else
feedbackValue = (uint32_t)(((((uint64_t)g_UsbDeviceAudioSpeaker.audioSendCount[1]) << 32U) |
g_UsbDeviceAudioSpeaker.audioSendCount[0]) *
1024UL / totalFrameValue / ((uint64_t)(AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE)));
#endif
}
audioSpeakerUsedSpace = USB_AudioSpeakerBufferSpaceUsed();
if (audioSpeakerUsedSpace <=
(g_UsbDeviceAudioSpeaker.audioPlayTransferSize * USB_AUDIO_PLAY_BUFFER_FEEDBACK_TOLERANCE_THRESHOLD))
{
feedbackValue += AUDIO_ADJUST_MIN_STEP;
}
if ((audioSpeakerUsedSpace +
(g_UsbDeviceAudioSpeaker.audioPlayTransferSize * USB_AUDIO_PLAY_BUFFER_FEEDBACK_TOLERANCE_THRESHOLD)) >=
g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
feedbackValue -= AUDIO_ADJUST_MIN_STEP;
}
g_UsbDeviceAudioSpeaker.lastFeedbackValue = feedbackValue;
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, feedbackValue);
}
#endif
/* The USB_AudioSpeakerPutBuffer() function fills the audioRecDataBuff with audioPlayPacket in every callback*/
void USB_AudioSpeakerPutBuffer(uint8_t *buffer, uint32_t size)
{
uint32_t remainBufferSpace;
uint32_t audioSpeakerPreWriteDataCount;
#if ((defined(USB_AUDIO_CHANNEL7_1) && (USB_AUDIO_CHANNEL7_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL5_1) && (USB_AUDIO_CHANNEL5_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL3_1) && (USB_AUDIO_CHANNEL3_1 > 0U)))
#if (defined(AUDIO_SPEAKER_MULTI_CHANNEL_PLAY) && (AUDIO_SPEAKER_MULTI_CHANNEL_PLAY > 0U))
uint8_t empty_channel = DEMO_TDM_AUDIO_OUTPUT_CHANNEL_COUNT - AUDIO_FORMAT_CHANNELS;
uint8_t *buffer_temp;
uint32_t buffer_length = 0;
uint8_t fill_zero = 1U;
uint8_t channel_data = 0U;
uint32_t total_data = 0U;
remainBufferSpace = g_UsbDeviceAudioSpeaker.audioPlayBufferSize - USB_AudioSpeakerBufferSpaceUsed();
if (size > remainBufferSpace) /* discard the overflow data */
{
if (remainBufferSpace > (AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE))
{
size = (remainBufferSpace - (AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE));
}
else
{
size = 0;
}
}
for (uint32_t i = 0; i < size; i += (AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS))
{
buffer_temp = buffer + i;
fill_zero = 1U;
channel_data = 0U;
for (uint32_t j = 0; j < (AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS); j++)
{
/* make up 32 bits */
if (1U == fill_zero)
{
for (uint8_t k = 0U; k < (4U - AUDIO_FORMAT_SIZE); k++)
{
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] = 0;
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay++;
total_data++;
if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
}
fill_zero = 0;
}
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] = *(buffer_temp + j);
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay++;
total_data++;
if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
if (4U != AUDIO_FORMAT_SIZE)
{
channel_data++;
if (channel_data == AUDIO_FORMAT_SIZE)
{
fill_zero = 1U;
channel_data = 0U;
}
}
}
/* if totoal channel is not 8, fill 0 to meet 8 channels for TDM */
if (empty_channel)
{
buffer_length = g_UsbDeviceAudioSpeaker.tdWriteNumberPlay + (4U * empty_channel);
if (buffer_length < g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
memset((void *)(&audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay]), 0U, 4U * empty_channel);
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay += (4U * empty_channel);
total_data += (4U * empty_channel);
}
else
{
uint32_t firstLength =
g_UsbDeviceAudioSpeaker.audioPlayBufferSize - g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
memset((void *)(&audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay]), 0U, firstLength);
total_data += firstLength;
buffer_length = (4U * empty_channel) - firstLength; /* the remain data length */
if ((buffer_length) > 0U)
{
memset((void *)(&audioPlayDataBuff[0]), 0U, buffer_length);
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = buffer_length;
total_data += buffer_length;
}
else
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
}
}
}
audioSpeakerPreWriteDataCount = g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0];
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0] += total_data;
if (audioSpeakerPreWriteDataCount > g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0])
{
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[1] += 1U;
}
#else
uint8_t *buffer_temp;
uint32_t play2ChannelLength;
remainBufferSpace = g_UsbDeviceAudioSpeaker.audioPlayBufferSize - USB_AudioSpeakerBufferSpaceUsed();
if ((size % (AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS)) != 0U)
{
size = (size / (AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS)) * (AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS);
}
play2ChannelLength = size / (AUDIO_FORMAT_CHANNELS / 2U); /* only play the selected two channels */
if (play2ChannelLength > remainBufferSpace) /* discard the overflow data */
{
play2ChannelLength = remainBufferSpace;
}
for (uint32_t i = 0; i < size; i += AUDIO_FORMAT_SIZE * AUDIO_FORMAT_CHANNELS)
{
buffer_temp = buffer + i;
if (play2ChannelLength <= 0U)
{
break;
}
for (uint32_t j = 0; j < AUDIO_FORMAT_SIZE * 2; j++)
{
if (play2ChannelLength)
{
#if ((defined(USB_AUDIO_7_1_CHANNEL_PAIR_SEL) && (0x01 == USB_AUDIO_7_1_CHANNEL_PAIR_SEL)) || \
(defined(USB_AUDIO_5_1_CHANNEL_PAIR_SEL) && (0x01 == USB_AUDIO_5_1_CHANNEL_PAIR_SEL)) || \
(defined(USB_AUDIO_3_1_CHANNEL_PAIR_SEL) && (0x01 == USB_AUDIO_3_1_CHANNEL_PAIR_SEL)))
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] = *(buffer_temp + j);
#endif
#if ((defined(USB_AUDIO_7_1_CHANNEL_PAIR_SEL) && (0x02 == USB_AUDIO_7_1_CHANNEL_PAIR_SEL)) || \
(defined(USB_AUDIO_5_1_CHANNEL_PAIR_SEL) && (0x02 == USB_AUDIO_5_1_CHANNEL_PAIR_SEL)) || \
(defined(USB_AUDIO_3_1_CHANNEL_PAIR_SEL) && (0x02 == USB_AUDIO_3_1_CHANNEL_PAIR_SEL)))
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] =
*(buffer_temp + j + AUDIO_FORMAT_SIZE * 2);
#endif
#if ((defined(USB_AUDIO_7_1_CHANNEL_PAIR_SEL) && (0x03 == USB_AUDIO_7_1_CHANNEL_PAIR_SEL)) || \
(defined(USB_AUDIO_5_1_CHANNEL_PAIR_SEL) && (0x03 == USB_AUDIO_5_1_CHANNEL_PAIR_SEL)))
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] =
*(buffer_temp + j + AUDIO_FORMAT_SIZE * 4);
#elif (defined(USB_AUDIO_7_1_CHANNEL_PAIR_SEL) && (0x04 == USB_AUDIO_7_1_CHANNEL_PAIR_SEL))
audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay] =
*(buffer_temp + j + AUDIO_FORMAT_SIZE * 6);
#endif
play2ChannelLength--;
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay++;
if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
}
else
{
break;
}
}
}
audioSpeakerPreWriteDataCount = g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0];
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0] += (size / (AUDIO_FORMAT_CHANNELS / 2U));
if (audioSpeakerPreWriteDataCount > g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0])
{
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[1] += 1U;
}
#endif /* AUDIO_SPEAKER_MULTI_CHANNEL_PLAY */
#else
uint32_t buffer_length = 0;
remainBufferSpace = g_UsbDeviceAudioSpeaker.audioPlayBufferSize - USB_AudioSpeakerBufferSpaceUsed();
if (size > remainBufferSpace) /* discard the overflow data */
{
if (remainBufferSpace > (AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE))
{
size = (remainBufferSpace - (AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE));
}
else
{
size = 0;
}
}
if (size > 0)
{
buffer_length = g_UsbDeviceAudioSpeaker.tdWriteNumberPlay + size;
if (buffer_length < g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
memcpy((void *)(&audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay]), (void *)(&buffer[0]), size);
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay += size;
}
else
{
uint32_t firstLength =
g_UsbDeviceAudioSpeaker.audioPlayBufferSize - g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
memcpy((void *)(&audioPlayDataBuff[g_UsbDeviceAudioSpeaker.tdWriteNumberPlay]), (void *)(&buffer[0]),
firstLength);
buffer_length = size - firstLength; /* the remain data length */
if ((buffer_length) > 0U)
{
memcpy((void *)(&audioPlayDataBuff[0]), (void *)((uint8_t *)(&buffer[0]) + firstLength), buffer_length);
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = buffer_length;
}
else
{
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
}
}
}
audioSpeakerPreWriteDataCount = g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0];
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0] += size;
if (audioSpeakerPreWriteDataCount > g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0])
{
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[1] += 1U;
}
#endif
}
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
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;
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
if ((g_UsbDeviceAudioSpeaker.attach) && (ep_cb_param->length != (USB_CANCELLED_TRANSFER_LENGTH)))
{
if (!feedbackValueUpdating)
{
*((uint32_t *)&usbAudioFeedBackBuffer[0]) = *((uint32_t *)&audioFeedBackBuffer[0]);
}
error = USB_DeviceSendRequest(deviceHandle, USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT, usbAudioFeedBackBuffer,
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize);
}
return error;
}
#endif
/* 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;
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
if ((g_UsbDeviceAudioSpeaker.attach) && (ep_cb_param->length != (USB_CANCELLED_TRANSFER_LENGTH)))
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
if (USB_SPEED_HIGH == g_UsbDeviceAudioSpeaker.speed) /* high speed and audio 2.0, use low latency solution */
{
if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >=
(g_UsbDeviceAudioSpeaker.audioPlayTransferSize * AUDIO_CLASS_2_0_HS_LOW_LATENCY_TRANSFER_COUNT))
{
g_UsbDeviceAudioSpeaker.startPlayFlag = 1;
}
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if (1U == HS_ISO_OUT_ENDP_INTERVAL)
if (s_microFrameCountIp3511HS < 7U)
{
s_microFrameCountIp3511HS++;
}
else
{
s_microFrameCountIp3511HS = 0U;
}
#elif (2U == HS_ISO_OUT_ENDP_INTERVAL)
if (s_microFrameCountIp3511HS < 6U)
{
s_microFrameCountIp3511HS += 2U;
}
else
{
s_microFrameCountIp3511HS = 0U;
}
#elif (3U == HS_ISO_OUT_ENDP_INTERVAL)
if (s_microFrameCountIp3511HS < 4U)
{
s_microFrameCountIp3511HS += 4U;
}
else
{
s_microFrameCountIp3511HS = 0U;
}
#else
s_microFrameCountIp3511HS = 0;
#endif
#endif
}
else
{
if ((g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= (g_UsbDeviceAudioSpeaker.audioPlayBufferSize / 2U)) &&
(g_UsbDeviceAudioSpeaker.startPlayFlag == 0))
{
g_UsbDeviceAudioSpeaker.startPlayFlag = 1;
}
}
#else
if ((g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= (g_UsbDeviceAudioSpeaker.audioPlayBufferSize / 2U)) &&
(g_UsbDeviceAudioSpeaker.startPlayFlag == 0))
{
g_UsbDeviceAudioSpeaker.startPlayFlag = 1;
}
#endif /* USB_DEVICE_CONFIG_EHCI, USB_DEVICE_CONFIG_LPCIP3511HS */
#else
if ((g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >= (g_UsbDeviceAudioSpeaker.audioPlayBufferSize / 2U)) &&
(g_UsbDeviceAudioSpeaker.startPlayFlag == 0))
{
g_UsbDeviceAudioSpeaker.startPlayFlag = 1;
}
#endif /* USB_DEVICE_CONFIG_AUDIO_CLASS_2_0 */
USB_AudioSpeakerPutBuffer(audioPlayPacket, ep_cb_param->length);
g_UsbDeviceAudioSpeaker.usbRecvCount += ep_cb_param->length;
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)
{
if ((NULL == buffer) || ((*length) > sizeof(s_SetupOutBuffer)))
{
return kStatus_USB_InvalidRequest;
}
*buffer = s_SetupOutBuffer;
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.startPlayFlag = 0;
g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
g_UsbDeviceAudioSpeaker.tdReadNumberPlay = 0;
g_UsbDeviceAudioSpeaker.audioSendCount[0] = 0;
g_UsbDeviceAudioSpeaker.audioSendCount[1] = 0;
g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[0] = 0;
g_UsbDeviceAudioSpeaker.audioSpeakerReadDataCount[1] = 0;
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[0] = 0;
g_UsbDeviceAudioSpeaker.audioSpeakerWriteDataCount[1] = 0;
g_UsbDeviceAudioSpeaker.usbRecvCount = 0;
g_UsbDeviceAudioSpeaker.audioSendTimes = 0;
g_UsbDeviceAudioSpeaker.usbRecvTimes = 0;
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 0;
g_UsbDeviceAudioSpeaker.speakerReservedSpace = 0;
g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput = 0;
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
g_UsbDeviceAudioSpeaker.audioPllTicksPrev = 0U;
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
(defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)))
g_UsbDeviceAudioSpeaker.usbFroTicksPrev = 0U;
g_UsbDeviceAudioSpeaker.usbFroTicksEma = AUDIO_FRO_USB_SOF_INTERVAL_TICK_COUNT;
g_UsbDeviceAudioSpeaker.usbFroTickEmaFrac = 0U;
g_UsbDeviceAudioSpeaker.usbFroTickBasedPrecision = AUDIO_USB_FRO_TRIM_TICK_BASED_PRECISION;
#endif
g_UsbDeviceAudioSpeaker.audioPllTicksEma = AUDIO_PLL_USB_SOF_INTERVAL_TICK_COUNT;
g_UsbDeviceAudioSpeaker.audioPllTickEmaFrac = 0U;
g_UsbDeviceAudioSpeaker.audioPllTickBasedPrecision = AUDIO_PLL_FRACTION_TICK_BASED_PRECISION;
g_UsbDeviceAudioSpeaker.stopDataLengthAudioAdjust = 0U;
#else
g_UsbDeviceAudioSpeaker.firstCalculateFeedback = 0U;
g_UsbDeviceAudioSpeaker.lastFrameCount = 0U;
g_UsbDeviceAudioSpeaker.currentFrameCount = 0U;
g_UsbDeviceAudioSpeaker.feedbackDiscardFlag = 0U;
g_UsbDeviceAudioSpeaker.feedbackDiscardTimes = AUDIO_SPEAKER_FEEDBACK_DISCARD_COUNT;
/* use the last saved feedback value */
if (g_UsbDeviceAudioSpeaker.lastFeedbackValue)
{
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, g_UsbDeviceAudioSpeaker.lastFeedbackValue);
}
#endif
}
/*!
* @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_InvalidRequest;
uint8_t *temp8 = (uint8_t *)param;
uint8_t count = 0U;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
for (count = 0U; count < USB_AUDIO_SPEAKER_INTERFACE_COUNT; count++)
{
g_UsbDeviceAudioSpeaker.currentInterfaceAlternateSetting[count] = 0U;
}
/* reset audio speaker status to be the initialized status */
USB_DeviceAudioSpeakerStatusReset();
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
/* reset the the last feedback value */
g_UsbDeviceAudioSpeaker.lastFeedbackValue = 0U;
#endif
g_UsbDeviceAudioSpeaker.attach = 0U;
g_UsbDeviceAudioSpeaker.currentConfiguration = 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)
{
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
g_UsbDeviceAudioSpeaker.currentStreamOutMaxPacketSize = (HS_ISO_OUT_ENDP_PACKET_SIZE);
#else
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 /* USB_DEVICE_AUDIO_USE_SYNC_MODE */
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_16_16);
#endif
/* high speed and audio 2.0, audio play interval is set by HS EP packet size */
#if ((defined(USB_AUDIO_CHANNEL7_1) && (USB_AUDIO_CHANNEL7_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL5_1) && (USB_AUDIO_CHANNEL5_1 > 0U)) || \
(defined(USB_AUDIO_CHANNEL3_1) && (USB_AUDIO_CHANNEL3_1 > 0U)))
#if defined(AUDIO_SPEAKER_MULTI_CHANNEL_PLAY) && (AUDIO_SPEAKER_MULTI_CHANNEL_PLAY > 0U)
g_UsbDeviceAudioSpeaker.audioPlayTransferSize =
(HS_ISO_OUT_ENDP_PACKET_SIZE / AUDIO_FORMAT_SIZE / AUDIO_FORMAT_CHANNELS) * 4U *
8U; /* TDM accepts 32-bit width */
#else
g_UsbDeviceAudioSpeaker.audioPlayTransferSize =
HS_ISO_OUT_ENDP_PACKET_SIZE / (AUDIO_FORMAT_CHANNELS / 2U);
#endif
#else
g_UsbDeviceAudioSpeaker.audioPlayTransferSize = HS_ISO_OUT_ENDP_PACKET_SIZE;
#endif
/* use short play buffer size, only use two elements */
g_UsbDeviceAudioSpeaker.audioPlayBufferSize =
AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME * AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT;
#else
/* high speed and audio 1.0, audio play interval is 1 ms using this play size */
g_UsbDeviceAudioSpeaker.audioPlayTransferSize = AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
/* use the whole play buffer size */
g_UsbDeviceAudioSpeaker.audioPlayBufferSize =
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT_NORMAL * AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_10_14);
#endif
#endif /* USB_DEVICE_CONFIG_AUDIO_CLASS_2_0 */
}
else
{
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize = FS_ISO_FEEDBACK_ENDP_PACKET_SIZE;
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_10_14);
#endif
/* full speed, audio play interval is 1 ms using this play size */
g_UsbDeviceAudioSpeaker.audioPlayTransferSize = AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
/* use the whole play buffer size */
g_UsbDeviceAudioSpeaker.audioPlayBufferSize =
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT_NORMAL * AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
}
#else
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize = FS_ISO_FEEDBACK_ENDP_PACKET_SIZE;
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_10_14);
#endif
/* full speed, audio play interval is 1 ms using this play size */
g_UsbDeviceAudioSpeaker.audioPlayTransferSize = AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
/* use the whole play buffer size */
g_UsbDeviceAudioSpeaker.audioPlayBufferSize =
AUDIO_SPEAKER_DATA_WHOLE_BUFFER_COUNT_NORMAL * AUDIO_PLAY_BUFFER_SIZE_ONE_FRAME;
#endif /* USB_DEVICE_CONFIG_EHCI, USB_DEVICE_CONFIG_LPCIP3511HS */
}
break;
case kUSB_DeviceEventSetConfiguration:
if (0U == (*temp8))
{
g_UsbDeviceAudioSpeaker.attach = 0U;
g_UsbDeviceAudioSpeaker.currentConfiguration = 0U;
error = kStatus_USB_Success;
error = kStatus_USB_Success;
}
else if (USB_AUDIO_SPEAKER_CONFIGURE_INDEX == (*temp8))
{
g_UsbDeviceAudioSpeaker.attach = 1U;
g_UsbDeviceAudioSpeaker.currentConfiguration = *temp8;
error = kStatus_USB_Success;
error = kStatus_USB_Success;
}
else
{
/* no action, invalid request */
}
break;
case kUSB_DeviceEventSetInterface:
if (g_UsbDeviceAudioSpeaker.attach)
{
uint8_t interface = (*temp8) & 0xFF;
uint8_t alternateSetting = g_UsbDeviceInterface[interface];
if (USB_AUDIO_SPEAKER_STREAM_INTERFACE_INDEX == interface)
{
if (alternateSetting < USB_AUDIO_SPEAKER_STREAM_INTERFACE_ALTERNATE_COUNT)
{
if (g_UsbDeviceAudioSpeaker.currentInterfaceAlternateSetting[interface] == alternateSetting)
{
error = kStatus_USB_Success;
break;
}
if (USB_AUDIO_SPEAKER_STREAM_INTERFACE_ALTERNATE_0 == alternateSetting)
{
error = USB_DeviceDeinitEndpoint(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_STREAM_ENDPOINT | (USB_OUT << 7U));
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
g_UsbDeviceAudioSpeaker.stopDataLengthAudioAdjust = 1U;
#endif
}
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)
{
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
epInitStruct.maxPacketSize = (HS_ISO_OUT_ENDP_PACKET_SIZE);
epInitStruct.interval = HS_ISO_OUT_ENDP_INTERVAL;
#else
epInitStruct.maxPacketSize =
(HS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
epInitStruct.interval = HS_ISO_OUT_ENDP_INTERVAL;
#endif
}
else
{
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
epInitStruct.maxPacketSize = (FS_ISO_OUT_ENDP_PACKET_SIZE);
epInitStruct.interval = FS_ISO_OUT_ENDP_INTERVAL;
#else
epInitStruct.maxPacketSize =
(FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE);
epInitStruct.interval = FS_ISO_OUT_ENDP_INTERVAL;
#endif
}
USB_DeviceInitEndpoint(g_UsbDeviceAudioSpeaker.deviceHandle, &epInitStruct, &epCallback);
error = USB_DeviceRecvRequest(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_STREAM_ENDPOINT, &audioPlayPacket[0],
g_UsbDeviceAudioSpeaker.currentStreamOutMaxPacketSize);
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
g_UsbDeviceAudioSpeaker.stopDataLengthAudioAdjust = 0U;
#else
epCallback.callbackFn = USB_DeviceAudioIsoIn;
epCallback.callbackParam = handle;
epInitStruct.zlt = 0U;
epInitStruct.interval = 1U;
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);
if (!feedbackValueUpdating)
{
*((uint32_t *)&usbAudioFeedBackBuffer[0]) = *((uint32_t *)&audioFeedBackBuffer[0]);
}
error = USB_DeviceSendRequest(g_UsbDeviceAudioSpeaker.deviceHandle,
USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT, usbAudioFeedBackBuffer,
g_UsbDeviceAudioSpeaker.currentFeedbackMaxPacketSize);
#endif
}
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#else
/* usb host stops the speaker, so there is no need for feedback */
if ((1U == g_UsbDeviceAudioSpeaker.startPlayFlag) &&
(USB_AUDIO_SPEAKER_STREAM_INTERFACE_ALTERNATE_0 == alternateSetting))
{
g_UsbDeviceAudioSpeaker.stopFeedbackUpdate = 1U;
}
/* usb host start the speaker, discard the feedback for AUDIO_SPEAKER_FEEDBACK_DISCARD_COUNT
* times */
if (USB_AUDIO_SPEAKER_STREAM_INTERFACE_ALTERNATE_1 == alternateSetting)
{
g_UsbDeviceAudioSpeaker.stopFeedbackUpdate = 0U;
g_UsbDeviceAudioSpeaker.feedbackDiscardFlag = 1U;
g_UsbDeviceAudioSpeaker.feedbackDiscardTimes = AUDIO_SPEAKER_FEEDBACK_DISCARD_COUNT;
}
#endif
g_UsbDeviceAudioSpeaker.currentInterfaceAlternateSetting[interface] = alternateSetting;
}
}
else if (USB_AUDIO_CONTROL_INTERFACE_INDEX == interface)
{
if (alternateSetting < USB_AUDIO_CONTROL_INTERFACE_ALTERNATE_COUNT)
{
g_UsbDeviceAudioSpeaker.currentInterfaceAlternateSetting[interface] = alternateSetting;
error = kStatus_USB_Success;
}
}
else
{
/* no action, invalid request */
}
}
break;
default:
break;
}
return error;
}
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
#if (((defined USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS)) || \
((defined USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI)))
void CTIMER_SOF_TOGGLE_HANDLER_FRO(uint32_t i)
{
uint32_t currentCtCap = 0, pllCountPeriod = 0;
uint32_t usedSpace = 0;
static int32_t pllCount = 0, pllDiff = 0;
static int32_t err, abs_err;
uint32_t up_change = 0;
uint32_t down_change = 0;
static uint32_t delay_adj_up = 0;
static uint32_t delay_adj_down = 0;
static uint32_t FroPreUsbRecvCount = 0U;
if (CTIMER_GetStatusFlags(CTIMER1) & (1 << 4U))
{
/* Clear interrupt flag.*/
CTIMER_ClearStatusFlags(CTIMER1, (1 << 4U));
}
if (g_UsbDeviceAudioSpeaker.froTrimIntervalCount != AUDIO_FRO_ADJUST_INTERVAL)
{
g_UsbDeviceAudioSpeaker.froTrimIntervalCount++;
return;
}
g_UsbDeviceAudioSpeaker.froTrimIntervalCount = 1;
currentCtCap = CTIMER1->CR[0];
pllCountPeriod = currentCtCap - g_UsbDeviceAudioSpeaker.usbFroTicksPrev;
g_UsbDeviceAudioSpeaker.usbFroTicksPrev = currentCtCap;
pllCount = pllCountPeriod;
if (g_UsbDeviceAudioSpeaker.attach)
{
if (abs(pllCount - AUDIO_FRO_USB_SOF_INTERVAL_TICK_COUNT) < AUDIO_FRO_USB_SOF_INTERVAL_VALID_DEVIATION)
{
pllDiff = pllCount - g_UsbDeviceAudioSpeaker.usbFroTicksEma;
g_UsbDeviceAudioSpeaker.usbFroTickEmaFrac += (pllDiff % 8);
g_UsbDeviceAudioSpeaker.usbFroTicksEma += (pllDiff / 8) + g_UsbDeviceAudioSpeaker.usbFroTickEmaFrac / 8;
g_UsbDeviceAudioSpeaker.usbFroTickEmaFrac = (g_UsbDeviceAudioSpeaker.usbFroTickEmaFrac % 8);
err = g_UsbDeviceAudioSpeaker.usbFroTicksEma - AUDIO_FRO_USB_SOF_INTERVAL_TICK_COUNT;
abs_err = abs(err);
if (abs_err >= g_UsbDeviceAudioSpeaker.usbFroTickBasedPrecision)
{
if (err > 0)
{
down_change = 1;
}
else
{
up_change = 1;
}
}
if (g_UsbDeviceAudioSpeaker.startPlayFlag)
{
/* if USB transfer stops, can not use data length to do adjustment */
if (0U == g_UsbDeviceAudioSpeaker.stopDataLengthAudioAdjust)
{
/* USB is transferring */
if (FroPreUsbRecvCount != g_UsbDeviceAudioSpeaker.usbRecvCount)
{
FroPreUsbRecvCount = g_UsbDeviceAudioSpeaker.usbRecvCount;
usedSpace = USB_AudioSpeakerBufferSpaceUsed();
if ((usedSpace + (g_UsbDeviceAudioSpeaker.audioPlayTransferSize *
AUDIO_SYNC_DATA_BASED_ADJUST_THRESHOLD)) >=
g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
if (delay_adj_up == 0)
{
delay_adj_down = 0;
delay_adj_up = AUDIO_FRO_TRIM_DATA_BASED_INTERVAL;
up_change = 1;
}
else
{
delay_adj_up--;
}
}
else if (usedSpace <= (g_UsbDeviceAudioSpeaker.audioPlayTransferSize *
AUDIO_SYNC_DATA_BASED_ADJUST_THRESHOLD))
{
if (delay_adj_down == 0)
{
delay_adj_up = 0;
delay_adj_down = AUDIO_FRO_TRIM_DATA_BASED_INTERVAL;
down_change = 1;
}
else
{
delay_adj_down--;
}
}
else
{
/* no action */
}
}
}
}
}
if (down_change)
{
audio_fro_trim_down();
}
if (up_change)
{
audio_fro_trim_up();
}
}
}
#endif /* USB_DEVICE_CONFIG_LPCIP3511FS USB_DEVICE_CONFIG_KHCI*/
void CTIMER_SOF_TOGGLE_HANDLER_PLL(uint32_t i)
{
uint32_t currentCtCap = 0, pllCountPeriod = 0, pll_change = 0;
uint32_t usedSpace = 0;
static int32_t pllCount = 0, pllDiff = 0;
static int32_t err, abs_err;
static uint32_t delay_adj_up = 0;
static uint32_t delay_adj_down = 0;
static uint32_t PllPreUsbRecvCount = 0U;
if (CTIMER_GetStatusFlags(CTIMER0) & (1 << 4U))
{
/* Clear interrupt flag.*/
CTIMER_ClearStatusFlags(CTIMER0, (1 << 4U));
}
if (g_UsbDeviceAudioSpeaker.speakerIntervalCount != AUDIO_PLL_ADJUST_INTERVAL)
{
g_UsbDeviceAudioSpeaker.speakerIntervalCount++;
return;
}
g_UsbDeviceAudioSpeaker.speakerIntervalCount = 1;
currentCtCap = CTIMER0->CR[0];
pllCountPeriod = currentCtCap - g_UsbDeviceAudioSpeaker.audioPllTicksPrev;
g_UsbDeviceAudioSpeaker.audioPllTicksPrev = currentCtCap;
pllCount = pllCountPeriod;
if (g_UsbDeviceAudioSpeaker.attach)
{
if (abs(pllCount - AUDIO_PLL_USB_SOF_INTERVAL_TICK_COUNT) < AUDIO_PLL_USB_SOF_INTERVAL_VALID_DEVIATION)
{
pllDiff = pllCount - g_UsbDeviceAudioSpeaker.audioPllTicksEma;
g_UsbDeviceAudioSpeaker.audioPllTickEmaFrac += (pllDiff % 8);
g_UsbDeviceAudioSpeaker.audioPllTicksEma += (pllDiff / 8) + g_UsbDeviceAudioSpeaker.audioPllTickEmaFrac / 8;
g_UsbDeviceAudioSpeaker.audioPllTickEmaFrac = (g_UsbDeviceAudioSpeaker.audioPllTickEmaFrac % 8);
err = g_UsbDeviceAudioSpeaker.audioPllTicksEma - AUDIO_PLL_USB_SOF_INTERVAL_TICK_COUNT;
abs_err = abs(err);
if (abs_err >= g_UsbDeviceAudioSpeaker.audioPllTickBasedPrecision)
{
if (err > 0)
{
g_UsbDeviceAudioSpeaker.curAudioPllFrac -=
abs_err / g_UsbDeviceAudioSpeaker.audioPllTickBasedPrecision;
}
else
{
g_UsbDeviceAudioSpeaker.curAudioPllFrac +=
abs_err / g_UsbDeviceAudioSpeaker.audioPllTickBasedPrecision;
}
pll_change = 1;
}
if (0U != g_UsbDeviceAudioSpeaker.startPlayFlag)
{
/* if USB transfer stops, can not use data length to do adjustment */
if (0U == g_UsbDeviceAudioSpeaker.stopDataLengthAudioAdjust)
{
/* USB is transferring */
if (PllPreUsbRecvCount != g_UsbDeviceAudioSpeaker.usbRecvCount)
{
PllPreUsbRecvCount = g_UsbDeviceAudioSpeaker.usbRecvCount;
usedSpace = USB_AudioSpeakerBufferSpaceUsed();
if (usedSpace <=
(g_UsbDeviceAudioSpeaker.audioPlayTransferSize * AUDIO_SYNC_DATA_BASED_ADJUST_THRESHOLD))
{
if (delay_adj_down == 0)
{
delay_adj_up = 0;
delay_adj_down = AUDIO_PLL_ADJUST_DATA_BASED_INTERVAL;
g_UsbDeviceAudioSpeaker.curAudioPllFrac -= AUDIO_PLL_ADJUST_DATA_BASED_STEP;
pll_change = 1;
}
else
{
delay_adj_down--;
}
}
else if ((usedSpace + (g_UsbDeviceAudioSpeaker.audioPlayTransferSize *
AUDIO_SYNC_DATA_BASED_ADJUST_THRESHOLD)) >=
g_UsbDeviceAudioSpeaker.audioPlayBufferSize)
{
if (delay_adj_up == 0)
{
delay_adj_down = 0;
delay_adj_up = AUDIO_PLL_ADJUST_DATA_BASED_INTERVAL;
g_UsbDeviceAudioSpeaker.curAudioPllFrac += AUDIO_PLL_ADJUST_DATA_BASED_STEP;
pll_change = 1;
}
else
{
delay_adj_up--;
}
}
}
}
}
}
if (pll_change)
{
USB_AudioPllChange();
}
}
}
#endif /* USB_DEVICE_AUDIO_USE_SYNC_MODE */
/*!
* @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 */
/*Initialize audio interface and codec.*/
HAL_AudioTxInit((hal_audio_handle_t)audioTxHandle, &audioTxConfig);
BOARD_Codec_Init();
AUDIO_DMA_EDMA_Start();
#if defined(USB_DEVICE_AUDIO_USE_SYNC_MODE) && (USB_DEVICE_AUDIO_USE_SYNC_MODE > 0U)
CTIMER_CaptureInit();
#else
AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, AUDIO_SAMPLING_RATE_TO_10_14);
#endif
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();
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
USB_DeviceRun(g_UsbDeviceAudioSpeaker.deviceHandle);
}
void USB_AudioCodecTask(void)
{
if (g_UsbDeviceAudioSpeaker.codecTask & MUTE_CODEC_TASK)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute20);
#else
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute);
#endif
g_UsbDeviceAudioSpeaker.codecTask &= ~MUTE_CODEC_TASK;
}
if (g_UsbDeviceAudioSpeaker.codecTask & UNMUTE_CODEC_TASK)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute20);
#else
usb_echo("Set Cur Mute : %x\r\n", g_UsbDeviceAudioSpeaker.curMute);
#endif
g_UsbDeviceAudioSpeaker.codecTask &= ~UNMUTE_CODEC_TASK;
}
if (g_UsbDeviceAudioSpeaker.codecTask & VOLUME_CHANGE_TASK)
{
#if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
usb_echo("Set Cur Volume : %x\r\n",
(uint16_t)(g_UsbDeviceAudioSpeaker.curVolume20[1] << 8U) | g_UsbDeviceAudioSpeaker.curVolume20[0]);
#else
usb_echo("Set Cur Volume : %x\r\n",
(uint16_t)(g_UsbDeviceAudioSpeaker.curVolume[1] << 8U) | g_UsbDeviceAudioSpeaker.curVolume[0]);
#endif
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(__ARMCC_VERSION)) || defined(__GNUC__)
int main(void)
#else
void main(void)
#endif
{
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
CLOCK_InitAudioPll(&audioPllConfig);
BOARD_InitDebugConsole();
/*Clock setting for LPI2C*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, DEMO_LPI2C_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, DEMO_LPI2C_CLOCK_SOURCE_DIVIDER);
/*Clock setting for SAI1*/
CLOCK_SetMux(kCLOCK_Sai1Mux, DEMO_SAI1_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Sai1PreDiv, DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER);
CLOCK_SetDiv(kCLOCK_Sai1Div, DEMO_SAI1_CLOCK_SOURCE_DIVIDER);
/*Enable MCLK clock*/
BOARD_EnableSaiMclkOutput(true);
dmaMuxTxConfig.dmaMuxConfig.dmaMuxInstance = DEMO_DMAMUX_INDEX;
dmaMuxTxConfig.dmaMuxConfig.dmaRequestSource = DEMO_SAI_TX_SOURCE;
dmaTxConfig.dmaMuxConfig = &dmaMuxTxConfig;
dmaTxConfig.instance = DEMO_DMA_INDEX;
dmaTxConfig.channel = DEMO_DMA_TX_CHANNEL;
dmaTxConfig.priority = kHAL_AudioDmaChannelPriorityDefault;
dmaTxConfig.dmaChannelMuxConfig = NULL;
ipTxConfig.sai.lineMask = 1U << 0U;
ipTxConfig.sai.syncMode = kHAL_AudioSaiModeAsync;
audioTxConfig.dmaConfig = &dmaTxConfig;
audioTxConfig.ipConfig = &ipTxConfig;
audioTxConfig.instance = DEMO_SAI_INSTANCE_INDEX;
audioTxConfig.srcClock_Hz = DEMO_SAI_CLK_FREQ;
audioTxConfig.sampleRate_Hz = (uint32_t)kHAL_AudioSampleRate48KHz;
audioTxConfig.msaterSlave = kHAL_AudioMaster;
audioTxConfig.bclkPolarity = kHAL_AudioSampleOnRisingEdge;
audioTxConfig.frameSyncWidth = kHAL_AudioFrameSyncWidthHalfFrame;
audioTxConfig.frameSyncPolarity = kHAL_AudioBeginAtFallingEdge;
audioTxConfig.dataFormat = kHAL_AudioDataFormatI2sClassic;
audioTxConfig.fifoWatermark = (uint8_t)(FSL_FEATURE_SAI_FIFO_COUNTn(DEMO_SAI) - 1);
audioTxConfig.bitWidth = (uint8_t)kHAL_AudioWordWidth16bits;
audioTxConfig.lineChannels = kHAL_AudioStereo;
APPInit();
while (1)
{
USB_AudioCodecTask();
USB_AudioSpeakerResetTask();
#if USB_DEVICE_CONFIG_USE_TASK
USB_DeviceTaskFn(g_UsbDeviceAudioSpeaker.deviceHandle);
#endif
}
}