⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc24xx_usb.c

📁 NXP LPC系列AMR7的开发程序源码(LCD
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************
 *
 *    Used with ICCARM and AARM.
 *
 *    (c) Copyright IAR Systems 2007
 *
 *    File name   : LPC24xx_usb.c
 *    Description : usb module (HAL)
 *
 *    History :
 *    1. Date        : January 7, 2007
 *       Author      : Stanimir Bonev
 *       Description : Create
 *
 *    $Revision: 18137 $
 **************************************************************************/

#define HAL_USB_GLOBAL
#include "LPC24xx_usb.h"

// Single/Double buffered EP flags
static const Boolean UsbEpDoubleBuffType[] =
{
  FALSE,  // OUT 0
  FALSE,  // IN 0
  FALSE,  // OUT 1
  FALSE,  // IN 1
  TRUE,   // OUT 2
  TRUE,   // IN 2
  TRUE,   // OUT 3
  TRUE,   // IN 3
  FALSE,  // OUT 4
  FALSE,  // IN 4
  TRUE,   // OUT 5
  TRUE,   // IN 5
  TRUE,   // OUT 6
  TRUE,   // IN 6
  FALSE,  // OUT 7
  FALSE,  // IN 7
  TRUE,   // OUT 8
  TRUE,   // IN 8
  TRUE,   // OUT 9
  TRUE,   // IN 9
  FALSE,  // OUT 10
  FALSE,  // IN 10
  TRUE,   // OUT 11
  TRUE,   // IN 11
  TRUE,   // OUT 12
  TRUE,   // IN 12
  FALSE,  // OUT 13
  FALSE,  // IN 13
  TRUE,   // OUT 14
  TRUE,   // IN 14
  TRUE,   // OUT 15
  TRUE,   // IN 15
};

static 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,
  // UsbClassEp0OutPacket
  NULL,
  // UsbVendorEp0OutPacket
  NULL,
  // UsbUserSofEvent
  NULL,
  // UsbUserClass
  NULL,
  // UsbUserVendor
  NULL,
  // UsbUserGetDescriptor
  NULL,
  // UsbUserConfigure
  NULL,
  // UsbUserReset
  NULL,
  // UsbUserConnect
  NULL,
  // UsbUserSuspend
  NULL,
  // UsbUserEpStall
  NULL,
  // UsbUserEpUnStall
  NULL,
  // UsbUserErrorEvent
  NULL,

};

static volatile UsbDevStat_t USB_DevStatus;

static EpInfo_t EpInfo[ENP_MAX_NUMB];

static UsbEpCtrl_t UsbEp0Ctrl;

static UsbSetupPacket_t UsbEp0SetupPacket;

#pragma data_alignment=4
static Int8U EpCtrlDataBuf[Ep0MaxSize];

static UsbDevCtrl_t UsbDevCtrl = {{UsbDevStatusUnknow,UsbDevStatusNoSuspend},0,0,0,0};

static CommUserFpnt_t UsbCoreT9Fun;

volatile Int32U EpPriority;
#include "usb_common.c"

/*************************************************************************
 * Function Name: USB_Cmd
 * Parameters:  Int16U Command, Int8U Data
 *
 * Return: Int32U - command result
 *
 * Description: Implement commands transmit to USB Engine
 *
 *************************************************************************/
static
Int32U USB_Cmd (Int16U Command, Int8U Data)
{
Int32U save, tmp = 0;
  // Disable interrupt and save current state of the interrupt flags
  save = __get_interrupt_state();
  __disable_interrupt();
  USBDEVINTCLR = bmUSB_CommDataFullInterrupt | bmUSB_CommRegEmptyInterrupt;
  // Load command in USB engine
  USBCMDCODE = ((Command&0xFF) << 16) + USB_CMD_WR;
  // Wait until command is accepted
  while ((USBDEVINTST & bmUSB_CommRegEmptyInterrupt) == 0);
  // clear Command reg. empty interrupt
  USBDEVINTCLR = 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:
    USBCMDCODE = (Data << 16) + USB_DATA_WR;
    while ((USBDEVINTST & bmUSB_CommRegEmptyInterrupt) == 0);
    break;
  case CMD_USB_RD_FRAME_NUMB:
  case CMD_USB_RD_TEST_REG:
    USBCMDCODE = (Command << 16) + USB_DATA_RD;
    while ((USBDEVINTST & bmUSB_CommDataFullInterrupt) == 0);
    USBDEVINTCLR = bmUSB_CommDataFullInterrupt;
    tmp = USBCMDDATA;
    USBCMDCODE = (Command << 16) + USB_DATA_RD;
    while ((USBDEVINTST & bmUSB_CommDataFullInterrupt) == 0);
    tmp |= USBCMDDATA << 8;
    break;
  case CMD_USB_GET_DEV_STAT:
  case CMD_USB_GET_ERROR:
  case CMD_USB_RD_ERROR_STAT:
  case CMD_USB_CLR_BUF:
    USBCMDCODE = (Command << 16) + USB_DATA_RD;
    while ((USBDEVINTST & bmUSB_CommDataFullInterrupt) == 0);
    tmp = USBCMDDATA;
    break;
  default:
    switch (Command & 0x1E0)
    {
    case CMD_USB_SEL_EP:
    case CMD_USB_SEL_CLR_INT_EP:
      USBCMDCODE = (Command << 16) + USB_DATA_RD;
      while ((USBDEVINTST & bmUSB_CommDataFullInterrupt) == 0);
      tmp = USBCMDDATA;
      break;
    case CMD_USB_SET_EP_STAT:
      USBCMDCODE = (Data << 16) + USB_DATA_WR;
      while ((USBDEVINTST & bmUSB_CommRegEmptyInterrupt) == 0);
      break;
    }
    break;
  }
  // restore the interrupt flags
  __set_interrupt_state(save);
  return(tmp);
}

/*************************************************************************
 * Function Name: USB_EpIntrClr
 * Parameters: USB_Endpoint_t EndPoint
 *
 * Return: Int8U
 *
 * Description: Clear the EP interrupt flag and return the current EP status
 *
 *************************************************************************/
static
Int8U USB_EpIntrClr(USB_Endpoint_t EndPoint)
{
volatile Int32U TO = 100;
  // Disable interrupt and save current state of the interrupt flags
Int32U save = __get_interrupt_state();
  __disable_interrupt();
  USBDEVINTCLR = bmUSB_CommDataFullInterrupt;
  USBEPINTCLR = 1 << EndPoint;
  while ((USBDEVINTST & bmUSB_CommDataFullInterrupt) == 0)
  {
    if(!--TO)
    {
      break;
    }
  }
  __set_interrupt_state(save);
  return(USBCMDDATA);
}

/*************************************************************************
 * Function Name: USB_Init
 * Parameters: Int32U IntrSlot,
 *
 * Return: none
 *
 * Description: Init USB
 *
 *************************************************************************/
void USB_Init(Int32U IntrSlot, CommUserFpnt_t UserCoreConfigure)
{
  // Init variables
  UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
  UsbCoreT9Fun = NULL;
  USB_UserFuncRegistering(UserCoreConfigure,UsbUserConfigure);
  EpPriority = 0;

  // Turn on USB
  PCONP_bit.PCUSB = 1;

#ifdef USB1_ERRATA
  // Errata 2006 Nov 16
  // USB_NEED_CLK is always asserted
  //  Introduction:The USB_NEED_CLK signal is used to facilitate going into and
  // waking up from chip Power Down mode. USB_NEED_CLK is asserted if any of the
  // bits of the USBClkSt register are asserted.
  //  Problem:The USB_NEED_CLK bit of the USBIntSt register (located at 0xE01F C1C0)
  // is always asserted, preventing the chip from entering Power Down mode when
  // the USBWAKE bit is set in the INTWAKE register (located at 0xE01F C144).
  //  Workaround:After setting the PCUSB bit in PCONP (located at 0xE01F C0C4),
  // write 0x1 to address 0xFFE0C008. The USB_NEED_CLK signal will now function correct
  if(RSIR_bit.POR == 1)
  {
    RSIR_bit.POR = 1;
    *(volatile unsigned int *)0xFFE0C008 = 1;
  }
#endif // USB1_ERRATA

  // Init USB engine clk freq - 48MHz
  // 1/3 Fpll - 48 MHz
  USBCLKCFG = USB_CLK_DIV-1;

  USBCLKCTRL = (1<<1) |   // Device clk enable
               (1<<3) |   // Port select clk enable
               (1<<2) |   // I2C clk enable
               (1<<4);    // AHB clk enable

  while((USBCLKST & ((1<<1) | (1<<3) | (1<<4))) != ((1<<1) | (1<<3) | (1<<4)));
  // USB IO assign
#if (USB_PORT_SEL==1)
  // Assign P0.29 to U1+, P0.30 to U1-
  PINSEL1_bit.P0_29  = 1;
  PINSEL1_bit.P0_30  = 1;

  // Enable Link LED, Connect, Vbus sense
  // and disable Pull Up/Down resistor of the Vbus pin
  PINSEL3_bit.P1_18  = 1;

  // Init OTG I2C
  PINSEL3_bit.P1_28  = 1;
  PINSEL3_bit.P1_29  = 1;

  // USB Port select
  USBPORTSEL_bit.PORTSEL = 0;

  USBCLKCTRL = (1<<1) |   // Device clk enable
               (1<<2) |   // I2C clk enable
               (1<<4);    // AHB clk enable

#else
  // Assign P0.31 to U2+
  PINSEL1_bit.P0_31  = 1;
  // Enable Link LED, Connect, Vbus sense
  // and disable Pull Up/Down resistor of the Vbus pin
  PINSEL0_bit.P0_13  = 1;

#ifdef USB3_ERRATA
  FIO0DIR_bit.P1_30  = 0;
  PINSEL3_bit.P1_30  = 0;
#else
  PINSEL3_bit.P1_30  = 2;
#endif // USB3_ERRATA
  PINMODE3_bit.P1_30 = 3;

  // USB Port select
  USBPORTSEL_bit.PORTSEL = 3;

  USBCLKCTRL = (1<<1) |   // Device clk enable
               (1<<4);    // AHB clk enable

#endif // (USB_PORT_SEL==1)

  // Disable USB interrupts
  USBINTS_bit.EN_USB_INTS = 0;

  // Clear all interrupts flags
  USBEPINTCLR = USBDEVINTCLR = 0xFFFFFFFF;

  // USB interrupt enable
  VIC_SetVectoredIRQ(USB_ISR,IntrSlot,VIC_USB);
  VICINTENABLE |= (1<<VIC_USB);

  // Disconnect device
  USB_ConnectRes(FALSE);

  // Set address 0
  USB_SetDefAdd();

  // Init controls endpoints
  USB_HwReset();

  // Init Device status
  UsbSetDevState(UsbDevStatusUnknow);

  // Enable USB interrupts
  USBINTS_bit.EN_USB_INTS = 1;

  // 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
 *
 *************************************************************************/
static
void USB_HwReset (void)
{

  // Disable all endpoint interrupts
  USBEPINTEN = 0;
  // Clear all EP interrupts flags
  USBEPINTCLR  = 0xFFFFFFFF;
  // Clear EP_SLOW, EP_FAST, FRAME interrupts flags
  USBDEVINTCLR = 0x7;
  // All endpoints interrupts are routed to LOW_PRIORITY interrupt
  EpPriority = USBEPINTPRI = 0;
  // USB_Configure
  USB_Configure(FALSE);

  // Control EP Init
  USB_UserFuncRegistering((UserFunc_t)UsbCtrlEp,UsbEp0Out);
  USB_UserFuncRegistering((UserFunc_t)UsbCtrlEp,UsbEp0In);
  USB_RealizeEp(CTRL_ENP_OUT,0,Ep0MaxSize,TRUE);

#if USB_DMA > 0
  // Enable End_of_Transfer_Interrupt and
  // System_Error_Interrupt USB DMA interrupts
	USB_DmaReset(DMA_INT_ENABLE_MASK);
#else
  // Disable the DMA operation
  USBEPDMADIS = 0xFFFFFFFF;
#endif

  // Assign high priority interrupt line
  USBDEVINTPRI = (USB_HIGH_PRIORITY_EVENT > 0)?
                  ((USB_HIGH_PRIORITY_EP  > 0)?bmUSB_HP_FastEp:bmUSB_HP_Frame):
                    0;

  // Enable Device interrupts
  USBDEVINTEN = bmUSB_SlowInterrupt | bmUSB_DevStatusInterrupt |
               (USB_SOF_EVENT   ? bmUSB_FrameInterrupt : 0)    |
               (USB_ERROR_EVENT ? bmUSB_ErrorInterrupt : 0)    |
              ((USB_FAST_EP || USB_HIGH_PRIORITY_EP)? bmUSB_FastInterrupt  : 0);
}

/*************************************************************************
 * Function Name: USB_RealizeEp
 * Parameters: USB_Endpoint_t EndPoint, Boolean FastIntr,
 *             Int32U MaxPacketSize, Boolean IntrEna
 *
 * Return: USB_ErrorCodes_t
 *
 * Description: Enable or disable endpoint
 *
 *************************************************************************/
USB_ErrorCodes_t USB_RealizeEp(USB_Endpoint_t EndPoint, Boolean FastIntr,
                               Int32U MaxPacketSize, Boolean IntrEna)
{
Int32U Mask = (1 << EndPoint);
  assert(!(((USB_FAST_EP == 0) && (USB_HIGH_PRIORITY_EP == 0)) && FastIntr));
  if (MaxPacketSize)
  {
    // Realize both directions of control EP
    if((EndPoint == CTRL_ENP_OUT) || (EndPoint == CTRL_ENP_IN))
    {
      // Output dir
      Mask = 1;
      EndPoint = CTRL_ENP_OUT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -