📄 lpc177x_8x_usbhost.c
字号:
/**********************************************************************
* $Id$ lpc177x_8x_usbhost.c 2011-09-05
*//**
* @file lpc177x_8x_usbhost.c
* @brief Host Controller functions.
* @version 1.0
* @date 05. September. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
**********************************************************************/
/* Peripheral group ----------------------------------------------------------- */
/** @addtogroup USBHostLite
* @{
*/
#ifdef __BUILD_WITH_EXAMPLE__
#include "lpc177x_8x_libcfg.h"
#else
#include "lpc177x_8x_libcfg_default.h"
#endif /* __BUILD_WITH_EXAMPLE__ */
#ifdef _USBHost
/*
**************************************************************************************************************
* INCLUDE HEADER FILES
**************************************************************************************************************
*/
#include "lpc177x_8x_usbhost.h"
#include "lpc177x_8x_pinsel.h"
#include "bsp.h"
/*
**************************************************************************************************************
* DEFINITIONS
**************************************************************************************************************
*/
#define DEVICE_DESCRIPTOR_SIZE 18
#define DEVICE_CONFIGURATION_SIZE 9
#define DEVICE_INTERFACE_SIZE 9
/*
**************************************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************************************
*/
static volatile int32_t gUSBConnected = 0;
static volatile USB_DEVICE_TYPE gUSBDeviceType = USB_DEVICE_UNKNOWN;
volatile uint32_t HOST_RhscIntr = 0; /* Root Hub Status Change interrupt */
volatile uint32_t HOST_WdhIntr = 0; /* Semaphore to wait until the TD is submitted */
volatile uint8_t HOST_TDControlStatus = 0;
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 */
uint16_t *TDBufNonVol; /* Identical to TDBuffer just to reduce compiler warnings */
volatile uint8_t *TDBuffer; /* Current Buffer Pointer of transfer descriptor */
volatile uint8_t *FATBuffer; /* Buffer used by FAT file system */
volatile uint8_t *UserBuffer; /* Buffer used by application */
volatile uint32_t UnrecoverableIntCount = 0;
volatile uint8_t* USB_DeviceDescriptor;
volatile uint8_t* USB_ConfigDescriptor;
volatile uint8_t* USB_InterfaceDescriptor;
int32_t Host_ParseConfiguration (void);
void Host_TDInit (volatile HCTD *td);
void Host_EDInit (volatile HCED *ed);
void Host_HCCAInit (volatile HCCA *hcca);
void Host_FillSetup( uint8_t bm_request_type,
uint8_t b_request,
uint16_t w_value,
uint16_t w_index,
uint16_t w_length);
void Host_WDHWait (void);
/*********************************************************************//**
* @brief delay in milli seconds
* @param[in] delay The delay required (in milliseconds)
* @return None.
**********************************************************************/
void Host_DelayMS (uint32_t delay)
{
volatile uint32_t i;
for (i = 0; i < delay; i++) {
Host_DelayUS(1000);
}
}
/*********************************************************************//**
* @brief delay in micro seconds
* @param[in] delay The delay required (in microseconds)
* @return None.
**********************************************************************/
void Host_DelayUS (uint32_t delay)
{
volatile uint32_t i;
for (i = 0; i < (4 * delay); i++) { /* This logic was tested. It gives app. 1 micro sec delay */
;
}
}
/*********************************************************************//**
* @brief Init OTG host controller.
* @param[in] None.
* @return None.
**********************************************************************/
void Host_CtrlInit(void)
{
uint32_t HostBaseAddr;
/* Set up host base address and TD and ED descriptors */
HostBaseAddr = HOST_BASE_ADDR;
Hcca = (volatile HCCA *)(HostBaseAddr+0x000);
TDHead = (volatile HCTD *)(HostBaseAddr+0x100);
TDTail = (volatile HCTD *)(HostBaseAddr+0x110);
EDCtrl = (volatile HCED *)(HostBaseAddr+0x120);
EDBulkIn = (volatile HCED *)(HostBaseAddr+0x130);
EDBulkOut = (volatile HCED *)(HostBaseAddr+0x140);
TDBuffer = (volatile uint8_t *)(HostBaseAddr+0x150);
FATBuffer = (volatile uint8_t *)(HostBaseAddr+0x1D0);
USB_DeviceDescriptor = (volatile uint8_t *)(HostBaseAddr+0x1000);
USB_ConfigDescriptor = (volatile uint8_t *) (USB_DeviceDescriptor + DEVICE_DESCRIPTOR_SIZE);
UserBuffer = (volatile uint8_t *)(USB_ConfigDescriptor+DEVICE_CONFIGURATION_SIZE);
/* 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 */
LPC_USB->Control = 0; /* HARDWARE RESET (HCFS = 00b) */
LPC_USB->ControlHeadED = 0; /* Initialize Control list head to Zero */
LPC_USB->BulkHeadED = 0; /* Initialize Bulk list head to Zero */
/* SOFTWARE RESET */
LPC_USB->CommandStatus = OR_CMD_STATUS_HCR;
LPC_USB->FmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
/* Put HC in operational state */
LPC_USB->Control = (LPC_USB->Control & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
LPC_USB->RhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
LPC_USB->HCCA = (uint32_t)Hcca;
LPC_USB->InterruptStatus |= LPC_USB->InterruptStatus; /* Clear Interrrupt Status */
LPC_USB->InterruptEnable = OR_INTR_ENABLE_MIE |
OR_INTR_ENABLE_WDH |
OR_INTR_ENABLE_RHSC |
OR_INTR_ENABLE_UE;
}
/*********************************************************************//**
* @brief Init host controller.
* @param[in] None.
* @return None.
**********************************************************************/
void Host_Init (void)
{
LPC_SC->PCONP |= 0x80000000; /* Enable USB Interface */
LPC_USB->OTGClkCtrl = 0x00000019; /* Enable USB host clock, OTG clock & AHB master clock */
while ((LPC_USB->OTGClkSt & 0x00000019) != 0x19);
LPC_USB->StCtrl = 0x1;
#if _CURR_USING_BRD == _EA_PA_BOARD
// Port U1
PINSEL_ConfigPin(0,29,1); /* USB_D+1 */
PINSEL_ConfigPin(0,30,1); /* USB_D-1 */
PINSEL_ConfigPin(2,9,1); /* USB_CONNECT1 */
PINSEL_ConfigPin(1,18,1); /* USB_UP_LED1 */
#if 0
PINSEL_ConfigPin(1,19,1); /* USB_TX_E1*/
PINSEL_ConfigPin(1,22,1); /* USB_RX_E1*/
PINSEL_ConfigPin(1,20,1); /* USB_TX_DP1 */
PINSEL_ConfigPin(1,21,1); /* USB_TX_DM1 */
PINSEL_ConfigPin(1,23,1); /* USB_RX_DP1 */
PINSEL_ConfigPin(1,24,1); /* USB_RX_DM1 */
#else
PINSEL_ConfigPin(1,19,2); /* USB_PPWR1 */
PINSEL_ConfigPin(1,27,1); /* USB_OVRCR1 */
#endif
// Port U2
PINSEL_ConfigPin(0,31,1); /* USB_D+2 */
PINSEL_ConfigPin(0,14,3); /* USB_CONNECT2 */
PINSEL_ConfigPin(0,13,1); /* USB_UP_LED2 */
#if 1 /* Use USB Power Switch */
PINSEL_ConfigPin(0,12,1); /* USB_PPWR2 */
PINSEL_ConfigPin(1,31,1); /* USB_OVRCR2 */
#else
PINSEL_ConfigPin(1,30,2); /* USB_VBUS */
#endif
#else /* _CURR_USING_BRD == _IAR_OLIMEX_BOARD */
// Port U2
PINSEL_ConfigPin(0,31,1); /* USB_D+2 */
PINSEL_ConfigPin(0,14,3); /* USB_CONNECT2 */
PINSEL_ConfigPin(0,13,1); /* USB_UP_LED2 */
PINSEL_ConfigPin(0,12,1); /* USB_PPWR2 */
PINSEL_ConfigPin(1,31,1); /* USB_OVRCR2 */
#endif /* _CURR_USING_BRD == _EA_PA_BOARD */
Host_CtrlInit();
/* Enable the USB Interrupt */
NVIC_EnableIRQ(USB_IRQn); /* enable USB interrupt */
NVIC_SetPriority (USB_IRQn, 0); /* highest priority */
}
/*********************************************************************//**
* @brief services the interrupt caused by host controller.
* @param[in] None.
* @return None.
**********************************************************************/
void USB_IRQHandler (void)
{
uint32_t int_status;
uint32_t ie_status;
int_status = LPC_USB->InterruptStatus; /* Read Interrupt Status */
ie_status = LPC_USB->InterruptEnable; /* 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 (LPC_USB->RhPortStatus1 & OR_RH_PORT_CSC) {
if (LPC_USB->RhStatus & OR_RH_STATUS_DRWE) {
/*
* When DRWE is on, Connect Status Change
* means a remote wakeup event.
*/
HOST_RhscIntr |= 0x01;// JUST SOMETHING FOR A BREAKPOINT
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -