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

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

?? usb-cdc.c

?? 最新版FreeRTOS, 包擴多種開發平臺的移植
?? C
?? 第 1 頁 / 共 2 頁
字號:

			pxControlRx.ulNextCharIndex = 0;
			if( ! (xRequest.ucReqType & 0x80) ) /* Host-to-Device transfer, may need to get data first */
			{
				if( xRequest.usLength > usbMAX_CONTROL_MESSAGE_SIZE )
				{	
					/* Too big!  No space for control data, stall and abort. */
					prvSendStall();
					return;
				}

				pxControlRx.ulTotalDataLength = xRequest.usLength;
			}
			else
			{
				/* We're sending the data, don't wait for any. */
				pxControlRx.ulTotalDataLength = 0; 
			}
		}
	}

	/* See if we've got a pending request and all its associated data ready */
	if( ( pxMessage->ulCSR0 & ( AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RXSETUP ) ) 
		&& ( pxControlRx.ulNextCharIndex >= pxControlRx.ulTotalDataLength ) )
	{
		unsigned portCHAR ucRequest;

		/* Manipulate the ucRequestType and the ucRequest parameters to 
		generate a zero based request selection.  This is just done to 
		break up the requests into subsections for clarity.  The 
		alternative would be to have more huge switch statement that would
		be difficult to optimise. */
		ucRequest = ( ( xRequest.ucReqType & 0x60 ) >> 3 );
		ucRequest |= ( xRequest.ucReqType & 0x03 );
			
		switch( ucRequest )
		{
			case usbSTANDARD_DEVICE_REQUEST:	
				/* Standard Device request */
				prvHandleStandardDeviceRequest( &xRequest );
				break;

			case usbSTANDARD_INTERFACE_REQUEST:	
				/* Standard Interface request */
				prvHandleStandardInterfaceRequest( &xRequest );
				break;

			case usbSTANDARD_END_POINT_REQUEST:	
				/* Standard Endpoint request */
				prvHandleStandardEndPointRequest( &xRequest );
				break;

			case usbCLASS_INTERFACE_REQUEST:	
				/* Class Interface request */
				prvHandleClassInterfaceRequest( &xRequest );
				break;

			default:	/* This is not something we want to respond to. */
				prvSendStall();	
		}
	}
}
/*------------------------------------------------------------*/

static void prvGetStandardDeviceDescriptor( xUSB_REQUEST *pxRequest )
{
	/* The type is in the high byte.  Return whatever has been requested. */
	switch( ( pxRequest->usValue & 0xff00 ) >> 8 )
	{
		case usbDESCRIPTOR_TYPE_DEVICE:
			prvSendControlData( ( unsigned portCHAR * ) &pxDeviceDescriptor, pxRequest->usLength, sizeof( pxDeviceDescriptor ), pdTRUE );
			break;

		case usbDESCRIPTOR_TYPE_CONFIGURATION:
			prvSendControlData( ( unsigned portCHAR * ) &( pxConfigDescriptor ), pxRequest->usLength, sizeof( pxConfigDescriptor ), pdTRUE );
			break;

		case usbDESCRIPTOR_TYPE_STRING:

			/* The index to the string descriptor is the lower byte. */
			switch( pxRequest->usValue & 0xff )
			{			
				case usbLANGUAGE_STRING:
					prvSendControlData( ( unsigned portCHAR * ) &pxLanguageStringDescriptor, pxRequest->usLength, sizeof(pxLanguageStringDescriptor), pdTRUE );
					break;

				case usbMANUFACTURER_STRING:
					prvSendControlData( ( unsigned portCHAR * ) &pxManufacturerStringDescriptor, pxRequest->usLength, sizeof( pxManufacturerStringDescriptor ), pdTRUE );
					break;

				case usbPRODUCT_STRING:
					prvSendControlData( ( unsigned portCHAR * ) &pxProductStringDescriptor, pxRequest->usLength, sizeof( pxProductStringDescriptor ), pdTRUE );
					break;

				case usbCONFIGURATION_STRING:
					prvSendControlData( ( unsigned portCHAR * ) &pxConfigurationStringDescriptor, pxRequest->usLength, sizeof( pxConfigurationStringDescriptor ), pdTRUE );
					break;

				case usbINTERFACE_STRING:
					prvSendControlData( ( unsigned portCHAR * ) &pxInterfaceStringDescriptor, pxRequest->usLength, sizeof( pxInterfaceStringDescriptor ), pdTRUE );
					break;

				default:
					prvSendStall();
					break;
			}
			break;

		default:
			prvSendStall();
			break;
	}
}
/*------------------------------------------------------------*/

static void prvHandleStandardDeviceRequest( xUSB_REQUEST *pxRequest )
{
unsigned portSHORT usStatus = 0;

	switch( pxRequest->ucRequest )
	{
		case usbGET_STATUS_REQUEST:
			/* Just send two byte dummy status. */
			prvSendControlData( ( unsigned portCHAR * ) &usStatus, sizeof( usStatus ), sizeof( usStatus ), pdFALSE );
			break;

		case usbGET_DESCRIPTOR_REQUEST:
			/* Send device descriptor */
			prvGetStandardDeviceDescriptor( pxRequest );
			break;

		case usbGET_CONFIGURATION_REQUEST:
			/* Send selected device configuration */
			prvSendControlData( ( unsigned portCHAR * ) &ucUSBConfig, sizeof( ucUSBConfig ), sizeof( ucUSBConfig ), pdFALSE );
			break;

		case usbSET_FEATURE_REQUEST:
			prvSendZLP();
			break;

		case usbSET_ADDRESS_REQUEST:			
			/* Get assigned address and send ack, but don't implement new address until we get a TXCOMP */
			prvSendZLP();			
			eDriverState = eJUST_GOT_ADDRESS;			
			ulReceivedAddress = ( unsigned portLONG ) pxRequest->usValue;
			break;

		case usbSET_CONFIGURATION_REQUEST:
			/* Ack SET_CONFIGURATION request, but don't implement until TXCOMP */
			ucUSBConfig = ( unsigned portCHAR ) ( pxRequest->usValue & 0xff );
			eDriverState = eJUST_GOT_CONFIG;
			prvSendZLP();
			break;

		default:
			/* Any unsupported request results in a STALL response. */
			prvSendStall();
			break;
	}
}
/*------------------------------------------------------------*/

static void prvHandleClassInterfaceRequest( xUSB_REQUEST *pxRequest )
{
	switch( pxRequest->ucRequest )
	{
		case usbSEND_ENCAPSULATED_COMMAND:
			prvSendStall();
			break;

		case usbGET_ENCAPSULATED_RESPONSE:
			prvSendStall();
			break;

		case usbSET_LINE_CODING:
			/* Set line coding - baud rate, data bits, parity, stop bits */
			prvSendZLP();
			memcpy( ( void * ) pxLineCoding, pxControlRx.ucBuffer, sizeof( pxLineCoding ) );
			break;

		case usbGET_LINE_CODING:
			/* Get line coding */
			prvSendControlData( (unsigned portCHAR *) &pxLineCoding, pxRequest->usLength, sizeof( pxLineCoding ), pdFALSE );
			break;

		case usbSET_CONTROL_LINE_STATE:
			/* D0: 1=DTR, 0=No DTR,  D1: 1=Activate Carrier, 0=Deactivate carrier (RTS, half-duplex) */
			prvSendZLP();
			ucControlState = pxRequest->usValue;
			break;

		default:
			prvSendStall();
			break;
	}
}
/*------------------------------------------------------------*/

static void prvGetStandardInterfaceDescriptor( xUSB_REQUEST *pxRequest )
{
	switch( ( pxRequest->usValue & ( unsigned portSHORT ) 0xff00 ) >> 8 )
	{
		default:
			prvSendStall();
			break;
	}
}
/*-----------------------------------------------------------*/

static void prvHandleStandardInterfaceRequest( xUSB_REQUEST *pxRequest )
{
unsigned portSHORT usStatus = 0;

	switch( pxRequest->ucRequest )
	{
		case usbGET_STATUS_REQUEST:
			/* Send dummy 2 bytes. */
			prvSendControlData( ( unsigned portCHAR * ) &usStatus, sizeof( usStatus ), sizeof( usStatus ), pdFALSE );
			break;

		case usbGET_DESCRIPTOR_REQUEST:
			prvGetStandardInterfaceDescriptor( pxRequest ); 
			break;

		/* This minimal implementation does not respond to these. */
		case usbGET_INTERFACE_REQUEST:
		case usbSET_FEATURE_REQUEST:
		case usbSET_INTERFACE_REQUEST:	

		default:
			prvSendStall();
			break;
	}
}
/*-----------------------------------------------------------*/

static void prvHandleStandardEndPointRequest( xUSB_REQUEST *pxRequest )
{
	switch( pxRequest->ucRequest )
	{
		/* This minimal implementation does not expect to respond to these. */
		case usbGET_STATUS_REQUEST:
		case usbCLEAR_FEATURE_REQUEST: 
		case usbSET_FEATURE_REQUEST:

		default:			
			prvSendStall();
			break;
	}
}
/*-----------------------------------------------------------*/

static void vDetachUSBInterface( void)
{
	/* Setup the PIO for the USB pull up resistor. */
	AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16;
	AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16;


	/* Disable pull up */
	AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA16;
} 
/*-----------------------------------------------------------*/

static void vInitUSBInterface( void )
{
extern void ( vUSB_ISR )( void );

	/* Create the queue used to communicate between the USB ISR and task. */
	xUSBInterruptQueue = xQueueCreate( usbQUEUE_LENGTH + 1, sizeof( xISRStatus * ) );
	
	/* Create the queues used to hold Rx and Tx characters. */
	xRxCDC = xQueueCreate( USB_CDC_QUEUE_SIZE, ( unsigned portCHAR ) sizeof( signed portCHAR ) );
	xTxCDC = xQueueCreate( USB_CDC_QUEUE_SIZE + 1, ( unsigned portCHAR ) sizeof( signed portCHAR ) );

	if( (!xUSBInterruptQueue) || (!xRxCDC) || (!xTxCDC) )
	{	
		/* Not enough RAM to create queues!. */
		return;
	}
	
	/* Initialise a few state variables. */
	pxControlTx.ulNextCharIndex = ( unsigned portLONG ) 0;
	pxControlRx.ulNextCharIndex = ( unsigned portLONG ) 0;
	ucUSBConfig = ( unsigned portCHAR ) 0;
	eDriverState = eNOTHING;
	ucControlState = 0;
	uiCurrentBank = AT91C_UDP_RX_DATA_BK0;


	/* HARDWARE SETUP */

	/* Set the PLL USB Divider */
	AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1;

	/* Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock. */
	AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);

	/* Setup the PIO for the USB pull up resistor. */
	AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16;
	AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16;


	/* Start without the pullup - this will get set at the end of this 
	function. */
   	AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA16;


	/* When using the USB debugger the peripheral registers do not always get
	set to the correct default values.  To make sure set the relevant registers
	manually here. */
	AT91C_BASE_UDP->UDP_IDR = ( unsigned portLONG ) 0xffffffff;
	AT91C_BASE_UDP->UDP_ICR = ( unsigned portLONG ) 0xffffffff;
	AT91C_BASE_UDP->UDP_CSR[ 0 ] = ( unsigned portLONG ) 0x00;
	AT91C_BASE_UDP->UDP_CSR[ 1 ] = ( unsigned portLONG ) 0x00;
	AT91C_BASE_UDP->UDP_CSR[ 2 ] = ( unsigned portLONG ) 0x00;
	AT91C_BASE_UDP->UDP_CSR[ 3 ] = ( unsigned portLONG ) 0x00;
	AT91C_BASE_UDP->UDP_GLBSTATE = 0;
	AT91C_BASE_UDP->UDP_FADDR = 0;

	/* Enable the transceiver. */
	AT91C_UDP_TRANSCEIVER_ENABLE = 0;

	/* Enable the USB interrupts - other interrupts get enabled as the 
	enumeration process progresses. */
	AT91F_AIC_ConfigureIt( AT91C_ID_UDP, usbINTERRUPT_PRIORITY, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vUSB_ISR );
	AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_UDP;


	/* Wait a short while before making our presence known. */
	vTaskDelay( usbINIT_DELAY );
	AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;
}
/*-----------------------------------------------------------*/

static void prvSendControlData( unsigned portCHAR *pucData, unsigned portSHORT usRequestedLength, unsigned portLONG ulLengthToSend, portLONG lSendingDescriptor )
{
	if( ( ( unsigned portLONG ) usRequestedLength < ulLengthToSend ) )
	{
		/* Cap the data length to that requested. */
		ulLengthToSend = ( unsigned portSHORT ) usRequestedLength;
	}
	else if( ( ulLengthToSend < ( unsigned portLONG ) usRequestedLength ) && lSendingDescriptor )
	{
		/* We are sending a descriptor.  If the descriptor is an exact 
		multiple of the FIFO length then it will have to be terminated
		with a NULL packet.  Set the state to indicate this if
		necessary. */
		if( ( ulLengthToSend % usbFIFO_LENGTH ) == 0 )
		{
			eDriverState = eSENDING_EVEN_DESCRIPTOR;
		}
	}

	/* Here we assume that the previous message has been sent.  THERE IS NO
	BUFFER OVERFLOW PROTECTION HERE.

	Copy the data to send into the buffer as we cannot send it all at once
	(if it is greater than 8 bytes in length). */
	memcpy( pxControlTx.ucBuffer, pucData, ulLengthToSend );

	/* Reinitialise the buffer index so we start sending from the start of 
	the data. */
	pxControlTx.ulTotalDataLength = ulLengthToSend;
	pxControlTx.ulNextCharIndex = ( unsigned portLONG ) 0;

	/* Send the first 8 bytes now.  The rest will get sent in response to 
	TXCOMP interrupts. */
	prvSendNextSegment();
}
/*-----------------------------------------------------------*/

static void prvSendNextSegment( void )
{
volatile unsigned portLONG ulNextLength, ulStatus, ulLengthLeftToSend;

	/* Is there any data to send? */
	if( pxControlTx.ulTotalDataLength > pxControlTx.ulNextCharIndex )
	{
		ulLengthLeftToSend = pxControlTx.ulTotalDataLength - pxControlTx.ulNextCharIndex;
	
		/* We can only send 8 bytes to the fifo at a time. */
		if( ulLengthLeftToSend > usbFIFO_LENGTH )
		{
			ulNextLength = usbFIFO_LENGTH;
		}
		else
		{
			ulNextLength = ulLengthLeftToSend;
		}

		/* Wait until we can place data in the fifo.  THERE IS NO TIMEOUT
		HERE! */
		while( AT91C_BASE_UDP->UDP_CSR[ usbEND_POINT_0 ] & AT91C_UDP_TXPKTRDY )
		{
			vTaskDelay( usbSHORTEST_DELAY );
		}

		/* Write the data to the FIFO. */
		while( ulNextLength > ( unsigned portLONG ) 0 )
		{
			AT91C_BASE_UDP->UDP_FDR[ usbEND_POINT_0 ] = pxControlTx.ucBuffer[ pxControlTx.ulNextCharIndex ];
	
			ulNextLength--;
			pxControlTx.ulNextCharIndex++;
		}
	
		/* Start the transmission. */
		portENTER_CRITICAL();
		{
			ulStatus = AT91C_BASE_UDP->UDP_CSR[ usbEND_POINT_0 ];
			usbCSR_SET_BIT( &ulStatus, ( ( unsigned portLONG ) 0x10 ) );
			AT91C_BASE_UDP->UDP_CSR[ usbEND_POINT_0 ] = ulStatus;
		}
		portEXIT_CRITICAL();
	}
	else
	{
		/* There is no data to send.  If we were sending a descriptor and the 
		descriptor was an exact multiple of the max packet size then we need
		to send a null to terminate the transmission. */
		if( eDriverState == eSENDING_EVEN_DESCRIPTOR )
		{
			prvSendZLP();
			eDriverState = eNOTHING;
		}
	}
}


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产99久久久久久免费看农村| 亚洲成人在线免费| 777xxx欧美| 欧美日韩国产综合一区二区| 91免费观看国产| 国产不卡在线播放| 国产一区二区三区四区在线观看| 免费人成网站在线观看欧美高清| 一区二区三区久久久| 亚洲精品日韩一| 亚洲精品高清在线观看| 国产精品不卡视频| 国产欧美一区二区三区网站| 亚洲国产精品高清| 日韩免费性生活视频播放| 在线成人午夜影院| 8x8x8国产精品| 精品日韩欧美在线| 国产欧美精品区一区二区三区| 国产无人区一区二区三区| 精品国产a毛片| 中文字幕欧美激情一区| 一区二区三区国产| 亚洲欧美激情视频在线观看一区二区三区 | 成人精品国产一区二区4080| 国产精品99久久久久久久女警 | 国产精品一区一区三区| 成人免费视频视频在线观看免费| 97久久精品人人做人人爽| 欧美视频自拍偷拍| 精品国产成人系列| 日韩毛片在线免费观看| 性做久久久久久免费观看| 久久爱www久久做| 91小宝寻花一区二区三区| 3d动漫精品啪啪一区二区竹菊| 久久久久一区二区三区四区| 综合网在线视频| 久久精品国产一区二区三| 99久久精品一区二区| 欧美一卡二卡在线观看| 国产精品乱码妇女bbbb| 首页欧美精品中文字幕| 99久久精品免费观看| 久久品道一品道久久精品| 亚洲aaa精品| 色综合久久久久综合体桃花网| 日韩欧美高清在线| 亚洲另类春色校园小说| 国产成人自拍网| 欧美精品一二三| 亚洲一区二区影院| eeuss国产一区二区三区| 欧美日韩亚洲国产综合| 综合欧美亚洲日本| 国产美女视频91| 日韩一区国产二区欧美三区| 亚洲精品第1页| 91麻豆6部合集magnet| 久久久久国产免费免费| 美脚の诱脚舐め脚责91| 91精品午夜视频| 亚洲成av人片在www色猫咪| 色婷婷国产精品久久包臀| 国产日韩av一区| 国产剧情一区在线| 国产清纯白嫩初高生在线观看91 | 欧美精品 日韩| 婷婷久久综合九色综合伊人色| 色激情天天射综合网| 国产精品午夜在线观看| 91麻豆免费观看| 亚洲黄色小说网站| 欧美自拍丝袜亚洲| 亚洲精品国产精品乱码不99| 91麻豆免费看| 日韩有码一区二区三区| 91精品国产综合久久久久久漫画| 男人的天堂久久精品| 久久综合精品国产一区二区三区 | 国产成人自拍高清视频在线免费播放| 国产欧美日韩久久| 色爱区综合激月婷婷| 一区二区欧美国产| 欧美刺激午夜性久久久久久久| 国产精品一品视频| 国产精品第五页| 欧美夫妻性生活| 国产一级精品在线| 亚洲精品福利视频网站| 欧美一区二区三区小说| 99久久精品免费| 激情欧美日韩一区二区| 亚洲色图视频网| 欧美一二三四区在线| 91福利视频网站| 亚洲精品一区二区精华| 日本高清不卡aⅴ免费网站| 韩国一区二区视频| 国产一本一道久久香蕉| 日韩电影在线观看网站| 国产午夜精品一区二区 | 日本麻豆一区二区三区视频| 久久亚洲精精品中文字幕早川悠里 | 亚洲午夜影视影院在线观看| 日韩亚洲欧美高清| 在线观看欧美精品| 成人高清视频在线| 国产一区二区三区四| 久草热8精品视频在线观看| 日本在线播放一区二区三区| 香蕉加勒比综合久久| 最近中文字幕一区二区三区| 久久综合久色欧美综合狠狠| 欧美成人高清电影在线| 在线不卡中文字幕播放| 欧美影院午夜播放| 色偷偷成人一区二区三区91 | 国产精品嫩草影院av蜜臀| 国产三级欧美三级日产三级99| 99久久国产综合色|国产精品| 欧美在线你懂的| 日韩一区二区三区视频在线| 日本一区二区三区在线不卡| 亚洲另类春色校园小说| 日韩精品1区2区3区| 国v精品久久久网| 欧美日韩在线电影| 欧美一卡二卡三卡| 久久久激情视频| 日韩一区在线看| 亚洲mv在线观看| 国产最新精品精品你懂的| 国产精华液一区二区三区| 国产成都精品91一区二区三| 成人在线视频首页| 从欧美一区二区三区| 日本韩国一区二区| 欧美探花视频资源| 久久色中文字幕| 亚洲一区二区精品久久av| 激情综合色综合久久综合| www.综合网.com| 欧美性感一区二区三区| 国产欧美1区2区3区| 天堂一区二区在线| 91在线国产观看| 久久伊99综合婷婷久久伊| 亚洲二区视频在线| 99国产精品久久久| 久久九九久精品国产免费直播| 亚洲尤物视频在线| aa级大片欧美| 国产精品欧美综合在线| 精品一区二区三区不卡| 欧美色中文字幕| 中文字幕一区不卡| 国产大片一区二区| 精品福利在线导航| 亚洲va韩国va欧美va精品 | 91精品国产美女浴室洗澡无遮挡| 亚洲人被黑人高潮完整版| 懂色av中文一区二区三区 | 一片黄亚洲嫩模| 成人av在线播放网站| 欧美国产精品久久| 成人一二三区视频| 中文字幕免费观看一区| 国产麻豆午夜三级精品| 久久久国产精品不卡| 国产伦精品一区二区三区视频青涩| 欧美不卡一区二区三区四区| 日韩成人精品视频| 日韩精品一区二区三区三区免费| 日韩—二三区免费观看av| 欧美电视剧在线观看完整版| 久久99精品久久久| 欧美激情一区二区三区蜜桃视频| 国产91精品露脸国语对白| 亚洲欧洲日本在线| 在线亚洲+欧美+日本专区| 日韩av成人高清| www久久精品| 色狠狠色狠狠综合| 日韩黄色小视频| 26uuu久久综合| 91玉足脚交白嫩脚丫在线播放| 亚洲一区二区视频| 国产日韩欧美电影| 欧美三级三级三级| 国产精品一区二区黑丝| 亚洲精品乱码久久久久久 | 亚洲精品一区二区三区精华液| 成人黄色片在线观看| 免费成人你懂的| 亚洲日本va在线观看| 久久伊人蜜桃av一区二区| 欧美主播一区二区三区美女| 国产老女人精品毛片久久| 亚洲成av人片一区二区梦乃 |