Files

copied
Last update 2 years 1 month by Gianpaolo Macario
Filesfirmwarecommon
..
rad1o
xapp058
LPC4320_M4_memory.ld
LPC4330_M4_memory.ld
LPC43xx_M0_memory.ld
LPC43xx_M4_M0_image_from_text.ld
LPC43xx_M4_memory.ld
README
bitband.c
bitband.h
clkin.c
clkin.h
configure_file.cmake
cpld_jtag.c
cpld_jtag.h
cpld_xc2c.c
cpld_xc2c.h
crc.c
crc.h
fault_handler.c
fault_handler.h
firmware_info.c
firmware_info.h
gpdma.c
gpdma.h
gpio.h
gpio_lpc.c
gpio_lpc.h
hackrf_core.c
hackrf_core.h
hackrf_ui.c
hackrf_ui.h
i2c_bus.c
i2c_bus.h
i2c_lpc.c
i2c_lpc.h
m0_bin.s.cmake
m0_sleep.c
max2837.c
max2837.h
max2837_regs.def
max2837_target.c
max2837_target.h
max2839.c
max2839.h
max2839_regs.def
max2839_target.c
max2839_target.h
max283x.c
max283x.h
max2871.c
max2871.h
max2871_regs.c
max2871_regs.h
max5864.c
max5864.h
max5864_target.c
max5864_target.h
mixer.c
mixer.h
operacake.c
operacake.h
operacake_sctimer.c
operacake_sctimer.h
platform_detect.c
platform_detect.h
portapack.c
portapack.h
rf_path.c
rf_path.h
rffc5071.c
rffc5071.h
rffc5071_regs.def
rffc5071_spi.c
rffc5071_spi.h
rom_iap.c
rom_iap.h
sct.h
sgpio.c
sgpio.h
si5351c.c
si5351c.h
spi_bus.c
spi_bus.h
spi_ssp.c
spi_ssp.h
streaming.c
streaming.h
tuning.c
tuning.h
ui_portapack.c
ui_portapack.h
ui_rad1o.c
ui_rad1o.h
usb.c
usb.h
usb_queue.c
usb_queue.h
usb_request.c
usb_request.h
usb_standard_request.c
usb_standard_request.h
usb_type.h
w25q80bv.c
w25q80bv.h
w25q80bv_target.c
w25q80bv_target.h
usb_standard_request.c
/* * Copyright 2012-2022 Great Scott Gadgets <info@greatscottgadgets.com> * Copyright 2012 Jared Boone * * This file is part of HackRF. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #include <stdint.h> #include <stddef.h> #include "usb_standard_request.h" #include "usb.h" #include "usb_type.h" #include "usb_queue.h" const uint8_t* usb_endpoint_descriptor(const usb_endpoint_t* const endpoint) { const usb_configuration_t* const configuration = endpoint->device->configuration; if (configuration) { const uint8_t* descriptor = configuration->descriptor; while (descriptor[0] != 0) { if (descriptor[1] == USB_DESCRIPTOR_TYPE_ENDPOINT) { if (descriptor[2] == endpoint->address) { return descriptor; } } descriptor += descriptor[0]; } } return 0; } uint_fast16_t usb_endpoint_descriptor_max_packet_size( const uint8_t* const endpoint_descriptor) { return (endpoint_descriptor[5] << 8) | endpoint_descriptor[4]; } usb_transfer_type_t usb_endpoint_descriptor_transfer_type( const uint8_t* const endpoint_descriptor) { return (endpoint_descriptor[3] & 0x3); } void (*usb_configuration_changed_cb)(usb_device_t* const) = NULL; void usb_set_configuration_changed_cb(void (*callback)(usb_device_t* const)) { usb_configuration_changed_cb = callback; } bool usb_set_configuration( usb_device_t* const device, const uint_fast8_t configuration_number) { const usb_configuration_t* new_configuration = 0; if (configuration_number != 0) { // Locate requested configuration. if (device->configurations) { usb_configuration_t** configurations = *(device->configurations); uint32_t i = 0; const usb_speed_t usb_speed_current = usb_speed(device); while (configurations[i]) { if ((configurations[i]->speed == usb_speed_current) && (configurations[i]->number == configuration_number)) { new_configuration = configurations[i]; break; } i++; } } // Requested configuration not found: request error. if (new_configuration == 0) { return false; } } if (new_configuration != device->configuration) { // Configuration changed. device->configuration = new_configuration; } if (usb_configuration_changed_cb) { usb_configuration_changed_cb(device); } return true; } static usb_request_status_t usb_send_descriptor( usb_endpoint_t* const endpoint, const uint8_t* const descriptor_data) { const uint32_t setup_length = endpoint->setup.length; uint32_t descriptor_length = descriptor_data[0]; if (descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION) { descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; } // We cast the const away but this shouldn't be a problem as this is a write transfer usb_transfer_schedule_block( endpoint->in, (uint8_t* const) descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length, NULL, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } static usb_request_status_t usb_send_descriptor_string(usb_endpoint_t* const endpoint) { if ((endpoint->setup.value_l == 0xee) && (endpoint->device->wcid_string_descriptor != NULL)) { /* MS WCID string */ return usb_send_descriptor( endpoint, endpoint->device->wcid_string_descriptor); } else { uint_fast8_t index = endpoint->setup.value_l; for (uint_fast8_t i = 0; endpoint->device->descriptor_strings[i] != 0; i++) { if (i == index) { return usb_send_descriptor( endpoint, endpoint->device->descriptor_strings[i]); } } } return USB_REQUEST_STATUS_STALL; } static usb_request_status_t usb_send_descriptor_config( usb_endpoint_t* const endpoint, usb_speed_t speed, const uint8_t config_num) { usb_configuration_t** config = *(endpoint->device->configurations); unsigned int i = 0; for (; *config != NULL; config++) { if ((*config)->speed == speed) { if (i == config_num) { return usb_send_descriptor( endpoint, (*config)->descriptor); } else { i++; } } } return USB_REQUEST_STATUS_STALL; } static usb_request_status_t usb_standard_request_get_descriptor_setup( usb_endpoint_t* const endpoint) { switch (endpoint->setup.value_h) { case USB_DESCRIPTOR_TYPE_DEVICE: return usb_send_descriptor(endpoint, endpoint->device->descriptor); case USB_DESCRIPTOR_TYPE_CONFIGURATION: // TODO: Duplicated code. Refactor. if (usb_speed(endpoint->device) == USB_SPEED_HIGH) { return usb_send_descriptor_config( endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); } else { return usb_send_descriptor_config( endpoint, USB_SPEED_FULL, endpoint->setup.value_l); } case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: return usb_send_descriptor( endpoint, endpoint->device->qualifier_descriptor); case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: // TODO: Duplicated code. Refactor. if (usb_speed(endpoint->device) == USB_SPEED_HIGH) { return usb_send_descriptor_config( endpoint, USB_SPEED_FULL, endpoint->setup.value_l); } else { return usb_send_descriptor_config( endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); } case USB_DESCRIPTOR_TYPE_STRING: return usb_send_descriptor_string(endpoint); case USB_DESCRIPTOR_TYPE_INTERFACE: case USB_DESCRIPTOR_TYPE_ENDPOINT: default: return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_get_descriptor( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_get_descriptor_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } usb_request_status_t usb_vendor_request_read_wcid( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { if ((endpoint->setup.index == 0x04) && (endpoint->device->wcid_feature_descriptor != NULL)) { usb_send_descriptor( endpoint, endpoint->device->wcid_feature_descriptor); return USB_REQUEST_STATUS_OK; } if ((endpoint->setup.index == 0x05) && (endpoint->device->wcid_extended_properties_descriptor != NULL)) { usb_send_descriptor( endpoint, endpoint->device->wcid_extended_properties_descriptor); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; } return USB_REQUEST_STATUS_OK; } /*********************************************************************/ static usb_request_status_t usb_standard_request_set_address_setup( usb_endpoint_t* const endpoint) { usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } static usb_request_status_t usb_standard_request_set_address( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_set_address_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: /* NOTE: Not necessary to set address here, as DEVICEADR.USBADRA bit * will cause controller to automatically perform set address * operation on IN ACK. */ return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ static usb_request_status_t usb_standard_request_set_configuration_setup( usb_endpoint_t* const endpoint) { const uint8_t usb_configuration = endpoint->setup.value_l; if (usb_set_configuration(endpoint->device, usb_configuration)) { usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_set_configuration( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_set_configuration_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ static usb_request_status_t usb_standard_request_get_configuration_setup( usb_endpoint_t* const endpoint) { if (endpoint->setup.length == 1) { endpoint->buffer[0] = 0; if (endpoint->device->configuration) { endpoint->buffer[0] = endpoint->device->configuration->number; } usb_transfer_schedule_block( endpoint->in, &endpoint->buffer, 1, NULL, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_get_configuration( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_get_configuration_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_get_status_setup( usb_endpoint_t* const endpoint) { if (endpoint->setup.length == 2) { endpoint->buffer[0] = 0; endpoint->buffer[1] = 0; usb_transfer_schedule_block( endpoint->in, &endpoint->buffer, 2, NULL, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_get_status( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_get_status_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_clear_feature_setup( usb_endpoint_t* const endpoint) { switch (endpoint->setup.value) { case USB_FEATURE_SELECTOR_ENDPOINT_HALT: usb_endpoint_reset_data_toggle( usb_endpoint_from_address(endpoint->setup.index)); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } static usb_request_status_t usb_standard_request_clear_feature( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (stage) { case USB_TRANSFER_STAGE_SETUP: return usb_standard_request_clear_feature_setup(endpoint); case USB_TRANSFER_STAGE_DATA: case USB_TRANSFER_STAGE_STATUS: return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ usb_request_status_t usb_standard_request( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { switch (endpoint->setup.request) { case USB_STANDARD_REQUEST_GET_STATUS: return usb_standard_request_get_status(endpoint, stage); case USB_STANDARD_REQUEST_GET_DESCRIPTOR: return usb_standard_request_get_descriptor(endpoint, stage); case USB_STANDARD_REQUEST_SET_ADDRESS: return usb_standard_request_set_address(endpoint, stage); case USB_STANDARD_REQUEST_SET_CONFIGURATION: return usb_standard_request_set_configuration(endpoint, stage); case USB_STANDARD_REQUEST_GET_CONFIGURATION: return usb_standard_request_get_configuration(endpoint, stage); case USB_STANDARD_REQUEST_CLEAR_FEATURE: return usb_standard_request_clear_feature(endpoint, stage); default: return USB_REQUEST_STATUS_STALL; } }
Report a bug