📄 usb_9.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2003
*
* File name : usb_9.c
* Description : USB chapter 9 (device framework) module
*
* History :
* 1. Data : August 5, 2005
* Author : Stanimir Bonev
* Description : Create
* 2. Data : December 19, 2005
* Author : Stanimir Bonev
* Description : Modify
* Add separate functions for In and Out Data transfer by EP0
* Change prameter transfered to function form packet type to
* pointer to UsbEp0Ctrl structure
*
* $Revision: 1.1.2.1 $
**************************************************************************/
#include "usb_9.h"
UsbEpCtrl_t UsbEp0Ctrl;
UsbSetupPacket_t UsbEp0SetupPacket;
#pragma data_alignment=4
Int8U EpCtrlDataBuf[Ep0MaxSize];
UsbDevCtrl_t UsbDevCtrl = {{UsbDevStatusUnknow,UsbDevStatusNoSuspend},0,0,0,0};
// User funcrions
CommUserFpnt_t UsbCoreUserFun[UsbUserLastInd] =
{
// UsbUserClass
NULL,
// UsbUserVendor
NULL,
// UsbClassEp0OutPacket
NULL,
// UsbVendorEp0OutPacket
NULL,
// UsbUserConfigure
NULL,
// UsbUserReset
NULL,
// UsbUserConnect
NULL,
// UsbUserSuspend
NULL,
};
/*************************************************************************
* Function Name: UsbCoreInit
* Parameters: CommUserFpnt_t UserCoreConfigure
*
* Return: none
*
* Description: USB init core
*
*************************************************************************/
void UsbCoreInit (CommUserFpnt_t UserCoreConfigure)
{
UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket;
UserCoreConfigure(NULL);
UsbCoreUserFuncRegistered(UserCoreConfigure,UsbUserConfigure);
UsbSetDevState(UsbDevStatusUnknow);
// Registerd Core functions
USB_UserFuncRegistered(UsbDevResetCallback ,UsbResetEvent );
USB_UserFuncRegistered(UsbDevConnectCallback,UsbConnectEvent);
USB_UserFuncRegistered(UsbDevSuspendCallback,UsbSuspendEvent);
USB_UserFuncRegistered(UsbCtrlEpCallback ,UsbEp0Out );
USB_UserFuncRegistered(UsbCtrlEpCallback ,UsbEp0In );
}
/*************************************************************************
* Function Name: UsbCoreUserFuncRegistered
* Parameters: CommUserFpnt_t UserFunc, UsbCoreUserFuncInd_t UserFuncInd
*
* Return: CommUserFpnt_t
*
* Description: Registed User core callback function
*
*************************************************************************/
CommUserFpnt_t UsbCoreUserFuncRegistered (CommUserFpnt_t UserCoreFunc,
UsbCoreUserFuncInd_t UserFuncInd)
{
CommUserFpnt_t PrevUserFunc = UsbCoreUserFun[UserFuncInd];
UsbCoreUserFun[UserFuncInd] = UserCoreFunc;
return(PrevUserFunc);
}
/*************************************************************************
* Function Name: UsbCoreReq
* Parameters: UsbCoreReqType_t Type
*
* Return: Int32U
*
* Description: Return different 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);
}
/*************************************************************************
* Function Name: UsbWakeUp
* Parameters: none
*
* Return: none
*
* Description: WakeUp device from suspend mode
*
*************************************************************************/
void UsbWakeUp (void)
{
if(UsbDevCtrl.Feature.RemoteWakeupEnable && UsbDevCtrl.State.Suspend)
{
USB_WakeUp();
}
}
/*************************************************************************
* Function Name: UsbSetDevState
* Parameters: _UsbDevState_t DevState
*
* Return: none
*
* Description: Set device state
*
*************************************************************************/
void UsbSetDevState (_UsbDevState_t DevState)
{
UsbDevCtrl.State.DS = DevState;
switch (DevState)
{
case UsbDevStatusConfigured:
USB_Configure(TRUE);
break;
case UsbDevStatusAddress:
UsbDevCtrl.Configuration = UsbDevCtrl.AlternateSetting =\
UsbDevCtrl.Interface = 0;
USB_Configure(FALSE);
break;
default:
UsbDevCtrl.DevAdd = UsbDevCtrl.Configuration = \
UsbDevCtrl.AlternateSetting = UsbDevCtrl.Interface = 0;
USB_Configure(FALSE);
}
}
/*************************************************************************
* Function Name: UsbGetDevState
* Parameters: none
*
* Return: UsbDevState_t
*
* Description: Get device state
*
*************************************************************************/
UsbDevState_t UsbGetDevState (void)
{
return(UsbDevCtrl.State);
}
/*************************************************************************
* Function Name: UsbSetDevSuspend
* Parameters: none
*
* Return: UsbDevState_t
*
* Description: Set device suspend mode
*
*************************************************************************/
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
*
*************************************************************************/
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);
}
}
return(UsbFault);
}
/*************************************************************************
* Function Name: UsbFindConfiguration
* Parameters: Int32U
*
* Return: UsbStandardConfigurationDescriptor_t *
*
* Description: Return pointer to current configuration
*
*************************************************************************/
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);
}
return(NULL);
}
/*************************************************************************
* Function Name: UsbDevConnectCallback
* Parameters: void * pArg
*
* Return: none
*
* Description: USB connect callback
*
*************************************************************************/
void UsbDevConnectCallback (void * pArg)
{
UsbSetDevState(pArg?UsbDevStatusAttached:UsbDevStatusUnknow);
if(UsbCoreUserFun[UsbUserConnect] != NULL)
{
UsbCoreUserFun[UsbUserConnect](pArg);
}
}
/*************************************************************************
* Function Name: UsbDevSuspendCallback
* Parameters: void * pArg
*
* Return: none
*
* Description: USB suspend callback
*
*************************************************************************/
void UsbDevSuspendCallback (void * pArg)
{
UsbSetDevSuspend(pArg?UsbDevStatusSuspend:UsbDevStatusNoSuspend);
if(UsbCoreUserFun[UsbUserSuspend] != NULL)
{
UsbCoreUserFun[UsbUserSuspend](pArg);
}
}
/*************************************************************************
* Function Name: UsbDevResetCallback
* Parameters: void * pArg
*
* Return: none
*
* Description: USB reset callback
*
*************************************************************************/
void UsbDevResetCallback (void * pArg)
{
UsbSetDevState(UsbDevStatusDefault);
UsbCoreUserFun[UsbUserConfigure](NULL);
if(UsbCoreUserFun[UsbUserReset] != NULL)
{
UsbCoreUserFun[UsbUserReset](pArg);
}
}
/*************************************************************************
* Function Name: UsbEp0SetupWrite
* Parameters: none
*
* Return: none
*
* Description: USB EP Write implement (IN)
*
*************************************************************************/
void UsbEp0SetupWrite (void)
{
Int32U CurrCount = Ep0MaxSize;
if((UsbEp0Ctrl.Counter == Ep0MaxSize) && UsbEp0Ctrl.EpStatus.NoZeroLength)
{
UsbEp0Ctrl.EpStatus.Status = UsbEpSetupLastIn;
}
else if(UsbEp0Ctrl.Counter < Ep0MaxSize)
{
CurrCount = UsbEp0Ctrl.Counter;
UsbEp0Ctrl.EpStatus.Status = UsbEpSetupLastIn;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpSetupDataIn;
}
USB_EpWrite(CTRL_ENP_IN,(Int32U *)UsbEp0Ctrl.pData,CurrCount);
UsbEp0Ctrl.Counter -= CurrCount;
UsbEp0Ctrl.pData += CurrCount;
}
/*************************************************************************
* Function Name: UsbSetConfigurtonState
* Parameters: Int32U
*
* Return: UsbCommStatus_t
*
* Description: Set configuration state
*
*************************************************************************/
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 Interfce 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 is exist into current conficuration?
if(UsbFindInterface(pData,&UsbDevCtrlNew) != UsbPass)
{
return(UsbFault);
}
// User function that realize EP and init buffers
UsbCoreUserFun[UsbUserConfigure]((void *)&UsbDevCtrlNew);
UsbDevCtrl = UsbDevCtrlNew;
UsbSetDevState(UsbDevStatusConfigured);
}
else
{
UsbCoreUserFun[UsbUserConfigure](NULL);
UsbSetDevState(UsbDevStatusAddress);
}
return(UsbPass);
}
/*************************************************************************
* Function Name: UsbDevStatus
* Parameters: Int8U * pData, Int16U Index
*
* Return: UsbCommStatus_t
*
* Description: Usb Return device status into pData
*
*************************************************************************/
inline
UsbCommStatus_t UsbDevStatus(Int8U * pData, Int16U Index)
{
if(Index == 0)
{
UsbEp0Ctrl.pData = pData;
UsbEp0Ctrl.Counter = 2;
*pData++ = UsbDevCtrl.Feature.Data;
*pData = 0;
return(UsbPass);
}
return(UsbFault);
}
/*************************************************************************
* Function Name: UsbInterfaceStatus
* Parameters: Int8U * pData, Int16U Index
*
* Return: UsbCommStatus_t
*
* Description: Usb Return interface status into pData
*
*************************************************************************/
inline
UsbCommStatus_t UsbInterfaceStatus(Int8U * pData, Int16U Index)
{
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
*
*************************************************************************/
inline
UsbCommStatus_t UsbEpStatus(Int8U * pData, Int16U Index)
{
if((Index & 0x7F) > 16)
{
return(UsbFault);
}
UsbEp0Ctrl.pData = pData;
UsbEp0Ctrl.Counter = 2;
*pData++ = USB_GetStallEP(USB_EpLogToPhysAdd(Index)) ? 1:0;
*pData = 0;
return(UsbPass);
}
/*************************************************************************
* Function Name: UsbGetStatus
* Parameters: none
*
* Return: none
*
* Description: Usb Get status implement
*
*************************************************************************/
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 mut 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)
{
UsbEp0SetupWrite();
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
case UsbRecipientInterface:
if(UsbInterfaceStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -