www.pudn.com > LPC2148_IAR_LPC2148.zip > lpc_usb.c
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2003
*
* File name : lpc_usb.c
* Description : usb module (HAL)
*
* History :
* 1. Data : June 13, 2005
* Author : Stanimir Bonev
* Description : Create
* 2. Data : August 4, 2005
* Author : Stanimir Bonev
* Description : Modify
* Modify some functions
* 3. Data : November 18, 2005
* Author : Stanimir Bonev
* Description : Modify
* Add DMA support
* 4. Data : December 9, 2005
* Author : Stanimir Bonev
* Description : Modify
* Fix DMA restart problem for IN EPs
* 5. Data : December 20, 2005
* Author : Stanimir Bonev
* Description : Modify
* Change user function prototype
* $Revision: 1.1.2.1 $
**************************************************************************/
#define LPC_USB_GLOBAL
#include "lpc_usb.h"
UsbDevStat_t USB_DevStatus;
UserFunc_t UsbUserFun [UsbLastEvent] =
{
// Ep 0 Out
NULL,
// Ep 0 In
NULL,
// Ep 1 Out
NULL,
// Ep 1 In
NULL,
// Ep 2 Out
NULL,
// Ep 2 Int
NULL,
// Ep 3 Out
NULL,
// Ep 3 In
NULL,
// Ep 4 Out
NULL,
// Ep 4 In
NULL,
// Ep 5 Out
NULL,
// Ep 5 In
NULL,
// Ep 6 Out
NULL,
// Ep 6 In
NULL,
// Ep 7 Out
NULL,
// Ep 7 In
NULL,
// Ep 8 Out
NULL,
// Ep 8 In
NULL,
// Ep 9 Out
NULL,
// Ep 9 In
NULL,
// Ep 10 Out
NULL,
// Ep 10 In
NULL,
// Ep 11 Out
NULL,
// Ep 11 In
NULL,
// Ep 12 Out
NULL,
// Ep 12 In
NULL,
// Ep 13 Out
NULL,
// Ep 13 In
NULL,
// Ep 14 Out
NULL,
// Ep 14 In
NULL,
// Ep 15 Out
NULL,
// Ep 15 In
NULL,
// UsbResetEvent
NULL,
// UsbConnectEvent
NULL,
// UsbSuspendEvent
NULL,
// UsbErrorEvent
NULL,
// UsbSofEvent
NULL,
// UsbHighPrioIntrEvent
NULL,
};
/*************************************************************************
* Function Name: USB_Cmd
* Parameters: Int16U Command, Int8U Data
*
* Return: Int32U - command result
*
* Description: Implement commands transmit to USB Engine
*
*************************************************************************/
Int32U USB_Cmd (Int16U Command, Int8U Data)
{
Int32U cpu_sr, tmp = 0;
// Disable interrurp and save current state of the interrupt flags
cpu_sr = disable_IRQ();
DEVINTCLR = bmUSB_CommDataFullInterrupt | bmUSB_CommRegEmptyInterrupt;
// Load commonad in USB engine
CMDCODE = ((Command&0xFF) << 16) + USB_CMD_WR;
// Wait until command is accepted
while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
// clear Command reg. empry interrupt
DEVINTCLR = bmUSB_CommRegEmptyInterrupt;
// determinate next phase of the command
switch (Command)
{
case CMD_USB_SET_ADDRESS:
case CMD_USB_CFG_DEV:
case CMD_USB_SET_MODE:
case CMD_USB_SET_DEV_STAT:
CMDCODE = (Data << 16) + USB_DATA_WR;
while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
break;
case CMD_USB_RD_FRAME_NUMB:
case CMD_USB_RD_TEST_REG:
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
DEVINTCLR = bmUSB_CommDataFullInterrupt;
tmp = CMDDATA;
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
tmp |= CMDDATA << 8;
break;
case CMD_USB_GET_DEV_STAT:
case CMD_USB_GET_ERROR:
case CMD_USB_RD_ERROR_STAT:
case CMD_USB_CLR_BUF:
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
tmp = CMDDATA;
break;
default:
switch (Command & 0x1E0)
{
case CMD_USB_SEL_EP:
case CMD_USB_SEL_CLR_INT_EP:
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
tmp = CMDDATA;
break;
case CMD_USB_SET_EP_STAT:
CMDCODE = (Data << 16) + USB_DATA_WR;
while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
break;
}
break;
}
// restore the interrupt flags
restore_IRQ(cpu_sr);
return(tmp);
}
/*************************************************************************
* Function Name: USB_UserFuncRegistered
* Parameters: UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd
*
* Return: UserFunc_t
*
* Description: Registered User callback function
*
*************************************************************************/
UserFunc_t USB_UserFuncRegistered (UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd)
{
UserFunc_t PrevUserFunc = UsbUserFun[UserFuncInd];
UsbUserFun[UserFuncInd] = (UserFunc_t) UserFunc;
return (PrevUserFunc);
}
/*************************************************************************
* Function Name: USB_EpIntrClr
* Parameters: USB_Endpoint_t EndPoint
*
* Return: Int8U
*
* Description: Clear the EP interrupt flag and return the current EP status
*
*************************************************************************/
Int8U USB_EpIntrClr(USB_Endpoint_t EndPoint)
{
ENDPINTCLR = 1 << EndPoint;
while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
return(CMDDATA);
}
/*************************************************************************
* Function Name: USB_HwInit
* Parameters: LPC_VicIrqSlots_t IntrSlot
*
* Return: none
*
* Description: Init USB
*
*************************************************************************/
void USB_HwInit(LPC_VicIrqSlots_t IntrSlot)
{
// Init softwate EP priority
USB_EpSoftPrio = 0;
// Init SOF number hold
#if USB_SOF_EVENT > 0
USB_SofNumbHold = 0;
#endif
// Disable USB inerrupts
USBINTS_bit.EN_USB_INTS = 0;
/* Turn on USB */
PM_OpenPeripheral(0x80000000);
// Enable Vbus sense and Connect
PINSEL1_bit.P0_23 = 1;
PINSEL1_bit.P0_31 = 2;
// Init Pll for USB engine freq - 48MHz
//USB_PLL_M, USB_PLL_P are define in lpc_usb_cfg.h
PLL48CFG_bit.MSEL = USB_PLL_M-1;
PLL48CFG_bit.PSEL = USB_PLL_P;
PLL48CON_bit.PLLE = TRUE; // Enable PLL
PLL48FEED = PLLFEED_DATA1;
PLL48FEED = PLLFEED_DATA2;
while (!PLL48STAT_bit.PLOCK); // Wait PLL lock
PLL48CON_bit.PLLC = TRUE; // Connect PLL
PLL48FEED = PLLFEED_DATA1;
PLL48FEED = PLLFEED_DATA2;
// USB interrupt connect to VIC
VIC_SetVectoredIRQ(USB_ISR,(LPC_VicIrqSlots_t)IntrSlot,VIC_USB);
VIC_EnableInt(1< 0
// Enable End_of_Transfer_Interrupt and
// System_Error_Interrupt USB DMA interrupts
USB_DmaReset(DMA_INT_ENABLE_MASK);
#endif
// Enable Device interrups
DEVINTEN = bmUSB_SlowInterrupt | bmUSB_DevStatusInterrupt |
(USB_HIGH_PRIORITY_EVENT ? bmUSB_FastInterrupt : 0) |
(USB_SOF_EVENT ? bmUSB_FrameInterrupt : 0) |
(USB_ERROR_EVENT ? bmUSB_ErrorInterrupt : 0);
}
/*************************************************************************
* Function Name: USB_SetEpPrio
* Parameters: USB_Endpoint_t EndPoint,Boolean EpPrio
*
* Return: none
*
* Description: Set Endpoint priority
*
*************************************************************************/
inline
void USB_SetEpPrio (USB_Endpoint_t EndPoint,Boolean EpPrio)
{
Int32U Mask = 1 << EndPoint;
USB_EpSoftPrio = (EpPrio)?(USB_EpSoftPrio | Mask):(USB_EpSoftPrio & ~Mask);
}
/*************************************************************************
* Function Name: USB_RealizeEndPoint
* Parameters: USB_Endpoint_t EndPoint, Boolean EpPrio,
* Int32U MaxPacketSize, Boolean IntrEna
*
* Return: none
*
* Description: Enable or disable endpoint
*
*************************************************************************/
void USB_RealizeEndPoint( USB_Endpoint_t EndPoint, Boolean EpPrio,
Int32U MaxPacketSize, Boolean IntrEna)
{
Int32U Mask = (1 << EndPoint);
// Init Ep software priority
USB_SetEpPrio(EndPoint,EpPrio);
if (MaxPacketSize)
{
// Clear Realize interrupt bit
DEVINTCLR = bmUSB_EPRealizeInterrupt;
// Realize endpoit
REALIZEENDP |= Mask;
// Set endpoit maximum packet size
ENDPIND = EndPoint;
MAXPACKSIZE = MaxPacketSize;
// Wait for Realize complete
while ((DEVINTS & bmUSB_EPRealizeInterrupt) == 0);
// Enable endpoint interrup
if (IntrEna)
{
ENDPINTEN |= Mask;
}
else
{
ENDPINTEN &= ~Mask;
}
}
else
{
Mask =~ Mask;
// Disable relevant endpoint and interrupt
REALIZEENDP &= Mask;
ENDPINTEN &= Mask;
}
}
/*************************************************************************
* Function Name: USB_ClearBuffer
* Parameters: USB_Endpoint_t EndPoint - endpoiunt index
*
* Return: Int32U Packet overwrite statrus
*
* Description: Clear buffer of the corresponding endpoint
*
*************************************************************************/
Int32U USB_ClearBuffer(USB_Endpoint_t EndPoint)
{
// Select endpoint
USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
// Clear selected end point
return(USB_Cmd(CMD_USB_CLR_BUF,0));
}
/*************************************************************************
* Function Name: USB_ValidateBuffer
* Parameters: USB_Endpoint_t EndPoint - endpoiunt index
*
* Return: none
*
* Description: Validate buffer(only for IN Endpoints)
*
*************************************************************************/
void USB_ValidateBuffer(USB_Endpoint_t EndPoint)
{
if (EndPoint & 1)
{
USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
USB_Cmd(CMD_USB_VAL_BUF,0);
}
}
/*************************************************************************
* Function Name: USB_SetAdd
* Parameters: Int32U DevAdd - device address between 0 - 127
*
* Return: none
*
* Description: Set device address
*
*************************************************************************/
void USB_SetAdd(Int32U DevAdd)
{
USB_Cmd(CMD_USB_SET_ADDRESS,DevAdd | 0x80);
USB_Cmd(CMD_USB_SET_ADDRESS,DevAdd | 0x80);
}
/*************************************************************************
* Function Name: USB_Connect
* Parameters: Boolean Conn
*
* Return: none
*
* Description: Connect Usb
*
*************************************************************************/
void USB_Connect (Boolean Conn)
{
USB_Cmd(CMD_USB_SET_DEV_STAT, (Conn ? bmUSB_Connect : 0));
}
/*************************************************************************
* Function Name: USB_Configure
* Parameters: Boolean Configure
*
* Return: none
*
* Description: Configure device
* When Configure != 0 enable all Realize Ep
*
*************************************************************************/
void USB_Configure (Boolean Configure)
{
USB_Cmd(CMD_USB_CFG_DEV,Configure);
}
/*************************************************************************
* Function Name: USB_WakeUp
* Parameters: none
*
* Return: none
*
* Description: Wake up Usb
*
*************************************************************************/
void USB_WakeUp (void)
{
USB_Cmd(CMD_USB_SET_DEV_STAT, bmUSB_Suspend | (USB_DevStatus.Connect?bmUSB_Connect:0));
}
/*************************************************************************
* Function Name: USB_GetDevStatus
* Parameters: USB_DevStatusReqType_t Type
*
* Return: Boolean
*
* Description: Return USB device status
*
*************************************************************************/
Boolean USB_GetDevStatus (USB_DevStatusReqType_t Type)
{
switch (Type)
{
case USB_DevConnectStatus:
return(USB_DevStatus.Connect);
case USB_SuspendStatus:
return(USB_DevStatus.Suspend);
case USB_ResetStatus:
return(USB_DevStatus.Reset);
}
return(FALSE);
}
/*************************************************************************
* 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; // А защо е така кой ще ми каже????
}
}
#endif // USB_DMA