📄 protocol.c
字号:
#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 + -