📄 usb_standard_requests.c
字号:
case DESC_TYPE_DEVICE:
usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetDeviceDesc();
usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
break;
// Configuration descriptor
case DESC_TYPE_CONFIG:
usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetConfigurationDesc(0, LOBYTE(usbSetupHeader.value));
usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_CONFIG_LENGTH_LSB_IDX] +
usbSetupData.pBuffer[DESC_CONFIG_LENGTH_MSB_IDX] * 256;
break;
// String descriptor
case DESC_TYPE_STRING:
// TODO: Implement language ID
usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetStringDesc(LOBYTE(usbSetupHeader.value));
usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
break;
// Other descriptor type
default:
// Perform a table search (on index and value)
usbSetupData.pBuffer = NULL;
for (n = 0; n < ((UINT16)pUsbDescLutEnd - (UINT16)pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) {
if ((pUsbDescLut[n].valueMsb == HIBYTE(usbSetupHeader.value)) && (pUsbDescLut[n].valueLsb == LOBYTE(usbSetupHeader.value)) &&
(pUsbDescLut[n].indexMsb == HIBYTE(usbSetupHeader.index)) && (pUsbDescLut[n].indexLsb == LOBYTE(usbSetupHeader.index))) {
usbSetupData.pBuffer = pUsbDescLut[n].pDescStart;
usbSetupData.bytesLeft = pUsbDescLut[n].length;
}
}
}
// Stall EP0 if no descriptor was found
if (usbSetupData.pBuffer == NULL) usbfwData.ep0Status = EP_STALL;
if (usbfwData.ep0Status != EP_STALL) {
// Limit the returned descriptor size (the PC wants to know about sizes before
// polling the complete descriptors)
if (usbSetupData.bytesLeft > usbSetupHeader.length) {
usbSetupData.bytesLeft = usbSetupHeader.length;
}
usbfwData.ep0Status = EP_TX;
}
} // usbsrGetDescriptor
/** \brief Internally used function that configures all endpoints for the specified interface
*
* The new endpoint setup overwrites the old, without any warning. Unused endpoints keep their current
* setup. The user is responsible for ensuring that no endpoint buffers overwrite each other, and that
* interfaces do not cause conflicts. The pUsbDblbufLutInfo table must contain an entry for each
* interface descriptor to define endpoint double-buffering.
*
* \param[in] *pInterface
* A pointer to the interface descriptor
*/
static void ConfigureEndpoints(USB_INTERFACE_DESCRIPTOR __xdata *pInterface) {
UINT8 n;
WORD maxpRegValue;
BYTE csRegValue;
UINT8 endpoint;
USB_ENDPOINT_DESCRIPTOR __xdata *pEndpoint;
DBLBUF_LUT_INFO __code *pUsbDblbufLutInfo;
// Locate the double buffer settings
if (pInterface->bNumEndpoints) {
pUsbDblbufLutInfo = (DBLBUF_LUT_INFO __code*) pUsbDblbufLut;
while (pUsbDblbufLutInfo->pInterface != pInterface) {
pUsbDblbufLutInfo++;
}
}
// For each endpoint in this interface
for (n = 0; n < pInterface->bNumEndpoints; n++) {
if (pEndpoint = usbdpFindNext(DESC_TYPE_ENDPOINT, 0)) {
// Get the endpoint index
endpoint = pEndpoint->bEndpointAddress & 0x0F;
USBFW_SELECT_ENDPOINT(endpoint);
csRegValue = 0x00;
maxpRegValue = (pEndpoint->wMaxPacketSize + 7) >> 3;
// For IN endpoints...
if (pEndpoint->bEndpointAddress & 0x80) {
// Clear data toggle, and flush twice (due to double buffering)
USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET;
USBCSIL = USBCSIL_FLUSH_PACKET;
// USBCSIH
if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSIH_ISO; // ISO flag
if (pUsbDblbufLutInfo->inMask & BM(endpoint)) csRegValue |= USBCSIH_IN_DBL_BUF; // Double buffering
USBCSIH = csRegValue;
// Max transfer size
USBMAXI = maxpRegValue;
// Endpoint status
usbfwData.pEpInStatus[endpoint - 1] = EP_IDLE;
// For OUT endpoints...
} else {
// Clear data toggle, and flush twice (due to double buffering)
USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET;
USBCSOL = USBCSOL_FLUSH_PACKET;
// USBCSOH
if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSOH_ISO; // ISO flag
if (pUsbDblbufLutInfo->outMask & BM(endpoint)) csRegValue |= USBCSOH_OUT_DBL_BUF; // Double buffering
USBCSOH = csRegValue;
// Max transfer size
USBMAXO = maxpRegValue;
// Endpoint status
usbfwData.pEpOutStatus[endpoint - 1] = EP_IDLE;
}
USBFW_SELECT_ENDPOINT(0);
}
}
} // ConfigureEndpoints
/** \brief Processes the \ref GET_CONFIGURATION request (returns the current device configuration value)
*
* If the returned value is 0, the device is not configured (not in the configured state)
*
* <b>Parameters</b>:
* - VALUE: Always 0
* - INDEX: Always 0
* - LENGTH: Always 1
*
* <b>Data (IN)</b>:
* The non-zero \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue of the currently selected
* configuration.
*/
void usbsrGetConfiguration(void) {
// Sanity check
if (usbSetupHeader.value || usbSetupHeader.index || (usbSetupHeader.length != 1)) {
usbfwData.ep0Status = EP_STALL;
// Return the current configuration
} else {
usbSetupData.pBuffer = &usbfwData.configurationValue;
usbSetupData.bytesLeft = 1;
usbfwData.ep0Status = EP_TX;
}
} // usbsrGetConfiguration
/** \brief Processes the \ref SET_CONFIGURATION request (sets the device configuration)
*
* The configuration value must either be 0, in which case the device enters the address state, or it
* must match a configuration value from one of the USB configuration descriptors. If there is a match,
* the device enters the configured state.
*
* This request resets all interfaces to alternate setting 0, and uses the \c ConfigureEndpoints()
* function to automatically setup all endpoint registers.
*
* <b>Parameters</b>:
* - VALUE: The configuration value (0-255)
* - INDEX: Always 0
* - LENGTH: Always 0
*/
void usbsrSetConfiguration(void) {
UINT8 n;
USB_CONFIGURATION_DESCRIPTOR __xdata *pConfiguration;
USB_INTERFACE_DESCRIPTOR __xdata *pInterface;
// Sanity check
if ((usbfwData.usbState == DEV_DEFAULT) || usbSetupHeader.index || usbSetupHeader.length || HIBYTE(usbSetupHeader.value)) {
usbfwData.ep0Status = EP_STALL;
// Default endpoint setup
} else {
usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGING, 0);
// Configure relevant endpoints
if (LOBYTE(usbSetupHeader.value)) {
// Find the correct configuration descriptor...
pConfiguration = usbdpGetConfigurationDesc(LOBYTE(usbSetupHeader.value), 0);
// If it exists...
if (pConfiguration) {
usbfwData.usbState = DEV_CONFIGURED;
usbfwData.configurationValue = LOBYTE(usbSetupHeader.value);
// For each interface...
for (n = 0; n < pConfiguration->bNumInterfaces; n++) {
usbfwData.pAlternateSetting[n] = 0x00;
// Look only for alternate setting 0
do {
pInterface = usbdpFindNext(DESC_TYPE_INTERFACE, 0);
} while (pInterface->bAlternateSetting != usbfwData.pAlternateSetting[n]);
// Configure all endpoints in this interface
ConfigureEndpoints(pInterface);
}
// If not, then stall the endpoint
} else {
usbfwData.ep0Status = EP_STALL;
}
// Unconfigure endpoints
} else {
usbfwData.usbState = DEV_ADDRESS;
usbfwSetAllEpStatus(EP_HALT);
}
usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGED, 0);
}
} // usbsrSetConfiguration
/** \brief Processes the \ref GET_INTERFACE request (returns the selected alternate setting for the
* specified interface)
*
* Some USB devices have configurations with mutually exclusive interface settings. This request allows
* the host to determine the currently selected alternate setting.
*
* <b>Parameters</b>:
* - VALUE: Always 0
* - INDEX: Interface number
* - LENGTH: Always 1
*
* <b>Data (IN)</b>:
* The alternate setting for the selected interface
*/
void usbsrGetInterface(void) {
// Sanity check
if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_IN_INTERFACE) || usbSetupHeader.value || (usbSetupHeader.length != 1)) {
usbfwData.ep0Status = EP_STALL;
// Return the current alternate setting
} else {
usbSetupData.pBuffer = &usbfwData.pAlternateSetting[usbSetupHeader.index];
usbSetupData.bytesLeft = 1;
usbfwData.ep0Status = EP_TX;
}
} // usbsrGetInterface
/** \brief Processes the \ref SET_INTERFACE request (selects an alternate setting for the specified
* interface)
*
* Some USB devices have configurations with mutually exclusive interface settings. This request allows
* the host to select the desired alternate setting.
*
* This function uses the \c ConfigureEndpoints() to automatically setup the relevant endpoint
* registers.
*
* <b>Parameters</b>:
* - VALUE: Alternate setting
* - INDEX: Interface number
* - LENGTH: Always 0
*/
void usbsrSetInterface(void) {
USB_INTERFACE_DESCRIPTOR __xdata *pInterface;
// Sanity check
if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_OUT_INTERFACE) || usbSetupHeader.length) {
usbfwData.ep0Status = EP_STALL;
// Verify that the desired alternate setting is available, and then make the switch
} else {
if (pInterface = usbdpGetInterfaceDesc(usbfwData.configurationValue, usbSetupHeader.index, usbSetupHeader.value)) {
usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGING, usbSetupHeader.index);
usbfwData.pAlternateSetting[usbSetupHeader.index] = usbSetupHeader.value;
// Configure all endpoints in this interface
ConfigureEndpoints(pInterface);
usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGED, usbSetupHeader.index);
// This interface does not exist
} else {
usbfwData.ep0Status = EP_STALL;
}
}
} // usbsrSetInterface
//@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -