I messed up the merge, so pushing it over to another repo so I don't lose it. Will tidy up and remove later

Dependencies:   BufferedSerial FatFileSystemCpp mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbhost_lpc17xx.cpp Source File

usbhost_lpc17xx.cpp

00001 /*
00002 **************************************************************************************************************
00003 *                                                 NXP USB Host Stack
00004 *
00005 *                                     (c) Copyright 2008, NXP SemiConductors
00006 *                                     (c) Copyright 2008, OnChip  Technologies LLC
00007 *                                                 All Rights Reserved
00008 *
00009 *                                                  www.nxp.com
00010 *                                               www.onchiptech.com
00011 *
00012 * File           : usbhost_lpc17xx.c
00013 * Programmer(s)  : Ravikanth.P
00014 * Version        :
00015 *
00016 **************************************************************************************************************
00017 */
00018  
00019 /*
00020 **************************************************************************************************************
00021 *                                            INCLUDE HEADER FILES
00022 **************************************************************************************************************
00023 */
00024 
00025 #include  "usbhost_lpc17xx.h"
00026 
00027 /*
00028 **************************************************************************************************************
00029 *                                              GLOBAL VARIABLES
00030 **************************************************************************************************************
00031 */
00032 int gUSBConnected;
00033 
00034 volatile  USB_INT32U   HOST_RhscIntr = 0;         /* Root Hub Status Change interrupt                       */
00035 volatile  USB_INT32U   HOST_WdhIntr  = 0;         /* Semaphore to wait until the TD is submitted            */
00036 volatile  USB_INT08U   HOST_TDControlStatus = 0;
00037 volatile  HCED        *EDCtrl;                    /* Control endpoint descriptor structure                  */
00038 volatile  HCED        *EDBulkIn;                  /* BulkIn endpoint descriptor  structure                  */
00039 volatile  HCED        *EDBulkOut;                 /* BulkOut endpoint descriptor structure                  */
00040 volatile  HCTD        *TDHead;                    /* Head transfer descriptor structure                     */
00041 volatile  HCTD        *TDTail;                    /* Tail transfer descriptor structure                     */
00042 volatile  HCCA        *Hcca;                      /* Host Controller Communications Area structure          */ 
00043           USB_INT16U  *TDBufNonVol;               /* Identical to TDBuffer just to reduce compiler warnings */
00044 volatile  USB_INT08U  *TDBuffer;                  /* Current Buffer Pointer of transfer descriptor          */
00045 
00046 // USB host structures
00047 // AHB SRAM block 1
00048 //#define HOSTBASEADDR 0x20080000
00049 // block 0
00050 #define HOSTBASEADDR 0x2007C000
00051 // reserve memory for the linker
00052 //static USB_INT08U HostBuf[0x200] __attribute__((at(HOSTBASEADDR)));
00053 static USB_INT08U HostBuf[0x200]; //__attribute__((at(HOSTBASEADDR)));
00054 /*
00055 **************************************************************************************************************
00056 *                                         DELAY IN MILLI SECONDS
00057 *
00058 * Description: This function provides a delay in milli seconds
00059 *
00060 * Arguments  : delay    The delay required
00061 *
00062 * Returns    : None
00063 *
00064 **************************************************************************************************************
00065 */
00066 
00067 void  Host_DelayMS (USB_INT32U  delay)
00068 {
00069     volatile  USB_INT32U  i;
00070 
00071 
00072     for (i = 0; i < delay; i++) {
00073         Host_DelayUS(1000);
00074     }
00075 }
00076 
00077 /*
00078 **************************************************************************************************************
00079 *                                         DELAY IN MICRO SECONDS
00080 *
00081 * Description: This function provides a delay in micro seconds
00082 *
00083 * Arguments  : delay    The delay required
00084 *
00085 * Returns    : None
00086 *
00087 **************************************************************************************************************
00088 */
00089 
00090 void  Host_DelayUS (USB_INT32U  delay)
00091 {
00092     volatile  USB_INT32U  i;
00093 
00094 
00095     for (i = 0; i < (4 * delay); i++) {    /* This logic was tested. It gives app. 1 micro sec delay        */
00096         ;
00097     }
00098 }
00099 
00100 // bits of the USB/OTG clock control register
00101 #define HOST_CLK_EN     (1<<0)
00102 #define DEV_CLK_EN      (1<<1)
00103 #define PORTSEL_CLK_EN  (1<<3)
00104 #define AHB_CLK_EN      (1<<4)
00105 
00106 // bits of the USB/OTG clock status register
00107 #define HOST_CLK_ON     (1<<0)
00108 #define DEV_CLK_ON      (1<<1)
00109 #define PORTSEL_CLK_ON  (1<<3)
00110 #define AHB_CLK_ON      (1<<4)
00111 
00112 // we need host clock, OTG/portsel clock and AHB clock
00113 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
00114 
00115 /*
00116 **************************************************************************************************************
00117 *                                         INITIALIZE THE HOST CONTROLLER
00118 *
00119 * Description: This function initializes lpc17xx host controller
00120 *
00121 * Arguments  : None
00122 *
00123 * Returns    : 
00124 *
00125 **************************************************************************************************************
00126 */
00127 void  Host_Init (void)
00128 {
00129     PRINT_Log("In Host_Init\n");
00130     NVIC_DisableIRQ(USB_IRQn);                           /* Disable the USB interrupt source           */
00131     
00132     // turn on power for USB
00133     LPC_SC->PCONP       |= (1UL<<31);
00134     // Enable USB host clock, port selection and AHB clock
00135     LPC_USB->USBClkCtrl |= CLOCK_MASK;
00136     // Wait for clocks to become available
00137     while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
00138         ;
00139     
00140     // it seems the bits[0:1] mean the following
00141     // 0: U1=device, U2=host
00142     // 1: U1=host, U2=host
00143     // 2: reserved
00144     // 3: U1=host, U2=device
00145     // NB: this register is only available if OTG clock (aka "port select") is enabled!!
00146     // since we don't care about port 2, set just bit 0 to 1 (U1=host)
00147     LPC_USB->OTGStCtrl |= 1;
00148     
00149     // now that we've configured the ports, we can turn off the portsel clock
00150     LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
00151     
00152     // power pins are not connected on mbed, so we can skip them
00153     /* P1[18] = USB_UP_LED, 01 */
00154     /* P1[19] = /USB_PPWR,     10 */
00155     /* P1[22] = USB_PWRD, 10 */
00156     /* P1[27] = /USB_OVRCR, 10 */
00157     /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));  
00158     LPC_PINCON->PINSEL3 |=  ((1<<4)|(2<<6) | (2<<12) | (2<<22));   // 0x00802080
00159     */
00160 
00161     // configure USB D+/D- pins
00162     /* P0[29] = USB_D+, 01 */
00163     /* P0[30] = USB_D-, 01 */
00164     LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));  
00165     LPC_PINCON->PINSEL1 |=  ((1<<26)|(1<<28));     // 0x14000000
00166         
00167     PRINT_Log("Initializing Host Stack\n");
00168 
00169     Hcca       = (volatile  HCCA       *)(HostBuf+0x000);
00170     TDHead     = (volatile  HCTD       *)(HostBuf+0x100);
00171     TDTail     = (volatile  HCTD       *)(HostBuf+0x110);
00172     EDCtrl     = (volatile  HCED       *)(HostBuf+0x120); 
00173     EDBulkIn   = (volatile  HCED       *)(HostBuf+0x130);
00174     EDBulkOut  = (volatile  HCED       *)(HostBuf+0x140);
00175     TDBuffer   = (volatile  USB_INT08U *)(HostBuf+0x150);
00176     
00177     /* Initialize all the TDs, EDs and HCCA to 0  */
00178     Host_EDInit(EDCtrl);
00179     Host_EDInit(EDBulkIn);
00180     Host_EDInit(EDBulkOut);
00181     Host_TDInit(TDHead);
00182     Host_TDInit(TDTail);
00183     Host_HCCAInit(Hcca);
00184     
00185     Host_DelayMS(50);                                   /* Wait 50 ms before apply reset              */
00186     LPC_USB->HcControl       = 0;                       /* HARDWARE RESET                             */
00187     LPC_USB->HcControlHeadED = 0;                       /* Initialize Control list head to Zero       */
00188     LPC_USB->HcBulkHeadED    = 0;                       /* Initialize Bulk list head to Zero          */
00189     
00190                                                         /* SOFTWARE RESET                             */
00191     LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
00192     LPC_USB->HcFmInterval    = DEFAULT_FMINTERVAL;      /* Write Fm Interval and Largest Data Packet Counter */
00193 
00194                                                         /* Put HC in operational state                */
00195     LPC_USB->HcControl  = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
00196     LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;            /* Set Global Power                           */
00197     
00198     LPC_USB->HcHCCA = (USB_INT32U)Hcca;
00199     LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;                   /* Clear Interrrupt Status                    */
00200 
00201 
00202     LPC_USB->HcInterruptEnable  = OR_INTR_ENABLE_MIE |
00203                          OR_INTR_ENABLE_WDH |
00204                          OR_INTR_ENABLE_RHSC;
00205 
00206     NVIC_SetPriority(USB_IRQn, 0);       /* highest priority */
00207     /* Enable the USB Interrupt */
00208     NVIC_EnableIRQ(USB_IRQn);
00209     PRINT_Log("Host Initialized\n");
00210 }
00211 
00212 /*
00213 **************************************************************************************************************
00214 *                                         INTERRUPT SERVICE ROUTINE
00215 *
00216 * Description: This function services the interrupt caused by host controller
00217 *
00218 * Arguments  : None
00219 *
00220 * Returns    : None
00221 *
00222 **************************************************************************************************************
00223 */
00224 
00225 void USB_IRQHandler (void) __irq
00226 {
00227     USB_INT32U   int_status;
00228     USB_INT32U   ie_status;
00229 
00230     int_status    = LPC_USB->HcInterruptStatus;                          /* Read Interrupt Status                */
00231     ie_status     = LPC_USB->HcInterruptEnable;                          /* Read Interrupt enable status         */
00232  
00233     if (!(int_status & ie_status)) {
00234         return;
00235     } else {
00236 
00237         int_status = int_status & ie_status;
00238         if (int_status & OR_INTR_STATUS_RHSC) {                 /* Root hub status change interrupt     */
00239             if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
00240                 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
00241                     /*
00242                      * When DRWE is on, Connect Status Change
00243                      * means a remote wakeup event.
00244                     */
00245                     HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
00246                 }
00247                 else {
00248                     /*
00249                      * When DRWE is off, Connect Status Change
00250                      * is NOT a remote wakeup event
00251                     */
00252                     if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
00253                         if (!gUSBConnected) {
00254                             HOST_TDControlStatus = 0;
00255                             HOST_WdhIntr = 0;
00256                             HOST_RhscIntr = 1;
00257                             gUSBConnected = 1;
00258                         }
00259                         else
00260                             PRINT_Log("Spurious status change (connected)?\n");
00261                     } else {
00262                         if (gUSBConnected) {
00263                             LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts???
00264                             HOST_RhscIntr = 0;
00265                             gUSBConnected = 0;
00266                         }
00267                         else
00268                             PRINT_Log("Spurious status change (disconnected)?\n");
00269                     }
00270                 }
00271                 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
00272             }
00273             if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
00274                 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
00275             }
00276         }
00277         if (int_status & OR_INTR_STATUS_WDH) {                  /* Writeback Done Head interrupt        */
00278             HOST_WdhIntr = 1;
00279             HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf;
00280         }            
00281         LPC_USB->HcInterruptStatus = int_status;                         /* Clear interrupt status register      */
00282     }
00283     return;
00284 }
00285 
00286 /*
00287 **************************************************************************************************************
00288 *                                     PROCESS TRANSFER DESCRIPTOR
00289 *
00290 * Description: This function processes the transfer descriptor
00291 *
00292 * Arguments  : ed            Endpoint descriptor that contains this transfer descriptor
00293 *              token         SETUP, IN, OUT
00294 *              buffer        Current Buffer Pointer of the transfer descriptor
00295 *              buffer_len    Length of the buffer
00296 *
00297 * Returns    : OK       if TD submission is successful
00298 *              ERROR    if TD submission fails
00299 *
00300 **************************************************************************************************************
00301 */
00302 
00303 USB_INT32S  Host_ProcessTD (volatile  HCED       *ed,
00304                             volatile  USB_INT32U  token,
00305                             volatile  USB_INT08U *buffer,
00306                                       USB_INT32U  buffer_len)
00307 {
00308     volatile  USB_INT32U   td_toggle;
00309 
00310 
00311     if (ed == EDCtrl) {
00312         if (token == TD_SETUP) {
00313             td_toggle = TD_TOGGLE_0;
00314         } else {
00315             td_toggle = TD_TOGGLE_1;
00316         }
00317     } else {
00318         td_toggle = 0;
00319     }
00320     TDHead->Control = (TD_ROUNDING    |
00321                       token           |
00322                       TD_DELAY_INT(0) |                           
00323                       td_toggle       |
00324                       TD_CC);
00325     TDTail->Control = 0;
00326     TDHead->CurrBufPtr   = (USB_INT32U) buffer;
00327     TDTail->CurrBufPtr   = 0;
00328     TDHead->Next         = (USB_INT32U) TDTail;
00329     TDTail->Next         = 0;
00330     TDHead->BufEnd       = (USB_INT32U)(buffer + (buffer_len - 1));
00331     TDTail->BufEnd       = 0;
00332 
00333     ed->HeadTd  = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002);
00334     ed->TailTd  = (USB_INT32U)TDTail;
00335     ed->Next    = 0;
00336 
00337     if (ed == EDCtrl) {
00338         LPC_USB->HcControlHeadED = (USB_INT32U)ed;
00339         LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
00340         LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_CLE;
00341     } else {
00342         LPC_USB->HcBulkHeadED    = (USB_INT32U)ed;
00343         LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
00344         LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_BLE;
00345     }    
00346 
00347     Host_WDHWait();
00348 
00349 //    if (!(TDHead->Control & 0xF0000000)) {
00350     if (!HOST_TDControlStatus) {
00351         return (OK);
00352     } else {      
00353         return (ERR_TD_FAIL);
00354     }
00355 }
00356 
00357 /*
00358 **************************************************************************************************************
00359 *                                       ENUMERATE THE DEVICE
00360 *
00361 * Description: This function is used to enumerate the device connected
00362 *
00363 * Arguments  : None
00364 *
00365 * Returns    : None
00366 *
00367 **************************************************************************************************************
00368 */
00369 
00370 USB_INT32S  Host_EnumDev (void)
00371 {
00372     USB_INT32S  rc;
00373 
00374     PRINT_Log("Connect a Mass Storage device\n");
00375     if (!HOST_RhscIntr)
00376         return 0;
00377         
00378             Host_DelayMS(100);                             /* USB 2.0 spec says atleast 50ms delay beore port reset */
00379     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
00380     while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
00381         __WFI(); // Wait for port reset to complete...
00382     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
00383     Host_DelayMS(200);                                                 /* Wait for 100 MS after port reset  */
00384 
00385     EDCtrl->Control = 8 << 16;                                         /* Put max pkt size = 8              */
00386                                                                        /* Read first 8 bytes of device desc */
00387     rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
00388     if (rc != OK) {
00389         PRINT_Err(rc);
00390         return (rc);
00391     }
00392     EDCtrl->Control = TDBuffer[7] << 16;                               /* Get max pkt size of endpoint 0    */
00393     rc = HOST_SET_ADDRESS(1);                                          /* Set the device address to 1       */
00394     if (rc != OK) {
00395         PRINT_Err(rc);
00396         return (rc);
00397     }
00398     Host_DelayMS(2);
00399     EDCtrl->Control = (EDCtrl->Control) | 1;                          /* Modify control pipe with address 1 */
00400                                                                       /* Get the configuration descriptor   */
00401     rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
00402     if (rc != OK) {
00403         PRINT_Err(rc);
00404         return (rc);
00405     }
00406                                                                        /* Get the first configuration data  */
00407     rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2]));
00408     if (rc != OK) {
00409         PRINT_Err(rc);
00410         return (rc);
00411     }
00412     rc = MS_ParseConfiguration();                                      /* Parse the configuration           */
00413     if (rc != OK) {
00414         PRINT_Err(rc);
00415         return (rc);
00416     }
00417     rc = USBH_SET_CONFIGURATION(1);                                    /* Select device configuration 1     */
00418     if (rc != OK) {
00419         PRINT_Err(rc);
00420     }
00421     Host_DelayMS(100);                                               /* Some devices may require this delay */
00422     return (rc);
00423 }
00424 
00425 /*
00426 **************************************************************************************************************
00427 *                                        RECEIVE THE CONTROL INFORMATION
00428 *
00429 * Description: This function is used to receive the control information
00430 *
00431 * Arguments  : bm_request_type
00432 *              b_request
00433 *              w_value
00434 *              w_index
00435 *              w_length
00436 *              buffer
00437 *
00438 * Returns    : OK       if Success
00439 *              ERROR    if Failed
00440 *
00441 **************************************************************************************************************
00442 */
00443    
00444 USB_INT32S  Host_CtrlRecv (         USB_INT08U   bm_request_type,
00445                                     USB_INT08U   b_request,
00446                                     USB_INT16U   w_value,
00447                                     USB_INT16U   w_index,
00448                                     USB_INT16U   w_length,
00449                           volatile  USB_INT08U  *buffer)
00450 {
00451     USB_INT32S  rc;
00452 
00453 
00454     Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
00455     rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
00456     if (rc == OK) {
00457         if (w_length) {
00458             rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length);
00459         }
00460         if (rc == OK) {
00461             rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0);
00462         }
00463     }
00464     return (rc);
00465 }
00466 
00467 /*
00468 **************************************************************************************************************
00469 *                                         SEND THE CONTROL INFORMATION
00470 *
00471 * Description: This function is used to send the control information
00472 *
00473 * Arguments  : None
00474 *
00475 * Returns    : OK                      if Success
00476 *              ERR_INVALID_BOOTSIG    if Failed
00477 *
00478 **************************************************************************************************************
00479 */
00480 
00481 USB_INT32S  Host_CtrlSend (          USB_INT08U   bm_request_type,
00482                                      USB_INT08U   b_request,
00483                                      USB_INT16U   w_value,
00484                                      USB_INT16U   w_index,
00485                                      USB_INT16U   w_length,
00486                            volatile  USB_INT08U  *buffer)
00487 {
00488     USB_INT32S  rc;
00489 
00490 
00491     Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
00492 
00493     rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
00494     if (rc == OK) {
00495         if (w_length) {
00496             rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length);
00497         }
00498         if (rc == OK) {
00499             rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0);
00500         }
00501     }
00502     return (rc);
00503 }
00504 
00505 /*
00506 **************************************************************************************************************
00507 *                                          FILL SETUP PACKET
00508 *
00509 * Description: This function is used to fill the setup packet
00510 *
00511 * Arguments  : None
00512 *
00513 * Returns    : OK                      if Success
00514 *              ERR_INVALID_BOOTSIG    if Failed
00515 *
00516 **************************************************************************************************************
00517 */
00518 
00519 void  Host_FillSetup (USB_INT08U   bm_request_type,
00520                       USB_INT08U   b_request,
00521                       USB_INT16U   w_value,
00522                       USB_INT16U   w_index,
00523                       USB_INT16U   w_length)
00524 {
00525     int i;
00526     for (i=0;i<w_length;i++)
00527         TDBuffer[i] = 0;
00528     
00529     TDBuffer[0] = bm_request_type;
00530     TDBuffer[1] = b_request;
00531     WriteLE16U(&TDBuffer[2], w_value);
00532     WriteLE16U(&TDBuffer[4], w_index);
00533     WriteLE16U(&TDBuffer[6], w_length);
00534 }
00535 
00536 
00537 
00538 /*
00539 **************************************************************************************************************
00540 *                                         INITIALIZE THE TRANSFER DESCRIPTOR
00541 *
00542 * Description: This function initializes transfer descriptor
00543 *
00544 * Arguments  : Pointer to TD structure
00545 *
00546 * Returns    : None
00547 *
00548 **************************************************************************************************************
00549 */
00550 
00551 void  Host_TDInit (volatile  HCTD *td)
00552 {
00553 
00554     td->Control    = 0;
00555     td->CurrBufPtr = 0;
00556     td->Next       = 0;
00557     td->BufEnd     = 0;
00558 }
00559 
00560 /*
00561 **************************************************************************************************************
00562 *                                         INITIALIZE THE ENDPOINT DESCRIPTOR
00563 *
00564 * Description: This function initializes endpoint descriptor
00565 *
00566 * Arguments  : Pointer to ED strcuture
00567 *
00568 * Returns    : None
00569 *
00570 **************************************************************************************************************
00571 */
00572 
00573 void  Host_EDInit (volatile  HCED *ed)
00574 {
00575 
00576     ed->Control = 0;
00577     ed->TailTd  = 0;
00578     ed->HeadTd  = 0;
00579     ed->Next    = 0;
00580 }
00581 
00582 /*
00583 **************************************************************************************************************
00584 *                                 INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA
00585 *
00586 * Description: This function initializes host controller communications area
00587 *
00588 * Arguments  : Pointer to HCCA
00589 *
00590 * Returns    : 
00591 *
00592 **************************************************************************************************************
00593 */
00594 
00595 void  Host_HCCAInit (volatile  HCCA  *hcca)
00596 {
00597     USB_INT32U  i;
00598 
00599 
00600     for (i = 0; i < 32; i++) {
00601 
00602         hcca->IntTable[i] = 0;
00603         hcca->FrameNumber = 0;
00604         hcca->DoneHead    = 0;
00605     }
00606 
00607 }
00608 
00609 /*
00610 **************************************************************************************************************
00611 *                                         WAIT FOR WDH INTERRUPT
00612 *
00613 * Description: This function is infinite loop which breaks when ever a WDH interrupt rises
00614 *
00615 * Arguments  : None
00616 *
00617 * Returns    : None
00618 *
00619 **************************************************************************************************************
00620 */
00621 
00622 void  Host_WDHWait (void)
00623 {
00624   while (!HOST_WdhIntr)
00625       __WFI();
00626 
00627   HOST_WdhIntr = 0;
00628 }
00629 
00630 /*
00631 **************************************************************************************************************
00632 *                                         READ LE 32U
00633 *
00634 * Description: This function is used to read an unsigned integer from a character buffer in the platform
00635 *              containing little endian processor
00636 *
00637 * Arguments  : pmem    Pointer to the character buffer
00638 *
00639 * Returns    : val     Unsigned integer
00640 *
00641 **************************************************************************************************************
00642 */
00643 
00644 USB_INT32U  ReadLE32U (volatile  USB_INT08U  *pmem)
00645 {
00646     USB_INT32U val = *(USB_INT32U*)pmem;
00647 #ifdef __BIG_ENDIAN
00648     return __REV(val);
00649 #else
00650     return val;
00651 #endif    
00652 }
00653 
00654 /*
00655 **************************************************************************************************************
00656 *                                        WRITE LE 32U
00657 *
00658 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform 
00659 *              containing little endian processor.
00660 *
00661 * Arguments  : pmem    Pointer to the charecter buffer
00662 *              val     Integer value to be placed in the charecter buffer
00663 *
00664 * Returns    : None
00665 *
00666 **************************************************************************************************************
00667 */
00668 
00669 void  WriteLE32U (volatile  USB_INT08U  *pmem,
00670                             USB_INT32U   val)
00671 {
00672 #ifdef __BIG_ENDIAN
00673     *(USB_INT32U*)pmem = __REV(val);
00674 #else
00675     *(USB_INT32U*)pmem = val;
00676 #endif
00677 }
00678 
00679 /*
00680 **************************************************************************************************************
00681 *                                          READ LE 16U
00682 *
00683 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
00684 *              containing little endian processor
00685 *
00686 * Arguments  : pmem    Pointer to the charecter buffer
00687 *
00688 * Returns    : val     Unsigned short integer
00689 *
00690 **************************************************************************************************************
00691 */
00692 
00693 USB_INT16U  ReadLE16U (volatile  USB_INT08U  *pmem)
00694 {
00695     USB_INT16U val = *(USB_INT16U*)pmem;
00696 #ifdef __BIG_ENDIAN
00697     return __REV16(val);
00698 #else
00699     return val;
00700 #endif    
00701 }
00702 
00703 /*
00704 **************************************************************************************************************
00705 *                                         WRITE LE 16U
00706 *
00707 * Description: This function is used to write an unsigned short integer into a charecter buffer in the
00708 *              platform containing little endian processor
00709 *
00710 * Arguments  : pmem    Pointer to the charecter buffer
00711 *              val     Value to be placed in the charecter buffer
00712 *
00713 * Returns    : None
00714 *
00715 **************************************************************************************************************
00716 */
00717 
00718 void  WriteLE16U (volatile  USB_INT08U  *pmem,
00719                             USB_INT16U   val)
00720 {
00721 #ifdef __BIG_ENDIAN
00722     *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
00723 #else
00724     *(USB_INT16U*)pmem = val;
00725 #endif
00726 }
00727 
00728 /*
00729 **************************************************************************************************************
00730 *                                         READ BE 32U
00731 *
00732 * Description: This function is used to read an unsigned integer from a charecter buffer in the platform
00733 *              containing big endian processor
00734 *
00735 * Arguments  : pmem    Pointer to the charecter buffer
00736 *
00737 * Returns    : val     Unsigned integer
00738 *
00739 **************************************************************************************************************
00740 */
00741 
00742 USB_INT32U  ReadBE32U (volatile  USB_INT08U  *pmem)
00743 {
00744     USB_INT32U val = *(USB_INT32U*)pmem;
00745 #ifdef __BIG_ENDIAN
00746     return val;
00747 #else
00748     return __REV(val);
00749 #endif
00750 }
00751 
00752 /*
00753 **************************************************************************************************************
00754 *                                         WRITE BE 32U
00755 *
00756 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform
00757 *              containing big endian processor
00758 *
00759 * Arguments  : pmem    Pointer to the charecter buffer
00760 *              val     Value to be placed in the charecter buffer
00761 *
00762 * Returns    : None
00763 *
00764 **************************************************************************************************************
00765 */
00766 
00767 void  WriteBE32U (volatile  USB_INT08U  *pmem,
00768                             USB_INT32U   val)
00769 {
00770 #ifdef __BIG_ENDIAN
00771     *(USB_INT32U*)pmem = val;
00772 #else
00773     *(USB_INT32U*)pmem = __REV(val);
00774 #endif
00775 }
00776 
00777 /*
00778 **************************************************************************************************************
00779 *                                         READ BE 16U
00780 *
00781 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
00782 *              containing big endian processor
00783 *
00784 * Arguments  : pmem    Pointer to the charecter buffer
00785 *
00786 * Returns    : val     Unsigned short integer
00787 *
00788 **************************************************************************************************************
00789 */
00790 
00791 USB_INT16U  ReadBE16U (volatile  USB_INT08U  *pmem)
00792 {
00793     USB_INT16U val = *(USB_INT16U*)pmem;
00794 #ifdef __BIG_ENDIAN
00795     return val;
00796 #else
00797     return __REV16(val);
00798 #endif    
00799 }
00800 
00801 /*
00802 **************************************************************************************************************
00803 *                                         WRITE BE 16U
00804 *
00805 * Description: This function is used to write an unsigned short integer into the charecter buffer in the
00806 *              platform containing big endian processor
00807 *
00808 * Arguments  : pmem    Pointer to the charecter buffer
00809 *              val     Value to be placed in the charecter buffer
00810 *
00811 * Returns    : None
00812 *
00813 **************************************************************************************************************
00814 */
00815 
00816 void  WriteBE16U (volatile  USB_INT08U  *pmem,
00817                             USB_INT16U   val)
00818 {
00819 #ifdef __BIG_ENDIAN
00820     *(USB_INT16U*)pmem = val;
00821 #else
00822     *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
00823 #endif
00824 }