📄 usbd_if.c
字号:
}
/* =============================================================================
// Function_Name: USBD_IFSetEPxConfiguration
// description : Set for specified EP
// argument : number Endpoint number
// pInformation Value to set in Endpoint
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFSetEPxConfiguration(UCHAR number,const PUSBD_IF_EP_INFORMATION pInformation)
{
LONG retValue;
volatile UCHAR tempSize;
retValue = STATUS_SUCCESS;
do { /* Don't loop */
if (number >= MAX_ENDPOINT) {
/* When Endpoint which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if ((pInformation->epAddress & 0x70) != 0x00) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if (number == 0x01 && pInformation->MaxPacketSize > 64) {
/* EPa can only be set up to MaxPacketSize 64 */
retValue = STATUS_INVALID_PARAMETER;
break;
}
/* EP0,EPa,EPb,EPc */
/* Setting for each transfer type individually */
switch (pInformation->type) {
case USBD_IF_TRANTYPE_CONTROL:
if (IS_BIT(EPxCapabirity[number].type,EPX_CAP_CONTROL) == FALSE) {
/* When Control transfer is not supported in this Endpoint */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if ((RegRead(REG08_D_USB_Status) & MASK_FSxHS) == BIT_FSxHS_FSmode) {
/* FS */
if (pInformation->MaxPacketSize != 8
&& pInformation->MaxPacketSize != 16
&& pInformation->MaxPacketSize != 32
&& pInformation->MaxPacketSize != 64) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
} else {
/* HS */
if (pInformation->MaxPacketSize != 64) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
}
/* Control transfer can only be set in EP0 */
tempSize = pInformation->MaxPacketSize;
RegWrite(REG08_D_EP0MaxSize,tempSize);
break;
case USBD_IF_TRANTYPE_BULK:
if (IS_BIT(EPxCapabirity[number].type,EPX_CAP_BULK) == FALSE) {
/* When Bulk transfer is not supported in this Endpoint */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if ((RegRead(REG08_D_USB_Status) & MASK_FSxHS) == BIT_FSxHS_FSmode) {
/* FS */
if (pInformation->MaxPacketSize != 8
&& pInformation->MaxPacketSize != 16
&& pInformation->MaxPacketSize != 32
&& pInformation->MaxPacketSize != 64) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
} else {
/* HS */
if (pInformation->MaxPacketSize != 512) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
}
RegWrite(REG08_D_EPxConfig_0(number - 1),pInformation->epAddress); /* Endpoint Address */
/* MaxPacket Size */
RegWrite(REG08_D_EPxMaxSize_H(number - 1),HIBYTE(pInformation->MaxPacketSize));
RegWrite(REG08_D_EPxMaxSize_L(number - 1),LOBYTE(pInformation->MaxPacketSize));
break;
case USBD_IF_TRANTYPE_INTERRUPT:
if (IS_BIT(EPxCapabirity[number].type,EPX_CAP_INT) == FALSE) {
/* When Interrupt transfer is not supported in this Endpoint */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if ((RegRead(REG08_D_USB_Status) & MASK_FSxHS) == BIT_FSxHS_FSmode) {
/* FS */
if (pInformation->MaxPacketSize > 64) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
} else {
if (pInformation->MaxPacketSize > 1024) {
/* When value which can't be set is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
}
RegWrite(REG08_D_EPxConfig_0(number - 1),pInformation->epAddress); /* Endpoint Address */
if (IS_EPX_DIRIN(pInformation->epAddress) == FALSE) {
/* Ping Flow Control = OFF */
RegSet(REG08_D_EPxConfig_0(number - 1),BIT_IntEP_Mode_InterruptOUT); /* IntEP_Mode */
}
/* MaxPacket Size */
RegWrite(REG08_D_EPxMaxSize_H(number - 1),HIBYTE(pInformation->MaxPacketSize));
RegWrite(REG08_D_EPxMaxSize_L(number - 1),LOBYTE(pInformation->MaxPacketSize));
break;
case USBD_IF_TRANTYPE_ISOCHRONOUS:
retValue = STATUS_INVALID_PARAMETER;
break;
default:
retValue = STATUS_INVALID_PARAMETER;
break;
}
} while (0);
return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFGetEPxStatus
// description : Return interrupt status of Endpoint
// argument : number Endpoint number
// pEpStatus Pointer to return status
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFGetEPxStatus(UCHAR number,PUSBD_IF_ENDPOINT_STATUS pEpStatus)
{
LONG retValue;
retValue = STATUS_SUCCESS;
do { /* Don't loop */
/* Clear */
pEpStatus->epOutShortAck = 0;
pEpStatus->epInAck = 0;
pEpStatus->epOutAck = 0;
pEpStatus->epInNak = 0;
pEpStatus->epOutNak = 0;
pEpStatus->epInStall = 0;
pEpStatus->epOutStall= 0;
pEpStatus->Reserved = 0;
if (number == 0) {
/* EP0 */
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_INACK) != 0) {
pEpStatus->epInAck = 1;
}
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTACK) != 0) {
pEpStatus->epOutAck = 1;
}
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_INNAK) != 0) {
pEpStatus->epInNak = 1;
}
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTNAK) != 0) {
pEpStatus->epOutNak = 1;
}
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_INSTALL) != 0) {
pEpStatus->epInStall = 1;
}
if (IS_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTSTALL) != 0) {
pEpStatus->epOutStall = 1;
}
} else {
/* EPa,EPb,EPc,EPd,EPe */
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTSHORTACK) != 0) {
pEpStatus->epOutShortAck = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INACK) != 0) {
pEpStatus->epInAck = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTACK) != 0) {
pEpStatus->epOutAck = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INNAK) != 0) {
pEpStatus->epInNak = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTNAK) != 0) {
pEpStatus->epOutNak = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INSTALL) != 0) {
pEpStatus->epInStall = 1;
}
if (IS_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTSTALL) != 0) {
pEpStatus->epOutStall = 1;
}
}
} while (0);
return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFClearEPxStatus
// description : Clear interrupt status of Endpoint
// argument : number Endpoint number
// pEpStatus Interrupt status to be cleared
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFClearEPxStatus(UCHAR number,PUSBD_IF_ENDPOINT_STATUS pEpStatus)
{
LONG retValue;
retValue = STATUS_SUCCESS;
do { /* Don't loop */
/* Clear */
if (pEpStatus->epOutShortAck == 1) {
/* OUTSHORTACK */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTSHORTACK);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTSHORTACK);
}
}
if (pEpStatus->epInAck == 1) {
/* INACK */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_INACK);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INACK);
}
}
if (pEpStatus->epOutAck == 1) {
/* OUTACK */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTACK);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTACK);
}
}
if (pEpStatus->epInNak == 1) {
/* INNAK */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_INNAK);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INNAK);
}
}
if (pEpStatus->epOutNak == 1) {
/* OUTNAK */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTNAK);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTNAK);
}
}
if (pEpStatus->epInStall == 1) {
/* INSTALL */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_INSTALL);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_INSTALL);
}
}
if (pEpStatus->epOutStall == 1) {
/* OUTSTALL */
if (number == 0) {
CLR_BIT(IntStat[IS_EP0_INT_STAT],INT_OUTSTALL);
} else {
CLR_BIT(IntStat[IS_EPA_INT_STAT + (number - 1)],INT_OUTSTALL);
}
}
} while (0);
return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFEPxEnable
// description : Set the Enable/Disable for Endpoint
// argument : number Endpoint number
// enable 1 Enable
// 0 Disable
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// : EP0 is ignored, for it can't be set
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFEPxEnable(UCHAR number,UCHAR enable)
{
LONG retValue;
retValue = STATUS_SUCCESS;
do { /* Don't loop */
if (number >= MAX_ENDPOINT) {
/* When Endpoint which can't be specified is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if (!(enable == USBD_IF_ENABLE || enable == USBD_IF_DISABLE)) {
/* When Endpoint which can't be specified is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
if (number > 0) {
number--;
if (enable == USBD_IF_ENABLE) {
RegSet(REG08_D_EPxConfig_0(number),BIT_EnEndpoint);
} else {
RegClear(REG08_D_EPxConfig_0(number),BIT_EnEndpoint);
}
}
} while (0);
return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFGetEPxForceNakEnable
// description : Return status of Enable/Disable for transfer of Endpoint
// argument : number Endpoint number
// enable Pointer to return status
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFGetEPxForceNakEnable(UCHAR number,UCHAR *enable)
{
LONG retValue;
UCHAR rTemp;
retValue = STATUS_SUCCESS;
do { /* Don't loop */
if ((number & 0x7F) >= MAX_ENDPOINT) {
/* When Endpoint which can't be specified is specified */
retValue = STATUS_INVALID_PARAMETER;
break;
}
*enable = USBD_IF_DISABLE;
if (number == USBD_IF_EP0_IN) {
rTemp = RegRead(REG08_D_EP0ControlIN);
} else if (number == USBD_IF_EP0_OUT) {
rTemp = RegRead(REG08_D_EP0ControlOUT);
} else {
rTemp = RegRead(REG08_D_EPxControl(number - 1));
}
if (IS_BIT(rTemp,BIT_ForceNAK)) {
*enable = USBD_IF_ENABLE;
}
} while (0);
return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFSetEPxForceNakEnable
// description : Set status of Enable/Disable for transfer of Endpoint
// argument : number Endpoint number
// enable Status to be set
// return : STATUS_SUCCESS Finished normally
// STATUS_NOT_OPENED Not be opened yet
// STATUS_INVALID_PARAMETER Parameter error
// flag :
// global :
// =============================================================================
*/
LONG USBD_IFSetEPxForceNakEnable(UCHAR number,UCHAR enable)
{
LONG retValue;
UCHAR rTemp,rTemp2;
OS_BOOL bCpuState; // State of CPU lock
retValue = STATUS_SUCCESS;
do { /* Don't loop */
if ((number & 0x7F) >= MAX_ENDPOINT) {
/* When Endpoint doesn't exist */
retValue = STATUS_INVALID_PARAMETER;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -