📄 protocol.c
字号:
//if the value of SetConfiguration request is 0,device should enter address state
//and all endpoint should be disabled except for endpoint0
D12SetEndpointEnable(0);
sSysInformation.bD12ConfigurationValue = 0x00;
ControlOutComplete();
}
else if (sSysInformation.sUsbDeviceRequest.wValue == 1)
{
//SetConfiguration has no data phase,return zero length data packet to host
D12SetEndpointEnable(1);
sSysInformation.bD12ConfigurationValue = 0x01;
ControlOutComplete();
}
//Interface studio PDIUSBD12 USB1.1 Develop Board only support one configuration: 1.
else //illegal request
{
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// See USB specification 9.4.4
void GetInterface(void)
{
unsigned char data bAlternateSetting = 0;
if (sSysInformation.sUsbDeviceRequest.wIndex == 0)
{
//Our device only support one interface,so AlternateSetting only has one value:0
D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,0x01,&bAlternateSetting);
}
else
{
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// See USB specification 9.4.10
void SetInterface(void)
{
//PDIUSBD12 Develop Board only support one interface,so
//SetInterface request will be returned STALL
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// Althouth this firmware support SetDescriptor command, but receiced
// descriptor has no any interpretion by this firmware.It should be
// interpreted by user.Descriptor is save at mEp0OutBuffer, and next
// control-out will overlapp those data.
void SetDescriptor(void)
{
//Note: Actually, receive descriptor is implemented in Ep0Out() routine
//and ControlOutDealWith() routine.
ControlOutComplete();
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// Although this firmware does not support isochronous transfer,
// synchronization frame request still is implementated.
void ReadSynFrameNumber(void)
{
D12ReadCurrentFrameNumber(&mEp0InBuffer);
D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN, 0x02, &mEp0InBuffer);
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////Vendor defined request//////////////////////////
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
void RamControl(void)
{
unsigned char xdata * data pRamBuffer ;
unsigned char data bDataLength;
sSysInformation.sRamControl.bRamCommand = sSysInformation.sUsbDeviceRequest.bRequest;
if (sSysInformation.sRamControl.bRamCommand != RAM_COMMAND_LOOPBACK)
{
sSysInformation.sRamControl.iRamStartAddress = sSysInformation.sUsbDeviceRequest.wIndex;
sSysInformation.sRamControl.iRamRwLength = sSysInformation.sUsbDeviceRequest.wValue;
sSysInformation.sRamControl.iRamRemaindLength = sSysInformation.sRamControl.iRamRwLength;
//if ram read
if (sSysInformation.sRamControl.iRamRemaindLength > RAM_BUFFER_SIZE)
{
//This firmware use P89C51RD2 internal RAM as ram buffer,it size is 512 bytes
//if data length of Host request is over 512 byte,stall this request
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
else
{
if (sSysInformation.sRamControl.bRamCommand == RAM_COMMAND_READ)
{
pRamBuffer = &mRamBuffer + sSysInformation.sRamControl.iRamStartAddress;
//if iRamRemaindLength is longer than D12_EP2_MAX_PACKET_SIZE,the ram read
//must split several IN transaction
if (sSysInformation.sRamControl.iRamRemaindLength > D12_EP2_MAX_PACKET_SIZE)
{
sSysInformation.sRamControl.bRamRwStatus = TRANSMIT;
bDataLength = D12_EP2_MAX_PACKET_SIZE;
}
//if iRamRemaindLength is less than D12_EP2_MAX_PACKET_SIZE,only one IN transaction
//will complete ram read request
else
{
sSysInformation.sRamControl.bRamRwStatus = IDLE;
bDataLength = (unsigned char)(sSysInformation.sRamControl.iRamRemaindLength);
}
//if (bDataLength >0)
//{
D12WriteBuffer(D12_SELECT_ENDPOINT_ENDPOINT2_IN,bDataLength,pRamBuffer);
sSysInformation.sRamControl.iRamRemaindLength -= bDataLength;
//}
}
//if ram write
else
{
sSysInformation.sRamControl.bRamRwStatus = RECEIVE;
}
}
}
ControlOutComplete();
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// Host software issue a GetFirmWareVersion request by vendor defined
// request.This function will return version number.
void GetFirmWareVersion(void)
{
//firmware version is one byte
unsigned char data bFirmWareVersion;
bFirmWareVersion = FIRMWARE_VERSION;
D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,0x01,&bFirmWareVersion);
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// SetDeviceSerialNumber() is a vendor defined request to demonstrate
// how to implement control-out transfer with data stage.
void SetDeviceSerialNumber(void)
{
//Note: Actually, receive serial number is implemented in Ep0Out() routine
//and ControlOutDealWith() routine.
unsigned char data i;
//device serial number is 4 byte
for (i=0;i<4;i++)
{
//save serial number
mSerialNumber[i] = mEp0OutBuffer[i];
}
ControlOutComplete();
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// In order to tell firmware that host application now is started,we use
// vendor defined request NotifyAppStart() to notify our firmware;when received
// this request,firmware refresh LED initial status and return current switch
// status to host,thus device's LED and switch has the same status with host
// application software .
void NotifyAppStart(void)
{
unsigned char data bSwitchStatus;
//refresh LED status
mEp1OutBuffer[0] = (unsigned char)(sSysInformation.sUsbDeviceRequest.wValue);
LED_ADDRESS = mEp1OutBuffer[0];
//return switch status
bSwitchStatus = SWITCH_ADDRESS;
D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN,0x01,&bSwitchStatus);
sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
}
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////other routine/////////////////////////////////////
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// After control-out transfer will finish,we set correspoding flag and
// return zero length data packet as status stage to complete this
// transfer.
void ControlOutComplete(void)
{
unsigned char data bNone = 0; //it is only used to provid a address needed by funcion D12WriteBuffer(),
//and it has no meaning when return zero length data packet to Host
//When control-out transfer will be finished,we set bControOutCommandIsPending
//flag,and return zero length data packet as status stage to complete this control-out
//transfer.
//see 8.5.3.1"
sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = FALSE;
D12WriteBuffer(D12_SELECT_ENDPOINT_CONTROL_IN, 0x00, &bNone);
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// This firmware implement SetDescriptor() and SetDeviceSerialNumber()
// request which all are control-out transfer with a data stage.Deal with
// them has some different from other contro-out transfer that without
// data stage.We should wait until all data are received and then deal
// with it.
void ControlOutDealWith(void)
{
if (sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete == TRUE)
{
if (sSysInformation.sUsbDeviceRequest.bRequest == USB_REQUEST_SET_DESCRIPTOR)
SetDescriptor();
else if (sSysInformation.sUsbDeviceRequest.bRequest == SET_DEVICE_SERIAL_NUMBER)
SetDeviceSerialNumber();
//because UsbSetUpDeal() has already checked whether bRequest is valid,
//so here no necessary to check bRequest again.
}
}
//
//*************************************************************************
// Parameter:
// In : None
// Out: None
// Function:
// When received a setup packet,this function dispatch routine according to
// different request.
void UsbSetUpDeal(void)
{
//This routine complete contro-in, and control-out that without data stage.
//For control-out with data stage,when data receice is finished,deal with them
//at ControlOutDealWith().
//if setup packet is USB standard request.
if ((sSysInformation.sUsbDeviceRequest.bmRequestType & USB_REQUEST_BMREQUESTTYPE_TPYE_MASK)\
== USB_REQUEST_BMREQUESTTYPE_TPYE_STANDARD)
{
switch(sSysInformation.sUsbDeviceRequest.bRequest )
{
case USB_REQUEST_GET_STATUS :
GetStatus();
break;
case USB_REQUEST_CLEAR_FEATURE :
ClearFeature();
break;
case USB_REQUEST_SET_FEATURE :
SetFeature();
break;
case USB_REQUEST_SET_ADDRESS :
SetAddress();
break;
case USB_REQUEST_GET_DESCRIPTOR :
GetDescriptor();
break;
case USB_REQUEST_SET_DESCRIPTOR:
//because SetDescriptor request has data stage,
//so here we have nothing to do. When data is received,
//deal with it in ControlOutDealWith() routine
break;
case USB_REQUEST_GET_CONFIGURATION :
GetConfiguration();
break;
case USB_REQUEST_SET_CONFIGURATION :
SetConfiguration();
break;
case USB_REQUEST_GET_INTERFACE:
GetInterface();
break;
case USB_REQUEST_SET_INTERFACE:
SetInterface();
break;
case USB_REQUEST_SYNC_FRAME:
ReadSynFrameNumber();
break;
case 2 :
case 4 :
default:
CONTROL_ENDPOINT_STALL //set control endpoint stall
break;
}
}
//else if USB request is Vendor request
else if ((sSysInformation.sUsbDeviceRequest.bmRequestType & USB_REQUEST_BMREQUESTTYPE_TPYE_MASK)\
== USB_REQUEST_BMREQUESTTYPE_TPYE_VENDOR)
{
switch(sSysInformation.sUsbDeviceRequest.bRequest )
{
//set looptest command
case RAM_COMMAND_LOOPBACK :
//set read ram command
case RAM_COMMAND_READ :
//set write ram command
case RAM_COMMAND_WRITE :
//for this firmware,RamControl is refered as ram control;
//include ram read ,ram write and loopback test
//sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = TRUE;
RamControl();
break;
//get firmware version command,it is a control-in transfer with data stage
case GET_FIRMWARE_VERSION:
GetFirmWareVersion();
break;
//set device serial number command is a control-out transfer with data stage
//note this only is an example to demenstrate how to deal with control-out
//transfer with data stage;serial number will be saved to mSerialNumber,and lost
//when powered off.
case SET_DEVICE_SERIAL_NUMBER:
//because SetDeviceSerialNumber() request has data stage,
//so here we have nothing to do. When data is received,
//deal with it in ControlOutDealWith() routine
break;
case NOTIFY_APP_START:
NotifyAppStart();
break;
//all other vendor request will be dealwith by user
default:
CONTROL_ENDPOINT_STALL //set control endpoint stall
break;
}
}
else
{
//this firmware does not support other request type,so stall endpoint0 here.
//If needed,user can implement other request type here.
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -