Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbhost_lpc17xx.c Source File

usbhost_lpc17xx.c

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