📄 usbddriver.c
字号:
USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
}
// Acknowledge the request
USBD_Write(0, 0, 0, 0, 0);
}
}
//------------------------------------------------------------------------------
/// Sends the currently active setting of the given interface to the USB
/// host. If alternate settings are not supported, this function STALLs the
/// control pipe.
/// \param pDriver Pointer to a USBDDriver instance.
/// \param infnum Interface number.
//------------------------------------------------------------------------------
static void GetInterface(
const USBDDriver *pDriver,
unsigned char infnum)
{
// Make sure alternate settings are supported, or STALL the control pipe
if (!pDriver->pInterfaces) {
USBD_Stall(0);
}
else {
// Sends the current interface setting to the host
USBD_Write(0, &(pDriver->pInterfaces[infnum]), 1, 0, 0);
}
}
#ifdef BOARD_USB_UDPHS
//------------------------------------------------------------------------------
// Performs the selected test on the USB device (high-speed only).
// \param test Test selector value.
//------------------------------------------------------------------------------
static void USBDDriver_Test(unsigned char test)
{
trace_LOG(trace_DEBUG, "UDPHS_Test\n\r");
// the lower byte of wIndex must be zero
// the most significant byte of wIndex is used to specify the specific test mode
switch (test) {
case USBFeatureRequest_TESTPACKET:
//Test mode Test_Packet:
//Upon command, a port must repetitively transmit the following test packet until
//the exit action is taken. This enables the testing of rise and fall times, eye
//patterns, jitter, and any other dynamic waveform specifications.
//The test packet is made up by concatenating the following strings.
//(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one
//transmitted. 揝?indicates that a bit stuff occurs, which inserts an 揺xtra?NRZI data bit.
//? N?is used to indicate N occurrences of a string of bits or symbols.)
//A port in Test_Packet mode must send this packet repetitively. The inter-packet timing
//must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and
//no greater than 125 us.
// Send ZLP
USBD_Test(USBFeatureRequest_TESTSENDZLP);
// Tst PACKET
USBD_Test(USBFeatureRequest_TESTPACKET);
while (1);
break;
case USBFeatureRequest_TESTJ:
//Test mode Test_J:
//Upon command, a port抯 transceiver must enter the high-speed J state and remain in that
//state until the exit action is taken. This enables the testing of the high output drive
//level on the D+ line.
// Send ZLP
USBD_Test(USBFeatureRequest_TESTSENDZLP);
// Tst J
USBD_Test(USBFeatureRequest_TESTJ);
while (1);
break;
case USBFeatureRequest_TESTK:
//Test mode Test_K:
//Upon command, a port抯 transceiver must enter the high-speed K state and remain in
//that state until the exit action is taken. This enables the testing of the high output drive
//level on the D- line.
// Send a ZLP
USBD_Test(USBFeatureRequest_TESTSENDZLP);
USBD_Test(USBFeatureRequest_TESTK);
while (1);
break;
case USBFeatureRequest_TESTSE0NAK:
//Test mode Test_SE0_NAK:
//Upon command, a port抯 transceiver must enter the high-speed receive mode
//and remain in that mode until the exit action is taken. This enables the testing
//of output impedance, low level output voltage, and loading characteristics.
//In addition, while in this mode, upstream facing ports (and only upstream facing ports)
//must respond to any IN token packet with a NAK handshake (only if the packet CRC is
//determined to be correct) within the normal allowed device response time. This enables testing of
//the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
//test for basic functional testing.
USBD_Test(USBFeatureRequest_TESTSE0NAK);
// Send a ZLP
USBD_Test(USBFeatureRequest_TESTSENDZLP);
while (1);
break;
default:
USBD_Stall( 0 );
break;
}
// The exit action is to power cycle the device.
// The device must be disconnected from the host
}
#endif
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Initializes a USBDDriver instance with a list of descriptors. If
/// interfaces can have multiple alternate settings, an array to store the
/// current setting for each interface must be provided.
/// \param pDriver Pointer to a USBDDriver instance.
/// \param pDescriptors Pointer to a USBDDriverDescriptors instance.
/// \param pInterfaces Pointer to an array for storing the current alternate
/// setting of each interface (optional).
//------------------------------------------------------------------------------
void USBDDriver_Initialize(
USBDDriver *pDriver,
const USBDDriverDescriptors *pDescriptors,
unsigned char *pInterfaces)
{
pDriver->cfgnum = 0;
#if (BOARD_USB_BMATTRIBUTES == USBConfigurationDescriptor_SELFPOWERED_RWAKEUP) \
|| (BOARD_USB_BMATTRIBUTES == USBConfigurationDescriptor_BUSPOWERED_RWAKEUP)
pDriver->isRemoteWakeUpEnabled = 1;
#else
pDriver->isRemoteWakeUpEnabled = 0;
#endif
pDriver->pDescriptors = pDescriptors;
pDriver->pInterfaces = pInterfaces;
// Initialize interfaces array if not null
if (pInterfaces != 0) {
memset(pInterfaces, sizeof(pInterfaces), 0);
}
}
//------------------------------------------------------------------------------
/// Handles the given request if it is standard, otherwise STALLs it.
/// \param pDriver Pointer to a USBDDriver instance.
/// \param pRequest Pointer to a USBGenericRequest instance.
//------------------------------------------------------------------------------
void USBDDriver_RequestHandler(
USBDDriver *pDriver,
const USBGenericRequest *pRequest)
{
unsigned char cfgnum;
unsigned char infnum;
unsigned char eptnum;
unsigned char setting;
unsigned char type;
unsigned char index;
unsigned int length;
unsigned int address;
trace_LOG(trace_INFO, "Std ");
// Check request code
switch (USBGenericRequest_GetRequest(pRequest)) {
case USBGenericRequest_GETDESCRIPTOR:
trace_LOG(trace_INFO, "Get Descriptor\n");
// Send the requested descriptor
type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
index = USBGetDescriptorRequest_GetDescriptorIndex(pRequest);
length = USBGenericRequest_GetLength(pRequest);
GetDescriptor(pDriver, type, index, length);
break;
case USBGenericRequest_SETADDRESS:
trace_LOG(trace_INFO, "set address\n");
// Sends a zero-length packet and then set the device address
address = USBSetAddressRequest_GetAddress(pRequest);
if( USBD_IsHighSpeed() ) {
USBD_SetAddress( address );
}
else {
USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address);
}
break;
case USBGenericRequest_SETCONFIGURATION:
trace_LOG(trace_INFO, "设置CONFIGURATION\n");
// Set the requested configuration
cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
SetConfiguration(pDriver, cfgnum);
break;
case USBGenericRequest_GETCONFIGURATION:
trace_LOG(trace_INFO, "获取CONFIGURATION\r\n");
// Send the current configuration number
GetConfiguration(pDriver);
break;
case USBGenericRequest_GETSTATUS:
trace_LOG(trace_INFO, "获取STATUS\r\n");
// Check who is the recipient
switch (USBGenericRequest_GetRecipient(pRequest)) {
case USBGenericRequest_DEVICE:
trace_LOG(trace_INFO, " DEVICE\r\n");
// Send the device status
GetDeviceStatus(pDriver);
break;
case USBGenericRequest_ENDPOINT:
trace_LOG(trace_INFO, " ENDPOINT\r\n");
// Send the endpoint status
eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
GetEndpointStatus(eptnum);
break;
default:
trace_LOG(trace_WARNING,
"W: USBDDriver_RequestHandler: Unknown recipient (%d)\n\r",
USBGenericRequest_GetRecipient(pRequest));
USBD_Stall(0);
}
break;
case USBGenericRequest_CLEARFEATURE:
trace_LOG(trace_INFO, "清除FEATURE\r\n");
// Check which is the requested feature
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
case USBFeatureRequest_ENDPOINTHALT:
trace_LOG(trace_INFO, " 端点halt\r\n");
// Unhalt endpoint and send a zero-length packet
USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
USBD_Write(0, 0, 0, 0, 0);
break;
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
trace_LOG(trace_INFO, " 设备remotewakeup");
// Disable remote wake-up and send a zero-length packet
pDriver->isRemoteWakeUpEnabled = 0;
USBD_Write(0, 0, 0, 0, 0);
break;
default:
trace_LOG(trace_WARNING,
"USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
USBFeatureRequest_GetFeatureSelector(pRequest));
USBD_Stall(0);
}
break;
case USBGenericRequest_SETFEATURE:
trace_LOG(trace_INFO, "设置FEATURE\r\n");
// Check which is the selected feature
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
trace_LOG(trace_INFO, " 设备remotewakeup\r\n");
// Enable remote wake-up and send a ZLP
pDriver->isRemoteWakeUpEnabled = 1;
USBD_Write(0, 0, 0, 0, 0);
break;
case USBFeatureRequest_ENDPOINTHALT:
trace_LOG(trace_INFO, " 端点halt\r\n");
// Halt endpoint
USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
USBD_Write(0, 0, 0, 0, 0);
break;
default:
trace_LOG(trace_WARNING,
"USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
USBFeatureRequest_GetFeatureSelector(pRequest));
USBD_Stall(0);
}
break;
case USBGenericRequest_SETINTERFACE:
trace_LOG(trace_INFO, "设置接口\r\n");
infnum = USBInterfaceRequest_GetInterface(pRequest);
setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
SetInterface(pDriver, infnum, setting);
break;
case USBGenericRequest_GETINTERFACE:
trace_LOG(trace_INFO, "获取接口\r\n");
infnum = USBInterfaceRequest_GetInterface(pRequest);
GetInterface(pDriver, infnum);
break;
default:
trace_LOG(trace_WARNING,
"USBDDriver_RequestHandler: Unknown request code (%d)\n\r",
USBGenericRequest_GetRequest(pRequest));
USBD_Stall(0);
}
}
//------------------------------------------------------------------------------
/// Returns 1 if remote wake up has been enabled by the host; otherwise, returns
/// 0.
/// \param pDriver Pointer to an USBDDriver instance.
//------------------------------------------------------------------------------
unsigned char USBDDriver_IsRemoteWakeUpEnabled(const USBDDriver *pDriver)
{
return pDriver->isRemoteWakeUpEnabled;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -