diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index a7ecac7f..4c74acf7 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -196,7 +196,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { sgpio_cpld_stream_enable(); } -bool usb_vendor_request_set_transceiver_mode( +usb_request_status_t usb_vendor_request_set_transceiver_mode( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -205,22 +205,22 @@ bool usb_vendor_request_set_transceiver_mode( case 1: set_transceiver_mode(TRANSCEIVER_MODE_RX); usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; case 2: set_transceiver_mode(TRANSCEIVER_MODE_TX); usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; default: - return false; + return USB_REQUEST_STATUS_STALL; } } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_write_max2837( +usb_request_status_t usb_vendor_request_write_max2837( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -229,16 +229,16 @@ bool usb_vendor_request_write_max2837( if( endpoint->setup.value < 0x3ff ) { max2837_reg_write(endpoint->setup.index, endpoint->setup.value); usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; } } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_read_max2837( +usb_request_status_t usb_vendor_request_read_max2837( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -249,15 +249,15 @@ bool usb_vendor_request_read_max2837( endpoint->buffer[1] = value >> 8; usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); usb_endpoint_schedule_ack(endpoint->out); - return true; + return USB_REQUEST_STATUS_OK; } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_write_si5351c( +usb_request_status_t usb_vendor_request_write_si5351c( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -266,16 +266,16 @@ bool usb_vendor_request_write_si5351c( if( endpoint->setup.value < 256 ) { si5351c_write_single(endpoint->setup.index, endpoint->setup.value); usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; } } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_read_si5351c( +usb_request_status_t usb_vendor_request_read_si5351c( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -285,15 +285,15 @@ bool usb_vendor_request_read_si5351c( endpoint->buffer[0] = value; usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); usb_endpoint_schedule_ack(endpoint->out); - return true; + return USB_REQUEST_STATUS_OK; } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_set_sample_rate( +usb_request_status_t usb_vendor_request_set_sample_rate( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -301,15 +301,15 @@ bool usb_vendor_request_set_sample_rate( const uint32_t sample_rate = (endpoint->setup.index << 16) | endpoint->setup.value; if( sample_rate_set(sample_rate) ) { usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -bool usb_vendor_request_set_baseband_filter_bandwidth( +usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { @@ -317,56 +317,42 @@ bool usb_vendor_request_set_baseband_filter_bandwidth( const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; if( baseband_filter_bandwidth_set(bandwidth) ) { usb_endpoint_schedule_ack(endpoint->in); - return true; + return USB_REQUEST_STATUS_OK; } - return false; + return USB_REQUEST_STATUS_STALL; } else { - return true; + return USB_REQUEST_STATUS_OK; } } -void usb_vendor_request( +static const usb_request_handler_fn vendor_request_handler[] = { + NULL, + usb_vendor_request_set_transceiver_mode, + usb_vendor_request_write_max2837, + usb_vendor_request_read_max2837, + usb_vendor_request_write_si5351c, + usb_vendor_request_read_si5351c, + usb_vendor_request_set_sample_rate, + usb_vendor_request_set_baseband_filter_bandwidth, +}; + +static const uint32_t vendor_request_handler_count = + sizeof(vendor_request_handler) / sizeof(vendor_request_handler[0]); + +usb_request_status_t usb_vendor_request( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { - bool success = false; + usb_request_status_t status = USB_REQUEST_STATUS_STALL; - switch(endpoint->setup.request) { - case 1: - success = usb_vendor_request_set_transceiver_mode(endpoint, stage); - break; - - case 2: - success = usb_vendor_request_write_max2837(endpoint, stage); - break; - - case 3: - success = usb_vendor_request_read_max2837(endpoint, stage); - break; - - case 4: - success = usb_vendor_request_write_si5351c(endpoint, stage); - break; - - case 5: - success = usb_vendor_request_read_si5351c(endpoint, stage); - break; - - case 6: - success = usb_vendor_request_set_sample_rate(endpoint, stage); - break; - - case 7: - success = usb_vendor_request_set_baseband_filter_bandwidth(endpoint, stage); - break; - - default: - break; + if( endpoint->setup.request < vendor_request_handler_count ) { + usb_request_handler_fn handler = vendor_request_handler[endpoint->setup.request]; + if( handler ) { + status = handler(endpoint, stage); + } } - if( success != true ) { - usb_endpoint_stall(endpoint); - } + return status; } const usb_request_handlers_t usb_request_handlers = { diff --git a/firmware/usb_performance/usb_request.c b/firmware/usb_performance/usb_request.c index bfa4ea75..25132fd4 100644 --- a/firmware/usb_performance/usb_request.c +++ b/firmware/usb_performance/usb_request.c @@ -28,6 +28,7 @@ static void usb_request( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { + usb_request_status_t status = USB_REQUEST_STATUS_STALL; usb_request_handler_fn handler = 0; switch( endpoint->setup.request_type & USB_SETUP_REQUEST_TYPE_mask ) { @@ -49,8 +50,10 @@ static void usb_request( } if( handler ) { - handler(endpoint, stage); - } else { + status = handler(endpoint, stage); + } + + if( status != USB_REQUEST_STATUS_OK ) { // USB 2.0 section 9.2.7 "Request Error" usb_endpoint_stall(endpoint); } diff --git a/firmware/usb_performance/usb_request.h b/firmware/usb_performance/usb_request.h index 2d32bcea..9c1ef84f 100644 --- a/firmware/usb_performance/usb_request.h +++ b/firmware/usb_performance/usb_request.h @@ -37,7 +37,12 @@ typedef enum { USB_TRANSFER_STAGE_STATUS, } usb_transfer_stage_t; -typedef void (*usb_request_handler_fn)( +typedef enum { + USB_REQUEST_STATUS_OK = 0, + USB_REQUEST_STATUS_STALL = 1, +} usb_request_status_t; + +typedef usb_request_status_t (*usb_request_handler_fn)( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ); diff --git a/firmware/usb_performance/usb_standard_request.c b/firmware/usb_performance/usb_standard_request.c index 286d783b..71a38232 100644 --- a/firmware/usb_performance/usb_standard_request.c +++ b/firmware/usb_performance/usb_standard_request.c @@ -63,7 +63,7 @@ extern bool usb_set_configuration( const uint_fast8_t configuration_number ); -static void usb_send_descriptor( +static usb_request_status_t usb_send_descriptor( usb_endpoint_t* const endpoint, uint8_t* const descriptor_data ) { @@ -77,113 +77,110 @@ static void usb_send_descriptor( descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length ); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; } -static void usb_send_descriptor_string( +static usb_request_status_t usb_send_descriptor_string( usb_endpoint_t* const endpoint ) { uint_fast8_t index = endpoint->setup.value_l; for( uint_fast8_t i=0; usb_descriptor_strings[i] != 0; i++ ) { if( i == index ) { - usb_send_descriptor(endpoint, usb_descriptor_strings[i]); - return; + return usb_send_descriptor(endpoint, usb_descriptor_strings[i]); } } - usb_endpoint_stall(endpoint); + return USB_REQUEST_STATUS_STALL; } -static void usb_standard_request_get_descriptor_setup( +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: - usb_send_descriptor(endpoint, usb_descriptor_device); - break; + return usb_send_descriptor(endpoint, usb_descriptor_device); case USB_DESCRIPTOR_TYPE_CONFIGURATION: // TODO: Duplicated code. Refactor. if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { - usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + return usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); } else { - usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + return usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); } - break; case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: - usb_send_descriptor(endpoint, usb_descriptor_device_qualifier); - break; + return usb_send_descriptor(endpoint, usb_descriptor_device_qualifier); case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: // TODO: Duplicated code. Refactor. if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { - usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + return usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); } else { - usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + return usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); } - break; case USB_DESCRIPTOR_TYPE_STRING: - usb_send_descriptor_string(endpoint); - break; + return usb_send_descriptor_string(endpoint); case USB_DESCRIPTOR_TYPE_INTERFACE: case USB_DESCRIPTOR_TYPE_ENDPOINT: default: - usb_endpoint_stall(endpoint); - break; + return USB_REQUEST_STATUS_STALL; } } -static void usb_standard_request_get_descriptor( +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: - usb_standard_request_get_descriptor_setup(endpoint); - usb_endpoint_schedule_ack(endpoint->out); - break; + return usb_standard_request_get_descriptor_setup(endpoint); case USB_TRANSFER_STAGE_DATA: - break; - case USB_TRANSFER_STAGE_STATUS: - break; + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ -static void usb_standard_request_set_address( +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_endpoint_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: - usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); - usb_endpoint_schedule_ack(endpoint->in); - break; + return usb_standard_request_set_address_setup(endpoint); case USB_TRANSFER_STAGE_DATA: - break; - 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. */ - break; + return USB_REQUEST_STATUS_OK; default: - break; + return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ -static void usb_standard_request_set_configuration_setup( +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; @@ -193,32 +190,32 @@ static void usb_standard_request_set_configuration_setup( usb_set_address_immediate(endpoint->device, 0); } usb_endpoint_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; } else { - usb_endpoint_stall(endpoint); + return USB_REQUEST_STATUS_STALL; } } -static void usb_standard_request_set_configuration( +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: - usb_standard_request_set_configuration_setup(endpoint); - break; + return usb_standard_request_set_configuration_setup(endpoint); case USB_TRANSFER_STAGE_DATA: - break; - case USB_TRANSFER_STAGE_STATUS: - break; + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ -static void usb_standard_request_get_configuration_setup( +static usb_request_status_t usb_standard_request_get_configuration_setup( usb_endpoint_t* const endpoint ) { if( endpoint->setup.length == 1 ) { @@ -227,52 +224,50 @@ static void usb_standard_request_get_configuration_setup( endpoint->buffer[0] = endpoint->device->configuration->number; } usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; } else { - usb_endpoint_stall(endpoint); + return USB_REQUEST_STATUS_STALL; } } -static void usb_standard_request_get_configuration( +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: - usb_standard_request_get_configuration_setup(endpoint); - usb_endpoint_schedule_ack(endpoint->out); - break; + return usb_standard_request_get_configuration_setup(endpoint); case USB_TRANSFER_STAGE_DATA: - break; - case USB_TRANSFER_STAGE_STATUS: - break; - + return USB_REQUEST_STATUS_OK; + + default: + return USB_REQUEST_STATUS_STALL; } } /*********************************************************************/ -void usb_standard_request( +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_DESCRIPTOR: - usb_standard_request_get_descriptor(endpoint, stage); - break; + return usb_standard_request_get_descriptor(endpoint, stage); case USB_STANDARD_REQUEST_SET_ADDRESS: - usb_standard_request_set_address(endpoint, stage); - break; + return usb_standard_request_set_address(endpoint, stage); case USB_STANDARD_REQUEST_SET_CONFIGURATION: - usb_standard_request_set_configuration(endpoint, stage); - break; + return usb_standard_request_set_configuration(endpoint, stage); case USB_STANDARD_REQUEST_GET_CONFIGURATION: - usb_standard_request_get_configuration(endpoint, stage); - break; - + return usb_standard_request_get_configuration(endpoint, stage); + + default: + return USB_REQUEST_STATUS_STALL; } } diff --git a/firmware/usb_performance/usb_standard_request.h b/firmware/usb_performance/usb_standard_request.h index e96dba21..5a0bdac6 100644 --- a/firmware/usb_performance/usb_standard_request.h +++ b/firmware/usb_performance/usb_standard_request.h @@ -25,7 +25,7 @@ #include "usb_type.h" #include "usb_request.h" -void usb_standard_request( +usb_request_status_t usb_standard_request( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage );