亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? usbhw_lpc.c

?? Free Usb Stack for NXP LPC2xxx microcontrollers.
?? C
字號:
/*
	LPCUSB, an USB device driver for LPC microcontrollers	
	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


/** @file
	USB hardware layer
 */

#include "type.h"
#include "usbdebug.h"
#include "usbhw_lpc.h"
#include "usbapi.h"


#ifdef DEBUG
// comment out the following line if you don't want to use debug LEDs
#define DEBUG_LED
#endif

#ifdef DEBUG_LED
#define DEBUG_LED_ON(x)		IOCLR0 = (1 << x);
#define DEBUG_LED_OFF(x)	IOSET0 = (1 << x);
#define DEBUG_LED_INIT(x)	PINSEL0 &= ~(0x3 << (2*x)); IODIR0 |= (1 << x); DEBUG_LED_OFF(x);
#else
#define DEBUG_LED_INIT(x)	/**< LED initialisation macro */
#define DEBUG_LED_ON(x)		/**< turn LED on */
#define DEBUG_LED_OFF(x)	/**< turn LED off */
#endif

/** Installed device interrupt handler */
static TFnDevIntHandler *_pfnDevIntHandler = NULL;
/** Installed endpoint interrupt handlers */
static TFnEPIntHandler	*_apfnEPIntHandlers[16];
/** Installed frame interrupt handlers */
static TFnFrameHandler	*_pfnFrameHandler = NULL;

/** convert from endpoint address to endpoint index */
#define EP2IDX(bEP)	((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
/** convert from endpoint index to endpoint address */
#define IDX2EP(idx)	((((idx)<<7)&0x80)|(((idx)>>1)&0xF))



/**
	Local function to wait for a device interrupt (and clear it)
		
	@param [in]	dwIntr		Bitmask of interrupts to wait for	
 */
static void Wait4DevInt(U32 dwIntr)
{
	// wait for specific interrupt
	while ((USBDevIntSt & dwIntr) != dwIntr);
	// clear the interrupt bits
	USBDevIntClr = dwIntr;
}


/**
	Local function to send a command to the USB protocol engine
		
	@param [in]	bCmd		Command to send
 */
static void USBHwCmd(U8 bCmd)
{
	// clear CDFULL/CCEMTY
	USBDevIntClr = CDFULL | CCEMTY;
	// write command code
	USBCmdCode = 0x00000500 | (bCmd << 16);
	Wait4DevInt(CCEMTY);
}


/**
	Local function to send a command + data to the USB protocol engine
		
	@param [in]	bCmd		Command to send
	@param [in]	bData		Data to send
 */
static void USBHwCmdWrite(U8 bCmd, U16 bData)
{
	// write command code
	USBHwCmd(bCmd);

	// write command data
	USBCmdCode = 0x00000100 | (bData << 16);
	Wait4DevInt(CCEMTY);
}


/**
	Local function to send a command to the USB protocol engine and read data
		
	@param [in]	bCmd		Command to send

	@return the data
 */
static U8 USBHwCmdRead(U8 bCmd)
{
	// write command code
	USBHwCmd(bCmd);
	
	// get data
	USBCmdCode = 0x00000200 | (bCmd << 16);
	Wait4DevInt(CDFULL);
	return USBCmdData;
}


/**
	'Realizes' an endpoint, meaning that buffer space is reserved for
	it. An endpoint needs to be realised before it can be used.
		
	From experiments, it appears that a USB reset causes USBReEP to
	re-initialise to 3 (= just the control endpoints).
	However, a USB bus reset does not disturb the USBMaxPSize settings.
		
	@param [in]	idx			Endpoint index
	@param [in] wMaxPSize	Maximum packet size for this endpoint
 */
static void USBHwEPRealize(int idx, U16 wMaxPSize)
{
	USBReEP |= (1 << idx);
	USBEpInd = idx;
	USBMaxPSize = wMaxPSize;
	Wait4DevInt(EP_RLZED);
}


/**
	Enables or disables an endpoint
		
	@param [in]	idx		Endpoint index
	@param [in]	fEnable	TRUE to enable, FALSE to disable
 */
static void USBHwEPEnable(int idx, BOOL fEnable)
{
	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
}


/**
	Configures an endpoint and enables it
		
	@param [in]	bEP				Endpoint number
	@param [in]	wMaxPacketSize	Maximum packet size for this EP
 */
void USBHwEPConfig(U8 bEP, U16 wMaxPacketSize)
{
	int idx;
	
	idx = EP2IDX(bEP);
	
	// realise EP
	USBHwEPRealize(idx, wMaxPacketSize);

	// enable EP
	USBHwEPEnable(idx, TRUE);
}


/**
	Registers an endpoint event callback
		
	@param [in]	bEP				Endpoint number
	@param [in]	pfnHandler		Callback function
 */
void USBHwRegisterEPIntHandler(U8 bEP, TFnEPIntHandler *pfnHandler)
{
	int idx;
	
	idx = EP2IDX(bEP);

	ASSERT(idx<32);

	/* add handler to list of EP handlers */
	_apfnEPIntHandlers[idx / 2] = pfnHandler;
	
	/* enable EP interrupt */
	USBEpIntEn |= (1 << idx);
	USBDevIntEn |= EP_SLOW;
	
	DBG("Registered handler for EP 0x%x\n", bEP);
}


/**
	Registers an device status callback
		
	@param [in]	pfnHandler	Callback function
 */
void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
{
	_pfnDevIntHandler = pfnHandler;
	
	// enable device interrupt
	USBDevIntEn |= DEV_STAT;

	DBG("Registered handler for device status\n");
}


/**
	Registers the frame callback
		
	@param [in]	pfnHandler	Callback function
 */
void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
{
	_pfnFrameHandler = pfnHandler;
	
	// enable device interrupt
	USBDevIntEn |= FRAME;

	DBG("Registered handler for frame\n");
}


/**
	Sets the USB address.
		
	@param [in]	bAddr		Device address to set
 */
void USBHwSetAddress(U8 bAddr)
{
	USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
}


/**
	Connects or disconnects from the USB bus
		
	@param [in]	fConnect	If TRUE, connect, otherwise disconnect
 */
void USBHwConnect(BOOL fConnect)
{
	USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
}


/**
	Enables interrupt on NAK condition
		
	For IN endpoints a NAK is generated when the host wants to read data
	from the device, but none is available in the endpoint buffer.
	For OUT endpoints a NAK is generated when the host wants to write data
	to the device, but the endpoint buffer is still full.
	
	The endpoint interrupt handlers can distinguish regular (ACK) interrupts
	from NAK interrupt by checking the bits in their bEPStatus argument.
	
	@param [in]	bIntBits	Bitmap indicating which NAK interrupts to enable
 */
void USBHwNakIntEnable(U8 bIntBits)
{
	USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
}


/**
	Gets the status from a specific endpoint.
		
	@param [in]	bEP		Endpoint number
	@return Endpoint status byte (containing EP_STATUS_xxx bits)
 */
U8	USBHwEPGetStatus(U8 bEP)
{
	int idx = EP2IDX(bEP);

	return USBHwCmdRead(CMD_EP_SELECT | idx);
}


/**
	Sets the stalled property of an endpoint
		
	@param [in]	bEP		Endpoint number
	@param [in]	fStall	TRUE to stall, FALSE to unstall
 */
void USBHwEPStall(U8 bEP, BOOL fStall)
{
	int idx = EP2IDX(bEP);

	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
}


/**
	Writes data to an endpoint buffer
		
	@param [in]	bEP		Endpoint number
	@param [in]	pbBuf	Endpoint data
	@param [in]	iLen	Number of bytes to write
			
	@return TRUE if the data was successfully written or <0 in case of error.
*/
int USBHwEPWrite(U8 bEP, U8 *pbBuf, int iLen)
{
	int idx;
	
	idx = EP2IDX(bEP);
	
	// set write enable for specific endpoint
	USBCtrl = WR_EN | ((bEP & 0xF) << 2);
	
	// set packet length
	USBTxPLen = iLen;
	
	// write data
	while (USBCtrl & WR_EN) {
		USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
		pbBuf += 4;
	}

	// select endpoint and validate buffer
	USBHwCmd(CMD_EP_SELECT | idx);
	USBHwCmd(CMD_EP_VALIDATE_BUFFER);
	
	return iLen;
}


/**
	Reads data from an endpoint buffer
		
	@param [in]	bEP		Endpoint number
	@param [in]	pbBuf	Endpoint data
	@param [in]	iMaxLen	Maximum number of bytes to read
			
	@return the number of bytes available in the EP (possibly more than iMaxLen),
	or <0 in case of error.
 */
int USBHwEPRead(U8 bEP, U8 *pbBuf, int iMaxLen)
{
	int i, idx;
	U32	dwData, dwLen;
	
	idx = EP2IDX(bEP);
	
	// set read enable bit for specific endpoint
	USBCtrl = RD_EN | ((bEP & 0xF) << 2);
	
	// wait for PKT_RDY
	do {
		dwLen = USBRxPLen;
	} while ((dwLen & PKT_RDY) == 0);
	
	// packet valid?
	if ((dwLen & DV) == 0) {
		return -1;
	}
	
	// get length
	dwLen &= PKT_LNGTH_MASK;
	
	// get data
	dwData = 0;
	for (i = 0; i < dwLen; i++) {
		if ((i % 4) == 0) {
			dwData = USBRxData;
		}
		if ((pbBuf != NULL) && (i < iMaxLen)) {
			pbBuf[i] = dwData & 0xFF;
		}
		dwData >>= 8;
	}

	// make sure RD_EN is clear
	USBCtrl = 0;

	// select endpoint and clear buffer
	USBHwCmd(CMD_EP_SELECT | idx);
	USBHwCmd(CMD_EP_CLEAR_BUFFER);
	
	return dwLen;
}


/**
	Sets the 'configured' state.
		
	All registered endpoints are 'realised' and enabled, and the
	'configured' bit is set in the device status register.
		
	@param [in]	fConfigured	If TRUE, configure device, else unconfigure
 */
void USBHwConfigDevice(BOOL fConfigured)
{
	// set configured bit
	USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
}


/**
	USB interrupt handler
		
	@todo Get all 11 bits of frame number instead of just 8

	Endpoint interrupts are mapped to the slow interrupt
 */
void USBHwISR(void)
{
	U32	dwStatus;
	U32 dwIntBit;
	U8	bEPStat, bDevStat, bStat;
	int i;
	U16	wFrame;

// LED9 monitors total time in interrupt routine
DEBUG_LED_ON(9);

	// handle device interrupts
	dwStatus = USBDevIntSt;
	
	// frame interrupt
	if (dwStatus & FRAME) {
		// clear int
		USBDevIntClr = FRAME;
		// call handler
		if (_pfnFrameHandler != NULL) {
			wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
			_pfnFrameHandler(wFrame);
		}
	}
	
	// device status interrupt
	if (dwStatus & DEV_STAT) {
		/*	Clear DEV_STAT interrupt before reading DEV_STAT register.
			This prevents corrupted device status reads, see
			LPC2148 User manual revision 2, 25 july 2006.
		*/
		USBDevIntClr = DEV_STAT;
		bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
		if (bDevStat & (CON_CH | SUS_CH | RST)) {
			// convert device status into something HW independent
			bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
					((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
					((bDevStat & RST) ? DEV_STATUS_RESET : 0);
			// call handler
			if (_pfnDevIntHandler != NULL) {
DEBUG_LED_ON(8);		
				_pfnDevIntHandler(bStat);
DEBUG_LED_OFF(8);		
			}
		}
	}
	
	// endpoint interrupt
	if (dwStatus & EP_SLOW) {
		// clear EP_SLOW
		USBDevIntClr = EP_SLOW;
		// check all endpoints
		for (i = 0; i < 32; i++) {
			dwIntBit = (1 << i);
			if (USBEpIntSt & dwIntBit) {
				// clear int (and retrieve status)
				USBEpIntClr = dwIntBit;
				Wait4DevInt(CDFULL);
				bEPStat = USBCmdData;
				// convert EP pipe stat into something HW independent
				bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
						((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
						((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
						((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
						((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
				// call handler
				if (_apfnEPIntHandlers[i / 2] != NULL) {
DEBUG_LED_ON(10);		
					_apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
DEBUG_LED_OFF(10);
				}
			}
		}
	}
	
DEBUG_LED_OFF(9);		
}



/**
	Initialises the USB hardware
		
	This function assumes that the hardware is connected as shown in
	section 10.1 of the LPC2148 data sheet:
	* P0.31 controls a switch to connect a 1.5k pull-up to D+ if low.
	* P0.23 is connected to USB VCC.
	
	Embedded artists board: make sure to disconnect P0.23 LED as it
	acts as a pull-up and so prevents detection of USB disconnect.
		
	@return TRUE if the hardware was successfully initialised
 */
BOOL USBHwInit(void)
{
	// configure P0.23 for Vbus sense
	PINSEL1 = (PINSEL1 & ~(3 << 14)) | (1 << 14);	// P0.23
	// configure P0.31 for CONNECT
	PINSEL1 = (PINSEL1 & ~(3 << 30)) | (2 << 30);	// P0.31

	// enable PUSB
	PCONP |= (1 << 31);		
	
	// initialise PLL
	PLL1CON = 1;			// enable PLL
	PLL1CFG = (1 << 5) | 3; // P = 2, M = 4
	PLL1FEED = 0xAA;
	PLL1FEED = 0x55;
	while ((PLL1STAT & (1 << 10)) == 0);

	PLL1CON = 3;			// enable and connect
	PLL1FEED = 0xAA;
	PLL1FEED = 0x55;
	
	// disable/clear all interrupts for now
	USBDevIntEn = 0;
	USBDevIntClr = 0xFFFFFFFF;
	USBDevIntPri = 0;

	USBEpIntEn = 0;
	USBEpIntClr = 0xFFFFFFFF;
	USBEpIntPri = 0;

	// by default, only ACKs generate interrupts
	USBHwNakIntEnable(0);
	
	// init debug leds
	DEBUG_LED_INIT(8);
	DEBUG_LED_INIT(9);
	DEBUG_LED_INIT(10);

	return TRUE;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人免费高清视频在线观看| 日韩一级欧美一级| 欧美一级欧美三级在线观看| 亚洲国产精品ⅴa在线观看| 亚洲国产裸拍裸体视频在线观看乱了 | 欧美一卡2卡3卡4卡| 国产精品久久久久久久久果冻传媒| 亚洲不卡av一区二区三区| 成人高清免费在线播放| 日韩一区二区免费在线观看| 亚洲男人的天堂在线aⅴ视频| 韩国理伦片一区二区三区在线播放| 一本到一区二区三区| 久久婷婷一区二区三区| 日韩av一级片| 欧美人牲a欧美精品| 亚洲欧美另类小说| eeuss鲁片一区二区三区| 精品久久五月天| 免费人成在线不卡| 欧美另类变人与禽xxxxx| 一二三四区精品视频| bt7086福利一区国产| 国产网站一区二区三区| 国产精品资源在线看| 欧美tickling挠脚心丨vk| 日本网站在线观看一区二区三区 | 国产精品一区二区无线| 欧美精品一区二区三区一线天视频| 三级欧美韩日大片在线看| 欧美性做爰猛烈叫床潮| 亚洲在线视频网站| 欧美日韩一区精品| 亚洲成人精品一区二区| 欧美军同video69gay| 午夜精品久久久久久久久久久| 日本丶国产丶欧美色综合| 亚洲精品伦理在线| 欧美最猛黑人xxxxx猛交| 亚洲一区二区三区四区五区中文| 一本大道av伊人久久综合| 亚洲欧美偷拍卡通变态| 日本韩国精品在线| 午夜久久久影院| 日韩欧美精品三级| 国产一区二区看久久| 中文字幕制服丝袜成人av | 最新国产精品久久精品| 97久久精品人人做人人爽50路| 亚洲视频在线观看一区| 欧美日韩一区二区三区不卡| 亚洲高清三级视频| 日韩视频一区在线观看| 国产精品一级片在线观看| 国产精品免费人成网站| 欧美性猛片aaaaaaa做受| 香蕉影视欧美成人| 久久久综合视频| 91论坛在线播放| 日本aⅴ免费视频一区二区三区 | 欧美日韩一区二区三区四区五区| 日韩国产欧美在线视频| 国产日韩在线不卡| 色天使色偷偷av一区二区| 日韩av中文在线观看| 国产视频不卡一区| 欧美午夜一区二区| 国产91色综合久久免费分享| 亚洲精品国产成人久久av盗摄| 7777精品伊人久久久大香线蕉完整版| 国产一区二区在线视频| 亚洲精品视频在线观看免费| 91精品国产美女浴室洗澡无遮挡| 国产美女精品在线| 亚洲无人区一区| 亚洲国产精品精华液ab| 在线播放欧美女士性生活| 丰满亚洲少妇av| 婷婷丁香激情综合| 亚洲欧洲精品天堂一级 | 91黄色激情网站| 久久97超碰国产精品超碰| 亚洲激情网站免费观看| 久久久精品免费观看| 91精品麻豆日日躁夜夜躁| aaa亚洲精品一二三区| 麻豆成人在线观看| 亚洲影院理伦片| 久久精品男人天堂av| 欧美绝品在线观看成人午夜影视| 91在线观看下载| 国产成人综合亚洲网站| 青青草国产精品97视觉盛宴 | 在线这里只有精品| 成人黄动漫网站免费app| 国内偷窥港台综合视频在线播放| 亚洲韩国一区二区三区| 中文字幕一区在线观看| 国产日本欧美一区二区| 欧美成人video| 91精品国产福利| 欧美日韩不卡在线| 欧美午夜影院一区| 欧美三级欧美一级| 91麻豆免费看片| 99国内精品久久| 国产成人精品免费| 国产激情一区二区三区桃花岛亚洲| 免费高清成人在线| 免费成人在线播放| 麻豆高清免费国产一区| 免费在线观看视频一区| 午夜国产精品一区| 天堂蜜桃一区二区三区| 午夜电影网一区| 日韩高清在线观看| 美女任你摸久久| 裸体一区二区三区| 精品在线播放免费| 国产福利91精品一区二区三区| 经典三级在线一区| 国产黄人亚洲片| av电影天堂一区二区在线| 91美女在线视频| 欧美日韩亚洲丝袜制服| 欧美区在线观看| 日韩视频永久免费| 国产亚洲综合在线| 中文字幕一区二区视频| 一区二区三区四区亚洲| 午夜一区二区三区在线观看| 日韩高清在线不卡| 极品尤物av久久免费看| 国产成人精品www牛牛影视| 色综合一区二区三区| 欧美日韩一区三区四区| 欧美大片免费久久精品三p| 337p粉嫩大胆色噜噜噜噜亚洲| 国产欧美一区二区三区网站| 国产精品家庭影院| 亚洲成a人v欧美综合天堂下载| 日本午夜精品一区二区三区电影| 国产一区二区福利| 色综合天天综合网天天狠天天| 欧美色图12p| 精品久久久网站| 亚洲视频电影在线| 人人精品人人爱| 东方欧美亚洲色图在线| 欧美在线999| 久久综合丝袜日本网| 樱花影视一区二区| 国产资源在线一区| 色婷婷久久久亚洲一区二区三区| 91精品在线一区二区| 国产精品视频九色porn| 视频一区在线播放| 成人妖精视频yjsp地址| 欧美精品777| 亚洲视频一区在线| 韩国一区二区三区| 欧美日韩一区二区在线观看视频| 久久无码av三级| 五月综合激情婷婷六月色窝| 国产99久久久国产精品潘金| 欧美日韩一二三区| 国产精品久久免费看| 黄一区二区三区| 欧美人与禽zozo性伦| 国产精品国产三级国产普通话99| 免费视频一区二区| 欧美三级中文字幕在线观看| 亚洲国产精品ⅴa在线观看| 麻豆国产精品视频| 777奇米四色成人影色区| 一区二区三区91| 成人性生交大片免费看在线播放| 717成人午夜免费福利电影| 亚洲另类一区二区| 成人免费va视频| 久久色.com| 精品中文字幕一区二区小辣椒| 欧美做爰猛烈大尺度电影无法无天| 国产精品丝袜91| 高清在线观看日韩| 久久婷婷综合激情| 国产一区二区中文字幕| 欧美v国产在线一区二区三区| 首页国产欧美久久| 欧美性色黄大片| 亚洲一区二区三区四区的| 91麻豆精品秘密| 又紧又大又爽精品一区二区| 成人av在线播放网址| 欧美国产精品一区| 成人午夜激情在线| 国产精品美女久久久久久久久久久| 精品一区二区三区视频在线观看| 欧美一区二区网站| 美女www一区二区|