📄 lpc24xx_usb.c
字号:
return (USB_OK);
}
/*************************************************************************
* 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_Cmd(CMD_USB_RD_FRAME_NUMB,0));
}
#endif // USB_SOF_EVENT > 0
/*************************************************************************
* Function Name: USB_ISR
* Parameters: none
*
* Return: none
*
* Description: USB interrupt subroutine
*
*************************************************************************/
static void USB_ISR (void)
{
Int32U EpIntr, i, Mask, Status;
usb_intr_loop:
#if USB_HIGH_PRIORITY_EVENT > 0
if(USBINTS_bit.USB_INT_REQ_HP)
{
#if (USB_HIGH_PRIORITY_EP == 0)
// Frame interrupt
if(USBDEVINTST_bit.FRAME)
{
USBDEVINTCLR = bmUSB_FrameInterrupt;
if(UsbUserFun[UsbUserSofEvent] != NULL)
{
UsbUserFun[UsbUserSofEvent]((void *)0);
}
}
#else // (USB_HIGH_PRIORITY_EP == 0)
while(USBDEVINTST_bit.EP_FAST)
{
// Get EPs interrupt flag
EpIntr = USBEPINTST;
// Mask with EPs interrupt enable flag
EpIntr &= USBEPINTEN;
// Mask with EPs high priority interrupt flag
EpIntr &= EpPriority;
// Processing EP interrupt
for(i = 0, Mask = 1; EpIntr; ++i, Mask <<= 1)
{
if(EpIntr & Mask)
{
Status = USB_EpIntrClr((USB_Endpoint_t)i);
if(UsbUserFun[i] != NULL)
{
if(Status & bmUSB_EpSetupPacket)
{
UsbUserFun[i]((void *)UsbSetupPacket);
}
else
{
UsbUserFun[i]((void *)((i & 1)?UsbDataInPacket:UsbDataOutPacket));
}
}
EpIntr &= ~Mask;
}
}
// Clear Fast EP interrupt
USBDEVINTCLR = bmUSB_FastInterrupt;
}
#endif // (USB_HIGH_PRIORITY_EP == 0)
}
#endif // USB_HIGH_PRIORITY_EVENT > 0
if (USBINTS_bit.USB_INT_REQ_LP)
{
#if USB_ERROR_EVENT > 0
// USB engine error interrupt
if(USBDEVINTST_bit.ERR_INT)
{
USBDEVINTCLR = bmUSB_ErrorInterrupt;
Status = USB_Cmd(CMD_USB_RD_ERROR_STAT,0);
if(UsbUserFun[UsbUserErrorEvent] != NULL)
{
UsbUserFun[UsbUserErrorEvent]((void *)Status);
}
}
#endif
#if ((USB_SOF_EVENT > 0) && \
((USB_HIGH_PRIORITY_EP == 0) || (USB_HIGH_PRIORITY_EP > 0)))
// Frame interrupt
if(USBDEVINTST_bit.FRAME)
{
USBDEVINTCLR = bmUSB_FrameInterrupt;
if(UsbUserFun[UsbUserSofEvent] != NULL)
{
UsbUserFun[UsbUserSofEvent]((void *)0);
}
}
#endif // ((USB_SOF_EVENT > 0) && \
((USB_HIGH_PRIORITY_EP == 0) || (USB_HIGH_PRIORITY_EP > 0)))
// Device Status interrupt
if(USBDEVINTST_bit.DEV_STAT)
{
// Clear Device status interrupt
USBDEVINTCLR = bmUSB_DevStatusInterrupt;
// Get device status
USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
// Device connection status
if(USB_DevStatus.ConnectChange)
{
UsbDevConnectCallback(USB_DevStatus.Connect);
if(UsbUserFun[UsbUserConnect] != NULL)
{
UsbUserFun[UsbUserConnect]((void *)USB_DevStatus.Connect);
}
}
// Device suspend status
if(USB_DevStatus.SuspendChange)
{
UsbDevSuspendCallback(USB_DevStatus.Suspend);
if(UsbUserFun[UsbUserSuspend] != NULL)
{
UsbUserFun[UsbUserSuspend]((void *)USB_DevStatus.Suspend);
}
}
// Device reset
if(USB_DevStatus.Reset)
{
USB_HwReset();
UsbDevResetCallback();
if(UsbUserFun[UsbUserReset] != NULL)
{
UsbUserFun[UsbUserReset](NULL);
}
}
}
#if (USB_FAST_EP > 0)
// Fast EP interrupt
while(USBDEVINTST_bit.EP_FAST)
{
// Check for pending high priority or fast EP interrupts
if((USBINTS_bit.USB_INT_REQ_HP && USB_HIGH_PRIORITY_EVENT))
{
goto usb_intr_loop;
}
// Get EPs interrupt flag
EpIntr = USBEPINTST;
// Mask with EPs interrupt enable flag
EpIntr &= USBEPINTEN;
// Mask with EPs high priority interrupt flag
EpIntr &= EpPriority;
// Processing EP interrupt
for(i = 0, Mask = 1; EpIntr; ++i, Mask <<= 1)
{
if(EpIntr & Mask)
{
Status = USB_EpIntrClr((USB_Endpoint_t)i);
if(UsbUserFun[i] != NULL)
{
if(Status & bmUSB_EpSetupPacket)
{
UsbUserFun[i]((void *)UsbSetupPacket);
}
else
{
UsbUserFun[i]((void *)((i & 1)?UsbDataInPacket:UsbDataOutPacket));
}
}
EpIntr &= ~Mask;
break;
}
}
// Clear Fast EP interrupt
USBDEVINTCLR = bmUSB_FastInterrupt;
}
#endif // (USB_FAST_EP > 0)
// Slow EP interrupt
while(USBDEVINTST_bit.EP_SLOW)
{
// Check for pending high priority or fast EP interrupts
if((USBINTS_bit.USB_INT_REQ_HP && USB_HIGH_PRIORITY_EVENT) ||
(USBDEVINTST_bit.EP_FAST && USB_FAST_EP))
{
goto usb_intr_loop;
}
// Get EPs interrupt flag
EpIntr = USBEPINTST;
// Mask with EPs interrupt enable flag
EpIntr &= USBEPINTEN;
// Processing EP interrupt
for(i = 0, Mask = 1; EpIntr; ++i, Mask <<= 1)
{
if(EpIntr & Mask)
{
Status = USB_EpIntrClr((USB_Endpoint_t)i);
if(UsbUserFun[i] != NULL)
{
if(Status & bmUSB_EpSetupPacket)
{
UsbUserFun[i]((void *)UsbSetupPacket);
}
else
{
UsbUserFun[i]((void *)((i & 1)?UsbDataInPacket:UsbDataOutPacket));
}
}
EpIntr &= ~Mask;
break;
}
}
// Clear Slow EP interrupt
USBDEVINTCLR = bmUSB_SlowInterrupt;
}
}
#if USB_DMA > 0
if (USBINTS_bit.USB_INT_REQ_DMA)
{
Int32U UsbDmaInt = 0,Tmp;
Tmp = USBEOTINTST;
if(USBDMAINTEN & 1)
{
UsbDmaInt |= Tmp;
}
USBEOTINTCLR = Tmp;
Tmp = USBNDDRINTST;
if(USBDMAINTEN & 2)
{
UsbDmaInt |= Tmp;
}
USBNDDRINTCLR = Tmp;
Tmp = USBSYSERRINTST;
if(USBDMAINTEN & 4)
{
UsbDmaInt |= Tmp;
}
USBSYSERRINTCLR = Tmp;
// Process EPs
EpIntr = UsbDmaInt;
// Processing all endpoints without ctrl EP_In, ctrl EP_Out
for(i = 2, Mask = 4; EpIntr; ++i, Mask <<= 1)
{
if(EpIntr & Mask)
{
if(UsbUserFun[i] != NULL)
{
UsbUserFun[i]((void *)UsbDmaPacket);
}
EpIntr &= ~Mask;
}
}
}
#endif
VICADDRESS = 0; // Clear interrupt in VIC.
}
/*************************************************************************
* U S B D M A P a r t *
*************************************************************************/
#if USB_DMA > 0
#pragma segment="USB_DMA_RAM"
#pragma location="USB_DMA_RAM"
#pragma data_alignment=128
__no_init pUSB_DmaDesc_t USB_DDCA[ENP_MAX_NUMB];
#pragma location="USB_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
USBDMAINTEN = 0;
// DMA Disable
USBEPDMADIS = 0xFFFFFFFF;
// DMA Request clear
USBDMARCLR = 0xFFFFFFFF;
// End of Transfer Interrupt Clear
USBEOTINTCLR = 0xFFFFFFFF;
// New DD Request Interrupt Clear
USBNDDRINTCLR = 0xFFFFFFFF;
// System Error Interrupt Clear
USBSYSERRINTCLR = 0xFFFFFFFF;
for(Int32U i = 0; i < ENP_MAX_NUMB; ++i)
{
USB_DDCA[i] = NULL;
}
// Set USB UDCA Head register
USBUDCAH = (Int32U)&USB_DDCA;
// Enable DMA interrupts
USBDMAINTEN = 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
USBEPDMAEN = 1 << EndPoint;
// Check state of IN/OUT EP buffer
EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
if(!EpTransferType &&
(((EndPoint & 1) && !(EpReg & 0x60)) ||
(!(EndPoint & 1) && ((EpReg & 0x60) == 0x60))))
{
if((USB_DmaDesc[DmaDescInd].DdState != UsbDmaBeingServiced))
{
// Retrigger DMA Transfer
USBDMARSET = 1 << EndPoint;
}
}
return(UsbDmaNoServiced);
}
/*************************************************************************
* Function Name: USB_DmaGetDesc
* Parameters: Int32U DmaDescInd
*
* Return: pUSB_DmaDesc_t
*
* Description: Return 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)
{
USBEPDMADIS = 1 << EndPoint;
}
/*************************************************************************
* Function Name: USB_DmaRestartTransfer
* 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_DmaRestartTransfer (USB_Endpoint_t EndPoint,Int32U DmaDescInd)
{
// Init DD DMA status
USB_DmaDesc[DmaDescInd].Status = UsbDmaNoServiced;
// Enable DMA Transfer
USBEPDMAEN = 1 << EndPoint;
if(USB_DmaDesc[DmaDescInd].Isochronous)
{
return;
}
// 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
USBDMARSET = 1 << EndPoint;
}
else if ((EndPoint & 1) && !(EpReg & 0x60))
{
// Retrigger DMA Transfer
USBDMARSET = 1 << EndPoint; //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -