📄 usb.c
字号:
//
// If the recipient is an endpoint, determine whether it is stalled or
// not and return that information to the host.
//
case USB_RT_RECIPIENT_ENDPOINT:
{
// Find out which endpoint is the recipient of the request.
ulEndpoint = sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK;
// Determine whether the IN or the OUT endpoint is being addressed
// in the device request.
ulEndpoint *= 2;
if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK)
{
ulEndpoint++;
}
// Read the endpoint status.
USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT);
ulEndpoint = USBReadData();
// Send the endpoint's status to the host.
if(ulEndpoint & USB_ENDPOINT_STALL)
{
ucStatus[0] = USB_ENDPOINT_STATUS_STALLED;
}
else
{
ucStatus[0] = 0;
}
ucStatus[1] = 0;
// Send our response back to the host.
USBSendControl(ucStatus, 2);
// We're done handling this request.
break;
}
// If an invalid request is received, stall the control endpoint.
default:
{
// Stall the both control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
// We're done handling this request.
break;
}
}
}
//****************************************************************************
//
// USBSendControl transmits a block of data back to the host via the control
// endpoint.
//
//****************************************************************************
unsigned long
USBSendControl(const unsigned char *pucData, unsigned long ulLength)
{
// If a block is already being transmitted, then return a failure.
if(sUSB.ulControlInCount)
{
return(0);
}
// Prepare to transmit this block back to the host.
sUSB.pucControlIn = pucData;
sUSB.ulControlInCount = ulLength;
// Send the first packet of this block back to the host.
USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, &sUSB.pucControlIn,&sUSB.ulControlInCount);
return(1);
}
//****************************************************************************
//
// USBClearFeature implements the USB Clear_Feature device request.
//
//****************************************************************************
void USBClearFeature(void)
{
U32 ulEndpoint;
// The only feature we support is stall on an endpoint.
if(((sUSB.sControlOut.bmRequestType & USB_RT_RECIPIENT_MASK) == USB_RT_RECIPIENT_ENDPOINT) &&
(sUSB.sControlOut.wValue == USB_FEATURE_ENDPOINT_STALL))
{
// Compute the endpoint number.
ulEndpoint = (sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK) * 2;
if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK)
{
ulEndpoint++;
}
// Clear the stall condition on the specified endpoint.
USBStallEndpoint(ulEndpoint, 0);
}
else
{
// An unknown feature was specified, so stall both control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
}
}
//****************************************************************************
//
// USBSetFeature implements the USB Set_Feature device request.
//
//****************************************************************************
void USBSetFeature(void)
{
U32 ulEndpoint;
// The only feature we support is stall on an endpoint.
if(((sUSB.sControlOut.bmRequestType & USB_RT_RECIPIENT_MASK) ==
USB_RT_RECIPIENT_ENDPOINT) &&
(sUSB.sControlOut.wValue == USB_FEATURE_ENDPOINT_STALL))
{
// Compute the endpoint number.
ulEndpoint = (sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK) * 2;
if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK)
{
ulEndpoint++;
}
// Set the stall condition on the specified endpoint.
USBStallEndpoint(ulEndpoint, 1);
}
else
{
// An unknown feature was specified, so stall both control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
}
}
//****************************************************************************
//
// USBSetAddress implements the USB Set_Address device request.
//
//****************************************************************************
void USBSetAddress(void)
{
// Configure our UBS controller for the USB address assigned by the host.
USBWriteCommand(USB_COMMAND_SET_ADDRESS_ENABLE);
USBWriteData(sUSB.sControlOut.wValue | 0x80);
// Respond to the host with an empty packet.
USBSendControl(0, 0);
}
//****************************************************************************
//
// USBGetDescriptor implements the USB Get_Descriptor device request.
//
//****************************************************************************
void USBGetDescriptor(void)
{
const U8 *pucDescriptor;
U32 ulLength;
// Determine how to handle this request based on the requested descriptor.
switch(sUSB.sControlOut.wValue & USB_DESCRIPTOR_TYPE_MASK)
{
// The device descriptor was requested.
case USB_DESCRIPTOR_DEVICE:
{
// Prepare to return the device descriptor.
pucDescriptor = ucDeviceDescriptor;
ulLength = sizeof(ucDeviceDescriptor);
// We're done handling this request.
break;
}
// The configuration descriptor was requested.
case USB_DESCRIPTOR_CONFIGURATION:
{
// Prepare to return the configuration descriptor.
pucDescriptor = ucConfigurationDescriptor;
ulLength = sizeof(ucConfigurationDescriptor);
// We're done handling this request.
break;
}
// A string descriptor was requested.
case USB_DESCRIPTOR_STRING:
{
// Make sure that the language and string index requested are valid.
if(((sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK) != 0) &&
((sUSB.sControlOut.wIndex != 0x0409) ||
((sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK) > 2)))
{
// Stall both of the control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
// We're done handling this request.
return;
}
// Prepare to return the requested string.
switch(sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK)
{
// String index 0 is the language ID string.
case 0x00:
{
pucDescriptor = ucString0;
ulLength = sizeof(ucString0);
break;
}
// String index 1 is the manufacturer name.
case 0x01:
{
pucDescriptor = ucString1;
ulLength = sizeof(ucString1);
break;
}
// String index 2 is the product name.
case 0x02:
{
pucDescriptor = ucString2;
ulLength = sizeof(ucString2);
break;
}
}
// We're done handling this request.
break;
}
// An invalid request is received, so stall both control endpoints.
default:
{
// Stall both of the control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
// We're done handling this request.
return;
}
}
// If the requested length is less than the length of the descriptor to be
// returned, then simply return the requested portion of the descriptor.
if(sUSB.sControlOut.wLength < ulLength)
{
ulLength = sUSB.sControlOut.wLength;
}
// Send the descriptor back to the host.
USBSendControl(pucDescriptor, ulLength);
}
//****************************************************************************
//
// USBGetConfiguration implements the USB Get_Configuration device request.
//
//****************************************************************************
void USBGetConfiguration(void)
{
// Send the current configuration value back to the host.
USBSendControl((U8 *)&sUSB.ulConfiguration, 1);
}
//****************************************************************************
//
// USBSetConfiguration implements the USB Set_Configuration device request.
//
//****************************************************************************
void USBSetConfiguration(void)
{
// If the requested configuration is zero, then go into the unconfigured state.
if(sUSB.sControlOut.wValue == 0)
{
// Clear the global configuration flag.
sUSB.ulConfiguration = 0;
// Disable the generic endpoints.
USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE);
USBWriteData(0);
// Respond to the host with an empty packet.
USBSendControl(0, 0);
}
// If the requested configuration is one, then go into the configured state.
else if(sUSB.sControlOut.wValue == 1)
{
// Set the global configuration flag.
sUSB.ulConfiguration = 1;
// Disable the generic endpoints.
USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE);
USBWriteData(0);
// Enable the generic endpoints.
USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE);
USBWriteData(1);
// Respond to the host with an empty packet.
USBSendControl(0, 0);
}
// If the requested configuration is anything else, then stall both of the control endpoints.
else
{
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
}
}
//****************************************************************************
//
// USBGetInterface implements the USB Get_Interface device request.
//
//****************************************************************************
void USBGetInterface(void)
{
U8 ucInterface = 0;
// We only support a single interface, so the current interface is always
// the first one. Send our response back to the host.
USBSendControl(&ucInterface, 1);
}
//****************************************************************************
//
// USBSetInterface implements the USB Set_Interface device request.
//
//****************************************************************************
void USBSetInterface(void)
{
// We only support a single interface.
if((sUSB.sControlOut.wValue == 0) && (sUSB.sControlOut.wIndex == 0))
{
// The first interface was requested, so do nothing.
return;
}
else
{
// A non-existent interface was requested, so stall both control endpoints.
USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1);
USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1);
}
}
//****************************************************************************
//
// USBReceiveBulk reads a block of data from the host via the bulk endpoint.
//
//****************************************************************************
unsigned long
USBReceiveBulk(unsigned char *pucData, unsigned long ulLength)
{
// If a block is already being read, then return a failure.
if(sUSB.ulBulkOutCount)
{
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -