📄 lpc_usb.c
字号:
}
/*************************************************************************
* Function Name: USB_SetStallEP
* Parameters: USB_Endpoint_t EndPoint, Boolean Stall
*
* Return: none
*
* Description: The endpoint stall/unstall
*
*************************************************************************/
void USB_SetStallEP (USB_Endpoint_t EndPoint, Boolean Stall)
{
USB_Cmd(CMD_USB_SET_EP_STAT | EndPoint, (Stall ? bmUSB_EpStall : 0));
}
/*************************************************************************
* Function Name: USB_GetStallEP
* Parameters: USB_Endpoint_t EndPoint
*
* Return: Boolean
*
* Description: Get stall state of the endpoint
*
*************************************************************************/
Boolean USB_GetStallEP (USB_Endpoint_t EndPoint)
{
return ((USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0) & bmUSB_EpStallStatus) != 0);
}
/*************************************************************************
* Function Name: USB_EpWrite
* Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
*
* Return: none
*
* Description: Endpoint Write (IN)
*
*************************************************************************/
void USB_EpWrite (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
{
// Convert EP physical address to logical and set write enable bit
USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlWrEna;
// Get data size
TPKTLEN = Count;
// Write data to SIE buffer
if(Count)
{
do
{
TDATA = *pData++;
}
while (USBCTRL_bit.WR_EN);
}
else
{
do
{
TDATA = 0;
}
while (USBCTRL_bit.WR_EN);
}
USBCTRL = 0;
USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
USB_Cmd(CMD_USB_VAL_BUF, 0);
}
/*************************************************************************
* Function Name: USB_EpRead
* Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
*
* Return: Int32
*
* Description: Endpoint Read (OUT)
*
*************************************************************************/
Int32U USB_EpRead (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
{
// Convert EP physical address to logical and set read enable bit
USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlRdEna;
while (RCVEPKTLEN_bit.PKT_RDY == 0);
// Get data size
Count = RCVEPKTLEN_bit.PKT_LNGTH;
// Read data from SIE buffer
while (RCVEPKTLEN_bit.DV)
{
*pData++ = RCVEDATA;
}
USBCTRL = 0;
USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
if(USB_Cmd(CMD_USB_CLR_BUF, 0) & bmUSB_PacketOverWritten)
{
Count |= 0x80000000;
}
return (Count);
}
/*************************************************************************
* Function Name: USB_ISR
* Parameters: none
*
* Return: none
*
* Description: USB interrupt subroutine
*
*************************************************************************/
void USB_ISR (void)
{
Int32U EpIntr,Val,EpIntHold;
UsbDevIntrStat_t UsbDevIntrSt = {DEVINTS};
#if USB_DMA > 0
if (USBINTS & 3)
{
#endif
#if USB_HIGH_PRIORITY_EVENT > 0
// Fast EP interrupt
if(UsbDevIntrSt.Fast)
{
DEVINTCLR = bmUSB_FastInterrupt;
if(UsbUserFun[UsbHighPrioIntrEvent] != NULL)
{
UsbUserFun[UsbHighPrioIntrEvent]((void *)0);
}
// Clear Fast EP interrupt
}
#endif
#if USB_ERROR_EVENT > 0
// USB engine error interrupt
if(UsbDevIntrSt.Error)
{
DEVINTCLR = bmUSB_ErrorInterrupt;
Val = USB_Cmd(CMD_USB_RD_ERROR_STAT,0);
if(UsbUserFun[UsbErrorEvent] != NULL)
{
UsbUserFun[UsbErrorEvent]((void *)Val);
}
}
#endif
#if USB_SOF_EVENT > 0
// Frame interrupt
if(UsbDevIntrSt.Frame)
{
DEVINTCLR = bmUSB_FrameInterrupt;
// Val = USB_Cmd(CMD_USB_RD_FRAME_NUMB,0);
if(UsbUserFun[UsbSofEvent] != NULL)
{
UsbUserFun[UsbSofEvent]((void *)Val);
}
}
#endif
// Device Status interrupt
if(UsbDevIntrSt.Status)
{
// Clear Device status interrupt
DEVINTCLR = bmUSB_DevStatusInterrupt;
// Get device status
USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
// Device connection status
if(USB_DevStatus.ConnectChange)
{
if(UsbUserFun[UsbConnectEvent] != NULL)
{
UsbUserFun[UsbConnectEvent]((void *)USB_DevStatus.Connect);
}
}
// Device suspend status
if(USB_DevStatus.SuspendChange)
{
if(UsbUserFun[UsbSuspendEvent] != NULL)
{
UsbUserFun[UsbSuspendEvent]((void *)USB_DevStatus.Suspend);
}
}
// Device reset
if(USB_DevStatus.Reset)
{
USB_HwReset();
if(UsbUserFun[UsbResetEvent] != NULL)
{
UsbUserFun[UsbResetEvent](NULL);
}
}
}
// Slow EP interrupt
if(UsbDevIntrSt.Slow)
{
// Clear Slow EP interrupt
DEVINTCLR = bmUSB_SlowInterrupt;
do
{
EpIntr = ENDPINTS;
// First Software High proirity and then low proirity
Int32U USB_EpSoftPrioHold = USB_EpSoftPrio;
for (Int32U i = 2; i; --i, USB_EpSoftPrioHold ^= 0xFFFFFFFF)
{
Int32U EpIntrCurrPrio = EpIntr & USB_EpSoftPrioHold;
// Output ctrl EP
if(EpIntrCurrPrio & 1)
{
Val = USB_EpIntrClr(CTRL_ENP_OUT);
if(UsbUserFun[UsbEp0Out] != NULL)
{
if(Val & bmUSB_EpSetupPacket)
{
UsbUserFun[UsbEp0Out]((void *)UsbSetupPacket);
}
else
{
UsbUserFun[UsbEp0Out]((void *)UsbDataOutPacket);
}
}
break;
}
// All other endpoints
for(Val = 1,EpIntHold = EpIntrCurrPrio >> 1; EpIntHold; ++Val,EpIntHold >>= 1)
{
if(EpIntHold & 1)
{
USB_EpIntrClr((USB_Endpoint_t)Val);
if(UsbUserFun[Val] != NULL)
{
UsbUserFun[Val]((void *)((Val&1)?UsbDataInPacket:UsbDataOutPacket));
}
break;
}
}
}
}
while(EpIntr);
}
#if USB_DMA > 0
}
if (USBINTS_bit.USB_INT_REQ_DMA)
{
// First Software High proirity and then low proirity
Int32U UsbDmaInt = 0,Tmp;
Tmp = EOTINTSTAT;
if(DMAINTEN & 1)
{
UsbDmaInt |= Tmp;
}
EOTINTCLR = Tmp;
Tmp = NEWDDRINTSTAT;
if(DMAINTEN & 2)
{
UsbDmaInt |= Tmp;
}
NEWDDRINTCLR = Tmp;
Tmp = SYSERRINTSTAT;
if(DMAINTEN & 4)
{
UsbDmaInt |= Tmp;
}
SYSERRINTCLR = Tmp;
for (Int32U i = 2; i; --i, USB_EpSoftPrio ^= 0xFFFFFFFF)
{
// All endpoints without ctrl EP_In, ctrl EP_Out
Int32U UsbDmaCurrPriorityInt = USB_EpSoftPrio & UsbDmaInt;
for(Int32U Val = 2, EpMask = 4; UsbDmaCurrPriorityInt; ++Val,EpMask <<= 1)
{
Int32U EpPriorityMask = UsbDmaCurrPriorityInt & EpMask;
if(EpPriorityMask == 0)
{
continue;
}
UsbDmaCurrPriorityInt &= ~EpMask;
// Collect Interrupts status flags and clear interrupt flags
if(EpPriorityMask && (UsbUserFun[Val] != NULL))
{
UsbUserFun[Val]((void *)UsbDmaPacket);
}
}
}
}
#endif
VICVectAddr = 0; // Clear interrupt in VIC.
}
/*************************************************************************
* 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);
}
/*************************************************************************
* Function Name: USB_GetFrameNumb
* Parameters: none
*
* Return: Int32U
*
* Description: Retunr curent value of SOF number
*
*************************************************************************/
#if USB_SOF_EVENT > 0
Int32U USB_GetFrameNumb (void)
{
return(USB_SofNumbHold);
}
#endif
/*************************************************************************
* U S B D M A P a r t *
*************************************************************************/
#if USB_DMA > 0
#pragma segment="DMA_RAM"
#pragma location="DMA_RAM"
#pragma data_alignment=128
__no_init pUSB_DmaDesc_t USB_DDCA[ENP_MAX_NUMB];
#pragma location="DMA_RAM"
__no_init USB_DmaDesc_t USB_DmaDesc[DMA_DD_MAX_NUMB];
/*************************************************************************
* Function Name: USB_DmaReset
* Parameters: Int32U IntrEna
*
* Return: none
*
* Description: Reset USB DMA
*
*************************************************************************/
void USB_DmaReset (Int32U IntrEna)
{
// Disable All DMA interrupts
DMAINTEN = 0;
// DMA Disable
EPDMADIS = 0xFFFFFFFF;
// DMA Request clear
DMARQSTCLR = 0xFFFFFFFF;
// End of Transfer Interrupt Clear
EOTINTCLR = 0xFFFFFFFF;
// New DD Request Interrupt Clear
NEWDDRINTCLR = 0xFFFFFFFF;
// System Error Interrupt Clear
SYSERRINTCLR = 0xFFFFFFFF;
for(Int32U i = 0; i < ENP_MAX_NUMB; ++i)
{
USB_DDCA[i] = NULL;
}
// Set USB UDCA Head register
UDCAHEAD = (Int32U)&USB_DDCA;
// Enable DMA interrupts
DMAINTEN = IntrEna;
}
/*************************************************************************
* Function Name: USB_DmaInitTransfer
* Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
* pInt32U pData, Int32U EpMaxSize, Int32U Size
* pDmaIsoPacket_t pDmaIsoPacket, Boolean EpTransferType
*
* Return: UsbDmaStateCode_t
*
* Description: Init Transfer by DMA
*
*************************************************************************/
UsbDmaStateCode_t USB_DmaInitTransfer (USB_Endpoint_t EndPoint,
Int32U DmaDescInd, pInt32U pData, Int32U EpMaxSize, Int32U Size,
pDmaIsoPacket_t pDmaIsoPacket, Boolean EpTransferType)
{
Int32U EpReg;
if ((EndPoint == CTRL_ENP_OUT) || (EndPoint == CTRL_ENP_IN))
{
return(UsbDmaParametersError);
}
if (USB_DmaDesc[DmaDescInd].Status == UsbDmaBeingServiced)
{
return(UsbDmaBeingServiced);
}
// Init DMA Descriptor
USB_DmaDesc[DmaDescInd].pNextDD = NULL;
USB_DmaDesc[DmaDescInd].NextDDValid = FALSE;
USB_DmaDesc[DmaDescInd].pDmaIsoPacket = pDmaIsoPacket;
USB_DmaDesc[DmaDescInd].DmaMode = UsbDmaNormalMode;
USB_DmaDesc[DmaDescInd].Isochronous = EpTransferType;
USB_DmaDesc[DmaDescInd].pDmaBuffer = pData;
USB_DmaDesc[DmaDescInd].DmaBufferLegtn = Size;
USB_DmaDesc[DmaDescInd].MaxPacketSize = EpMaxSize;
USB_DmaDesc[DmaDescInd].Status = UsbDmaNoServiced;
// Set DD
USB_DDCA[EndPoint] = &USB_DmaDesc[DmaDescInd];
// Enable DMA Transfer
EPDMAEN = 1 << EndPoint;
// Check state of IN/OUT Ep buffer
EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
if( ((EndPoint & 1) && !(EpReg & 0x60)) ||
(!(EndPoint & 1) && ((EpReg & 0x60) == 0x60)))
{
if((USB_DmaDesc[DmaDescInd].DdState != UsbDmaBeingServiced))
{
// Retrigger DMA Transfer
DMARQSTSET = 1 << EndPoint;
}
}
return(UsbDmaNoServiced);
}
/*************************************************************************
* Function Name: USB_DmaGetDesc
* Parameters: Int32U DmaDescInd
*
* Return: pUSB_DmaDesc_t
*
* Description: Retur pointer to DMA descriptor
*
*************************************************************************/
pUSB_DmaDesc_t USB_DmaGetDesc (Int32U DmaDescInd)
{
return(&USB_DmaDesc[DmaDescInd]);
}
/*************************************************************************
* Function Name: USB_DmaDisable
* Parameters: USB_Endpoint_t EndPoint
*
* Return: none
*
* Description: Disable DMA transfer for the EP
*
*************************************************************************/
void USB_DmaDisable (USB_Endpoint_t EndPoint)
{
EPDMADIS = 1 << EndPoint;
}
/*************************************************************************
* Function Name: USB_DmaRestattTransfer
* Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
* pInt32U pData, Int32U EpMaxSize, Int32U Size
* pDmaIsoPacket_t pDmaIsoPacket, Boolean EpTransferType
*
* Return: none
*
* Description: Restart DMA Transfer
*
*************************************************************************/
void USB_DmaRestattTransfer (USB_Endpoint_t EndPoint,Int32U DmaDescInd)
{
// Init DD DMA status
USB_DmaDesc[DmaDescInd].Status = UsbDmaNoServiced;
// Enable DMA Transfer
EPDMAEN = 1 << EndPoint;
// Check state of IN/OUT Ep buffer
Int32U EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
if(!(EndPoint & 1) && ((EpReg & 0x60) == 0x60))
{
// Retrigger DMA Transfer
DMARQSTSET = 1 << EndPoint;
}
else if ((EndPoint & 1) && !(EpReg & 0x60))
{
// Retrigger DMA Transfer
DMARQSTSET = 1 << EndPoint; //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -