📄 uacsys.c
字号:
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include <string.h>
#include "DrvUSB.h"
#include "UACSys.h"
#include "UAC_API.h"
//#define DBG_PRINTF printf
#define DBG_PRINTF(...)
#define Maximum(a,b) ((a)>(b) ? (a) : (b))
#define Minimum(a,b) ((a)<(b) ? (a) : (b))
S_UAC_DEVICE g_UAC_sDevice;
/* The UAC control and data callback */
UAC_DEVICE_ENABLE pfnUacDeviceEnable;
UAC_DEVICE_DISABLE pfnUacDeviceDisable;
UAC_ISO_IN pfnUacSendRecData;
UAC_ISO_OUT pfnUacGetPlayData;
void UAC_EpNum1InEvent(void * pVoid);
void UAC_EpNum2OutEvent(void * pVoid);
void UAC_CtrlSetupSetInterface(void * pVoid);
void UAC_CtrlGetDescriptorIn(void * pVoid);
void UAC_CtrlGetDescriptorOut(void * pVoid);
#define CFG_ISO_IN (CFG_ISOCH | ISO_IN_EP_NUM | CFG_EPT_IN)
#define CFG_ISO_OUT (CFG_ISOCH | ISO_OUT_EP_NUM | CFG_EPT_OUT)
/* Endpoint description */
S_DRVUSB_EP_CTRL sEpDescription[] =
{
{CTRL_EP_NUM | EP_INPUT, UAC_MAX_PACKET_SIZE_EP0, NULL},
{CTRL_EP_NUM | EP_OUTPUT, UAC_MAX_PACKET_SIZE_EP0, NULL},
{ISO_IN_EP_NUM | EP_INPUT, ISO_IN_MXPLD, NULL},
{ISO_OUT_EP_NUM | EP_OUTPUT, ISO_OUT_MXPLD, NULL},
{0,0,0}
};
//bus event call back function
S_DRVUSB_EVENT_PROCESS g_sBusOps[6] =
{
{NULL, NULL},//attach
{NULL, NULL},//detach
{DrvUSB_BusResetCallback, &g_UAC_sDevice},//bus reset
{NULL, NULL},//bus suspend
{NULL, NULL},//bus resume
{DrvUSB_CtrlSetupAck, &g_UAC_sDevice},//setup
};
//USB event call back function
S_DRVUSB_EVENT_PROCESS g_sUsbOps[12] =
{
{DrvUSB_CtrlDataInAck, &g_UAC_sDevice},
{DrvUSB_CtrlDataOutAck, &g_UAC_sDevice},//ctrl pipe0
{UAC_EpNum1InEvent, &g_UAC_sDevice},
{NULL, NULL},//endpoint address 1
{NULL, NULL},
{UAC_EpNum2OutEvent, &g_UAC_sDevice},//endpoint address 2
{NULL, NULL},
{NULL, NULL},//endpoint address 3
{NULL, NULL},
{NULL, NULL},//endpoint address 4
{NULL, NULL},
{NULL, NULL},//endpoint address 5
};
/* ctrl pipe call back. */
/* it will be call by DrvUSB_CtrlSetupAck, DrvUSB_CtrlDataInAck and DrvUSB_CtrlDataOutAck */
/* if in ack handler and out ack handler is 0, default handler will be called */
S_DRVUSB_CTRL_CALLBACK_ENTRY g_asCtrlCallbackEntry[] =
{ /* request type,command ,setup ack handler , in ack handler ,out ack handler, parameter */
{REQ_STANDARD, SET_ADDRESS, DrvUSB_CtrlSetupSetAddress, DrvUSB_CtrlDataInSetAddress, NULL, &g_UAC_sDevice},
{REQ_STANDARD, CLEAR_FEATURE, DrvUSB_CtrlSetupClearSetFeature, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, SET_FEATURE, DrvUSB_CtrlSetupClearSetFeature, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, GET_CONFIGURATION, DrvUSB_CtrlSetupGetConfiguration, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, GET_STATUS, DrvUSB_CtrlSetupGetStatus, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, GET_INTERFACE, UAC_CtrlSetupGetInterface, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, SET_INTERFACE, UAC_CtrlSetupSetInterface, NULL, NULL, &g_UAC_sDevice},
{REQ_STANDARD, GET_DESCRIPTOR, UAC_CtrlSetupGetDescriptor, UAC_CtrlGetDescriptorIn, UAC_CtrlGetDescriptorOut, &g_UAC_sDevice},
{REQ_STANDARD, SET_CONFIGURATION, DrvUSB_CtrlSetupSetConfiguration, NULL, NULL, &g_UAC_sDevice},
{REQ_CLASS, UAC_SET_CUR, UAC_ClassCtrlSetCurRequest, NULL, UAC_ClassCtrlSetCurOutData, &g_UAC_sDevice},
{REQ_CLASS, UAC_GET_CUR, UAC_ClassCtrlGetCurRequest, NULL, NULL, &g_UAC_sDevice},
{REQ_CLASS, UAC_GET_MIN, UAC_ClassCtrlGetMinRequest, NULL, NULL, &g_UAC_sDevice},
{REQ_CLASS, UAC_GET_MAX, UAC_ClassCtrlGetMaxRequest, NULL, NULL, &g_UAC_sDevice},
{REQ_CLASS, UAC_GET_RES, UAC_ClassCtrlGetResRequest, NULL, NULL, &g_UAC_sDevice},
};
/* -128 ~ 24 dB in 2 dB step in Q12. Formula: x = 10.^([-128:2:24]/20) */
uint32_t gVolumeTbl[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,3,3,4,5,6,8,10,13,16,21,26,33,41,52,65,82,103,130,163,205,258,325,410,516,649,817,1029,1295,1631,2053,2584,3254,4096,5157,6492,8173,10289,12953,16306,20529,25844,32536,40960,51566,64917
};
/* The structure registered to USB driver */
S_DRVUSB_CLASS sUacUsbClass =
{
(void *)&g_UAC_sDevice,
(PFN_DRVUSB_CALLBACK)UAC_Reset,
UAC_IsCfgId
};
static volatile uint16_t s_u16Len;
static volatile uint16_t s_u16SendLength, s_u16CurPtr, s_u16Toggle;
static volatile uint8_t s_u8ConfigLenOver64;
static const uint8_t * gpu8UsbBuf = 0;
static uint32_t gu32BytesInUsbBuf = 0;
static int8_t gIsOverRequest = 0;
void UAC_CtrlSetupGetInterface(void * pVoid)
{
S_UAC_DEVICE *psDevice = (S_UAC_DEVICE *) pVoid;
DrvUSB_DataIn(0, &psDevice->u8AlternativeSetting, 1);
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UAC_CtrlSetupSetInterface() */
/* */
/* DESCRIPTION */
/* Setup ACK handler for SET_INTERFACE request */
/* */
/* INPUTS */
/* pVoid The function point of UAC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UAC_CtrlSetupSetInterface(void * pVoid)
{
S_DRVUSB_DEVICE *psUSBDevice = &gsUsbDevice;
S_UAC_DEVICE *psDevice = (S_UAC_DEVICE *)pVoid;
psDevice->u8AlternativeSetting = psUSBDevice->au8Setup[2];
if (psUSBDevice->au8Setup[4] == 1)
{
/* Audio Iso IN interface */
if (psDevice->u8AlternativeSetting == 1)
{
psDevice->u8AudioState = UAC_START_AUDIO_RECORD;
DrvUSB_DataIn(ISO_IN_EP_NUM, NULL, 0);
pfnUacDeviceEnable(UAC_MICROPHONE, 0);
}
else if (psDevice->u8AlternativeSetting == 0)
{
pfnUacDeviceDisable(UAC_MICROPHONE);
DrvUSB_DataIn(ISO_IN_EP_NUM, NULL, 0);
psDevice->u8AudioState = UAC_STOP_AUDIO_RECORD;
}
}
else if (psUSBDevice->au8Setup[4] == 2)
{
/* Audio Iso OUT interface */
if (psDevice->u8AlternativeSetting == 1)
{
DrvUSB_DataOutTrigger(ISO_OUT_EP_NUM, psDevice->u8IsoOutPacketSize);
pfnUacDeviceEnable(UAC_SPEAKER, 0);
psDevice->u8IsoOutToggle = 0;
}
else
{
pfnUacDeviceDisable(UAC_SPEAKER);
}
}
DrvUSB_DataIn(0, NULL, 0);
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UAC_EpNum1InEvent() */
/* */
/* DESCRIPTION */
/* Call back function for ISO pipe IN ack of endpoint number 1. */
/* */
/* INPUTS */
/* pVoid The function point of UAC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UAC_EpNum1InEvent(void * pVoid)
{
uint32_t u32PacketType;
S_UAC_DEVICE *psDevice = (S_UAC_DEVICE *) pVoid;
S_DRVUSB_DEVICE *psUsbDevice;
int32_t u32EpId;
psUsbDevice = (S_DRVUSB_DEVICE *)psDevice->device;
u32EpId = DrvUSB_GetEpId(ISO_IN_EP_NUM | 0x80);
u32PacketType = ((psUsbDevice->u32EPSTS >> (4 + u32EpId * 3)) & EPSTS_STS);
/* Confirm it is ISO in event */
if (u32PacketType == EPSTS_ISO)
{
if (psDevice->u8AudioState == UAC_START_AUDIO_RECORD)
{
pfnUacDeviceEnable(UAC_MICROPHONE, 1);
psDevice->u8AudioState = UAC_PROCESSING_AUDIO_RECORD;
}
else if (psDevice->u8AudioState == UAC_PROCESSING_AUDIO_RECORD)
{
psDevice->u8AudioState = UAC_BUSY_AUDIO_RECORD;
}
if (psDevice->u8AudioState == UAC_BUSY_AUDIO_RECORD)
{
pfnUacSendRecData();
}
else
{
u32EpId = DrvUSB_GetEpIdentity(ISO_IN_EP_NUM, EP_INPUT);
_DRVUSB_TRIG_EP(u32EpId, 0);
}
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UAC_EpNum2OutEvent() */
/* */
/* DESCRIPTION */
/* Call back function for ISO pipe OUT ack of endpoint number 2. */
/* */
/* INPUTS */
/* pVoid The function point of UAC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UAC_EpNum2OutEvent(void * pVoid)
{
uint32_t tmp;
uint8_t *pcmBuf;
uint32_t u32EpId;
S_UAC_DEVICE *psDevice = (S_UAC_DEVICE *) pVoid;
pcmBuf = DrvUSB_GetOutData(ISO_OUT_EP_NUM, &tmp);
pfnUacGetPlayData((int16_t *)pcmBuf, (int16_t)tmp);
u32EpId = DrvUSB_GetEpIdentity(ISO_OUT_EP_NUM, EP_OUTPUT);
_DRVUSB_SET_EP_BUF(u32EpId, (uint32_t)(pcmBuf));
_DRVUSB_TRIG_EP(u32EpId, ISO_OUT_MXPLD);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -