/************************************************************************* * Function Name: UsbEpStatus * Parameters: Int16U Index * * Return: UsbCommStatus_t * * Description: USB Return EP status into pData * *************************************************************************/ inline static UsbCommStatus_t UsbEpStatus(Int16U Index) { if((Index & 0x7F) > 16) { return(UsbFault); } InData = 0; USB_GetStallEP(USB_EpLogToPhysAdd(Index),(pBoolean)&InData); USB_IO_Data(CTRL_ENP_IN,(pInt8U)&InData,2,(void*)USB_StatusHandler); return(UsbPass); }
/************************************************************************* * Function Name: UsbClearEpFeature * Parameters: Int16U Feature,Int16U Index * * Return: UsbCommStatus_t * * Description: USB Clear EP feature implement * *************************************************************************/ inline static UsbCommStatus_t UsbClearEpFeature(Int16U Feature,Int16U Index) { USB_Endpoint_t UsbEpAdd; if(((Index & 0x7F) > 16) || (Feature != UsbEpHaltSelector)) { return(UsbFault); } UsbEpAdd = USB_EpLogToPhysAdd(Index); USB_SetStallEP(UsbEpAdd,FALSE); USB_EP_UNSTALL_HOOK(UsbEpAdd); return(UsbPass); }
/************************************************************************* * Function Name: USB_RealizeEp * Parameters: const UsbStandardEpDescriptor_t * pEP_Desc, * const UsbEP_ExtData_t * pUsbEP_ExtData, Boolean Enable * * Return: USB_ErrorCodes_t * * Description: Enable or disable an endpoint * *************************************************************************/ USB_ErrorCodes_t USB_RealizeEp(const UsbStandardEpDescriptor_t * pEP_Desc, const UsbEP_ExtData_t * pUsbEP_ExtData, Boolean Enable) { USB_Endpoint_t EP; pEpCnfg_t pEP; __IO pInt32U pEpCtrlBaseAddr; Int16U Offset,Offset1; Int32U MaxPacketSizeTmp; assert(pEP_Desc); EP = (USB_Endpoint_t)USB_EpLogToPhysAdd(pEP_Desc->bEndpointAddress); pEP = &EpCnfg[EP]; if (Enable) { assert(pUsbEP_ExtData); // Allocate packet memory for EP buffer/s // calculate actual size only for the OUT EPs MaxPacketSizeTmp = pEP_Desc->wMaxPacketSize; if(!USB_AllocateBuffer(&Offset,&MaxPacketSizeTmp,EP)) { return(USB_MEMORY_FULL); } if(pUsbEP_ExtData->DoubleBuff) { // To use double buffered and ISO EP the USB_HIGH_INTR must be enabled assert(USB_HIGH_PRIORITY_EVENT); // Allocate packet second buffer MaxPacketSizeTmp = pEP_Desc->wMaxPacketSize; if(!USB_AllocateBuffer(&Offset1,&MaxPacketSizeTmp,EP)) { // release buffer USB_ReleaseBuffer(EP); return(USB_MEMORY_FULL); } } // Set EP status pEP->Status = NOT_READY; // Init EP flags pEP->Flags = 0; // Set endpoint type pEP->EpType = (UsbEpTransferType_t)pEP_Desc->bmAttributes.TransferType; // Init EP max packet size pEP->MaxSize = pEP_Desc->wMaxPacketSize; // Set Extra data pEP->bDoubleBuffered = pUsbEP_ExtData->DoubleBuff; pEP->EpSlot = pUsbEP_ExtData->EpSlot; if (EP & 1) { pEP->AvbBuff = EpCnfg[EP].bDoubleBuffered + 1; } else { pEP->AvbBuff = 0; } pEpCtrlBaseAddr = (pInt32U)&USB_EP0R; pEpCtrlBaseAddr += pUsbEP_ExtData->EpSlot; // Set Ep Address EpCtrlSet_EA(pEpCtrlBaseAddr,EP >> 1); pEP->pEpCtrl = pEpCtrlBaseAddr; if(EP & 1) { // IN EP // Disable EP EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED); // Clear Tx toggle EpCtrlSet_DTOG_TX(pEpCtrlBaseAddr,0); // Clear Correct Transfer for transmission flag EpCtrlClr_CTR_TX(pEpCtrlBaseAddr); // Update EP description table WriteEpDTB_AddrTx(pEP->EpSlot,Offset); WriteEpDTB_CountTx(pEP->EpSlot,0); // Set EP Kind & enable switch(pEP->EpType) { case UsbEpTransferControl: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_CTRL); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK); break; case UsbEpTransferIsochronous: assert(pEP->bDoubleBuffered); // Disable receiving (only singe direction is possible) EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED); WriteEpDTB_AddrRx(pEP->EpSlot,Offset1); WriteEpDTB_CountRx(pEP->EpSlot,0); EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_ISO); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_VALID); break; case UsbEpTransferBulk: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,pEP->bDoubleBuffered); if (pEP->bDoubleBuffered) { // EP_BULK_DOUB_BUF // Disable receiving (only singe direction is possible) EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED); // Clear Tx Software toggle WriteEpDTB_AddrRx(pEP->EpSlot,Offset1); WriteEpDTB_CountRx(pEP->EpSlot,0); EpCtrlSet_DTOG_RX(pEpCtrlBaseAddr,0); } // Enable EP EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK); break; case UsbEpTransferInterrupt: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_INTERRUPT); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK); break; default: assert(0); } // Clear Correct Transfer for transmission flag EpCtrlClr_CTR_TX(pEpCtrlBaseAddr); } else { RxCount_t RxCount = {0}; // OUT EP // Disable EP EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED); // Clear Rx toggle EpCtrlSet_DTOG_RX(pEpCtrlBaseAddr,0); // Clear Correct Transfer for reception flag EpCtrlClr_CTR_RX(pEpCtrlBaseAddr); // Update EP description table MaxPacketSizeTmp = pEP_Desc->wMaxPacketSize; RxCount.BlSizeField = (MaxPacketSizeTmp > 62); RxCount.NubBlockField = (MaxPacketSizeTmp > 62) ? (MaxPacketSizeTmp>>5)-1:MaxPacketSizeTmp>>1; WriteEpDTB_AddrRx(pEP->EpSlot,Offset); WriteEpDTB_CountRx(pEP->EpSlot,RxCount.Count); // Set EP Kind & enable switch(pEP->EpType) { case UsbEpTransferControl: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_CTRL); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_NAK); break; case UsbEpTransferIsochronous: WriteEpDTB_CountTx(pEP->EpSlot,RxCount.Count); // Disable transmitting (only singe direction is possible) EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED); WriteEpDTB_AddrTx(pEP->EpSlot,Offset1); EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_ISO); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID); break; case UsbEpTransferBulk: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,pEP->bDoubleBuffered); if (pEP->bDoubleBuffered) { // EP_BULK_DOUB_BUF // Disable transmitting (only singe direction is possible) EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED); WriteEpDTB_CountTx(pEP->EpSlot,RxCount.Count); WriteEpDTB_AddrTx(pEP->EpSlot,Offset1); EpCtrlSet_DTOG_TX(pEpCtrlBaseAddr,0); } // Enable EP EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID); break; case UsbEpTransferInterrupt: EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_INTERRUPT); EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0); // Enable EP EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID); break; default: assert(0); } } } else { if (EpCnfg[EP].pEpCtrl)