static void handle_osmosdr_write(const USBGenericRequest* request) { uint16_t func = USBGenericRequest_GetValue(request); int len = USBGenericRequest_GetLength(request); int i; /* printf("OsmoSDR SET request: type:%d, request:%d, value:%04x, index: %04x, length: %d\n\r", USBGenericRequest_GetType(request), USBGenericRequest_GetRequest(request), USBGenericRequest_GetValue(request), USBGenericRequest_GetIndex(request), len); */ for(i = 0; i < ARRAY_SIZE(g_writeRequests); i++) { if(g_writeRequests[i].func == func) break; } if(i == ARRAY_SIZE(g_writeRequests)) { USBD_Stall(0); return; } if(len != g_writeRequests[i].len) { USBD_Stall(0); return; } g_writeState.func = func; if(len > 0) USBD_Read(0, g_writeState.data, len, finalize_write, 0); else finalize_write(NULL, 0, 0, 0); }
//----------------------------------------------------------------------------- /// Handles composite-specific USB requests sent by the host, and forwards /// standard ones to the USB device driver. /// \param request Pointer to a USBGenericRequest instance. //----------------------------------------------------------------------------- void MULTIDriver_RequestHandler(const USBGenericRequest *request) { // Check if this is a class request if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { unsigned char rc = 0; //rc = CCID_RequestHandler(request); if (!rc) { TRACE_WARNING( "MULTIDriver_RequestHandler: Unsupported request (%d)\n\r", USBGenericRequest_GetRequest(request)); USBD_Stall(0); } } // Check if this is a standard request else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { unsigned char rc = 0; // Forward request to the standard handler if (rc == 0) USBDDriver_RequestHandler(&(usbdDriver), request); } // Unsupported request type else { TRACE_WARNING( "MULTIDriver_RequestHandler: Unsupported request type (%d)\n\r", USBGenericRequest_GetType(request)); USBD_Stall(0); } }
void fastsource_req_hdlr(const USBGenericRequest *request) { unsigned char entity; unsigned char interface; switch (USBGenericRequest_GetType(request)) { case USBGenericRequest_STANDARD: USBDDriver_RequestHandler(&fast_source_driver, request); return; case USBGenericRequest_CLASS: /* continue below */ break; default: TRACE_WARNING("Unsupported request type %u\n\r", USBGenericRequest_GetType(request)); USBD_Stall(0); return; } switch (USBGenericRequest_GetRequest(request)) { case AUDGenericRequest_SETCUR: entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) || (entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) && (interface == AUDDLoopRecDriverDescriptors_CONTROL)) { fastsource_set_feat_cur_val(entity, AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; case AUDGenericRequest_GETCUR: entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) || (entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) && (interface == AUDDLoopRecDriverDescriptors_CONTROL)) { fastsource_get_feat_cur_val(entity, AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; default: TRACE_WARNING("Unsupported request %u\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); break; } }
//------------------------------------------------------------------------------ /// Sets the current value of a particular Feature control of a channel. /// \param entity Entity number. /// \param channel Channel number. /// \param control Control selector value (see TODO). /// \param length Length of the data containing the new value. //------------------------------------------------------------------------------ static void AUDDSpeakerDriver_SetFeatureCurrentValue(unsigned char entity, unsigned char channel, unsigned char control, unsigned short length) { TRACE_INFO_WP("sFeature "); TRACE_DEBUG("\b(E%d, CS%d, CN%d, L%d) ", entity, control, channel, length); // Check the the requested control is supported // Control/channel combination not supported if ((control == AUDFeatureUnitRequest_MUTE) && (channel < (AUDDSpeakerDriver_NUMCHANNELS+1)) && (length == 1)) { unsigned int argument = channel; // Avoids compiler warning USBD_Read(0, // Endpoint #0 &muted, sizeof(muted), (TransferCallback) AUDDSpeakerDriver_MuteReceived, (void *) argument); } // Control/channel combination not supported else { USBD_Stall(0); } }
/** * Handles audio-specific USB requests sent by the host, and forwards * standard ones to the USB device driver. * \param request Pointer to a USBGenericRequest instance. */ void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request) { AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; AUDDSpeakerPhone *pAudf = &pAudd->fun; USBDDriver *pUsbd = pAudf->pUsbd; TRACE_INFO_WP("NewReq "); /* Handle Audio Class requests */ if (AUDDSpeakerPhone_RequestHandler(pAudf, request) == USBRC_SUCCESS) { return; } /* Handle STD requests */ if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { USBDDriver_RequestHandler(pUsbd, request); } /* Unsupported request */ else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d,%x)\n\r", USBGenericRequest_GetType(request), USBGenericRequest_GetRequest(request)); USBD_Stall(0); } }
/** * Handles composite-specific USB requests sent by the host, and forwards * standard ones to the USB device driver. * \param request Pointer to a USBGenericRequest instance. */ void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request) { CDCDSerialPort *pCdcd = 0; USBDDriver *pUsbd = 0; uint32_t rc, i; TRACE_INFO_WP("NewReq "); for (i = 0; i < NUM_PORTS; i ++) { pCdcd = &dualcdcdDriver.cdcdSerialPort[i]; rc = CDCDSerialPort_RequestHandler(pCdcd, request); if (rc == USBRC_SUCCESS) break; } /* Not handled by CDC Serial */ if (rc != USBRC_SUCCESS) { if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { pUsbd = pCdcd->pUsbd; USBDDriver_RequestHandler(pUsbd, request); } else { TRACE_WARNING( "DUALCDCDDriver_RequestHandler: Unsupported request (%d,%d)\n\r", USBGenericRequest_GetType(request), USBGenericRequest_GetRequest(request)); USBD_Stall(0); } } }
/** * Sets the active setting of the given interface if the configuration supports * it; otherwise, the control pipe is STALLed. If the setting of an interface * changes. * \parma pDriver Pointer to a USBDDriver instance. * \parma infnum Interface number. * \parma setting New active setting for the interface. */ static void SetInterface( USBDDriver *pDriver, uint8_t infnum, uint8_t setting) { /* Make sure alternate settings are supported */ if (!pDriver->pInterfaces) { USBD_Stall(0); } else { /* Change the current setting of the interface and trigger the callback */ /* if necessary */ if (pDriver->pInterfaces[infnum] != setting) { pDriver->pInterfaces[infnum] = setting; USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting); } /* Acknowledge the request */ USBD_Write(0, 0, 0, 0, 0); } }
static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel, uint8_t control, uint8_t length) { TRACE_INFO("set_feat(E%u, CO%u, CH%u, L%u) ", entity, channel, control, length); if (channel == 0 && control == AUDFeatureUnitDescriptor_MUTE && length == 1) USBD_Read(0, &usb_state.muted, sizeof(usb_state.muted), 0, 0); else USBD_Stall(0); }
static void handle_osmosdr_read(const USBGenericRequest* request) { int len = USBGenericRequest_GetLength(request); printf("OsmoSDR GET request: type:%d, request:%d, value:%d, index: %d, length: %d\n\r", USBGenericRequest_GetType(request), USBGenericRequest_GetRequest(request), USBGenericRequest_GetValue(request), USBGenericRequest_GetIndex(request), len); USBD_Stall(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); } }
/** * Handle the SET_CUR request. * \param pAudf Pointer to AUDDSpeakerPhone instance. * \param pReq Pointer to USBGenericRequest instance. */ static void AUDD_SetCUR( AUDDSpeakerPhone *pAudf, const USBGenericRequest* pReq) { uint8_t bIf = AUDGenericRequest_GetInterface(pReq); uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); uint8_t bLength = USBGenericRequest_GetLength(pReq); uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); uint8_t bSet = 1; AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh); TransferCallback fCallback; TRACE_INFO_WP("sCUR "); TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); /* Set Mute to AC, 1 byte */ if (bCtrl == AUDFeatureUnitRequest_MUTE && bLength == 1 && pAuds) { fCallback = (TransferCallback) AUDD_MuteReceived; } else if (bCtrl == AUDFeatureUnitRequest_VOLUME && bLength == 2 && pAuds && pAuds->pwVolumes) { fCallback = (TransferCallback) AUDD_VolumeReceived; } else bSet = 0; if (bSet) { auddXfrData.pStream = pAuds; auddXfrData.bEntity = bEntity; auddXfrData.bCh = bCh; USBD_Read(0, &auddXfrData.usbBuffer, bLength, fCallback, (void *) &auddXfrData); } else { USBD_Stall(0); } }
/** * Callback function which should be invoked after the data of a * SetLineCoding request has been retrieved. Sends a zero-length packet * to the host for acknowledging the request. * \param pCdcd Pointer to CDCDSerialPort instance. */ static void _SetLineCodingCallback(CDCDSerialPort * pCdcd) { uint32_t exec = 1; if (pCdcd->fEventHandler) { uint32_t rc = pCdcd->fEventHandler( CDCDSerialPortEvent_SETLINECODING, (uint32_t)(&lineCoding), pCdcd->pArg); if (rc == USBD_STATUS_SUCCESS) { pCdcd->lineCoding.dwDTERate = lineCoding.dwDTERate; pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat; pCdcd->lineCoding.bParityType = lineCoding.bParityType; pCdcd->lineCoding.bDataBits = lineCoding.bDataBits; } else exec = 0; } if (exec) USBD_Write(0, 0, 0, 0, 0); else USBD_Stall(0); }
/** * Sends the current status of an endpoints to the USB host. * \param bEndpoint Endpoint number. */ static void GetEndpointStatus(uint8_t bEndpoint) { static unsigned short data; data = 0; switch (USBD_HAL_Halt(bEndpoint, 0xFF)) { case USBD_STATUS_INVALID_PARAMETER: /* the endpoint not exists */ USBD_Stall(0); break; case 1: data = 1; case 0: /* Send the endpoint status */ USBD_Write(0, &data, 2, 0, 0); break; } }
//------------------------------------------------------------------------------ /// Sends the current status of an endpoints to the USB host. /// \param bEndpoint Endpoint number. //------------------------------------------------------------------------------ static void GetEndpointStatus(unsigned char bEndpoint) { unsigned short data = 0; // Check if the endpoint exists if (bEndpoint > BOARD_USB_NUMENDPOINTS) { USBD_Stall(0); } else { // Check if the endpoint if currently halted if (USBD_IsHalted(bEndpoint)) { data = 1; } // Send the endpoint status USBD_Write(0, &data, 2, 0, 0); } }
//----------------------------------------------------------------------------- /// Sends the current value of a particular channel Feature to the USB host. /// \param channel Number of the channel whose feature will be sent. /// \param control The feature control that will be sent. /// \param length The feature data size. //----------------------------------------------------------------------------- static void AUDD_GetFeatureCurrentValue(unsigned char channel, unsigned char control, unsigned char length) { TRACE_INFO_WP("gFeature "); TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length); // Check that the requested control is supported // Master channel mute control if ((control == AUDFeatureUnitRequest_MUTE) && (channel < (AUDD_NUMCHANNELS+1)) && (length == 1)) { muted = auddSpeakerChannels[channel].muted; USBD_Write(0, &muted, sizeof(muted), 0, 0); } else { USBD_Stall(0); } }
/** * Handle the GET_CUR request. * \param pAudf Pointer to AUDDSpeakerPhone instance. * \param pReq Pointer to USBGenericRequest instance. */ static void AUDD_GetCUR( AUDDSpeakerPhone *pAudf, const USBGenericRequest *pReq) { uint8_t bIf = AUDGenericRequest_GetInterface(pReq); uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); uint8_t bLength = USBGenericRequest_GetLength(pReq); uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); uint8_t bGet = 1; AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh); TRACE_INFO_WP("gCUR "); TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); /* Get Mute 1 byte */ if (bCtrl == AUDFeatureUnitRequest_MUTE && bLength == 1 && pAuds) { auddXfrData.usbBuffer = ((pAuds->bmMute & (1<<bCh)) > 0); } else if (bCtrl == AUDFeatureUnitRequest_VOLUME && bLength == 2 && pAuds && pAuds->pwVolumes) { auddXfrData.usbBuffer = pAuds->pwVolumes[bCh]; } else bGet = 0; if (bGet) { USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0); } else { USBD_Stall(0); } }
//------------------------------------------------------------------------------ /// Sets the active setting of the given interface if the configuration supports /// it; otherwise, the control pipe is STALLed. If the setting of an interface /// changes. /// \parma pDriver Pointer to a USBDDriver instance. /// \parma infnum Interface number. /// \parma setting New active setting for the interface. //------------------------------------------------------------------------------ static void SetInterface( USBDDriver *pDriver, unsigned char infnum, unsigned char setting) { // Make sure alternate settings are supported if (!pDriver->pInterfaces) { USBD_Stall(0); } else { // Change the current setting of the interface and trigger the callback // if necessary if (pDriver->pInterfaces[infnum] != setting) { pDriver->pInterfaces[infnum] = setting; USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting); } // Acknowledge the request USBD_Write(0, 0, 0, 0, 0); } }
//------------------------------------------------------------------------------ /// Handles audio-specific USB requests sent by the host, and forwards /// standard ones to the USB device driver. /// \param request Pointer to a USBGenericRequest instance. //------------------------------------------------------------------------------ void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request) { unsigned char entity; unsigned char interface; TRACE_INFO_WP("NewReq "); // Check if this is a class request if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { // Check if the request is supported switch (USBGenericRequest_GetRequest(request)) { case AUDGenericRequest_SETCUR: TRACE_INFO_WP( "sCur(0x%04X) ", USBGenericRequest_GetIndex(request)); // Check the target interface and entity entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT) && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) { AUDDSpeakerDriver_SetFeatureCurrentValue( entity, AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; case AUDGenericRequest_GETCUR: TRACE_INFO_WP( "gCur(0x%04X) ", USBGenericRequest_GetIndex(request)); // Check the target interface and entity entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT) && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) { AUDDSpeakerDriver_GetFeatureCurrentValue( entity, AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; default: TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d)\n\r", USBGenericRequest_GetRequest(request)); USBD_Stall(0); } } // Check if this is a standard request else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { // Forward request to the standard handler USBDDriver_RequestHandler(&(auddSpeakerDriver.usbdDriver), request); } // Unsupported request type else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported request type (%d)\n\r", USBGenericRequest_GetType(request)); USBD_Stall(0); } }
//------------------------------------------------------------------------------ /// Sends the requested USB descriptor to the host if available, or STALLs the /// request. /// \param pDriver Pointer to a USBDDriver instance. /// \param type Type of the requested descriptor /// \param index Index of the requested descriptor. /// \param length Maximum number of bytes to return. //------------------------------------------------------------------------------ static void GetDescriptor( const USBDDriver *pDriver, unsigned char type, unsigned char index, unsigned int length) { const USBDeviceDescriptor *pDevice; const USBConfigurationDescriptor *pConfiguration; const USBGenericDescriptor **pStrings = (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings; unsigned char numStrings = pDriver->pDescriptors->numStrings; const USBGenericDescriptor *pString; pDevice = pDriver->pDescriptors->pFsDevice; pConfiguration = pDriver->pDescriptors->pFsConfiguration; // Check the descriptor type switch (type) { case USBGenericDescriptor_DEVICE: TRACE_INFO_WP("Dev "); // Adjust length and send descriptor if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) { length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice); } USBD_Write(0, pDevice, length, 0, 0); break; case USBGenericDescriptor_CONFIGURATION: TRACE_INFO_WP("Cfg "); // Adjust length and send descriptor if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) { length = USBConfigurationDescriptor_GetTotalLength(pConfiguration); } USBD_Write(0, pConfiguration, length, 0, 0); break; case USBGenericDescriptor_STRING: TRACE_INFO_WP("Str%d ", index); // Check if descriptor exists if (index > numStrings) { USBD_Stall(0); } else { pString = pStrings[index]; // Adjust length and send descriptor if (length > USBGenericDescriptor_GetLength(pString)) { length = USBGenericDescriptor_GetLength(pString); } USBD_Write(0, pString, length, 0, 0); } break; default: TRACE_WARNING( "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r", type); USBD_Stall(0); } }
static void finalize_write(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining) { int res; if((status != 0) ||(remaining != 0)) { USBD_Stall(0); return; } printf("Func: %04x ...", g_writeState.func); switch(g_writeState.func) { // general api case FUNC(GROUP_GENERAL, 0x00): // init all printf("general_init()"); res = 0; // no op so far break; case FUNC(GROUP_GENERAL, 0x01): // power down printf("general_power_down()"); osdr_fpga_power(0); sam3u_e4k_stby(&e4k, 1); sam3u_e4k_power(&e4k, 0); res = 0; break; case FUNC(GROUP_GENERAL, 0x02): // power up printf("general_power_up()"); osdr_fpga_power(1); sam3u_e4k_power(&e4k, 1); sam3u_e4k_stby(&e4k, 0); res = 0; break; // fpga commands case FUNC(GROUP_FPGA_V2, 0x00): // fpga init printf("fpga_v2_init()"); res = 0; // no op so far break; case FUNC(GROUP_FPGA_V2, 0x01): printf("fpga_v2_reg_write()"); osdr_fpga_reg_write(g_writeState.data[0], read_bytewise32(g_writeState.data + 1)); res = 0; break; case FUNC(GROUP_FPGA_V2, 0x02): printf("osdr_fpga_set_decimation()"); osdr_fpga_set_decimation(g_writeState.data[0]); res = 0; break; case FUNC(GROUP_FPGA_V2, 0x03): printf("osdr_fpga_set_iq_swap()"); osdr_fpga_set_iq_swap(g_writeState.data[0]); res = 0; break; case FUNC(GROUP_FPGA_V2, 0x04): printf("osdr_fpga_set_iq_gain()"); osdr_fpga_set_iq_gain(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2)); res = 0; break; case FUNC(GROUP_FPGA_V2, 0x05): printf("osdr_fpga_set_iq_ofs()"); osdr_fpga_set_iq_ofs(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2)); res = 0; break; // si570 vcxo commands case FUNC(GROUP_VCXO_SI570, 0x00): // si570_init() printf("si570_init()"); res = si570_reinit(&si570); break; case FUNC(GROUP_VCXO_SI570, 0x01): printf("si570_reg_write()"); res = si570_reg_write(&si570, g_writeState.data[0], g_writeState.data[1], g_writeState.data + 2); break; case FUNC(GROUP_VCXO_SI570, 0x02): printf("si570_set_freq()"); res = si570_set_freq(&si570, read_bytewise32(g_writeState.data), read_bytewise32(g_writeState.data + 4)); break; // e4000 tuner commands case FUNC(GROUP_TUNER_E4K, 0x00): printf("e4k_init()"); res = e4k_init(&e4k); break; case FUNC(GROUP_TUNER_E4K, 0x01): // reg write printf("e4k_reg_write()"); res = -1; break; case FUNC(GROUP_TUNER_E4K, 0x02): printf("e4k_if_gain_set()"); res = e4k_if_gain_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1)); break; case FUNC(GROUP_TUNER_E4K, 0x03): printf("e4k_mixer_gain_set()"); res = e4k_mixer_gain_set(&e4k, g_writeState.data[0]); break; case FUNC(GROUP_TUNER_E4K, 0x04): printf("e4K_commonmode_set()"); res = e4k_commonmode_set(&e4k, g_writeState.data[0]); break; case FUNC(GROUP_TUNER_E4K, 0x05): printf("e4k_tune_freq()"); res = e4k_tune_freq(&e4k, read_bytewise32(g_writeState.data)); break; case FUNC(GROUP_TUNER_E4K, 0x06): printf("e4k_if_filter_bw_set()"); res = e4k_if_filter_bw_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1)); break; case FUNC(GROUP_TUNER_E4K, 0x07): printf("e4k_if_filter_chan_enable()"); res = e4k_if_filter_chan_enable(&e4k, g_writeState.data[0]); break; case FUNC(GROUP_TUNER_E4K, 0x08): printf("e4k_manual_dc_offset()"); res = e4k_manual_dc_offset(&e4k, g_writeState.data[0], g_writeState.data[1], g_writeState.data[2], g_writeState.data[3]); break; case FUNC(GROUP_TUNER_E4K, 0x09): printf("e4k_dc_offset_calibrate()"); res = e4k_dc_offset_calibrate(&e4k); break; case FUNC(GROUP_TUNER_E4K, 0x0a): printf("e4k_dc_offset_gen_table()"); res = e4k_dc_offset_gen_table(&e4k); break; case FUNC(GROUP_TUNER_E4K, 0x0b): printf("e4k_set_lna_gain()"); res = e4k_set_lna_gain(&e4k, read_bytewise32(g_writeState.data)); if(res == -EINVAL) res = -1; else res = 0; break; case FUNC(GROUP_TUNER_E4K, 0x0c): printf("e4k_enable_manual_gain()"); res = e4k_enable_manual_gain(&e4k, g_writeState.data[0]); break; case FUNC(GROUP_TUNER_E4K, 0x0d): printf("e4k_set_enh_gain()"); res = e4k_set_enh_gain(&e4k, read_bytewise32(g_writeState.data)); break; default: res = -1; break; } printf(" res: %d\n\r", res); if(res == 0) USBD_Write(0, 0, 0, 0, 0); else USBD_Stall(0); }
/** * Handler for incoming SETUP requests on default Control endpoint 0. * * Standard requests are forwarded to the USBDDriver_RequestHandler * method. * \param pMsdDriver Pointer to MSDDriver instance. * \param request Pointer to a USBGenericRequest instance */ uint32_t MSDFunction_RequestHandler( const USBGenericRequest *request) { MSDDriver *pMsdDriver = &msdFunction; uint32_t reqCode = (USBGenericRequest_GetType(request) << 8) | (USBGenericRequest_GetRequest(request)); TRACE_INFO_WP("Msdf "); /* Handle requests */ switch (reqCode) { /*--------------------- */ case USBGenericRequest_CLEARFEATURE: /*--------------------- */ TRACE_INFO_WP("ClrFeat "); switch (USBFeatureRequest_GetFeatureSelector(request)) { /*--------------------- */ case USBFeatureRequest_ENDPOINTHALT: /*--------------------- */ TRACE_INFO_WP("Hlt "); /* Do not clear the endpoint halt status if the device is waiting */ /* for a reset recovery sequence */ if (!pMsdDriver->waitResetRecovery) { /* Forward the request to the standard handler */ USBDDriver_RequestHandler(USBD_GetDriver(), request); } else { TRACE_INFO_WP("No "); } USBD_Write(0, 0, 0, 0, 0); return USBRC_SUCCESS; /* Handled */ } break; /*------------------- */ case (USBGenericRequest_CLASS<<8)|MSD_GET_MAX_LUN: /*------------------- */ TRACE_INFO_WP("gMaxLun "); /* Check request parameters */ if ((request->wValue == 0) && (request->wIndex == pMsdDriver->interfaceNb) && (request->wLength == 1)) { USBD_Write(0, &(pMsdDriver->maxLun), 1, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } return USBRC_SUCCESS; /* Handled */ /*----------------------- */ case (USBGenericRequest_CLASS<<8)|MSD_BULK_ONLY_RESET: /*----------------------- */ TRACE_INFO_WP("Rst "); /* Check parameters */ if ((request->wValue == 0) && (request->wIndex == pMsdDriver->interfaceNb) && (request->wLength == 0)) { /* Reset the MSD driver */ MSDFunction_Reset(); USBD_Write(0, 0, 0, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } return USBRC_SUCCESS; /* Handled */ } return USBRC_PARAM_ERR; }
//----------------------------------------------------------------------------- /// Handles AUDIO-specific USB requests sent by the host /// \param request Pointer to a USBGenericRequest instance. /// \return 0 if the request is Unsupported, 1 if the request handled. //----------------------------------------------------------------------------- unsigned char AUDDFunctionDriver_RequestHandler( const USBGenericRequest *request) { unsigned char entity; unsigned char interface; // Check if the request is supported switch (USBGenericRequest_GetRequest(request)) { case AUDGenericRequest_SETCUR: TRACE_INFO_WP( "sCur(0x%04X) ", USBGenericRequest_GetIndex(request)); // Check the target interface and entity entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if ((entity == AUDD_Descriptors_FEATUREUNIT) && (interface == AUDD_Descriptors_CONTROL)) { AUDD_SetFeatureCurrentValue( AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; case AUDGenericRequest_GETCUR: TRACE_INFO_WP( "gCur(0x%04X) ", USBGenericRequest_GetIndex(request)); // Check the target interface and entity entity = AUDGenericRequest_GetEntity(request); interface = AUDGenericRequest_GetInterface(request); if ((entity == AUDD_Descriptors_FEATUREUNIT) && (interface == AUDD_Descriptors_CONTROL)) { AUDD_GetFeatureCurrentValue( AUDFeatureUnitRequest_GetChannel(request), AUDFeatureUnitRequest_GetControl(request), USBGenericRequest_GetLength(request)); } else { TRACE_WARNING( "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", USBGenericRequest_GetIndex(request)); USBD_Stall(0); } break; default: return 0; } return 1; }
//------------------------------------------------------------------------------ /// 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 indexDesc; unsigned int length; unsigned int address; TRACE_INFO_WP("Std "); // Check request code switch (USBGenericRequest_GetRequest(pRequest)) { case USBGenericRequest_GETDESCRIPTOR: TRACE_INFO_WP("gDesc "); // Send the requested descriptor type = USBGetDescriptorRequest_GetDescriptorType(pRequest); indexDesc = USBGetDescriptorRequest_GetDescriptorIndex(pRequest); length = USBGenericRequest_GetLength(pRequest); GetDescriptor(pDriver, type, indexDesc, length); break; case USBGenericRequest_SETADDRESS: TRACE_INFO_WP("sAddr "); // Sends a zero-length packet and then set the device address address = USBSetAddressRequest_GetAddress(pRequest); USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address); break; case USBGenericRequest_SETCONFIGURATION: TRACE_INFO_WP("sCfg "); // Set the requested configuration cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest); SetConfiguration(pDriver, cfgnum); break; case USBGenericRequest_GETCONFIGURATION: TRACE_INFO_WP("gCfg "); // Send the current configuration number GetConfiguration(pDriver); break; case USBGenericRequest_GETSTATUS: TRACE_INFO_WP("gSta "); // Check who is the recipient switch (USBGenericRequest_GetRecipient(pRequest)) { case USBGenericRequest_DEVICE: TRACE_INFO_WP("Dev "); // Send the device status GetDeviceStatus(pDriver); break; case USBGenericRequest_ENDPOINT: TRACE_INFO_WP("Ept "); // Send the endpoint status eptnum = USBGenericRequest_GetEndpointNumber(pRequest); GetEndpointStatus(eptnum); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown recipient (%d)\n\r", USBGenericRequest_GetRecipient(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_CLEARFEATURE: TRACE_INFO_WP("cFeat "); // Check which is the requested feature switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { case USBFeatureRequest_ENDPOINTHALT: TRACE_INFO_WP("Hlt "); // 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_INFO_WP("RmWU "); // Disable remote wake-up and send a zero-length packet pDriver->isRemoteWakeUpEnabled = 0; USBD_Write(0, 0, 0, 0, 0); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_SETFEATURE: TRACE_INFO_WP("sFeat "); // Check which is the selected feature switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { case USBFeatureRequest_DEVICEREMOTEWAKEUP: TRACE_INFO_WP("RmWU "); // Enable remote wake-up and send a ZLP pDriver->isRemoteWakeUpEnabled = 1; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_ENDPOINTHALT: TRACE_INFO_WP("Halt "); // Halt endpoint USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); USBD_Write(0, 0, 0, 0, 0); break; #if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) case USBFeatureRequest_TESTMODE: // 7.1.20 Test Mode Support if ((USBGenericRequest_GetType(pRequest) == USBGenericRequest_DEVICE) && ((USBGenericRequest_GetIndex(pRequest) & 0x000F) == 0)) { // Handle test request USBDDriver_Test(USBFeatureRequest_GetTestSelector(pRequest)); } else { USBD_Stall(0); } break; #endif #if defined(CHIP_USB_OTGHS) case USBFeatureRequest_OTG_B_HNP_ENABLE: TRACE_INFO_WP("OTG_B_HNP_ENABLE "); otg_features_supported |= 1<<USBFeatureRequest_OTG_B_HNP_ENABLE; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_OTG_A_HNP_SUPPORT: TRACE_INFO_WP("OTG_A_HNP_SUPPORT "); otg_features_supported |= 1<<USBFeatureRequest_OTG_A_HNP_SUPPORT; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT: TRACE_INFO_WP("OTG_A_ALT_HNP_SUPPORT "); otg_features_supported |= 1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT; USBD_Write(0, 0, 0, 0, 0); break; #endif default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_SETINTERFACE: TRACE_INFO_WP("sInterface "); infnum = USBInterfaceRequest_GetInterface(pRequest); setting = USBInterfaceRequest_GetAlternateSetting(pRequest); SetInterface(pDriver, infnum, setting); break; case USBGenericRequest_GETINTERFACE: TRACE_INFO_WP("gInterface "); infnum = USBInterfaceRequest_GetInterface(pRequest); GetInterface(pDriver, infnum); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown request code (%d)\n\r", USBGenericRequest_GetRequest(pRequest)); USBD_Stall(0); } }
//------------------------------------------------------------------------------ // Performs the selected test on the USB device (high-speed only). // \param test Test selector value. //------------------------------------------------------------------------------ static void USBDDriver_Test(unsigned char test) { 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. “S” indicates that a bit stuff occurs, which inserts an “extra” 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; not reached case USBFeatureRequest_TESTJ: //Test mode Test_J: //Upon command, a port’s 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; not reached case USBFeatureRequest_TESTK: //Test mode Test_K: //Upon command, a port’s 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; not reached case USBFeatureRequest_TESTSE0NAK: //Test mode Test_SE0_NAK: //Upon command, a port’s 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. // Send a ZLP USBD_Test(USBFeatureRequest_TESTSENDZLP); // Test SE0_NAK USBD_Test(USBFeatureRequest_TESTSE0NAK); while (1); //break; not reached default: USBD_Stall(0); break; } // The exit action is to power cycle the device. // The device must be disconnected from the host }
static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel, uint8_t control, uint8_t length) { /* FIXME */ USBD_Stall(0); }
/** * Handles HID-specific SETUP request sent by the host. * \param request Pointer to a USBGenericRequest instance */ void HIDDTransferDriver_RequestHandler(const USBGenericRequest *request) { HIDDTransferDriver *pDrv = &hiddTransferDriver; HIDDFunction *pHidd = &pDrv->hidFunction; TRACE_INFO("NewReq "); /* Check if this is a standard request */ if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { /* This is a standard request */ switch (USBGenericRequest_GetRequest(request)) { case USBGenericRequest_GETDESCRIPTOR: /* Check if this is a HID descriptor, otherwise forward it to the standard driver */ if (!HIDDTransferDriver_GetDescriptor( USBGetDescriptorRequest_GetDescriptorType(request), USBGenericRequest_GetLength(request))) { USBDDriver_RequestHandler(pHidd->pUsbd, request); } return; /* Handled, no need to do others */ case USBGenericRequest_CLEARFEATURE: /* Check which is the requested feature */ switch (USBFeatureRequest_GetFeatureSelector(request)) { case USBFeatureRequest_ENDPOINTHALT: { uint8_t ep = USBGenericRequest_GetEndpointNumber(request); if (USBD_IsHalted(ep)) { /* Unhalt endpoint restart OUT EP */ USBD_Unhalt(ep); if (ep == pHidd->bPipeOUT) { HIDDFunction_StartPollingOutputs(pHidd); } } /* and send a zero-length packet */ USBD_Write(0, 0, 0, 0, 0); return; /* Handled, no need to do others */ } } break; } } /* We use different buffer for SetReport */ else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { switch (USBGenericRequest_GetRequest(request)) { case HIDGenericRequest_SETREPORT: { uint16_t length = USBGenericRequest_GetLength(request); uint8_t type = HIDReportRequest_GetReportType(request); if (type == HIDReportRequest_OUTPUT) { if (length > HIDDTransferDriver_REPORTSIZE) length = HIDDTransferDriver_REPORTSIZE; USBD_Read(0, pDrv->iReportBuf, length, HIDDTransferDriver_ReportReceived, 0); /* No argument to the callback function */ } else { USBD_Stall(0); } } return; /* Handled, no need do others */ } } /* Process HID requests */ if (USBRC_SUCCESS == HIDDFunction_RequestHandler(pHidd, request)) { return; } else USBDDriver_RequestHandler(pHidd->pUsbd, request); }
//----------------------------------------------------------------------------- /// Handler for incoming SETUP requests on default Control endpoint 0. /// /// Standard requests are forwarded to the USBDDriver_RequestHandler /// method. /// \param request Pointer to a USBGenericRequest instance //----------------------------------------------------------------------------- void MSDDriver_RequestHandler(const USBGenericRequest *request) { TRACE_INFO_WP("NewReq "); // Handle requests switch (USBGenericRequest_GetRequest(request)) { //--------------------- case USBGenericRequest_CLEARFEATURE: //--------------------- TRACE_INFO_WP("ClrFeat "); switch (USBFeatureRequest_GetFeatureSelector(request)) { //--------------------- case USBFeatureRequest_ENDPOINTHALT: //--------------------- TRACE_INFO_WP("Hlt "); // Do not clear the endpoint halt status if the device is waiting // for a reset recovery sequence if (!msdDriver.waitResetRecovery) { // Forward the request to the standard handler USBDDriver_RequestHandler(&usbdDriver, request); } else { TRACE_INFO_WP("No "); } USBD_Write(0, 0, 0, 0, 0); break; //------ default: //------ // Forward the request to the standard handler USBDDriver_RequestHandler(&usbdDriver, request); } break; //------------------- case MSD_GET_MAX_LUN: //------------------- TRACE_INFO_WP("gMaxLun "); // Check request parameters if ((request->wValue == 0) && (request->wIndex == 0) && (request->wLength == 1)) { USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } break; //----------------------- case MSD_BULK_ONLY_RESET: //----------------------- TRACE_INFO_WP("Rst "); // Check parameters if ((request->wValue == 0) && (request->wIndex == 0) && (request->wLength == 0)) { // Reset the MSD driver MSDDriver_Reset(); USBD_Write(0, 0, 0, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } break; //------ default: //------ // Forward request to standard handler USBDDriver_RequestHandler(&usbdDriver, request); break; } }
/** * 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) { uint8_t cfgnum; uint8_t infnum; uint8_t eptnum; uint8_t setting; uint8_t type; uint8_t indexDesc; uint32_t length; uint32_t address; TRACE_INFO_WP("Std "); /* Check request code */ switch (USBGenericRequest_GetRequest(pRequest)) { case USBGenericRequest_GETDESCRIPTOR: TRACE_INFO_WP("gDesc "); /* Send the requested descriptor */ type = USBGetDescriptorRequest_GetDescriptorType(pRequest); indexDesc = USBGetDescriptorRequest_GetDescriptorIndex(pRequest); length = USBGenericRequest_GetLength(pRequest); GetDescriptor(pDriver, type, indexDesc, length); break; case USBGenericRequest_SETADDRESS: TRACE_INFO_WP("sAddr "); /* Sends a zero-length packet and then set the device address */ address = USBSetAddressRequest_GetAddress(pRequest); USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address); break; case USBGenericRequest_SETCONFIGURATION: TRACE_INFO_WP("sCfg "); /* Set the requested configuration */ cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest); SetConfiguration(pDriver, cfgnum); break; case USBGenericRequest_GETCONFIGURATION: TRACE_INFO_WP("gCfg "); /* Send the current configuration number */ GetConfiguration(pDriver); break; case USBGenericRequest_GETSTATUS: TRACE_INFO_WP("gSta "); /* Check who is the recipient */ switch (USBGenericRequest_GetRecipient(pRequest)) { case USBGenericRequest_DEVICE: TRACE_INFO_WP("Dev "); /* Send the device status */ GetDeviceStatus(pDriver); break; case USBGenericRequest_ENDPOINT: TRACE_INFO_WP("Ept "); /* Send the endpoint status */ eptnum = USBGenericRequest_GetEndpointNumber(pRequest); GetEndpointStatus(eptnum); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown recipient (%d)\n\r", USBGenericRequest_GetRecipient(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_CLEARFEATURE: TRACE_INFO_WP("cFeat "); /* Check which is the requested feature */ switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { case USBFeatureRequest_ENDPOINTHALT: TRACE_INFO_WP("Hlt "); /* 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_INFO_WP("RmWU "); /* Disable remote wake-up and send a zero-length packet */ pDriver->isRemoteWakeUpEnabled = 0; USBD_Write(0, 0, 0, 0, 0); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_SETFEATURE: TRACE_INFO_WP("sFeat "); /* Check which is the selected feature */ switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { case USBFeatureRequest_DEVICEREMOTEWAKEUP: TRACE_INFO_WP("RmWU "); /* Enable remote wake-up and send a ZLP */ pDriver->isRemoteWakeUpEnabled = 1; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_ENDPOINTHALT: TRACE_INFO_WP("Halt "); /* Halt endpoint */ USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_OTG_B_HNP_ENABLE: TRACE_INFO_WP("OTG_B_HNP_ENABLE "); pDriver->otg_features_supported |= 1<<USBFeatureRequest_OTG_B_HNP_ENABLE; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_OTG_A_HNP_SUPPORT: TRACE_INFO_WP("OTG_A_HNP_SUPPORT "); pDriver->otg_features_supported |= 1<<USBFeatureRequest_OTG_A_HNP_SUPPORT; USBD_Write(0, 0, 0, 0, 0); break; case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT: TRACE_INFO_WP("OTG_A_ALT_HNP_SUPPORT "); pDriver->otg_features_supported |= 1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT; USBD_Write(0, 0, 0, 0, 0); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest)); USBD_Stall(0); } break; case USBGenericRequest_SETINTERFACE: TRACE_INFO_WP("sInterface "); infnum = USBInterfaceRequest_GetInterface(pRequest); setting = USBInterfaceRequest_GetAlternateSetting(pRequest); SetInterface(pDriver, infnum, setting); break; case USBGenericRequest_GETINTERFACE: TRACE_INFO_WP("gInterface "); infnum = USBInterfaceRequest_GetInterface(pRequest); GetInterface(pDriver, infnum); break; default: TRACE_WARNING( "USBDDriver_RequestHandler: Unknown request code (%d)\n\r", USBGenericRequest_GetRequest(pRequest)); USBD_Stall(0); } }
//------------------------------------------------------------------------------ /// Sends the requested USB descriptor to the host if available, or STALLs the /// request. /// \param pDriver Pointer to a USBDDriver instance. /// \param type Type of the requested descriptor /// \param index Index of the requested descriptor. /// \param length Maximum number of bytes to return. //------------------------------------------------------------------------------ static void GetDescriptor( const USBDDriver *pDriver, unsigned char type, unsigned char indexRDesc, unsigned int length) { const USBDeviceDescriptor *pDevice; const USBConfigurationDescriptor *pConfiguration; const USBDeviceQualifierDescriptor *pQualifier; const USBConfigurationDescriptor *pOtherSpeed; const USBGenericDescriptor **pStrings = (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings; const USBGenericDescriptor *pString; unsigned char numStrings = pDriver->pDescriptors->numStrings; unsigned char terminateWithNull = 0; // Use different set of descriptors depending on device speed if (USBD_IsHighSpeed()) { TRACE_DEBUG("HS "); pDevice = pDriver->pDescriptors->pHsDevice; pConfiguration = pDriver->pDescriptors->pHsConfiguration; pQualifier = pDriver->pDescriptors->pHsQualifier; pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed; } else { TRACE_DEBUG("FS "); pDevice = pDriver->pDescriptors->pFsDevice; pConfiguration = pDriver->pDescriptors->pFsConfiguration; pQualifier = pDriver->pDescriptors->pFsQualifier; pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed; } // Check the descriptor type switch (type) { case USBGenericDescriptor_DEVICE: TRACE_INFO_WP("Dev "); // Adjust length and send descriptor if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) { length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice); } USBD_Write(0, pDevice, length, 0, 0); break; case USBGenericDescriptor_CONFIGURATION: TRACE_INFO_WP("Cfg "); // Adjust length and send descriptor if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) { length = USBConfigurationDescriptor_GetTotalLength(pConfiguration); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pConfiguration, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); break; case USBGenericDescriptor_DEVICEQUALIFIER: TRACE_INFO_WP("Qua "); // Check if descriptor exists if (!pQualifier) { USBD_Stall(0); } else { // Adjust length and send descriptor if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) { length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier); } USBD_Write(0, pQualifier, length, 0, 0); } break; case USBGenericDescriptor_OTHERSPEEDCONFIGURATION: TRACE_INFO_WP("OSC "); // Check if descriptor exists if (!pOtherSpeed) { USBD_Stall(0); } else { // Adjust length and send descriptor if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) { length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pOtherSpeed, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); } break; case USBGenericDescriptor_STRING: TRACE_INFO_WP("Str%d ", indexRDesc); // Check if descriptor exists if (indexRDesc > numStrings) { USBD_Stall(0); } else { pString = pStrings[indexRDesc]; // Adjust length and send descriptor if (length > USBGenericDescriptor_GetLength(pString)) { length = USBGenericDescriptor_GetLength(pString); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pString, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); } break; default: TRACE_WARNING( "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r", type); USBD_Stall(0); } }
// https://github.com/pbatard/libwdi/wiki/WCID-Devices static void GetMSDescriptor( const USBDDriver *pDriver, uint16_t indexRDesc, uint32_t length) { const USBDeviceDescriptor *pDevice; uint8_t terminateWithNull = 0; /* Use different set of descriptors depending on device speed */ if (USBD_IsHighSpeed()) { TRACE_DEBUG("HS "); pDevice = pDriver->pDescriptors->pHsDevice; } else { TRACE_DEBUG("FS "); pDevice = pDriver->pDescriptors->pFsDevice; } /* Check the descriptor index */ switch (indexRDesc) { // https://github.com/pbatard/libwdi/wiki/WCID-Devices case 0x0004: { // Extended Compat ID (Microsoft OS 1.0 Descriptors) const uint8_t extendedCompatID[] = { 0x28, 0x00, 0x00, 0x00, // dwLength 0x00, 0x01, // bcdVersion 0x04, 0x00, // wIndex 0x01, // bCount 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved 0x00, // bFirstInterfaceNumber 0x01, // Reserved 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // CompatibleID "WINUSB\0\0" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SubCompatibleID 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved }; const uint8_t extendedCompatIDLength = sizeof(extendedCompatID); /* Adjust length and send descriptor */ if (length > extendedCompatIDLength) { length = extendedCompatIDLength; terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); USBD_Write(0, extendedCompatID, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); break; } case 0x0005: { // Extended Properties (Microsoft OS 1.0 Descriptors) const uint8_t extendedProperties[] = { 0x92, 0x00, 0x00, 0x00, // dwLength 0x00, 0x01, // bcdVersion 0x05, 0x00, // wIndex 0x01, 0x00, // wCount 0x88, 0x00, 0x00, 0x00, // dwSize 0x07, 0x00, 0x00, 0x00, // dwPropertyDataType 0x2a, 0x00, // wPropertyNameLength 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x47, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, 0x73, 0x00, 0x00, 0x00, // bPropertyName "DeviceInterfaceGUIDs\0" 0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength 0x7b, 0x00, 0x38, 0x00, 0x37, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x33, 0x00, 0x44, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x46, 0x00, 0x42, 0x00, 0x31, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x42, 0x00, 0x44, 0x00, 0x37, 0x00, 0x2d, 0x00, 0x41, 0x00, 0x39, 0x00, 0x36, 0x00, 0x43, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x46, 0x00, 0x30, 0x00, 0x42, 0x00, 0x37, 0x00, 0x44, 0x00, 0x33, 0x00, 0x31, 0x00, 0x41, 0x00, 0x46, 0x00, 0x34, 0x00, 0x31, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, // bPropertyData "{870013DD-FB1D-4BD7-A96C-1F0B7D31AF41}\0\0" }; const uint8_t extendedPropertiesLength = sizeof(extendedProperties); /* Adjust length and send descriptor */ if (length > extendedPropertiesLength) { length = extendedPropertiesLength; terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); USBD_Write(0, extendedProperties, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); break; } default: TRACE_WARNING( "USBDDriver_GetMSDescriptor: Unknown descriptor index (%d)\n\r", indexRDesc); USBD_Stall(0); } }