📄 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.2.4.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<<VIC_USB);
// Enable USB inerrupts
USBINTS_bit.EN_USB_INTS = 1;
// Disconnect device
USB_Connect(FALSE);
// Set Arrdess 0
USB_SetDefAdd();
// Init controls endpoints
USB_HwReset();
// Init Device state var
USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
}
/*************************************************************************
* Function Name: USB_HwReset
* Parameters: none
*
* Return: none
*
* Description: Reset Usb engine
*
*************************************************************************/
void USB_HwReset (void)
{
// Disable all endpoint interrups
ENDPINTEN = 0;
// Frame is Hp interrupt
DEVINTPRI = 1;
// Clear all interupts flag
ENDPINTCLR = DEVINTCLR = 0xFFFFFFFF;
// USB_Configure
USB_Configure(FALSE);
// EndPoint Init
USB_RealizeEndPoint(CTRL_ENP_OUT,0,Ep0MaxSize,TRUE);
USB_RealizeEndPoint(CTRL_ENP_IN, 1,Ep0MaxSize,TRUE);
#if USB_DMA > 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -