suu pen / MSCUsbHost

Dependencies:   FatFileSystemCpp

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