📄 usb.c
字号:
//****************************************************************************
//
// 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);
}
// Prepare to read data from the host into this buffer.
sUSB.pucBulkOut = pucData;
sUSB.ulBulkOutCount = ulLength;
return(1);
}
//****************************************************************************
//
// USBReceiveBulkDone determines if the data receive from the bulk endpoint
// has completed.
//
//****************************************************************************
unsigned long
USBReceiveBulkDone(void)
{
// Is there more data to receive from the bulk endpoint?
if(sUSB.ulBulkOutCount)
{
// There's more data to receive, so indicate that we're not done.
return(0);
}
else
{
// We've received all the data, so indicate that we're done.
return(1);
}
}
//****************************************************************************
//
// USBReceiveCommand reads a block of data from the host via the bulk endpoint 1.
//
//****************************************************************************
unsigned long
USBReceiveCommand(unsigned char *pucData, unsigned long ulLength)
{
// If a block is already being read, then return a failure.
if(sUSB.ulCommandOutCount)
{
return(0);
}
// Prepare to read data from the host into this buffer.
sUSB.pucCommandOut = pucData;
sUSB.ulCommandOutCount = ulLength;
return(1);
}
//****************************************************************************
//
// USBReceiveCommandDone determines if the data receive from the bulk endpoint
// has completed.
//
//****************************************************************************
unsigned long
USBReceiveCommandDone(void)
{
// Is there more data to receive from the bulk endpoint?
if(sUSB.ulCommandOutCount)
{ // There's more data to receive, so indicate that we're not done.
return(0);
}
else
{
// We've received all the data, so indicate that we're done.
return(1);
}
}
//****************************************************************************
//
// USBSendACKDone determines if the data transmit to the bulk endpoint 2 has
// completed.
//
//****************************************************************************
unsigned long
USBSendACKDone(void)
{
// Is there more data to be sent to the bulk endpoint?
if(sUSB.ulACKInCount != 0)
{
// There's more data to transmit, so indicate that we're not done.
return(0);
}
else
{ // We've sent all the data, so indicate that we're done.
return(1);
}
}
//****************************************************************************
//
// USBSendBulk transmits a block of data back to the host via the bulk
// endpoint.
//
//****************************************************************************
unsigned long
USBSendBulk(const unsigned char *pucData, unsigned long ulLength)
{
// If a block is already being transmitted, then return a failure.
if(sUSB.ulBulkInCount)
{
return(0);
}
// Prepare to transmit this block back to the host.
sUSB.pucBulkIn = pucData;
sUSB.ulBulkInCount = ulLength;
USBWriteEndpoint(USB_ENDPOINT_BULK_IN, &sUSB.pucBulkIn, &sUSB.ulBulkInCount);
return(1);
}
//****************************************************************************
//
// USBSendBulkDone determines if the data transmit to the bulk endpoint has
// completed.
//
//****************************************************************************
unsigned long
USBSendBulkDone(void)
{
// Is there more data to be sent to the bulk endpoint?
if(sUSB.ulBulkInCount)
{
// There's more data to transmit, so indicate that we're not done.
return(0);
}
else
{
// We've sent all the data, so indicate that we're done.
return(1);
}
}
//****************************************************************************
//
// USBSendControlDone determines if the data transmit to the control endpoint
// has completed.
//
//****************************************************************************
unsigned long
USBSendControlDone(void)
{
// Is there more data to be sent to the control endpoint?
if(sUSB.ulControlInCount)
{
// There's more data to transmit, so indicate that we're not done.
return(0);
}
else
{
// We've sent all the data, so indicate that we're done.
return(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -