📄 lpc_usb.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2003
*
* File name : main.c
* Description : Define main module
*
* History :
* 1. Data : June 13, 2005
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 1.2 $
**************************************************************************/
#include "lpc_usb.h"
Fnpr IntrCallback;
/*************************************************************************
* Function Name: USB_Cmd
* Parameters: unsigned char Command
* unsigned char Data
* Return: unsigned int - command result
* Description: Implement a command transmit to USB Engine
*
*************************************************************************/
unsigned int USB_Cmd (unsigned short Command, unsigned char Data)
{
unsigned int cpu_sr, tmp = 0;
// Disable interrurp and save current state of the interrupt flags
cpu_sr = disable_interrupts();
// Clear Data reg full and Command reg. empry interrupts
DEVINTCLR = USB_CommRegEmptyInterrupt + USB_CommDataFullInterrupt;
// Load commonad in USB engine
CMDCODE = ((Command&0xFF) << 16) + USB_CMD_WR;
// Wait until command is accepted
while ((DEVINTS & USB_CommRegEmptyInterrupt) == 0);
// clear Command reg. empry interrupt
DEVINTCLR = USB_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 & USB_CommRegEmptyInterrupt) == 0);
break;
case CMD_USB_RD_FRAME_NUMB:
case CMD_USB_RD_TEST_REG:
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & USB_CommDataFullInterrupt) == 0);
DEVINTCLR = USB_CommDataFullInterrupt;
tmp = CMDDATA;
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & USB_CommDataFullInterrupt) == 0);
DEVINTCLR = USB_CommDataFullInterrupt;
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 & USB_CommDataFullInterrupt) == 0);
tmp = CMDDATA;
break;
default:
switch (Command & 0xE0)
{
case CMD_USB_SEL_EP:
case CMD_USB_SEL_CLR_INT_EP:
CMDCODE = (Command << 16) + USB_DATA_RD;
while ((DEVINTS & USB_CommDataFullInterrupt) == 0);
tmp = CMDDATA;
break;
case CMD_USB_SET_EP_STAT:
CMDCODE = (Data << 16) + USB_DATA_WR;
while ((DEVINTS & USB_CommRegEmptyInterrupt) == 0);
break;
}
break;
}
DEVINTCLR = USB_CommRegEmptyInterrupt + USB_CommDataFullInterrupt;
// restore the interrupt flags
restore_interrupts(cpu_sr);
return(tmp);
}
/*************************************************************************
* Function Name: USB_Init
* Parameters: int IntrSlot
* Fnpr UserIntrCallback
* USB_DEV_INT_PRIORITY_DEF DevIntrPrio
* Return: USB_ERROR_CODE_DEF
* USB_OK 0: Pass
* USB_ERROR 1: Error
* Description: Init USB
*
*************************************************************************/
USB_ERROR_CODES_DEF USB_Init(int IntrSlot, Fnpr UserIntrCallback,USB_DEV_INT_PRIORITY_DEF DevIntrPrio)
{
int p = 1, m = 48000000 / FOSC, Fpll, i;
if (IntrSlot > VIC_Slot15)
{
return(USB_INTR_ERROR);
}
// Find suitable value for P
for (i = 0; i < 4 ; ++i, p <<= 1)
{
Fpll = (FOSC << 1) * p * m;
if ((Fpll >= Fcco_MIN) && (Fpll <= Fcco_MAX))
{
break;
}
}
if (i >= 4)
{
// can't fond suitable value
return(USB_PLL_ERROR);
}
/* Turn on USB */
PM_OpenPeripheral(0x80000000);
// Enable Vbus sense
PINSEL1_bit.P0_23 = 1;
// 1 - GoodLinc
// 2 - ~Connect
PINSEL1_bit.P0_31 = 2;
// Init Pll for USB engine freq - 48MHz
PLL48CFG_bit.MSEL = m-1; //Fosc is define in LPC2148_sys_cnfg.h into [Hz]
PLL48CFG_bit.PSEL = i;
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;
IntrCallback = UserIntrCallback;
// USB interrupt connect to VIC
VIC_SetVectoredIRQ(USB_ISR,(LPC_VicIrqSlots_t)IntrSlot,VIC_USB);
VIC_EnableInt(1<<VIC_USB);
// init USB engine
DEVINTPRI = DevIntrPrio;
// EndPoint Init
REALIZEENDP = ENDPINTEN = 0x3;
ENDPINTCLR = 0xFFFFFFFF;
// Clear all interrupt flags
DEVINTCLR = 0x3FF;
// Eanble all interrupts
// without EP Realize, Command Reg Empty, Command Data Reg Full
DEVINTEN = 0x20E;
// Enable USB inerrupt
USBINTS_bit.EN_USB_INTS = 1;
return (USB_OK);
}
/*************************************************************************
* Function Name: USB_RealizeEndPoint
* Parameters: USB_ENDOPINT_DEF EndPoint - endpoiunt index
* int MaxPacketSize - When is 0 disable relevant endpoint
* USB_INT_PRIORITY_DEF IntrPriority
* int IntrEna
* Return: none
* Description: Enable or disable endpoint
*
*************************************************************************/
void USB_RealizeEndPoint( USB_ENDOPINT_DEF EndPoint,int MaxPacketSize,
USB_INT_PRIORITY_DEF IntrPriority, int IntrEna)
{
unsigned int Mask = (1 << EndPoint);
if (MaxPacketSize)
{
// Realize endpoit
REALIZEENDP |= Mask;
// Set endpoit maximum packet size
ENDPIND = EndPoint;
MAXPACKSIZE = MaxPacketSize;
// Wait for Realize complete
while ((DEVINTS & USB_EPRealizeInterrupt) == 0);
// Clear Endpoint Realize interrupt flag
DEVINTCLR = USB_EPRealizeInterrupt;
// Set endpoint interrupt priority
if (IntrPriority)
{
ENDPINTPRI |= Mask;
}
// Endpoint interrup flag clear and CDFULL flag!!!
ENDPINTCLR = Mask;
// Enable endpoint interrup
if (IntrEna) ENDPINTEN |= Mask;
}
else
{
Mask =~ Mask;
// Disable relevant endpoint and interrupt
REALIZEENDP &= Mask;
ENDPINTEN &= Mask;
}
}
/*************************************************************************
* Function Name: USB_ClearBuffer
* Parameters: USB_ENDOPINT_DEF EndPoint - endpoiunt index
* Return: Packet overwrite statrus
* Description: Clear buffer of the corresponding endpoint
*
*************************************************************************/
unsigned int USB_ClearBuffer(USB_ENDOPINT_DEF 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_ENDOPINT_DEF EndPoint - endpoiunt index
* Return: none
* Description: Validate buffer only of IN Endpoint
*
*************************************************************************/
void USB_ValidateBuffer(USB_ENDOPINT_DEF EndPoint)
{
if (EndPoint & 1)
{
USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
USB_Cmd(CMD_USB_VAL_BUF,0);
}
}
/*************************************************************************
* Function Name: USB_SetAdd
* Parameters: unsigned int DevAdd - defice address between 0 - 127
* Return: none
* Description: Set device address
*
*************************************************************************/
void USB_SetAdd(unsigned int DevAdd)
{
for(int i=2;i;--i)
{
USB_Cmd(CMD_USB_SET_ADDRESS,DevAdd | 0x80);
}
}
/*************************************************************************
* Function Name: USB_ISR
* Parameters: none
* Return: none
* Description: USB interrupt subroutine
*
*************************************************************************/
void USB_ISR (void)
{
IntrCallback();
VICVectAddr = 0; // Clear interrupt in VIC.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -