📄 usb_hw.c
字号:
// Validate buffer
if(pEP->EpType == UsbEpTransferBulk && pEP->bDoubleBuffered)
{
// Toggle Filled buffer bit
EpCtrlToggle_DTOG_RX(pEP->pEpCtrl);
}
if (CurrentBuffer)
{
WriteEpDTB_CountTx(pEP->EpSlot,CountHold);
}
else
{
WriteEpDTB_CountRx(pEP->EpSlot,CountHold);
}
EpCtrlSet_STAT_TX(pEP->pEpCtrl,EP_VALID);
--EpCnfg[EP].AvbBuff;
Count = pEP->Size - pEP->Offset;
}
if(!pEP->bZeroPacket && !Count)
{
pEP->Status = COMPLETE;
//call callback function
if(pEP->pFn)
{
((void(*)(USB_Endpoint_t))pEP->pFn)(EP);
}
}
}
else
{
// OUT
while(pEP->AvbBuff)
{
// Get data size and buffer begin address
switch (pEP->EpType)
{
case UsbEpTransferControl:
case UsbEpTransferInterrupt:
// Get received bytes number
Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
// Get address of the USB packet buffer for corresponding EP
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
break;
case UsbEpTransferBulk:
if (!pEP->bDoubleBuffered)
{
// Get received bytes number
Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
// Get address of the USB packet buffer for corresponding EP
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
}
else
{
if (!(*pEP->pEpCtrl & (1UL << 6))) // DTOGTX
{
// Tx Buffer
Count = ReadEpDTB_CountTx(pEP->EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
}
else
{
// Rx Buffer
Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
}
}
break;
case UsbEpTransferIsochronous:
if(*pEP->pEpCtrl & (1UL <<14)) // DTOGRX
{
// Tx Buffer
Count = ReadEpDTB_CountTx(pEP->EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
}
else
{
// Rx Buffer
Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
}
break;
default:
assert(0);
return;
}
if(Count > (pEP->Size - pEP->Offset))
{
pEP->Status = BUFFER_OVERRUN;
pEP->Size = EpCnfg[EP].Offset;
break;
}
else if (Count < EpCnfg[EP].MaxSize)
{
pEP->Status = BUFFER_UNDERRUN;
pEP->Size = EpCnfg[EP].Offset + Count;
}
else
{
pEP->Status = BEGIN_SERVICED;
}
Int32U Offset = pEP->Offset;
pEP->Offset += Count;
// Read data from SIE buffer
while (Count)
{
Data = *pSrc++;
*(pEP->pBuffer+Offset++) = Data;
if (--Count)
{
Data >>= 8;
*(pEP->pBuffer+Offset++) = Data;
--Count;
}
}
if(pEP->EpType == UsbEpTransferBulk && pEP->bDoubleBuffered)
{
EpCtrlToggle_DTOG_TX(pEP->pEpCtrl);
}
EpCtrlSet_STAT_RX(pEP->pEpCtrl,EP_VALID);
--EpCnfg[EP].AvbBuff;
if(*pEP->pEpCtrl & (1UL<<11))
{
EpCnfg[EP].Status = SETUP_OVERWRITE;
return;
}
if (!(Count = (pEP->Size - pEP->Offset)))
{
pEP->Status = COMPLETE;
break;
}
}
if (pEP->Status != BEGIN_SERVICED && pEP->Status != NO_SERVICED)
{
//call callback function
if(pEP->pFn)
{
((void(*)(USB_Endpoint_t))pEP->pFn)(EP);
}
}
}
}
/*************************************************************************
* Function Name: USB_EpLogToPhysAdd
* Parameters: Int8U EpLogAdd
*
* Return: USB_Endpoint_t
*
* Description: Convert the logical to physical address
*
*************************************************************************/
USB_Endpoint_t USB_EpLogToPhysAdd (Int8U EpLogAdd)
{
USB_Endpoint_t Address = (USB_Endpoint_t)((EpLogAdd & 0x0F)<<1);
if(EpLogAdd & 0x80)
{
++Address;
}
return(Address);
}
#if USB_SOF_EVENT > 0
/*************************************************************************
* Function Name: USB_GetFrameNumb
* Parameters: none
*
* Return: Int32U
*
* Description: Return current value of SOF number
*
*************************************************************************/
Int32U USB_GetFrameNumb (void)
{
return(USB_FNR_bit.FN);
}
#endif // USB_SOF_EVENT > 0
/*************************************************************************
* Function Name: USB_StatusPhase
* Parameters: Boolean In
*
* Return: none
*
* Description: Prepare status phase
*
*************************************************************************/
void USB_StatusPhase (Boolean In)
{
if(In)
{
USB_IO_Data(CTRL_ENP_IN,NULL,0,NULL);
}
}
#if USB_HIGH_PRIORITY_EVENT > 0
/*************************************************************************
* Function Name: USB_HIGH_ISR
* Parameters: none
*
* Return: none
*
* Description: High priority USB interrupt subroutine
*
*************************************************************************/
void USB_HIGH_ISR (void)
{
IntrStatus_t IntrStatus;
Int32U Status;
USB_HIGH_INTR_ENTRY_HOOK();
IntrStatus.Status = USB_ISTR;
IntrStatus.Status &= USB_CNTR | 0x1F;
// Get masked interrupt flags
if(IntrStatus.CTR)
{
USB_Endpoint_t EP;
// find corresponding EP
pInt32U pReg = (pInt32U)&USB_EP0R;
pReg += IntrStatus.EP_ID;
EP = (USB_Endpoint_t)(((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1));
// The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
if(EpCnfg[EP].bDoubleBuffered)
{
if(EP & 1)
{
// IN EP
assert(EpCnfg[EP].pEpCtrl);
EpCtrlClr_CTR_TX(EpCnfg[EP].pEpCtrl);
Status = EpCtrlGet_DTOG_RX(EpCnfg[EP].pEpCtrl);
EpCnfg[EP].AvbBuff = 1;
if( (EpCnfg[EP].EpType != UsbEpTransferIsochronous)
&&(Status == EpCtrlGet_DTOG_TX(EpCnfg[EP].pEpCtrl)))
{
// The both buffers are drained
++EpCnfg[EP].AvbBuff;
}
USB_EP_IO(EP);
}
else
{
// OUT EP
assert(EpCnfg[EP].pEpCtrl);
EpCtrlClr_CTR_RX(EpCnfg[EP].pEpCtrl);
Status = EpCtrlGet_DTOG_TX(EpCnfg[EP].pEpCtrl);
EpCnfg[EP].AvbBuff = 1;
if( (EpCnfg[EP].EpType != UsbEpTransferIsochronous)
&&(Status == EpCtrlGet_DTOG_RX(EpCnfg[EP].pEpCtrl)))
{
// The both buffers are drained
++EpCnfg[EP].AvbBuff;
}
USB_EP_IO(EP);
}
}
}
USB_HIGH_INTR_EXIT_HOOK();
}
#endif // USB_HIGH_PRIORITY_EVENT > 0
/*************************************************************************
* Function Name: USB_ISR
* Parameters: none
*
* Return: none
*
* Description: USB interrupt subroutine
*
*************************************************************************/
void USB_ISR (void)
{
IntrStatus_t IntrStatus;
USB_INTR_ENTRY_HOOK();
// Get masked interrupt flags
IntrStatus.Status = USB_ISTR;
IntrStatus.Status &= USB_CNTR | 0x1F;
#if USB_DOVR_EVENT > 0
// DMA over / underrun (for speed up retry process)
if(IntrStatus.PMAOVR)
{
USB_ISTR = ~bmPMAOVRM;
USB_ERR_HOOK(PMAOVR_ERROR);
}
#endif
#if USB_ERROR_EVENT > 0
// USB engine error interrupt
if(IntrStatus.ERR)
{
USB_ISTR = ~bmERRM;
USB_ERR_HOOK(GENERAL_ERROR);
}
#endif
// Device reset
if(IntrStatus.RESET)
{
USB_ISTR = ~bmRESETM;
USB_HwReset();
UsbDevSuspendCallback(FALSE);
UsbDevResetCallback();
}
#if USB_SOF_EVENT > 0
// Frame interrupt
if(IntrStatus.SOF)
{
USB_ISTR = ~bmSOFM;
#if USB_SOF_FRAME_NUMB > 0
USB_FRAME_HOOK(USB_GetFrameNumb());
#else
USB_FRAME_HOOK(0);
#endif
}
#endif
// Wake-up interrupt
if(IntrStatus.WKUP)
{
USB_ISTR = ~(bmSUSPM | bmWKUPM);
USB_Resume(USB_RESUME_WAKE_UP_EVENT);
}
// Device suspend
if(IntrStatus.SUSP)
{
USB_Suspend();
USB_ISTR = ~(bmSUSPM | bmWKUPM);
UsbDevSuspendCallback(TRUE);
}
// Expected Frame interrupt
if(IntrStatus.ESOF)
{
USB_ISTR = ~bmESOFM;
USB_Resume(USB_RESUME_SOF_EVENT);
}
// Low priority EP interrupt
if(IntrStatus.CTR)
{
USB_Endpoint_t EP;
// find corresponding EP
pInt32U pReg = (pInt32U)&USB_EP0R;
pReg += IntrStatus.EP_ID;
EP = (USB_Endpoint_t)(((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1));
// The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
if(!EpCnfg[EP].bDoubleBuffered)
{
EpCnfg[EP].AvbBuff = 1;
if (EP & 1)
{
assert(EpCnfg[EP].pEpCtrl);
EpCtrlClr_CTR_TX(EpCnfg[EP].pEpCtrl);
}
else
{
assert(EpCnfg[EP].pEpCtrl);
EpCtrlClr_CTR_RX(EpCnfg[EP].pEpCtrl);
}
if(EP == CTRL_ENP_OUT)
{
// determinate type of packet (only for control EP)
Boolean SetupPacket = EpCtrlGet_SETUP(EpCnfg[CTRL_ENP_OUT].pEpCtrl);
if (SetupPacket)
{
EpCnfg[CTRL_ENP_IN].AvbBuff = 1;
// init IO to receive Setup packet
USB_IO_Data(CTRL_ENP_IN,NULL,(Int32U)-1,NULL);
USB_IO_Data(CTRL_ENP_OUT,UsbEp0SetupPacket.Data,sizeof(UsbSetupPacket_t),NULL);
// reset EP IO ctrl
if (UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host)
{
USB_StatusHandler(CTRL_ENP_OUT);
}
USB_SetupHandler();
if(EpCnfg[CTRL_ENP_OUT].Status == STALLED)
{
USB_StallCtrlEP();
}
}
else
{
if(UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host &&
EpCnfg[CTRL_ENP_OUT].pFn)
{
((void(*)(USB_Endpoint_t))EpCnfg[CTRL_ENP_OUT].pFn)(CTRL_ENP_OUT);
}
else
{
USB_EP_IO(EP);
}
}
}
else if (EP == CTRL_ENP_IN)
{
if(UsbEp0SetupPacket.mRequestType.Dir == UsbHost2Device &&
EpCnfg[CTRL_ENP_IN].pFn)
{
((void(*)(USB_Endpoint_t))EpCnfg[CTRL_ENP_IN].pFn)(CTRL_ENP_IN);
}
else
{
USB_EP_IO(EP);
}
}
else
{
USB_EP_IO(EP);
}
}
}
USB_INTR_EXIT_HOOK();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -