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

📄 protocol.c

📁 单片机和D12通讯的C程序.实现了单片机通过USB口和电脑通讯.
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "InsUsb.h"

void SetDescriptor(void);
void RamControl(void);
void GetFirmWareVersion(void);
void SetDeviceSerialNumber(void);
void ControlOutDealWith(void);
void ControlOutComplete(void);
extern void D12SetDMA(unsigned char bValue);
extern void D12ReadCurrentFrameNumber(unsigned char *pBuffer);
extern unsigned char xdata mRamBuffer[RAM_BUFFER_SIZE];

//follow is descriptor :
USB_DEVICE_DESCRIPTOR code D12_DEVICE_DESCRIPTOR =
{
	sizeof(USB_DEVICE_DESCRIPTOR),			//bLength;
    USB_DEVICE_DESCRIPTOR_TYPE,				//bDescriptorType;
    WORD_SWAP(0x0100),						//bcdUSB;ver1.1,note high and low byte should WORD_SWAP 
    0xDC,									//bDeviceClass;vendor specific
    0x00, 									//bDeviceSubClass;
	0x00,									//bDeviceProtocol;
	D12_EP0_MAX_PACKET_SIZE,				//bMaxPacketSize0;
	WORD_SWAP(0x0471),						//idVendor;philips vendor ID is 0x0471
	WORD_SWAP(0xFFF0),						//idProduct;production ID
	WORD_SWAP(0x0100),						//bcdDevice;
    0x00, 									//iManufacturer;
	0x00,									//iProduct;
	0x00,									//iSerialNumber;
	0x01									//bNumConfigurations;
};


struct {
	USB_CONFIGURATION_DESCRIPTOR 	D12_CONFIGURATION_DESCRIPTOR;
	USB_INTERFACE_DESCRIPTOR		D12_INTERFACE_DESCRIPTOR;
	USB_ENDPOINT_DESCRIPTOR			D12_ENDPOINT_DESCRIPTOR[4];
} code D12_CONFIGURATION_INTERFACE_ENDPOINT_DESCRIPTOR =

{
	{
    sizeof(USB_CONFIGURATION_DESCRIPTOR),	//bLength;
    USB_CONFIGURATION_DESCRIPTOR_TYPE,		//bDescriptorType;
    WORD_SWAP(USB_CONFIGURATION_DESCRIPTOR_LENGTH),	//wTotalLength;
	0x01,									//bNumInterfaces;
	0x01,									//bConfigurationValue;
    0x00,									//iConfiguration;
	0x60,									//bmAttributes;
	0x01									//MaxPower;
	},
	{
    sizeof(USB_INTERFACE_DESCRIPTOR),		//bLength;
    USB_INTERFACE_DESCRIPTOR_TYPE,			//bDescriptorType;
    0x00,									//bInterfaceNumber;
    0x00,									//bAlternateSetting;
	0x04,									//bNumEndpoints;
	0x00,									//bInterfaceClass;
	0x00,									//bInterfaceSubClass;
	0x00,									//bInterfaceProtocol;
	0x00									//iInterface;
	},
	{
	sizeof(USB_ENDPOINT_DESCRIPTOR),		//bLength;
	USB_ENDPOINT_DESCRIPTOR_TYPE,			//bDescriptorType;
	0x81,									//bEndpointAddress;
	USB_ENDPOINT_TYPE_INTERRUPT,			//bmAttributes;
	WORD_SWAP(D12_EP1_MAX_PACKET_SIZE),		//wMaxPacketSize;
	200,									//bInterval;200ms


	sizeof(USB_ENDPOINT_DESCRIPTOR),		//bLength;
	USB_ENDPOINT_DESCRIPTOR_TYPE,			//bDescriptorType;
	0x01,									//bEndpointAddress;
	USB_ENDPOINT_TYPE_INTERRUPT,			//bmAttributes;
	WORD_SWAP(D12_EP1_MAX_PACKET_SIZE),		//wMaxPacketSize;
	200,									//bInterval;200ms

	sizeof(USB_ENDPOINT_DESCRIPTOR),		//bLength;
	USB_ENDPOINT_DESCRIPTOR_TYPE,			//bDescriptorType;
	0x82,									//bEndpointAddress;
	USB_ENDPOINT_TYPE_BULK,					//bmAttributes;
	WORD_SWAP(D12_EP2_MAX_PACKET_SIZE),		//wMaxPacketSize;
	0,										//bInterval;

	sizeof(USB_ENDPOINT_DESCRIPTOR),		//bLength;
	USB_ENDPOINT_DESCRIPTOR_TYPE,			//bDescriptorType;
	0x02,									//bEndpointAddress;
	USB_ENDPOINT_TYPE_BULK,					//bmAttributes;
	WORD_SWAP(D12_EP2_MAX_PACKET_SIZE),		//wMaxPacketSize;
	0										//bInterval;
}};


extern SYS_INFORMATION data sSysInformation;

extern unsigned char xdata mEp0OutBuffer[EP0_OUT_BUFFER_SIZE];
extern unsigned char data  mEp0InBuffer[EP0_IN_BUFFER_SIZE];
extern unsigned char data  mEp1OutBuffer[EP1_OUT_BUFFER_SIZE];		//store led status
extern unsigned char data  mEp1InBuffer[EP1_IN_BUFFER_SIZE];		//store switch status
extern unsigned char xdata  mSerialNumber[4];


extern void D12SetAddressEnable(unsigned char bAddress, unsigned char bEnable);
extern void D12SetEndpointEnable(unsigned char bEndpointEnable);
extern void D12WriteBuffer(unsigned char bEndpointIndex,unsigned char bLength, unsigned char * pBuffer);
extern void D12SetEndpointStatus(unsigned char bEndpointIndex, unsigned char bStalled);
extern unsigned char D12SelectEndpoint(unsigned char bEndpointIndex);


////////////////////////////////////////////////////////////////////////////
////////////////////////////USB standard request////////////////////////////

//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		GetStatus will return two bytes,see USB1.1 specification "9.4.5"
void GetStatus(void)
{
	unsigned char data bEndpointIndex;
	unsigned char data bRecipient;
	unsigned char data bSlectEndpoint;

	//bRecipient is used to judge the recipient of SetUp packet is device/interface/endpoint or other
	bRecipient = sSysInformation.sUsbDeviceRequest.bmRequestType & 0x1F;	
	if (bRecipient >2)			//not supported request,and stall endpoint0
	{
		CONTROL_ENDPOINT_STALL	//set control endpoint stall
	}
	else
	{
		if (bRecipient == 0) 	//if recipient is device
		{
			if(sSysInformation.bRemoteWakeUpEnable == TRUE)	
					mEp0InBuffer[0]=0x03;		//self powered,remote wakeup enabled
			else	mEp0InBuffer[0]=0x01;		//self powered,remote wakeup disabled
	
			mEp0InBuffer[1]=0x00;				//the second byte always is 0x00
			#ifdef _Debug_
				printf("GetStatus: Remote wakeup is %x.\n",(unsigned int)(mEp0InBuffer[0] & 0x02));
			#endif
		} 
		else if (bRecipient == 1)		//else if recipient is interface
		{
			mEp0InBuffer[0]=0x00;		//always return two bytes: 0x00,0x00
			mEp0InBuffer[1]=0x00;
		} 
		else	// if (bRecipient == 2) 
		{
			//when the recipient of GetStatus is endpoint
			//the wIndex will express the endpoint direction and endpoint number,see "9.3.4"
			bEndpointIndex = (unsigned char)(sSysInformation.sUsbDeviceRequest.wIndex) & 0x0F;		
			if (sSysInformation.sUsbDeviceRequest.wIndex & 0x80)
				bSlectEndpoint = D12SelectEndpoint(bEndpointIndex*2 + 1);	//if wIndex direction bit is 1,select 
																			//endpoint index 1/3/5,and read one byte
			else
				bSlectEndpoint = D12SelectEndpoint(bEndpointIndex*2);		//else select endpoint 0/2/4,
			if(bSlectEndpoint & 0x02)		
				//if the bit1 of byte that read back is 1,this endpoint is in stall status,namely,halt status
				mEp0InBuffer[0]=0x01;
			else
				mEp0InBuffer[0]=0x00;	//else not halt
			mEp0InBuffer[1] = 0x00;		//the second byte will return is always 0x00
	
			#ifdef _Debug_
				printf("GetStatus: Endpoint status is %x.\n",(unsigned int)(mEp0InBuffer[0]));
			#endif
	
		} 
	
		D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,0x02,&mEp0InBuffer);
	}
	sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}
//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		ClearFeature,see "9.4.1"
void ClearFeature(void)
{
	unsigned char bEndpointIndex;
	unsigned char bRecipient;

	//bRecipient is used to judge the recipient of SetUp packet is device/interface/endpoint or other
	bRecipient = sSysInformation.sUsbDeviceRequest.bmRequestType & 0x1F;	

	if ((bRecipient == 0)&& (sSysInformation.sUsbDeviceRequest.wValue==1))	
	{	//if recipient is device and feature selector is DEVICE_REMOPTE_WAKEUP
		sSysInformation.bRemoteWakeUpEnable = FALSE;	//remote wakeup is disabled

		#ifdef _Debug_
			printf("ClearFeature: Remote wakeup is %x.\n",(unsigned int)(sSysInformation.bRemoteWakeUpEnable));
		#endif

		ControlOutComplete();
	}
	else if ((bRecipient == 2) && (sSysInformation.sUsbDeviceRequest.wValue==0))
	{	//if recipient is endpoint and feature selector is ENDPOINT_HALT
		bEndpointIndex = sSysInformation.sUsbDeviceRequest.wIndex & 0x0F;		
		if (sSysInformation.sUsbDeviceRequest.wIndex & 0x80)
			D12SetEndpointStatus((bEndpointIndex*2) + 1 +0x40,D12_ENDPOINT_NO_STALL);	//if wIndex direction bit is 1,select 
																		//endpoint index 1/3/5,and clear stall bit
		else
			D12SetEndpointStatus((bEndpointIndex*2) + 0x40,D12_ENDPOINT_NO_STALL);		//else select endpoint 0/2/4,

		#ifdef _Debug_
			printf("ClearFeature: Endpoint %x not be stalled.\n",(unsigned int)(sSysInformation.bRemoteWakeUpEnable));
		#endif

		ControlOutComplete();
	}
	else	//else,not supported request,and stall endpoint0
	{
		CONTROL_ENDPOINT_STALL	//set control endpoint stall
	}
}
//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		the process of SetFeature is very similar to ClearFeature
void SetFeature(void)
{
	unsigned char bEndpointIndex;
	unsigned char bRecipient ;

	bRecipient= sSysInformation.sUsbDeviceRequest.bmRequestType & 0x1F;

	if ((bRecipient == 0)&& (sSysInformation.sUsbDeviceRequest.wValue==1))
	{	//if recipient is device and feature selector is DEVICE_REMOPTE_WAKEUP
		sSysInformation.bRemoteWakeUpEnable = TRUE;	//remote wakeup is enabled
		#ifdef _Debug_
			printf("SetFeature: Device remote wakeup enabled!\n");
		#endif

		ControlOutComplete();
	}
	else if ((bRecipient == 2) && (sSysInformation.sUsbDeviceRequest.wValue==0))
	{	//if recipient is endpoint and feature selector is ENDPOINT_HALT
		bEndpointIndex = (unsigned char)(sSysInformation.sUsbDeviceRequest.wIndex) & 0x0F;		
		if ((unsigned char)(sSysInformation.sUsbDeviceRequest.wIndex) & 0x80)
		{	D12SetEndpointStatus((bEndpointIndex*2) + 1 + 0x40,D12_ENDPOINT_STALL);	//if wIndex direction bit is 1,select 
																					//endpoint index 1/3/5,and set stall bit
		}
		else
		{
			D12SetEndpointStatus((bEndpointIndex*2)+0x40,D12_ENDPOINT_STALL);		//else select endpoint 0/2/4,
		}
		#ifdef _Debug_
			printf("SetFeature: Endpoint %x is stalled!\n",(unsigned int)(bEndpointIndex));
		#endif

		ControlOutComplete();		
	} 
	else
	{
		CONTROL_ENDPOINT_STALL	//set control endpoint stall
	}
}
//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		After host read device descriptor the first time,it will assignments 
//		a new address to our device.
void SetAddress(void)
{
	D12SetAddressEnable(sSysInformation.sUsbDeviceRequest.wValue, 1);

	ControlOutComplete();
}

//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		Different form other request,get descriptor may be need more than one times IN data transaction.
//		For example,when received get configuration+interface+endpoint descriptor request,several 
//		times IN transaction is needed.This function will prepare for the data buffer for the first 
//		IN token,but the succeed IN request will be dealed by endpoint0 IN interrupt routine.

void GetDescriptor(void)
{
	unsigned char data bDescriptorType =(unsigned char)((sSysInformation.sUsbDeviceRequest.wValue>>8) & 0xFF);		//


	if ((bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE) || (bDescriptorType == 	USB_CONFIGURATION_DESCRIPTOR_TYPE))
	{
		if (bDescriptorType == 	USB_DEVICE_DESCRIPTOR_TYPE)
		{
		//Device Descriptor always is 18 bytes, see USB specification 9.6.1,
		//but the maximum length of endpoint0 of PDIUSBD12 is 16 bytes,so this request need 
		//more than one times IN transaction.Here we will ready for the data of first IN transaction,
		//the succeed IN transaction will be dealed with in endpoint0 IN interrupt routine.

		//in fact,when Host issue GetDescriptor request,the length that host
 		//required usually is longer than the descriptor that device declared,
 		//but when host received short packet,host will believe he had already got
		//what he want.So here we adjust the wRemaindLength to device's actual length.
			sSysInformation.sUsbSetUpDealwith.pDataSourceAddress = &D12_DEVICE_DESCRIPTOR.bLength;
			if (sSysInformation.sUsbSetUpDealwith.wRemaindLength>sizeof(USB_DEVICE_DESCRIPTOR))
					sSysInformation.sUsbSetUpDealwith.wRemaindLength = sizeof(USB_DEVICE_DESCRIPTOR);
		}
		else
		{
			sSysInformation.sUsbSetUpDealwith.pDataSourceAddress = &D12_CONFIGURATION_INTERFACE_ENDPOINT_DESCRIPTOR.D12_CONFIGURATION_DESCRIPTOR.bLength;		
			if (sSysInformation.sUsbSetUpDealwith.wRemaindLength>USB_CONFIGURATION_DESCRIPTOR_LENGTH)
					sSysInformation.sUsbSetUpDealwith.wRemaindLength = USB_CONFIGURATION_DESCRIPTOR_LENGTH;
		
		}

		if (sSysInformation.sUsbSetUpDealwith.wRemaindLength >= D12_EP0_MAX_PACKET_SIZE)
		{	
			D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,D12_EP0_MAX_PACKET_SIZE,sSysInformation.sUsbSetUpDealwith.pDataSourceAddress);

			//remains bytes count should be transmit
			sSysInformation.sUsbSetUpDealwith.wRemaindLength -= D12_EP0_MAX_PACKET_SIZE;
			//data start address of next transmit 
			sSysInformation.sUsbSetUpDealwith.pDataSourceAddress += D12_EP0_MAX_PACKET_SIZE;
			//to tell interrupt routine that there has data should be transmit to Host 
			sSysInformation.bUsbStatus = TRANSMIT;
		}
		else
		{
			D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,sSysInformation.sUsbSetUpDealwith.wRemaindLength,sSysInformation.sUsbSetUpDealwith.pDataSourceAddress);		
			sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
		}
	}
	else	//GetDescriptor request only has two kinds, device and configuration descriptor,all others are illegal
	{
		CONTROL_ENDPOINT_STALL	//set control endpoint stall
	}

}
//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		If device has been configed,a non-zero value should be returned to Host
//		For PDIUSBD12 Develop Board,only one configuration value 1 is avaliable.
//		See USB specification 9.4.2
void GetConfiguration(void)
{
	unsigned char data bConfigurationValue ;
	
	bConfigurationValue = sSysInformation.bD12ConfigurationValue;
	D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,0x01,&bConfigurationValue );
	sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}

//
//*************************************************************************
//	Parameter:
//		In : None
//		Out: None
//	Function:
//		See USB specification 9.4.7
void SetConfiguration(void)
{
	if (sSysInformation.sUsbDeviceRequest.wValue == 0) 
	{
		//SetConfiguration has no data phase,return zero length data packet to host

⌨️ 快捷键说明

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