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

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

?? usbdrv.c

?? amega8 實現的摸擬USB芯片的AVR程序
?? C
字號:
/* Name: usbdrv.c * Project: AVR USB driver * Author: Christian Starkjohann * Creation Date: 2004-12-29 * Tabsize: 4 * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH * License: Proprietary, free under certain conditions. See Documentation. * This Revision: $Id: usbdrv.c 53 2005-04-12 17:11:29Z cs $ */#include <avr/io.h>#include <avr/pgmspace.h>#include "usbdrv.h"#include "oddebug.h"/*General Description:This module implements the C-part of the USB driver. See usbdrv.h for adocumentation of the entire driver.*//* ------------------------------------------------------------------------- *//* raw USB registers / interface to assembler code: *//* usbRxBuf MUST be in 1 byte addressable range (because usbInputBuf is only 1 byte) */static char	usbRxBuf[2][USB_BUFSIZE];/* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */uchar		usbDeviceId;		/* assigned during enumeration, defaults to 0 */uchar		usbInputBuf;		/* ptr to raw buffer used for receiving */uchar		usbAppBuf;			/* ptr to raw buffer passed to app for processing */volatile char usbRxLen;			/* = 0; number of bytes in usbAppBuf; 0 means free */uchar		usbCurrentTok;		/* last token received */uchar		usbRxToken;			/* token for data we received */uchar		usbMsgLen = 0xff;	/* remaining number of bytes, no msg to send if -1 (see usbMsgPtr) */volatile char usbTxLen = -1;	/* number of bytes to transmit with next IN token */uchar		usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen == -1 */#if USB_CFG_HAVE_INTRIN_ENDPOINT/* uchar		usbRxEndp;		endpoint which was addressed (1 bit in MSB) [not impl] */volatile char usbTxLen1 = -1;	/* TX count for endpoint 1 */uchar		usbTxBuf1[USB_BUFSIZE];/* TX data for endpoint 1 */#endifuchar		usbAckBuf[1] = {USBPID_ACK};	/* transmit buffer for ack tokens */uchar		usbNakBuf[1] = {USBPID_NAK};	/* transmit buffer for nak tokens *//* USB status registers / not shared with asm code */uchar			*usbMsgPtr;		/* data to transmit next -- ROM or RAM address */static uchar	usbMsgFlags;	/* flag values see below */static uchar	usbNewDeviceId;	/* = 0; device ID which should be set after status phase */static uchar	usbIsReset;		/* = 0; USB bus is in reset phase */#define	USB_FLG_TX_PACKET		(1<<0)/* Leave free 6 bits after TX_PACKET. This way we can increment usbMsgFlags to toggle TX_PACKET */#define	USB_FLG_MSGPTR_IS_ROM	(1<<6)#define	USB_FLG_USE_DEFAULT_RW	(1<<7)/*optimizing hints:- do not post/pre inc/dec integer values in operations- assign value of PRG_RDB() to register variables and don't use side effects in arg- use narrow scope for variables which should be in X/Y/Z register- assign char sized expressions to variables to force 8 bit arithmetics*//* ------------------------------------------------------------------------- */static char	usbDescrDevice[] PROGMEM = {	/* USB device descriptor */	18,			/* sizeof(usbDescrDevice): length of descriptor in bytes */	1,			/* descriptor type */	0x01, 0x01,	/* USB version supported */	USB_CFG_DEVICE_CLASS,	USB_CFG_DEVICE_SUBCLASS,	0,			/* protocol */	8,			/* max packet size */	USB_CFG_VENDOR_ID,	/* 2 bytes */	USB_CFG_DEVICE_ID,	/* 2 bytes */	USB_CFG_DEVICE_VERSION,	/* 2 bytes */#if USB_CFG_VENDOR_NAME_LEN	1,			/* manufacturer string index */#else	0,			/* manufacturer string index */#endif#if USB_CFG_DEVICE_NAME_LEN	2,			/* product string index */#else	0,			/* product string index */#endif	0,			/* serial number string index */	1,			/* number of configurations */};static char	usbDescrConfig[] PROGMEM = {	/* USB configuration descriptor */	9,			/* sizeof(usbDescrConfig): length of descriptor in bytes */	2,			/* descriptor type */	(18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT), 0,	/* total length of data returned (including inlined descriptors) */	1,			/* number of interfaces in this configuration */	1,			/* index of this configuration */	0,			/* configuration name string index */#if USB_CFG_IS_SELF_POWERED	USBATTR_SELFPOWER,	/* attributes */#else	USBATTR_BUSPOWER,	/* attributes */#endif	USB_CFG_MAX_BUS_POWER/2,			/* max USB current in 2mA units *//* interface descriptor follows inline: */	9,			/* sizeof(usbDescrInterface): length of descriptor in bytes */	4,			/* descriptor type */	0,			/* index of this interface */	0,			/* alternate setting for this interface */	USB_CFG_HAVE_INTRIN_ENDPOINT,	/* endpoints excl 0: number of endpoint descriptors to follow */	USB_CFG_INTERFACE_CLASS,	USB_CFG_INTERFACE_SUBCLASS,	USB_CFG_INTERFACE_PROTOCOL,	0,			/* string index for interface */#if USB_CFG_HAVE_INTRIN_ENDPOINT	/* endpoint descriptor for endpoint 1 */	7,			/* sizeof(usbDescrEndpoint) */	5,			/* descriptor type = endpoint */	0x81,		/* IN endpoint number 1 */	0x03,		/* attrib: Interrupt endpoint */	8, 0,		/* maximum packet size */	USB_CFG_INTR_POLL_INTERVAL,	/* in ms */#endif};static char	usbDescrString0[] PROGMEM = {	/* language descriptor */	4,			/* sizeof(usbDescrString0): length of descriptor in bytes */	3,			/* descriptor type */	0x09, 0x04,	/* language index (0x0409 = US-English) */};#if USB_CFG_VENDOR_NAME_LENstatic int	usbDescrString1[] PROGMEM = {	(2 * USB_CFG_VENDOR_NAME_LEN + 2) | (3<<8),	/* length of descriptor in bytes | descriptor type */	USB_CFG_VENDOR_NAME};#endif#if USB_CFG_DEVICE_NAME_LENstatic int	usbDescrString2[] PROGMEM = {	(2 * USB_CFG_DEVICE_NAME_LEN + 2) | (3<<8),	/* length of descriptor in bytes | descriptor type */	USB_CFG_DEVICE_NAME};#endif/* We don't use prog_int or prog_int16_t for compatibility with various libc * versions. Here's an other compatibility hack: */#ifndef PRG_RDB#define	PRG_RDB(addr)	pgm_read_byte(addr)#endiftypedef union{	unsigned	word;	uchar		*ptr;	uchar		bytes[2];}converter_t;/* We use this union to do type conversions. This is better optimized than * type casts in gcc 3.4.3 and much better than using bit shifts to build * ints from chars. Byte ordering is not a problem on an 8 bit platform. *//* ------------------------------------------------------------------------- */#if USB_CFG_HAVE_INTRIN_ENDPOINTstatic uchar	usbTxPacketCnt1;void	usbSetInterrupt(uchar *data, uchar len){uchar		*p, i;converter_t	crc;	if(len > 7)		len = 7;	i = USBPID_DATA1;	if(usbTxPacketCnt1 & 1)		i = USBPID_DATA0;	if(usbTxLen1 < 0){		/* packet buffer was empty */		usbTxPacketCnt1++;	}else{		usbTxLen1 = -1;		/* avoid sending incomplete interrupt data */	}	p = usbTxBuf1;	*p++ = i;	for(i=len;i--;)		*p++ = *data++;	crc.word = usbCrc16(&usbTxBuf1[1], len);	usbTxBuf1[len + 1] = crc.bytes[0];	usbTxBuf1[len + 2] = crc.bytes[1];	usbTxLen1 = len + 4;	/* len must be given including sync byte */}#endifstatic void	usbWrite(uchar *data, uchar len){#if USB_CFG_IMPLEMENT_FN_WRITE	if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){		if(usbFunctionWrite(data, len) == 0xff){	/* an error occurred */			/* usbMsgLen = 0xff; cancel potentially pending ACK [has been done by ASM module when OUT token arrived] */			usbTxBuf[0] = USBPID_STALL;			usbTxLen = 2;		/* length including sync byte */			return;		}	}#endif	usbMsgLen = 0;		/* send zero-sized block as ACK */	usbMsgFlags = 0;	/* start with a DATA1 package */}static uchar	usbRead(uchar *data, uchar len){#if USB_CFG_IMPLEMENT_FN_READ	if(usbMsgFlags & USB_FLG_USE_DEFAULT_RW){#endif		uchar i = len, *r = usbMsgPtr;		if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){	/* ROM data */			while(i--){				char c = PRG_RDB(r);	/* assign to char size variable to enforce byte ops */				*data++ = c;				r++;			}		}else{					/* RAM data */			while(i--)				*data++ = *r++;		}		usbMsgPtr = r;		return len;#if USB_CFG_IMPLEMENT_FN_READ	}else{		if(len != 0)	/* don't bother app with 0 sized reads */			return usbFunctionRead(data, len);		return 0;	}#endif}/* Don't make this function static to avoid inlining. * The entire function would become too large and exceed the range of * relative jumps. */void	usbProcessRx(uchar *data, uchar len){/* We use if() cascades because the compare is done byte-wise while switch() * is int-based. The if() cascades are therefore more efficient. */	DBG2(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, len);	if(usbRxToken == (uchar)USBPID_SETUP){		uchar replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW;		if(len == 8){	/* Setup size must be always 8 bytes. Ignore otherwise. */			uchar type = data[0] & (3 << 5);			if(type == USBRQ_TYPE_STANDARD << 5){				uchar *replyData = usbTxBuf + 9; /* there is 3 bytes free space at the end of the buffer */				replyData[0] = 0;				if(data[1] == 0){/* GET_STATUS */#if USB_CFG_IS_SELF_POWERED					uchar recipient = data[0] & 0x1f;	/* assign arith ops to variables to enforce byte size */					if(recipient == USBRQ_RCPT_DEVICE)						replyData[0] =  USB_CFG_IS_SELF_POWERED;#endif					replyData[1] = 0;					replyLen = 2;				}else if(data[1] == 5){		/* SET_ADDRESS */					usbNewDeviceId = data[2];				}else if(data[1] == 6){		/* GET_DESCRIPTOR */					flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;					if(data[3] == 1){		/* descriptor type requested */						replyLen = sizeof(usbDescrDevice);						replyData = (uchar *)usbDescrDevice;					}else if(data[3] == 2){						replyLen = sizeof(usbDescrConfig);						replyData = (uchar *)usbDescrConfig;					}else if(data[3] == 3){	/* string descriptor */						if(data[2] == 0){	/* descriptor index */							replyLen = sizeof(usbDescrString0);							replyData = (uchar *)usbDescrString0;#if USB_CFG_VENDOR_NAME_LEN						}else if(data[2] == 1){							replyLen = sizeof(usbDescrString1);							replyData = (uchar *)usbDescrString1;#endif#if USB_CFG_DEVICE_NAME_LEN						}else if(data[2] == 2){							replyLen = sizeof(usbDescrString2);							replyData = (uchar *)usbDescrString2;#endif						}					}				}else if(data[1] == 8){		/* GET_CONFIGURATION */					replyLen = 1;					replyData[0] = 1;	/* config is always 1, no setConfig required */				}else if(data[1] == 10){	/* GET_INTERFACE */					replyLen = 1;#if USB_CFG_HAVE_INTRIN_ENDPOINT				}else if(data[1] == 11){	/* SET_INTERFACE */					usbTxPacketCnt1 = 0;	/* reset data toggling for interrupt socket */#endif				}else{					/* the following requests can be ignored, send default reply */					/* 1: CLEAR_FEATURE, 3: SET_FEATURE, 7: SET_DESCRIPTOR */					/* 9: SET_CONFIGURATION, 11: SET_INTERFACE, 12: SYNCH_FRAME */				}				usbMsgPtr = replyData;				if(!data[7] && replyLen > data[6])	/* max length is in data[7]:data[6] */					replyLen = data[6];			}else{	/* not a standard request -- must be vendor or class request */#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE				uchar	len;				replyLen = data[6];	/* if this is an OUT operation, the next token will reset usbMsgLen */				if((len = usbFunctionSetup(data)) != 0xff){					replyLen = len;				}else{					flags = 0;	/* we have no valid msg, use read/write functions */				}#else				replyLen = usbFunctionSetup(data);#endif			}		}		usbMsgLen = replyLen;		usbMsgFlags = flags;	}else{	/* out request */		usbWrite(data, len);	}}/* ------------------------------------------------------------------------- */static void	usbBuildTxBlock(void){uchar		wantLen, len, txLen, x;converter_t	crc;	x = USBPID_DATA1;	if(usbMsgFlags & USB_FLG_TX_PACKET)		x = USBPID_DATA0;	usbMsgFlags++;	usbTxBuf[0] = x;	wantLen = usbMsgLen;	if(wantLen > 8)		wantLen = 8;	usbMsgLen -= wantLen;	len = usbRead(usbTxBuf + 1, wantLen);	if(len <= 8){	/* valid data packet */		crc.word = usbCrc16(&usbTxBuf[1], len);		usbTxBuf[len + 1] = crc.bytes[0];		usbTxBuf[len + 2] = crc.bytes[1];		txLen = len + 4;	/* length including sync byte */		if(len < 8)		/* a partial package identifies end of message */			usbMsgLen = 0xff;	}else{		usbTxBuf[0] = USBPID_STALL;		txLen = 2;	/* length including sync byte */		usbMsgLen = 0xff;	}	usbTxLen = txLen;	DBG2(0x20, usbTxBuf, txLen-1);}static inline uchar	isNotSE0(void){uchar	rval;/* We want to do *     return (USBIN & USBMASK); * here, but the compiler does int-expansion acrobatics. * We can avoid this by assigning to a char-sized variable. */	rval = USBIN & USBMASK;	return rval;}/* ------------------------------------------------------------------------- */void	usbPoll(void){uchar	len;	if((len = usbRxLen) > 0){/* We could check CRC16 here -- but ACK has already been sent anyway. If you * need data integrity checks with this driver, check the CRC in your app * code and report errors back to the host. Since the ACK was already sent, * retries must be handled on application level. * unsigned crc = usbCrc16((uchar *)(unsigned)(usbAppBuf + 1), usbRxLen - 3); */		len -= 3;	/* remove PID and CRC */		if(len < 128){			usbProcessRx((uchar *)(unsigned)(usbAppBuf + 1), len);		}		usbRxLen = 0;	/* mark rx buffer as available */	}	if(usbTxLen < 0){	/* TX system is idle */		if(usbMsgLen != 0xff){			usbBuildTxBlock();		}else if(usbNewDeviceId){			usbDeviceId = usbNewDeviceId;			DBG1(1, &usbNewDeviceId, 1);			usbNewDeviceId = 0;		}	}	if(isNotSE0()){	/* SE0 state */		usbIsReset = 0;	}else{		/* check whether SE0 lasts for more than 2.5us (3.75 bit times) */		if(!usbIsReset){			uchar i;			for(i=100;i;i--){				if(isNotSE0())					goto notUsbReset;			}			usbIsReset = 1;			usbDeviceId = 0;			usbNewDeviceId = 0;			DBG1(0xff, 0, 0);notUsbReset:;		}	}}/* ------------------------------------------------------------------------- */void	usbInit(void){	usbInputBuf = (uchar)usbRxBuf[0];	usbAppBuf = (uchar)usbRxBuf[1];#if USB_INTR_CFG_SET != 0	USB_INTR_CFG |= USB_INTR_CFG_SET;#endif#if USB_INTR_CFG_CLR != 0	USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);#endif	USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);}/* ------------------------------------------------------------------------- */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美剧情片在线观看| 不卡一区中文字幕| 国产精品乱码妇女bbbb| 欧美日韩黄色一区二区| 国产成人午夜视频| 丝袜美腿成人在线| 亚洲桃色在线一区| 久久久久久久国产精品影院| 精品视频在线视频| 99视频精品全部免费在线| 捆绑变态av一区二区三区| 一区二区三区电影在线播| 久久久亚洲精品一区二区三区| 欧美日韩中文国产| 91啦中文在线观看| 国产91高潮流白浆在线麻豆 | 国产精品综合网| 日韩影院免费视频| 国产精品超碰97尤物18| 2021国产精品久久精品| 日韩一级二级三级| 欧美日韩aaaaaa| 色94色欧美sute亚洲13| 成人av影院在线| 国产成人在线网站| 狠狠狠色丁香婷婷综合激情| 日本亚洲三级在线| 亚洲18色成人| 亚洲一区二区免费视频| 亚洲免费视频中文字幕| 国产精品久久久久影院老司| 欧美极品美女视频| 国产偷国产偷精品高清尤物| 精品久久人人做人人爽| 欧美成人官网二区| 欧美岛国在线观看| 日韩午夜精品视频| 欧美成人vr18sexvr| 欧美成人精品福利| 欧美成人国产一区二区| 欧美xxxxx牲另类人与| 日韩欧美精品在线视频| 日韩欧美一级在线播放| 欧美xxx久久| 久久这里只有精品首页| 久久一二三国产| 久久精品视频一区二区三区| 国产欧美一区二区精品仙草咪| 久久久久久毛片| 国产精品系列在线| 亚洲天堂成人网| 亚洲自拍另类综合| 丝袜亚洲另类欧美综合| 男男成人高潮片免费网站| 蓝色福利精品导航| 国产精品中文有码| 成人avav影音| 欧美主播一区二区三区| 欧美日韩在线直播| 日韩欧美久久久| 欧美国产日韩亚洲一区| 亚洲色图19p| 日日骚欧美日韩| 精品一区二区精品| 成人福利视频在线看| 欧美在线短视频| 日韩三级在线免费观看| 久久精品亚洲一区二区三区浴池| 中文字幕永久在线不卡| 亚洲不卡av一区二区三区| 极品少妇xxxx精品少妇| 99在线精品观看| 欧美日本在线播放| 久久久国产精品麻豆| 玉米视频成人免费看| 奇米亚洲午夜久久精品| 国产精品影视在线观看| 91社区在线播放| 欧美日韩三级在线| 国产午夜精品一区二区| 亚洲欧美激情小说另类| 蜜臀精品久久久久久蜜臀| 成人精品鲁一区一区二区| 欧美三级中文字| 精品av久久707| 亚洲精品v日韩精品| 九色porny丨国产精品| 91免费看`日韩一区二区| 欧美丰满高潮xxxx喷水动漫| 国产女人18毛片水真多成人如厕| 一区二区三区在线播放| 精品夜夜嗨av一区二区三区| 91一区二区在线| 久久欧美一区二区| 天天做天天摸天天爽国产一区| 国产91丝袜在线观看| 91精品欧美一区二区三区综合在| 国产精品久久久久aaaa| 日本三级亚洲精品| 91色|porny| 日韩你懂的电影在线观看| 日韩理论片一区二区| 狠狠色丁香婷婷综合| 91成人免费网站| 1024成人网| 国产精品1区2区3区| 91精品在线免费观看| 一区二区三区中文字幕精品精品| 国产综合色精品一区二区三区| 欧美三级电影在线看| 成人免费在线视频观看| 国产麻豆精品久久一二三| 欧美日韩国产首页| 亚洲人精品一区| 成人毛片老司机大片| 久久婷婷色综合| 午夜精品成人在线视频| 在线看一区二区| 国产精品久久久久影视| 国产一区二区在线影院| 精品久久久久久综合日本欧美| 午夜久久久影院| 在线观看视频一区二区| 亚洲欧美综合在线精品| www.欧美日韩| 欧美国产综合色视频| 精品午夜一区二区三区在线观看| 欧美精品99久久久**| 亚洲高清视频在线| 91成人国产精品| 一区二区欧美视频| 欧美亚洲动漫另类| 亚洲最新在线观看| 欧美午夜寂寞影院| 亚欧色一区w666天堂| 欧美吞精做爰啪啪高潮| 亚洲一区自拍偷拍| 欧美欧美午夜aⅴ在线观看| 亚洲永久精品国产| 在线观看欧美黄色| 天天综合日日夜夜精品| 91精品午夜视频| 久久成人18免费观看| 久久久久久久久一| 成人福利电影精品一区二区在线观看| 国产欧美日本一区视频| 国产91精品久久久久久久网曝门| 欧美激情在线一区二区三区| 国v精品久久久网| 亚洲视频一区在线观看| 日本高清无吗v一区| 水野朝阳av一区二区三区| 日韩午夜在线观看视频| 国产一区欧美一区| 中文字幕一区二区三区色视频 | 91麻豆精品国产91久久久久久 | 不卡一二三区首页| 一区二区三区蜜桃| 欧美丰满嫩嫩电影| 狠狠色丁香婷婷综合| 国产精品国产精品国产专区不片 | 国产激情一区二区三区四区| 亚洲国产高清在线观看视频| 97久久久精品综合88久久| 亚洲第一在线综合网站| 日韩精品一区二区三区视频在线观看 | 亚洲一区二区在线观看视频| 正在播放一区二区| 国产成人a级片| 亚洲精品一二三| 欧美一级视频精品观看| 国产99久久久国产精品潘金| 亚洲女子a中天字幕| 欧美一个色资源| caoporen国产精品视频| 日韩精品91亚洲二区在线观看| 精品久久五月天| 一道本成人在线| 麻豆精品国产传媒mv男同| 国产精品乱码人人做人人爱 | 久久这里只精品最新地址| av中文一区二区三区| 天天综合色天天| 国产精品毛片大码女人| 欧美一区中文字幕| 成人网在线播放| 日韩中文字幕亚洲一区二区va在线| 日韩亚洲欧美在线| 播五月开心婷婷综合| 日韩精品欧美精品| 国产精品成人午夜| 日韩精品一区二区三区在线播放| 97久久超碰精品国产| 久久99精品国产91久久来源| 一区二区日韩电影| 国产精品视频九色porn| 欧美一级欧美三级在线观看| 99久久精品99国产精品| 国产麻豆9l精品三级站| 亚洲va在线va天堂|