📄 uvcsys.c
字号:
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include <string.h>
#include "DrvUSB.h"
#include "UVCSys.h"
#include "UVC_API.h"
#define Maximum(a,b) ((a)>(b) ? (a) : (b))
#define Minimum(a,b) ((a)<(b) ? (a) : (b))
S_UVC_DEVICE g_UVC_sDevice;
/* The UVC control and data callback */
UVC_DEVICE_ENABLE pfnUvcDeviceEnable;
UVC_DEVICE_DISABLE pfnUvcDeviceDisable;
UVC_ISO_IN pfnUvcSendData;
UVC_ISO_OUT pfnUvcGetPlayData;
void UVC_EpNum1InEvent(void * pVoid);
void UVC_EpNum2OutEvent(void * pVoid);
void UVC_CtrlSetupSetInterface(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)
__align(4) VIDEOSTREAMCMDDATA VideoStreamCmdCtlData;
/* Endpoint description */
S_DRVUSB_EP_CTRL sEpDescription[] =
{
{CTRL_EP_NUM | EP_INPUT, UVC_MAX_PACKET_SIZE_EP0, NULL},
{CTRL_EP_NUM | EP_OUTPUT, UVC_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_UVC_sDevice},//bus reset
{NULL, NULL},//bus suspend
{NULL, NULL},//bus resume
{DrvUSB_CtrlSetupAck, &g_UVC_sDevice},//setup
};
//USB event call back function
S_DRVUSB_EVENT_PROCESS g_sUsbOps[12] =
{
{DrvUSB_CtrlDataInAck, &g_UVC_sDevice},
{DrvUSB_CtrlDataOutAck, &g_UVC_sDevice},//ctrl pipe0
{UVC_EpNum1InEvent, &g_UVC_sDevice},
{NULL, NULL},//endpoint address 1
{NULL, NULL},
{UVC_EpNum2OutEvent, &g_UVC_sDevice},//endpoint address 2
{NULL, NULL},
{NULL, NULL},//endpoint address 3
{UVC_EpNum1InEvent, &g_UVC_sDevice},
{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[64] =
{ /* request type,command ,setup ack handler , in ack handler ,out ack handler, parameter */
{REQ_STANDARD, SET_ADDRESS, DrvUSB_CtrlSetupSetAddress, DrvUSB_CtrlDataInSetAddress, NULL, &g_UVC_sDevice},
{REQ_STANDARD, CLEAR_FEATURE, DrvUSB_CtrlSetupClearSetFeature, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, SET_FEATURE, DrvUSB_CtrlSetupClearSetFeature, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, GET_CONFIGURATION, DrvUSB_CtrlSetupGetConfiguration, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, GET_STATUS, DrvUSB_CtrlSetupGetStatus, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, GET_INTERFACE, UVC_CtrlSetupGetInterface, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, SET_INTERFACE, UVC_CtrlSetupSetInterface, NULL, NULL, &g_UVC_sDevice},
{REQ_STANDARD, GET_DESCRIPTOR, UVC_CtrlSetupGetDescriptor, UVC_CtrlDataInGetDescriptor, NULL, &g_UVC_sDevice},
{REQ_STANDARD, SET_CONFIGURATION, DrvUSB_CtrlSetupSetConfiguration, NULL, NULL, &g_UVC_sDevice},
{REQ_CLASS, UVC_SET_CUR, UVC_ClassCtrlSetCurRequest, NULL, UVC_ClassCtrlSetCurOutData, &g_UVC_sDevice},
{REQ_CLASS, UVC_GET_CUR, UVC_ClassCtrlGetCurRequest, NULL, NULL, &g_UVC_sDevice},
{REQ_CLASS, UVC_GET_MIN, UVC_ClassCtrlGetMinRequest, NULL, NULL, &g_UVC_sDevice},
{REQ_CLASS, UVC_GET_MAX, UVC_ClassCtrlGetMaxRequest, NULL, NULL, &g_UVC_sDevice},
{REQ_CLASS, UVC_GET_RES, UVC_ClassCtrlGetResRequest, NULL, NULL, &g_UVC_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 sUvcUsbClass =
{
(void *)&g_UVC_sDevice,
(PFN_DRVUSB_CALLBACK)UVC_Reset,
UVC_IsCfgId
};
static volatile uint16_t s_u16Len;
static volatile uint16_t s_u16SendLength, s_u16CurPtr, s_u16Toggle;
static volatile uint8_t s_u8ConfigLenOver64;
void UVC_CtrlSetupGetInterface(void * pVoid)
{
S_UVC_DEVICE *psDevice = (S_UVC_DEVICE *) pVoid;
DrvUSB_DataIn(0, &psDevice->u8AlternativeSetting, 1);
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UVC_CtrlSetupSetInterface() */
/* */
/* DESCRIPTION */
/* Setup ACK handler for SET_INTERFACE request */
/* */
/* INPUTS */
/* pVoid The function point of UVC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UVC_CtrlSetupSetInterface(void * pVoid)
{
S_DRVUSB_DEVICE *psUSBDevice = &gsUsbDevice;
S_UVC_DEVICE *psDevice = (S_UVC_DEVICE *)pVoid;
psDevice->u8AlternativeSetting = psUSBDevice->au8Setup[2];
if (psUSBDevice->au8Setup[4] == 1)
{
/* Iso IN interface */
if (psDevice->u8AlternativeSetting == 1)
{
DrvUSB_DataIn(ISO_IN_EP_NUM, NULL, 0);
}
else if (psDevice->u8AlternativeSetting == 0)
{
DrvUSB_DataIn(ISO_IN_EP_NUM, NULL, 0);
}
}
else if (psUSBDevice->au8Setup[4] == 2)
{
/* Iso OUT interface */
}
DrvUSB_DataIn(0, NULL, 0);
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UVC_EpNum1InEvent() */
/* */
/* DESCRIPTION */
/* Call back function for ISO pipe IN ack of endpoint number 1. */
/* */
/* INPUTS */
/* pVoid The function point of UVC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UVC_EpNum1InEvent(void * pVoid)
{
uint32_t u32PacketType;
S_UVC_DEVICE *psDevice = (S_UVC_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)
{
pfnUvcSendData();
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UVC_EpNum2OutEvent() */
/* */
/* DESCRIPTION */
/* Call back function for ISO pipe OUT ack of endpoint number 2. */
/* */
/* INPUTS */
/* pVoid The function point of UVC device */
/* */
/* OUTPUTS */
/* None */
/* */
/* RETURN */
/* None */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void UVC_EpNum2OutEvent(void * pVoid)
{
uint32_t tmp;
uint8_t *pcmBuf;
uint32_t u32EpId;
S_UVC_DEVICE *psDevice = (S_UVC_DEVICE *) pVoid;
pcmBuf = DrvUSB_GetOutData(ISO_OUT_EP_NUM, &tmp);
tmp = (PLAY_RATE / 1000) * PLAY_CHANNELS;
pfnUvcGetPlayData((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);
if (psDevice->u8IsoOutToggle == 0)
{
psDevice->u8IsoOutToggle = 1;
}
else
{
psDevice->u8IsoOutToggle = 0;
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* UVC_GetVersion() */
/* */
/* DESCRIPTION */
/* To get the UVC driver version. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -