📄 usb_common.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2006
*
* File name : usb_common.c
* Description : USB common subroutines
*
* History :
* 1. Date : August 25, 2006
* Author : Stanimir Bonev
* Description : Create
* 2. Date : January 16, 2007
* Author : Stanimir Bonev
* Description : Modify
* Add log messages
*
* $Revision: 18137 $
**************************************************************************/
/*************************************************************************
* Function Name: USB_UserFuncRegistering
* Parameters: UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd
*
* Return: UserFunc_t
*
* Description: Registered User callback function
*
*************************************************************************/
UserFunc_t USB_UserFuncRegistering (UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd)
{
UserFunc_t PrevUserFunc = UsbUserFun[UserFuncInd];
USB_T9M_TRACE_INFO("T9M USB_UserFuncRegistering() index - %d, address 0x%08x\n\r",
UserFuncInd,UserFunc);
UsbUserFun[UserFuncInd] = (UserFunc_t) UserFunc;
return (PrevUserFunc);
}
/*************************************************************************
* Function Name: UsbCoreReq
* Parameters: UsbCoreReqType_t Type
*
* Return: Int32U
*
* Description: Return device states
*
*************************************************************************/
Int32U UsbCoreReq (UsbCoreReqType_t Type)
{
switch(Type)
{
case UsbCoreReqDevState:
return(UsbDevCtrl.State.DS);
case UsbCoreReqDevSusState:
return(UsbDevCtrl.State.Suspend);
case UsbCoreReqConfiquration:
return(UsbDevCtrl.Configuration);
case UsbCoreReqInterface:
return(UsbDevCtrl.Interface);
case UsbCoreReqAlternateSetting:
return(UsbDevCtrl.AlternateSetting);
case UsbCoreReqDevOwnAddress:
return(UsbDevCtrl.DevAdd);
case UsbCoreReqWakeUpEnableStatus:
return(UsbDevCtrl.Feature.RemoteWakeupEnable);
case UsbCoreReqSelfPoweredStatus:
return(UsbDevCtrl.Feature.SelfPowered);
}
return((Int32U) -1);
}
#if USB_REMOTE_WAKEUP != 0
/*************************************************************************
* Function Name: UsbWakeUp
* Parameters: none
*
* Return: none
*
* Description: Wake-up device from suspend mode
*
*************************************************************************/
void UsbWakeUp (void)
{
USB_T9M_TRACE_INFO("T9M UsbWakeUp()\n\r");
if(UsbDevCtrl.Feature.RemoteWakeupEnable && UsbDevCtrl.State.Suspend)
{
USB_WakeUp();
}
}
#endif // USB_REMOTE_WAKEUP != 0
/*************************************************************************
* Function Name: UsbSetDevState
* Parameters: UsbT9DevState_t DevState
*
* Return: none
*
* Description: Set device state
*
*************************************************************************/
static
void UsbSetDevState (UsbT9DevState_t DevState)
{
UsbDevCtrl.State.DS = DevState;
USB_T9M_TRACE_INFO("T9M UsbSetDevState() state - %d\n\r",DevState);
switch (DevState)
{
case UsbDevStatusAttached:
case UsbDevStatusPowered:
case UsbDevStatusDefault:
USB_Configure(FALSE);
USB_SetDefAdd(); // Set address 0
UsbUserFun[UsbUserConfigure](NULL);
UsbDevCtrl.DevAdd = UsbDevCtrl.Configuration = \
UsbDevCtrl.AlternateSetting = UsbDevCtrl.Interface = 0;
break;
case UsbDevStatusAddress:
USB_Configure(FALSE);
UsbDevCtrl.Configuration = UsbDevCtrl.AlternateSetting =\
UsbDevCtrl.Interface = 0;
break;
case UsbDevStatusConfigured:
USB_Configure(TRUE);
break;
default: // unknow state - disconnected or in process of a connection
USB_Configure(FALSE);
UsbUserFun[UsbUserConfigure](NULL);
UsbDevCtrl.DevAdd = UsbDevCtrl.Configuration = \
UsbDevCtrl.AlternateSetting = UsbDevCtrl.Interface = 0;
}
}
/*************************************************************************
* Function Name: UsbSetDevSuspend
* Parameters: none
*
* Return: UsbDevState_t
*
* Description: Set device suspend mode
*
*************************************************************************/
static void UsbSetDevSuspend (Boolean Suspend)
{
UsbDevCtrl.State.Suspend = Suspend ? UsbDevStatusSuspend : UsbDevStatusNoSuspend;
}
/*************************************************************************
* Function Name: UsbFindInterface
* Parameters: UsbStandardConfigurationDescriptor_t * pConfiguration
* Int32U Interface,Int32U AlternativeSetting
*
* Return: UsbCommStatus_t
*
* Description: Set Interface and Alternative setting state
*
*************************************************************************/
static
UsbCommStatus_t UsbFindInterface (UsbStandardConfigurationDescriptor_t * pConfiguration,
UsbDevCtrl_t * UsbDev)
{
UsbStandardInterfaceDescriptor_t *pData;
// Find Interface
for( pData = (UsbStandardInterfaceDescriptor_t *)pConfiguration;
(Int8U*)pData < (Int8U *)pConfiguration + pConfiguration->wTotalLength;
pData =(UsbStandardInterfaceDescriptor_t *)((Int8U *)pData + pData->bLength))
{
if((pData->bDescriptorType == UsbDescriptorInterface) &&
(pData->bInterfaceNumber == UsbDev->Interface) &&
(pData->bAlternateSetting == UsbDev->AlternateSetting))
{
return(UsbPass);
}
}
USB_T9W_TRACE_INFO("T9W UsbFindInterface() can't find interface\n\r");
return(UsbFault);
}
/*************************************************************************
* Function Name: UsbFindConfiguration
* Parameters: Int32U
*
* Return: UsbStandardConfigurationDescriptor_t *
*
* Description: Return pointer to current configuration
*
*************************************************************************/
static
UsbStandardConfigurationDescriptor_t * UsbFindConfiguration(Int32U Configuration)
{
UsbStandardConfigurationDescriptor_t * pData =
(UsbStandardConfigurationDescriptor_t *) &UsbStandardConfigurationDescriptor[0];
while(pData->bLength)
{
if(pData->bDescriptorType == UsbDescriptorConfiguration)
{
if(pData->bConfigurationValue == Configuration)
{
return(pData);
}
}
pData = (UsbStandardConfigurationDescriptor_t *)((Int8U *)pData + pData->bLength);
}
USB_T9W_TRACE_INFO("T9W UsbFindConfiguration() can't find configuration - %d\n\r",
Configuration);
return(NULL);
}
/*************************************************************************
* Function Name: UsbSetConfigurtonState
* Parameters: Int32U
*
* Return: UsbCommStatus_t
*
* Description: Set configuration state
*
*************************************************************************/
static inline
UsbCommStatus_t UsbSetConfigurtonState (Int32U Configuration)
{
if(Configuration)
{
// Find configuration
UsbStandardConfigurationDescriptor_t * pData = UsbFindConfiguration(Configuration);
UsbDevCtrl_t UsbDevCtrlNew = UsbDevCtrl;
if(pData == NULL)
{
return(UsbFault);
}
// Set Interface and Alternative Setting
UsbDevCtrlNew.Configuration = Configuration;
UsbDevCtrlNew.Interface = UsbDevCtrlNew.AlternateSetting = 0;
UsbDevCtrlNew.Feature.RemoteWakeupEnable = 0;
UsbDevCtrlNew.Feature.SelfPowered = pData->bmAttributes.SelfPowered?1:0;
// Whether the interface exist into current configuration?
if(UsbFindInterface(pData,&UsbDevCtrlNew) != UsbPass)
{
return(UsbFault);
}
// User function that realize EP and init buffers
UsbUserFun[UsbUserConfigure]((void *)&UsbDevCtrlNew);
UsbDevCtrl = UsbDevCtrlNew;
UsbSetDevState(UsbDevStatusConfigured);
USB_T9M_TRACE_INFO("T9M UsbSetConfigurtonState()\n\r"
" Configuration - %d\n\r",
Configuration);
}
else
{
USB_T9M_TRACE_INFO("T9M UsbSetConfigurtonState()\n\r"
" Configuration - %d\n\r",
Configuration);
UsbUserFun[UsbUserConfigure](NULL);
UsbSetDevState(UsbDevStatusAddress);
}
return(UsbPass);
}
/*************************************************************************
* Function Name: UsbDevStatus
* Parameters: Int8U * pData, Int16U Index
*
* Return: UsbCommStatus_t
*
* Description: Usb Return device status
*
*************************************************************************/
static inline
UsbCommStatus_t UsbDevStatus(Int8U * pData, Int16U Index)
{
if(Index == 0)
{
UsbEp0Ctrl.pData = pData;
UsbEp0Ctrl.Counter = 2;
*pData++ = UsbDevCtrl.Feature.Data;
USB_T9M_TRACE_INFO("T9M UsbDevStatus() device status - %d\n\r",
UsbDevCtrl.Feature.Data);
*pData = 0;
return(UsbPass);
}
USB_T9W_TRACE_INFO("T9W UsbDevStatus()\n\r"
" Index (0==) - %d\n\r",Index);
return(UsbFault);
}
/*************************************************************************
* Function Name: UsbInterfaceStatus
* Parameters: Int8U * pData, Int16U Index
*
* Return: UsbCommStatus_t
*
* Description: USB Return interface status into pData
*
*************************************************************************/
static inline
UsbCommStatus_t UsbInterfaceStatus(Int8U * pData, Int16U Index)
{
USB_T9M_TRACE_INFO("T9M UsbInterfaceStatus()\n\r");
UsbEp0Ctrl.pData = pData;
UsbEp0Ctrl.Counter = 2;
*pData++ = 0;
*pData = 0;
return(UsbPass);
}
/*************************************************************************
* Function Name: UsbEpStatus
* Parameters: Int8U * pData, Int16U Index
*
* Return: UsbCommStatus_t
*
* Description: USB Return EP status into pData
*
*************************************************************************/
static inline
UsbCommStatus_t UsbEpStatus(Int8U * pData, Int16U Index)
{
if((Index & 0x7F) > 16)
{
USB_T9W_TRACE_INFO("T9W UsbEpStatus()\n\r"
" Index (16<) - %d\n\r",
Index);
return(UsbFault);
}
UsbEp0Ctrl.pData = pData;
UsbEp0Ctrl.Counter = 2;
USB_GetStallEP(USB_EpLogToPhysAdd(Index),pData);
USB_T9M_TRACE_INFO("T9M UsbEpStatus() stall - %d\n\r", *pData);
*++pData = 0;
return(UsbPass);
}
/*************************************************************************
* Function Name: UsbGetStatus
* Parameters: none
*
* Return: none
*
* Description: USB Get status implement
*
*************************************************************************/
static inline
void UsbGetStatus (void)
{
if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) &&
// Length must be 2
(UsbEp0SetupPacket.wLength.Word == 2) &&
// Direction of data from device
(UsbEp0SetupPacket.mRequestType.Dir == 1) &&
// wValue must be 0
(UsbEp0SetupPacket.wValue.Word == 0) )
{
// This request is valid only for Address and Configured device's states
switch(UsbEp0SetupPacket.mRequestType.Recipient)
{
case UsbRecipientDevice:
if(UsbDevStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass)
{
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
case UsbRecipientInterface:
if(UsbInterfaceStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass)
{
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
case UsbRecipientEndpoint:
if(UsbEpStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass)
{
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
default:
USB_T9W_TRACE_INFO("T9W UsbGetStatus() unknow recipient\n\r");
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
}
else
{
USB_T9W_TRACE_INFO("T9W UsbGetStatus()\n\r"
" State (4>=) - %d\n\r"
" wLength.Word (2==) - %d\n\r"
" mRequestType.Dir (1==) - %d\n\r"
" wValue.Word (0==) - %d\n\r",
UsbDevCtrl.State.DS,UsbEp0SetupPacket.wLength.Word,
UsbEp0SetupPacket.mRequestType.Dir,UsbEp0SetupPacket.wValue.Word);
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
}
/*************************************************************************
* Function Name: UsbClearFeature
* Parameters: Int16U Feature,Int16U Index
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -