Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbhost_lpc17xx.c Source File

usbhost_lpc17xx.c

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