LPC_USB.c
上传用户:sourcesun
上传日期:2013-09-23
资源大小:362k
文件大小:26k
源码类别:

DNA

开发平台:

Asm

  1. /*************************************************************************
  2.  *
  3.  *    Used with ICCARM and AARM.
  4.  *
  5.  *    (c) Copyright IAR Systems 2003
  6.  *
  7.  *    File name   : lpc_usb.c
  8.  *    Description : usb module (HAL)
  9.  *
  10.  *    History :
  11.  *    1. Data        : June 13, 2005
  12.  *       Author      : Stanimir Bonev
  13.  *       Description : Create
  14.  *    2. Data        : August 4, 2005
  15.  *       Author      : Stanimir Bonev
  16.  *       Description : Modify
  17.  *        Modify some functions
  18.  *    3. Data        : November 18, 2005
  19.  *       Author      : Stanimir Bonev
  20.  *       Description : Modify
  21.  *        Add DMA support
  22.  *    4. Data        : December 9, 2005
  23.  *       Author      : Stanimir Bonev
  24.  *       Description : Modify
  25.  *        Fix DMA restart problem for IN EPs
  26.  *    5. Data        : December 20, 2005
  27.  *       Author      : Stanimir Bonev
  28.  *       Description : Modify
  29.  *        Change user function prototype
  30.  *    $Revision: 1.2.4.1 $
  31. **************************************************************************/
  32. #define LPC_USB_GLOBAL
  33. #include "lpc_usb.h"
  34. UsbDevStat_t USB_DevStatus;
  35. UserFunc_t UsbUserFun [UsbLastEvent] =
  36. {
  37.   // Ep 0 Out
  38.   NULL,
  39.   // Ep 0 In
  40.   NULL,
  41.   // Ep 1 Out
  42.   NULL,
  43.   // Ep 1 In
  44.   NULL,
  45.   // Ep 2 Out
  46.   NULL,
  47.   // Ep 2 Int
  48.   NULL,
  49.   // Ep 3 Out
  50.   NULL,
  51.   // Ep 3 In
  52.   NULL,
  53.   // Ep 4 Out
  54.   NULL,
  55.   // Ep 4 In
  56.   NULL,
  57.   // Ep 5 Out
  58.   NULL,
  59.   // Ep 5 In
  60.   NULL,
  61.   // Ep 6 Out
  62.   NULL,
  63.   // Ep 6 In
  64.   NULL,
  65.   // Ep 7 Out
  66.   NULL,
  67.   // Ep 7 In
  68.   NULL,
  69.   // Ep 8 Out
  70.   NULL,
  71.   // Ep 8 In
  72.   NULL,
  73.   // Ep 9 Out
  74.   NULL,
  75.   // Ep 9 In
  76.   NULL,
  77.   // Ep 10 Out
  78.   NULL,
  79.   // Ep 10 In
  80.   NULL,
  81.   // Ep 11 Out
  82.   NULL,
  83.   // Ep 11 In
  84.   NULL,
  85.   // Ep 12 Out
  86.   NULL,
  87.   // Ep 12 In
  88.   NULL,
  89.   // Ep 13 Out
  90.   NULL,
  91.   // Ep 13 In
  92.   NULL,
  93.   // Ep 14 Out
  94.   NULL,
  95.   // Ep 14 In
  96.   NULL,
  97.   // Ep 15 Out
  98.   NULL,
  99.   // Ep 15 In
  100.   NULL,
  101.   // UsbResetEvent
  102.   NULL,
  103.   // UsbConnectEvent
  104.   NULL,
  105.   // UsbSuspendEvent
  106.   NULL,
  107.   // UsbErrorEvent
  108.   NULL,
  109.   // UsbSofEvent
  110.   NULL,
  111.   // UsbHighPrioIntrEvent
  112.   NULL,
  113. };
  114. /*************************************************************************
  115.  * Function Name: USB_Cmd
  116.  * Parameters:  Int16U Command, Int8U Data
  117.  *
  118.  * Return: Int32U - command result
  119.  *
  120.  * Description: Implement commands transmit to USB Engine
  121.  *
  122.  *************************************************************************/
  123. Int32U USB_Cmd (Int16U Command, Int8U Data)
  124. {
  125. Int32U cpu_sr, tmp = 0;
  126.   // Disable interrurp and save current state of the interrupt flags
  127.   cpu_sr = disable_IRQ();
  128.   DEVINTCLR = bmUSB_CommDataFullInterrupt | bmUSB_CommRegEmptyInterrupt;
  129.   // Load commonad in USB engine
  130.   CMDCODE = ((Command&0xFF) << 16) + USB_CMD_WR;
  131.   // Wait until command is accepted
  132.   while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
  133.   // clear Command reg. empry interrupt
  134.   DEVINTCLR = bmUSB_CommRegEmptyInterrupt;
  135.   // determinate next phase of the command
  136.   switch (Command)
  137.   {
  138.   case CMD_USB_SET_ADDRESS:
  139.   case CMD_USB_CFG_DEV:
  140.   case CMD_USB_SET_MODE:
  141.   case CMD_USB_SET_DEV_STAT:
  142.     CMDCODE = (Data << 16) + USB_DATA_WR;
  143.     while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
  144.     break;
  145.   case CMD_USB_RD_FRAME_NUMB:
  146.   case CMD_USB_RD_TEST_REG:
  147.     CMDCODE = (Command << 16) + USB_DATA_RD;
  148.     while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
  149.     DEVINTCLR = bmUSB_CommDataFullInterrupt;
  150.     tmp = CMDDATA;
  151.     CMDCODE = (Command << 16) + USB_DATA_RD;
  152.     while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
  153.     tmp |= CMDDATA << 8;
  154.     break;
  155.   case CMD_USB_GET_DEV_STAT:
  156.   case CMD_USB_GET_ERROR:
  157.   case CMD_USB_RD_ERROR_STAT:
  158.   case CMD_USB_CLR_BUF:
  159.     CMDCODE = (Command << 16) + USB_DATA_RD;
  160.     while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
  161.     tmp = CMDDATA;
  162.     break;
  163.   default:
  164.     switch (Command & 0x1E0)
  165.     {
  166.     case CMD_USB_SEL_EP:
  167.     case CMD_USB_SEL_CLR_INT_EP:
  168.       CMDCODE = (Command << 16) + USB_DATA_RD;
  169.       while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
  170.       tmp = CMDDATA;
  171.       break;
  172.     case CMD_USB_SET_EP_STAT:
  173.       CMDCODE = (Data << 16) + USB_DATA_WR;
  174.       while ((DEVINTS & bmUSB_CommRegEmptyInterrupt) == 0);
  175.       break;
  176.     }
  177.     break;
  178.   }
  179.   // restore the interrupt flags
  180.   restore_IRQ(cpu_sr);
  181.   return(tmp);
  182. }
  183. /*************************************************************************
  184.  * Function Name: USB_UserFuncRegistered
  185.  * Parameters: UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd
  186.  *
  187.  * Return: UserFunc_t
  188.  *
  189.  * Description: Registered User callback function
  190.  *
  191.  *************************************************************************/
  192. UserFunc_t USB_UserFuncRegistered (UserFunc_t UserFunc, UsbUserEvent_t UserFuncInd)
  193. {
  194. UserFunc_t PrevUserFunc = UsbUserFun[UserFuncInd];
  195.   UsbUserFun[UserFuncInd] = (UserFunc_t) UserFunc;
  196.   return (PrevUserFunc);
  197. }
  198. /*************************************************************************
  199.  * Function Name: USB_EpIntrClr
  200.  * Parameters: USB_Endpoint_t EndPoint
  201.  *
  202.  * Return: Int8U
  203.  *
  204.  * Description: Clear the EP interrupt flag and return the current EP status
  205.  *
  206.  *************************************************************************/
  207. Int8U USB_EpIntrClr(USB_Endpoint_t EndPoint)
  208. {
  209.   ENDPINTCLR = 1 << EndPoint;
  210.   while ((DEVINTS & bmUSB_CommDataFullInterrupt) == 0);
  211.   return(CMDDATA);
  212. }
  213. /*************************************************************************
  214.  * Function Name: USB_HwInit
  215.  * Parameters: LPC_VicIrqSlots_t IntrSlot
  216.  *
  217.  * Return: none
  218.  *
  219.  * Description: Init USB
  220.  *
  221.  *************************************************************************/
  222. void USB_HwInit(LPC_VicIrqSlots_t IntrSlot)
  223. {
  224.   // Init softwate EP priority
  225.   USB_EpSoftPrio = 0;
  226.   // Init SOF number hold
  227.   #if  USB_SOF_EVENT > 0
  228.   USB_SofNumbHold = 0;
  229.   #endif
  230.   // Disable USB inerrupts
  231.   USBINTS_bit.EN_USB_INTS = 0;
  232.   /* Turn on USB */
  233.   PM_OpenPeripheral(0x80000000);
  234.   // Enable Vbus sense and Connect
  235.   PINSEL1_bit.P0_23 = 1;
  236.   PINSEL1_bit.P0_31 = 2;
  237.   // Init Pll for USB engine freq - 48MHz
  238.   //USB_PLL_M, USB_PLL_P are define in lpc_usb_cfg.h
  239.   PLL48CFG_bit.MSEL = USB_PLL_M-1;
  240.   PLL48CFG_bit.PSEL = USB_PLL_P;
  241.   PLL48CON_bit.PLLE = TRUE;     // Enable PLL
  242.   PLL48FEED = PLLFEED_DATA1;
  243.   PLL48FEED = PLLFEED_DATA2;
  244.   while (!PLL48STAT_bit.PLOCK); // Wait PLL lock
  245.   PLL48CON_bit.PLLC = TRUE;     // Connect PLL
  246.   PLL48FEED = PLLFEED_DATA1;
  247.   PLL48FEED = PLLFEED_DATA2;
  248.   // USB interrupt connect to VIC
  249.   VIC_SetVectoredIRQ(USB_ISR,(LPC_VicIrqSlots_t)IntrSlot,VIC_USB);
  250.   VIC_EnableInt(1<<VIC_USB);
  251.   // Enable USB inerrupts
  252.   USBINTS_bit.EN_USB_INTS = 1;
  253.   // Disconnect device
  254.   USB_Connect(FALSE);
  255.   // Set Arrdess 0
  256.   USB_SetDefAdd();
  257.   // Init controls endpoints
  258.   USB_HwReset();
  259.   // Init Device state var
  260.   USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
  261. }
  262. /*************************************************************************
  263.  * Function Name: USB_HwReset
  264.  * Parameters: none
  265.  *
  266.  * Return: none
  267.  *
  268.  * Description: Reset Usb engine
  269.  *
  270.  *************************************************************************/
  271. void USB_HwReset (void)
  272. {
  273.   // Disable all endpoint interrups
  274.   ENDPINTEN = 0;
  275.   // Frame is Hp interrupt
  276.   DEVINTPRI = 1;
  277.   // Clear all interupts flag
  278.   ENDPINTCLR  = DEVINTCLR = 0xFFFFFFFF;
  279.   // USB_Configure
  280.   USB_Configure(FALSE);
  281.   // EndPoint Init
  282.   USB_RealizeEndPoint(CTRL_ENP_OUT,0,Ep0MaxSize,TRUE);
  283.   USB_RealizeEndPoint(CTRL_ENP_IN, 1,Ep0MaxSize,TRUE);
  284. #if USB_DMA > 0
  285.   // Enable End_of_Transfer_Interrupt and
  286.   // System_Error_Interrupt USB DMA interrupts
  287. USB_DmaReset(DMA_INT_ENABLE_MASK);
  288. #endif
  289.   // Enable Device interrups
  290.   DEVINTEN = bmUSB_SlowInterrupt | bmUSB_DevStatusInterrupt |
  291.             (USB_HIGH_PRIORITY_EVENT ? bmUSB_FastInterrupt  : 0) |
  292.             (USB_SOF_EVENT           ? bmUSB_FrameInterrupt : 0) |
  293.             (USB_ERROR_EVENT         ? bmUSB_ErrorInterrupt : 0);
  294. }
  295. /*************************************************************************
  296.  * Function Name: USB_SetEpPrio
  297.  * Parameters: USB_Endpoint_t EndPoint,Boolean EpPrio
  298.  *
  299.  * Return: none
  300.  *
  301.  * Description: Set Endpoint priority
  302.  *
  303.  *************************************************************************/
  304. inline
  305. void USB_SetEpPrio (USB_Endpoint_t EndPoint,Boolean EpPrio)
  306. {
  307. Int32U Mask = 1 << EndPoint;
  308.   USB_EpSoftPrio = (EpPrio)?(USB_EpSoftPrio | Mask):(USB_EpSoftPrio & ~Mask);
  309. }
  310. /*************************************************************************
  311.  * Function Name: USB_RealizeEndPoint
  312.  * Parameters: USB_Endpoint_t EndPoint, Boolean EpPrio,
  313.  *                Int32U MaxPacketSize, Boolean IntrEna
  314.  *
  315.  * Return: none
  316.  *
  317.  * Description: Enable or disable endpoint
  318.  *
  319.  *************************************************************************/
  320. void USB_RealizeEndPoint( USB_Endpoint_t EndPoint, Boolean EpPrio,
  321.                              Int32U MaxPacketSize, Boolean IntrEna)
  322. {
  323. Int32U Mask = (1 << EndPoint);
  324.   // Init Ep software priority
  325.   USB_SetEpPrio(EndPoint,EpPrio);
  326.   if (MaxPacketSize)
  327.   {
  328.     // Clear  Realize interrupt bit
  329.     DEVINTCLR = bmUSB_EPRealizeInterrupt;
  330.     // Realize endpoit
  331.     REALIZEENDP  |= Mask;
  332.     // Set endpoit maximum packet size
  333.     ENDPIND       = EndPoint;
  334.     MAXPACKSIZE   = MaxPacketSize;
  335.     // Wait for Realize complete
  336.     while ((DEVINTS & bmUSB_EPRealizeInterrupt) == 0);
  337.     // Enable endpoint interrup
  338.     if (IntrEna)
  339.     {
  340.       ENDPINTEN |= Mask;
  341.     }
  342.     else
  343.     {
  344.       ENDPINTEN &= ~Mask;
  345.     }
  346.   }
  347.   else
  348.   {
  349.     Mask =~ Mask;
  350.     // Disable relevant endpoint and interrupt
  351.     REALIZEENDP &= Mask;
  352.     ENDPINTEN   &= Mask;
  353.   }
  354. }
  355. /*************************************************************************
  356.  * Function Name: USB_ClearBuffer
  357.  * Parameters: USB_Endpoint_t EndPoint - endpoiunt index
  358.  *
  359.  * Return: Int32U Packet overwrite statrus
  360.  *
  361.  * Description: Clear buffer of the corresponding endpoint
  362.  *
  363.  *************************************************************************/
  364. Int32U USB_ClearBuffer(USB_Endpoint_t EndPoint)
  365. {
  366.   // Select endpoint
  367.   USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
  368.   // Clear selected end point
  369.   return(USB_Cmd(CMD_USB_CLR_BUF,0));
  370. }
  371. /*************************************************************************
  372.  * Function Name: USB_ValidateBuffer
  373.  * Parameters: USB_Endpoint_t EndPoint - endpoiunt index
  374.  *
  375.  * Return: none
  376.  *
  377.  * Description: Validate buffer(only for IN Endpoints)
  378.  *
  379.  *************************************************************************/
  380. void USB_ValidateBuffer(USB_Endpoint_t EndPoint)
  381. {
  382.   if (EndPoint & 1)
  383.   {
  384.     USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
  385.     USB_Cmd(CMD_USB_VAL_BUF,0);
  386.   }
  387. }
  388. /*************************************************************************
  389.  * Function Name: USB_SetAdd
  390.  * Parameters: Int32U DevAdd - device address between 0 - 127
  391.  *
  392.  * Return: none
  393.  *
  394.  * Description: Set device address
  395.  *
  396.  *************************************************************************/
  397. void USB_SetAdd(Int32U DevAdd)
  398. {
  399.   USB_Cmd(CMD_USB_SET_ADDRESS,DevAdd | 0x80);
  400.   USB_Cmd(CMD_USB_SET_ADDRESS,DevAdd | 0x80);
  401. }
  402. /*************************************************************************
  403.  * Function Name: USB_Connect
  404.  * Parameters: Boolean Conn
  405.  *
  406.  * Return: none
  407.  *
  408.  * Description: Connect Usb
  409.  *
  410.  *************************************************************************/
  411. void USB_Connect (Boolean Conn)
  412. {
  413.   USB_Cmd(CMD_USB_SET_DEV_STAT, (Conn ? bmUSB_Connect : 0));
  414. }
  415. /*************************************************************************
  416.  * Function Name: USB_Configure
  417.  * Parameters: Boolean Configure
  418.  *
  419.  * Return: none
  420.  *
  421.  * Description: Configure device
  422.  *  When Configure != 0 enable all Realize Ep
  423.  *
  424.  *************************************************************************/
  425. void USB_Configure (Boolean Configure)
  426. {
  427.   USB_Cmd(CMD_USB_CFG_DEV,Configure);
  428. }
  429. /*************************************************************************
  430.  * Function Name: USB_WakeUp
  431.  * Parameters: none
  432.  *
  433.  * Return: none
  434.  *
  435.  * Description: Wake up Usb
  436.  *
  437.  *************************************************************************/
  438. void USB_WakeUp (void)
  439. {
  440.   USB_Cmd(CMD_USB_SET_DEV_STAT, bmUSB_Suspend | (USB_DevStatus.Connect?bmUSB_Connect:0));
  441. }
  442. /*************************************************************************
  443.  * Function Name: USB_GetDevStatus
  444.  * Parameters: USB_DevStatusReqType_t Type
  445.  *
  446.  * Return: Boolean
  447.  *
  448.  * Description: Return USB device status
  449.  *
  450.  *************************************************************************/
  451. Boolean USB_GetDevStatus (USB_DevStatusReqType_t Type)
  452. {
  453.   switch (Type)
  454.   {
  455.   case USB_DevConnectStatus:
  456.     return(USB_DevStatus.Connect);
  457.   case USB_SuspendStatus:
  458.     return(USB_DevStatus.Suspend);
  459.   case USB_ResetStatus:
  460.     return(USB_DevStatus.Reset);
  461.   }
  462.   return(FALSE);
  463. }
  464. /*************************************************************************
  465.  * Function Name: USB_SetStallEP
  466.  * Parameters: USB_Endpoint_t EndPoint, Boolean Stall
  467.  *
  468.  * Return: none
  469.  *
  470.  * Description: The endpoint stall/unstall
  471.  *
  472.  *************************************************************************/
  473. void USB_SetStallEP (USB_Endpoint_t EndPoint, Boolean Stall)
  474. {
  475.   USB_Cmd(CMD_USB_SET_EP_STAT | EndPoint, (Stall ? bmUSB_EpStall : 0));
  476. }
  477. /*************************************************************************
  478.  * Function Name: USB_GetStallEP
  479.  * Parameters: USB_Endpoint_t EndPoint
  480.  *
  481.  * Return: Boolean
  482.  *
  483.  * Description: Get stall state of the endpoint
  484.  *
  485.  *************************************************************************/
  486. Boolean USB_GetStallEP (USB_Endpoint_t EndPoint)
  487. {
  488.   return ((USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0) & bmUSB_EpStallStatus) != 0);
  489. }
  490. /*************************************************************************
  491.  * Function Name: USB_EpWrite
  492.  * Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
  493.  *
  494.  * Return: none
  495.  *
  496.  * Description: Endpoint Write (IN)
  497.  *
  498.  *************************************************************************/
  499. void USB_EpWrite (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
  500. {
  501.   // Convert EP physical address to logical and set write enable bit
  502.   USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlWrEna;
  503.   // Get data size
  504.   TPKTLEN = Count;
  505.   // Write data to SIE buffer
  506.   if(Count)
  507.   {
  508.     do
  509.     {
  510.       TDATA = *pData++;
  511.     }
  512.     while (USBCTRL_bit.WR_EN);
  513.   }
  514.   else
  515.   {
  516.     do
  517.     {
  518.       TDATA = 0;
  519.     }
  520.     while (USBCTRL_bit.WR_EN);
  521.   }
  522.   USBCTRL = 0;
  523.   USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
  524.   USB_Cmd(CMD_USB_VAL_BUF, 0);
  525. }
  526. /*************************************************************************
  527.  * Function Name: USB_EpRead
  528.  * Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
  529.  *
  530.  * Return: Int32
  531.  *
  532.  * Description: Endpoint Read (OUT)
  533.  *
  534.  *************************************************************************/
  535. Int32U USB_EpRead (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
  536. {
  537.   // Convert EP physical address to logical and set read enable bit
  538.   USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlRdEna;
  539.   while (RCVEPKTLEN_bit.PKT_RDY == 0);
  540.   // Get data size
  541.   Count = RCVEPKTLEN_bit.PKT_LNGTH;
  542.   // Read data from SIE buffer
  543.   while (RCVEPKTLEN_bit.DV)
  544.   {
  545.     *pData++ = RCVEDATA;
  546.   }
  547.   USBCTRL = 0;
  548.   USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
  549.   if(USB_Cmd(CMD_USB_CLR_BUF, 0) & bmUSB_PacketOverWritten)
  550.   {
  551.     Count |= 0x80000000;
  552.   }
  553.   return (Count);
  554. }
  555. /*************************************************************************
  556.  * Function Name: USB_ISR
  557.  * Parameters: none
  558.  *
  559.  * Return: none
  560.  *
  561.  * Description: USB interrupt subroutine
  562.  *
  563.  *************************************************************************/
  564. void USB_ISR (void)
  565. {
  566. Int32U EpIntr,Val,EpIntHold;
  567. UsbDevIntrStat_t UsbDevIntrSt = {DEVINTS};
  568. #if USB_DMA > 0
  569. if (USBINTS & 3)
  570. {
  571. #endif
  572. #if USB_HIGH_PRIORITY_EVENT > 0
  573.   // Fast EP interrupt
  574.   if(UsbDevIntrSt.Fast)
  575.   {
  576.     DEVINTCLR = bmUSB_FastInterrupt;
  577.     if(UsbUserFun[UsbHighPrioIntrEvent] != NULL)
  578.     {
  579.       UsbUserFun[UsbHighPrioIntrEvent]((void *)0);
  580.     }
  581.     // Clear Fast EP interrupt
  582.   }
  583. #endif
  584. #if USB_ERROR_EVENT > 0
  585.   // USB engine error interrupt
  586.   if(UsbDevIntrSt.Error)
  587.   {
  588.     DEVINTCLR = bmUSB_ErrorInterrupt;
  589.     Val = USB_Cmd(CMD_USB_RD_ERROR_STAT,0);
  590.     if(UsbUserFun[UsbErrorEvent] != NULL)
  591.     {
  592.       UsbUserFun[UsbErrorEvent]((void *)Val);
  593.     }
  594.   }
  595. #endif
  596. #if USB_SOF_EVENT > 0
  597.   // Frame interrupt
  598.   if(UsbDevIntrSt.Frame)
  599.   {
  600.     DEVINTCLR = bmUSB_FrameInterrupt;
  601. //     Val = USB_Cmd(CMD_USB_RD_FRAME_NUMB,0);
  602.     if(UsbUserFun[UsbSofEvent] != NULL)
  603.     {
  604.       UsbUserFun[UsbSofEvent]((void *)Val);
  605.     }
  606.   }
  607. #endif
  608.   // Device Status interrupt
  609.   if(UsbDevIntrSt.Status)
  610.   {
  611.     // Clear Device status interrupt
  612.     DEVINTCLR = bmUSB_DevStatusInterrupt;
  613.     // Get device status
  614.     USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
  615.     // Device connection status
  616.     if(USB_DevStatus.ConnectChange)
  617.     {
  618.       if(UsbUserFun[UsbConnectEvent] != NULL)
  619.       {
  620.         UsbUserFun[UsbConnectEvent]((void *)USB_DevStatus.Connect);
  621.       }
  622.     }
  623.     // Device suspend status
  624.     if(USB_DevStatus.SuspendChange)
  625.     {
  626.       if(UsbUserFun[UsbSuspendEvent] != NULL)
  627.       {
  628.         UsbUserFun[UsbSuspendEvent]((void *)USB_DevStatus.Suspend);
  629.       }
  630.     }
  631.     // Device reset
  632.     if(USB_DevStatus.Reset)
  633.     {
  634.       USB_HwReset();
  635.       if(UsbUserFun[UsbResetEvent] != NULL)
  636.       {
  637.         UsbUserFun[UsbResetEvent](NULL);
  638.       }
  639.     }
  640.   }
  641.   // Slow EP interrupt
  642.   if(UsbDevIntrSt.Slow)
  643.   {
  644.       // Clear Slow EP interrupt
  645.       DEVINTCLR = bmUSB_SlowInterrupt;
  646.     do
  647.     {
  648.       EpIntr = ENDPINTS;
  649.       // First Software High proirity and then low proirity
  650.         Int32U USB_EpSoftPrioHold = USB_EpSoftPrio;
  651.       for (Int32U i = 2; i; --i, USB_EpSoftPrioHold ^= 0xFFFFFFFF)
  652.       {
  653.       Int32U EpIntrCurrPrio = EpIntr & USB_EpSoftPrioHold;
  654.         // Output ctrl EP
  655.         if(EpIntrCurrPrio & 1)
  656.         {
  657.           Val = USB_EpIntrClr(CTRL_ENP_OUT);
  658.           if(UsbUserFun[UsbEp0Out] != NULL)
  659.           {
  660.             if(Val & bmUSB_EpSetupPacket)
  661.             {
  662.               UsbUserFun[UsbEp0Out]((void *)UsbSetupPacket);
  663.             }
  664.             else
  665.             {
  666.               UsbUserFun[UsbEp0Out]((void *)UsbDataOutPacket);
  667.             }
  668.           }
  669.           break;
  670.         }
  671.         // All other endpoints
  672.         for(Val = 1,EpIntHold = EpIntrCurrPrio >> 1; EpIntHold; ++Val,EpIntHold >>= 1)
  673.         {
  674.           if(EpIntHold & 1)
  675.           {
  676.             USB_EpIntrClr((USB_Endpoint_t)Val);
  677.             if(UsbUserFun[Val] != NULL)
  678.             {
  679.               UsbUserFun[Val]((void *)((Val&1)?UsbDataInPacket:UsbDataOutPacket));
  680.             }
  681.             break;
  682.           }
  683.         }
  684.       }
  685.     }
  686.     while(EpIntr);
  687.   }
  688. #if USB_DMA > 0
  689. }
  690. if (USBINTS_bit.USB_INT_REQ_DMA)
  691. {
  692.     // First Software High proirity and then low proirity
  693.     Int32U UsbDmaInt = 0,Tmp;
  694.     Tmp = EOTINTSTAT;
  695.     if(DMAINTEN & 1)
  696.     {
  697.       UsbDmaInt |= Tmp;
  698.     }
  699.     EOTINTCLR = Tmp;
  700.     Tmp = NEWDDRINTSTAT;
  701.     if(DMAINTEN & 2)
  702.     {
  703.       UsbDmaInt |= Tmp;
  704.     }
  705.     NEWDDRINTCLR = Tmp;
  706.     Tmp = SYSERRINTSTAT;
  707.     if(DMAINTEN & 4)
  708.     {
  709.       UsbDmaInt |= Tmp;
  710.     }
  711.     SYSERRINTCLR = Tmp;
  712.     for (Int32U i = 2; i; --i, USB_EpSoftPrio ^= 0xFFFFFFFF)
  713.     {
  714.       // All endpoints without ctrl EP_In, ctrl EP_Out
  715.       Int32U UsbDmaCurrPriorityInt = USB_EpSoftPrio & UsbDmaInt;
  716.       for(Int32U Val = 2, EpMask = 4; UsbDmaCurrPriorityInt; ++Val,EpMask <<= 1)
  717.       {
  718.         Int32U EpPriorityMask = UsbDmaCurrPriorityInt & EpMask;
  719.         if(EpPriorityMask == 0)
  720.         {
  721.           continue;
  722.         }
  723.         UsbDmaCurrPriorityInt &= ~EpMask;
  724.         // Collect Interrupts status flags and clear interrupt flags
  725.         if(EpPriorityMask && (UsbUserFun[Val] != NULL))
  726.         {
  727.           UsbUserFun[Val]((void *)UsbDmaPacket);
  728.         }
  729.       }
  730.     }
  731. }
  732. #endif
  733.   VICVectAddr = 0;    // Clear interrupt in VIC.
  734. }
  735. /*************************************************************************
  736.  * Function Name: USB_EpLogToPhysAdd
  737.  * Parameters: Int8U EpLogAdd
  738.  *
  739.  * Return: USB_Endpoint_t
  740.  *
  741.  * Description: Convert the logical to physical address
  742.  *
  743.  *************************************************************************/
  744. USB_Endpoint_t USB_EpLogToPhysAdd (Int8U EpLogAdd)
  745. {
  746. USB_Endpoint_t Address = (USB_Endpoint_t)((EpLogAdd & 0x0F)<<1);
  747.   if(EpLogAdd & 0x80)
  748.   {
  749.     ++Address;
  750.   }
  751.   return(Address);
  752. }
  753. /*************************************************************************
  754.  * Function Name: USB_GetFrameNumb
  755.  * Parameters: none
  756.  *
  757.  * Return: Int32U
  758.  *
  759.  * Description: Retunr curent value of SOF number
  760.  *
  761.  *************************************************************************/
  762. #if USB_SOF_EVENT > 0
  763. Int32U USB_GetFrameNumb (void)
  764. {
  765.   return(USB_SofNumbHold);
  766. }
  767. #endif
  768. /*************************************************************************
  769.  *                          U S B   D M A  P a r t                       *
  770.  *************************************************************************/
  771. #if USB_DMA > 0
  772. #pragma segment="DMA_RAM"
  773. #pragma location="DMA_RAM"
  774. #pragma data_alignment=128
  775. __no_init pUSB_DmaDesc_t USB_DDCA[ENP_MAX_NUMB];
  776. #pragma location="DMA_RAM"
  777. __no_init USB_DmaDesc_t USB_DmaDesc[DMA_DD_MAX_NUMB];
  778. /*************************************************************************
  779.  * Function Name: USB_DmaReset
  780.  * Parameters:  Int32U IntrEna
  781.  *
  782.  * Return: none
  783.  *
  784.  * Description: Reset USB DMA
  785.  *
  786.  *************************************************************************/
  787. void USB_DmaReset (Int32U IntrEna)
  788. {
  789.   // Disable All DMA interrupts
  790.   DMAINTEN = 0;
  791.   // DMA Disable
  792.   EPDMADIS      = 0xFFFFFFFF;
  793.   // DMA Request clear
  794.   DMARQSTCLR    = 0xFFFFFFFF;
  795.   // End of Transfer Interrupt Clear
  796.   EOTINTCLR     = 0xFFFFFFFF;
  797.   // New DD Request Interrupt Clear
  798.   NEWDDRINTCLR  = 0xFFFFFFFF;
  799.   // System Error Interrupt Clear
  800.   SYSERRINTCLR  = 0xFFFFFFFF;
  801. for(Int32U i = 0; i < ENP_MAX_NUMB; ++i)
  802.   {
  803.     USB_DDCA[i] = NULL;
  804.   }
  805.   // Set USB UDCA Head register
  806.   UDCAHEAD = (Int32U)&USB_DDCA;
  807.   // Enable DMA interrupts
  808.   DMAINTEN = IntrEna;
  809. }
  810. /*************************************************************************
  811.  * Function Name: USB_DmaInitTransfer
  812.  * Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
  813.  *             pInt32U pData, Int32U EpMaxSize, Int32U Size
  814.  *             pDmaIsoPacket_t pDmaIsoPacket,  Boolean EpTransferType
  815.  *
  816.  * Return: UsbDmaStateCode_t
  817.  *
  818.  * Description: Init Transfer by DMA
  819.  *
  820.  *************************************************************************/
  821. UsbDmaStateCode_t USB_DmaInitTransfer (USB_Endpoint_t EndPoint,
  822.           Int32U DmaDescInd, pInt32U pData, Int32U EpMaxSize, Int32U Size,
  823.           pDmaIsoPacket_t pDmaIsoPacket, Boolean EpTransferType)
  824. {
  825. Int32U EpReg;
  826.   if ((EndPoint == CTRL_ENP_OUT) || (EndPoint == CTRL_ENP_IN))
  827.   {
  828.     return(UsbDmaParametersError);
  829.   }
  830.   if (USB_DmaDesc[DmaDescInd].Status == UsbDmaBeingServiced)
  831.   {
  832.     return(UsbDmaBeingServiced);
  833.   }
  834.   // Init DMA Descriptor
  835.   USB_DmaDesc[DmaDescInd].pNextDD        = NULL;
  836.   USB_DmaDesc[DmaDescInd].NextDDValid    = FALSE;
  837.   USB_DmaDesc[DmaDescInd].pDmaIsoPacket  = pDmaIsoPacket;
  838.   USB_DmaDesc[DmaDescInd].DmaMode        = UsbDmaNormalMode;
  839.   USB_DmaDesc[DmaDescInd].Isochronous    = EpTransferType;
  840.   USB_DmaDesc[DmaDescInd].pDmaBuffer     = pData;
  841.   USB_DmaDesc[DmaDescInd].DmaBufferLegtn = Size;
  842.   USB_DmaDesc[DmaDescInd].MaxPacketSize  = EpMaxSize;
  843.   USB_DmaDesc[DmaDescInd].Status         = UsbDmaNoServiced;
  844.   // Set DD
  845.   USB_DDCA[EndPoint] = &USB_DmaDesc[DmaDescInd];
  846.   // Enable DMA Transfer
  847.   EPDMAEN = 1 << EndPoint;
  848.   // Check state of IN/OUT Ep buffer
  849.   EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
  850.   if( ((EndPoint & 1) && !(EpReg & 0x60)) ||
  851.      (!(EndPoint & 1) && ((EpReg & 0x60) == 0x60)))
  852.   {
  853.     if((USB_DmaDesc[DmaDescInd].DdState != UsbDmaBeingServiced))
  854.     {
  855.       // Retrigger DMA Transfer
  856.       DMARQSTSET = 1 << EndPoint;
  857.     }
  858.   }
  859.   return(UsbDmaNoServiced);
  860. }
  861. /*************************************************************************
  862.  * Function Name: USB_DmaGetDesc
  863.  * Parameters: Int32U DmaDescInd
  864.  *
  865.  * Return: pUSB_DmaDesc_t
  866.  *
  867.  * Description: Retur pointer to DMA descriptor
  868.  *
  869.  *************************************************************************/
  870. pUSB_DmaDesc_t USB_DmaGetDesc (Int32U DmaDescInd)
  871. {
  872.   return(&USB_DmaDesc[DmaDescInd]);
  873. }
  874. /*************************************************************************
  875.  * Function Name: USB_DmaDisable
  876.  * Parameters: USB_Endpoint_t EndPoint
  877.  *
  878.  * Return: none
  879.  *
  880.  * Description: Disable DMA transfer for the EP
  881.  *
  882.  *************************************************************************/
  883. void USB_DmaDisable (USB_Endpoint_t EndPoint)
  884. {
  885.   EPDMADIS = 1 << EndPoint;
  886. }
  887. /*************************************************************************
  888.  * Function Name: USB_DmaRestattTransfer
  889.  * Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
  890.  *             pInt32U pData, Int32U EpMaxSize, Int32U Size
  891.  *             pDmaIsoPacket_t pDmaIsoPacket,  Boolean EpTransferType
  892.  *
  893.  * Return: none
  894.  *
  895.  * Description: Restart DMA Transfer
  896.  *
  897.  *************************************************************************/
  898. void USB_DmaRestattTransfer (USB_Endpoint_t EndPoint,Int32U DmaDescInd)
  899. {
  900.   // Init DD DMA status
  901.   USB_DmaDesc[DmaDescInd].Status = UsbDmaNoServiced;
  902.   // Enable DMA Transfer
  903.   EPDMAEN = 1 << EndPoint;
  904.   // Check state of IN/OUT Ep buffer
  905.   Int32U EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
  906.   if(!(EndPoint & 1) && ((EpReg & 0x60) == 0x60))
  907.   {
  908.     // Retrigger DMA Transfer
  909.     DMARQSTSET = 1 << EndPoint;
  910.   }
  911.   else if ((EndPoint & 1) && !(EpReg & 0x60))
  912.   {
  913.     // Retrigger DMA Transfer
  914.     DMARQSTSET = 1 << EndPoint;   //