⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbhost_lpc2468.c

📁 NXP LPC24xx USB Hsot Lite
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
**************************************************************************************************************
*                                                 NXP USB Host Stack
*
*                                     (c) Copyright 2008, NXP SemiConductors
*                                     (c) Copyright 2008, OnChip  Technologies LLC
*                                                 All Rights Reserved
*
*                                                  www.nxp.com
*                                               www.onchiptech.com
*
* File           : usbhost_lpc2468.c
* Programmer(s)  : Ravikanth.P
* Version        :
*
**************************************************************************************************************
*/

/*
**************************************************************************************************************
*                                            INCLUDE HEADER FILES
**************************************************************************************************************
*/

#include  "usbhost_lpc2468.h"

/*
**************************************************************************************************************
*                                              GLOBAL VARIABLES
**************************************************************************************************************
*/

volatile  USB_INT32U   HOST_RhscIntr = 0;         /* Root Hub Status Change interrupt                       */
volatile  USB_INT32U   HOST_WdhIntr  = 0;         /* Semaphore to wait until the TD is submitted            */
volatile  HCED        *EDCtrl;                    /* Control endpoint descriptor structure                  */
volatile  HCED        *EDBulkIn;                  /* BulkIn endpoint descriptor  structure                  */
volatile  HCED        *EDBulkOut;                 /* BulkOut endpoint descriptor structure                  */
volatile  HCTD        *TDHead;                    /* Head transfer descriptor structure                     */
volatile  HCTD        *TDTail;                    /* Tail transfer descriptor structure                     */
volatile  HCCA        *Hcca;                      /* Host Controller Communications Area structure          */ 
volatile  USB_INT08U  *TDBuffer;                  /* Current Buffer Pointer of transfer descriptor          */
volatile  USB_INT08U  *FATBuffer;                 /* Buffer used by FAT file system                         */
volatile  USB_INT08U  *UserBuffer;                /* Buffer used by application                             */

/*
**************************************************************************************************************
*                                         DELAY IN MILLI SECONDS
*
* Description: This function provides a delay in milli seconds
*
* Arguments  : delay    The delay required
*
* Returns    : None
*
**************************************************************************************************************
*/

void  Host_DelayMS (USB_INT32U  delay)
{
    volatile  USB_INT32U  i;


    for (i = 0; i < delay; i++) {
        Host_DelayUS(1000);
    }
}

/*
**************************************************************************************************************
*                                         DELAY IN MICRO SECONDS
*
* Description: This function provides a delay in micro seconds
*
* Arguments  : delay    The delay required
*
* Returns    : None
*
**************************************************************************************************************
*/

void  Host_DelayUS (USB_INT32U  delay)
{
    volatile  USB_INT32U  i;


    for (i = 0; i < (4 * delay); i++) {    /* This logic was tested. It gives app. 1 micro sec delay        */
        ;
    }
}

/*
**************************************************************************************************************
*                                         INITIALIZE THE HOST CONTROLLER
*
* Description: This function initializes lpc2468 host controller
*
* Arguments  : None
*
* Returns    : 
*
**************************************************************************************************************
*/

void  Host_Init (void)
{
    USB_INT32U  pinsel;
    USB_INT32U  pinmode;


    PCONP         |= 0x80000000;
    VICIntEnClr    = (1 << 22);                               /* Enable the USB interrupt source            */
    OTG_CLK_CTRL   = 0x00000001;                              /* Enable USB host clock                      */

    while ((OTG_CLK_STAT & 0x00000001) == 0) {
        ;
    }
                                                              /* P0[12] = USB_PPWR2          01             */
                                                              /* P0[13] = USB_UP_LED2        01             */
                                                              /* P0[14] = USB_CONNECT2       10             */
    pinsel    = PINSEL0;
    pinsel   &= 0xC0FFFFFF;
    pinsel   |= 0x15000000;
    PINSEL0   = pinsel;

    pinmode   = PINMODE0;
    pinmode  &= 0xCFFFFFFF;
    pinmode  |= 0x30000000;
    PINMODE0  = pinmode;

                                                              /* P0[29] = USB_D+1                           */
                                                              /* P0[30] = USB_D-1                           */
                                                              /* P0[31] = USB_D+2                           */
    pinsel    = PINSEL1;
    pinsel   &= 0x03FFFFFF;
    pinsel   |= 0x54000000;
    PINSEL1   = pinsel;

                                                              /* P1[18] = USB_UP_LED1        01             */
                                                              /* P1[19] = USB_PPWR1          10             */
                                                              /* P1[22] = USB_PWRD1          10             */
                                                              /* P1[27] = USB_OVRCR1         10             */
                                                              /* P1[30] = USB_VBUS           10             */
                                                              /* P1[31] = USB_OVRCR2         01             */
    pinsel    = PINSEL3;
    pinsel   &= 0x0F3F3F0F;
    pinsel   |= 0x60802090;
    PINSEL3   = pinsel;


    PRINT_Log("Initializing Host Stack\n");
    Hcca       = (volatile  HCCA       *)0x7FD00000;
    TDHead     = (volatile  HCTD       *)0x7FD00100;
    TDTail     = (volatile  HCTD       *)0x7FD00110;
    EDCtrl     = (volatile  HCED       *)0x7FD00120; 
    EDBulkIn   = (volatile  HCED       *)0x7FD00130;
    EDBulkOut  = (volatile  HCED       *)0x7FD00140;
    TDBuffer   = (volatile  USB_INT08U *)0x7FD00150;
    FATBuffer  = (volatile  USB_INT08U *)0x7FD001D0;
    UserBuffer = (volatile  USB_INT08U *)0x7FD01000;

                                                              /* Initialize all the TDs, EDs and HCCA to 0  */
    Host_EDInit(EDCtrl);
    Host_EDInit(EDBulkIn);
    Host_EDInit(EDBulkOut);
    Host_TDInit(TDHead);
    Host_TDInit(TDTail);
    Host_HCCAInit(Hcca);

    
    Host_DelayMS(50);                                         /* Wait 50 ms before apply reset              */
    HcControl       = 0;                                      /* HARDWARE RESET                             */
    HcControlHeadED = 0;                                      /* Initialize Control list head to Zero       */
    HcBulkHeadED    = 0;                                      /* Initialize Bulk list head to Zero          */
    
                                                              /* SOFTWARE RESET                             */
    HcCommandStatus = OR_CMD_STATUS_HCR;
    HcFmInterval    = DEFAULT_FMINTERVAL;              /* Write Fm Interval and Largest Data Packet Counter */

                                                              /* Put HC in operational state                */
    HcControl  = (HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
    HcRhStatus = OR_RH_STATUS_LPSC;                           /* Set Global Power                           */
    
    HcHCCA = (USB_INT32U)Hcca;
    HcInterruptStatus |= HcInterruptStatus;                   /* Clear Interrrupt Status                    */
                                                              /* Enable  interrupts                         */
    HcInterruptEnable  = OR_INTR_ENABLE_MIE |
                         OR_INTR_ENABLE_WDH |
                         OR_INTR_ENABLE_RHSC;


    VICIntSelect &= ~(1 << 22);                               /* Configure the ISR handler                  */
    VICVectAddr22 =  (USB_INT32U)Host_Isr;                    /* Set the vector address                     */
    VICIntEnable  = (1 << 22);                                /* Enable the USB interrupt source            */
    PRINT_Log("Host Initialized\n");
}

/*
**************************************************************************************************************
*                                         INTERRUPT SERVICE ROUTINE
*
* Description: This function services the interrupt caused by host controller
*
* Arguments  : None
*
* Returns    : None
*
**************************************************************************************************************
*/

void  Host_Isr (void) __irq
{
    USB_INT32U   int_status;
    USB_INT32U   ie_status;


    if ((USB_INT_STAT & 0x00000008) > 0) {
          
        int_status    = HcInterruptStatus;                          /* Read Interrupt Status                */
        ie_status     = HcInterruptEnable;                          /* Read Interrupt enable status         */
 
        if (!(int_status & ie_status)) {
            return;
        } else {

            int_status = int_status & ie_status;

            if (int_status & OR_INTR_STATUS_RHSC) {                 /* Root hub status change interrupt     */
                if (HcRhPortStatus & OR_RH_PORT_CSC) {
                    if (HcRhPortStatus & OR_RH_PORT_CCS) {
                        HOST_RhscIntr = 1;
                    } else {
                        HOST_RhscIntr = 0;
                        PRINT_Log("Device Disconnected\n");
                    }
                HcRhPortStatus = OR_RH_PORT_CSC;
                }
                if (HcRhPortStatus & OR_RH_PORT_PRSC) {
                    HcRhPortStatus = OR_RH_PORT_PRSC;
                }
            }
            if (int_status & OR_INTR_STATUS_WDH) {                  /* Writeback Done Head interrupt        */
                HOST_WdhIntr = 1;
            }            
            HcInterruptStatus = int_status;                         /* Clear interrupt status register      */
        }      
        VICVectAddr = 0;        
    }
}

/*
**************************************************************************************************************
*                                     PROCESS TRANSFER DESCRIPTOR
*
* Description: This function processes the transfer descriptor
*
* Arguments  : ed            Endpoint descriptor that contains this transfer descriptor
*              token         SETUP, IN, OUT
*              buffer        Current Buffer Pointer of the transfer descriptor
*              buffer_len    Length of the buffer
*
* Returns    : OK       if TD submission is successful
*              ERROR    if TD submission fails
*
**************************************************************************************************************
*/

USB_INT32S  Host_ProcessTD (volatile  HCED       *ed,
                            volatile  USB_INT32U  token,
                            volatile  USB_INT08U *buffer,
                                      USB_INT32U  buffer_len)
{
    volatile  USB_INT32U   td_toggle;


    if (ed == EDCtrl) {
        if (token == TD_SETUP) {
            td_toggle = TD_TOGGLE_0;
        } else {
            td_toggle = TD_TOGGLE_1;
        }
    } else {
        td_toggle = 0;
    }
    TDHead->Control = (TD_ROUNDING    |
                      token           |
                      TD_DELAY_INT(0) |                           
                      td_toggle       |
                      TD_CC);
    TDTail->Control = 0;
    TDHead->CurrBufPtr   = (USB_INT32U) buffer;
    TDTail->CurrBufPtr   = 0;
    TDHead->Next         = (USB_INT32U) TDTail;
    TDTail->Next         = 0;
    TDHead->BufEnd       = (USB_INT32U)(buffer + (buffer_len - 1));
    TDTail->BufEnd       = 0;

    ed->HeadTd  = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002);
    ed->TailTd  = (USB_INT32U)TDTail;
    ed->Next    = 0;

    if (ed == EDCtrl) {
        HcControlHeadED = (USB_INT32U)ed;
        HcCommandStatus = HcCommandStatus | OR_CMD_STATUS_CLF;
        HcControl       = HcControl       | OR_CONTROL_CLE;
    } else {
        HcBulkHeadED    = (USB_INT32U)ed;
        HcCommandStatus = HcCommandStatus | OR_CMD_STATUS_BLF;
        HcControl       = HcControl       | OR_CONTROL_BLE;
    }    

    Host_WDHWait();

    if (!(TDHead->Control & 0xF0000000)) {
        return (OK);
    } else {      
        return (ERR_TD_FAIL);
    }
}

/*
**************************************************************************************************************
*                                       ENUMERATE THE DEVICE
*
* Description: This function is used to enumerate the device connected
*
* Arguments  : None
*
* Returns    : None
*
**************************************************************************************************************
*/

USB_INT32S  Host_EnumDev (void)
{
    USB_INT32S  rc;


    PRINT_Log("Connect a Mass Storage device\n");
    while (!HOST_RhscIntr);
    Host_DelayMS(100);                             /* USB 2.0 spec says atleast 50ms delay beore port reset */
    HcRhPortStatus |= OR_RH_PORT_PRS;                                  /* Apply port reset                  */
    Host_DelayMS(100);                                                 /* Wait for 100 MS after port reset  */

    EDCtrl->Control = 8 << 16;                                         /* Put max pkt size = 8              */
                                                                       /* Read first 8 bytes of device desc */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
    if (rc != OK) {
        PRINT_Err(rc);
        return (rc);
    }
    EDCtrl->Control = TDBuffer[7] << 16;                               /* Get max pkt size of endpoint 0    */
    rc = HOST_SET_ADDRESS(1);                                          /* Set the device address to 1       */
    if (rc != OK) {
        PRINT_Err(rc);
        return (rc);
    }
    Host_DelayMS(2);
    EDCtrl->Control = (EDCtrl->Control) | 1;                          /* Modify control pipe with address 1 */
                                                                      /* Get the configuration descriptor   */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
    if (rc != OK) {
        PRINT_Err(rc);
        return (rc);
    }
                                                                       /* Get the first configuration data  */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2]));
    if (rc != OK) {
        PRINT_Err(rc);
        return (rc);
    }
    rc = MS_ParseConfiguration();                                      /* Parse the configuration           */
    if (rc != OK) {
        PRINT_Err(rc);
        return (rc);
    }
    rc = USBH_SET_CONFIGURATION(1);                                    /* Select device configuration 1     */
    if (rc != OK) {
        PRINT_Err(rc);
    }
    Host_DelayMS(100);                                               /* Some devices may require this delay */
    return (rc);
}

/*
**************************************************************************************************************
*                                        RECEIVE THE CONTROL INFORMATION
*
* Description: This function is used to receive the control information
*
* Arguments  : bm_request_type

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -