Merge pull request #1081 from martinling/clear-feature

Implement USB CLEAR_FEATURE request for ENDPOINT_HALT
This commit is contained in:
Michael Ossmann
2022-04-04 11:53:50 -04:00
committed by GitHub
4 changed files with 60 additions and 2 deletions

View File

@ -44,7 +44,7 @@ usb_queue_head_t* usb_queue_head(
return &usb_qh[USB_QH_INDEX(endpoint_address)]; return &usb_qh[USB_QH_INDEX(endpoint_address)];
} }
static usb_endpoint_t* usb_endpoint_from_address( usb_endpoint_t* usb_endpoint_from_address(
const uint_fast8_t endpoint_address const uint_fast8_t endpoint_address
) { ) {
return (usb_endpoint_t*)usb_queue_head(endpoint_address)->_reserved_0; return (usb_endpoint_t*)usb_queue_head(endpoint_address)->_reserved_0;
@ -302,6 +302,17 @@ void usb_endpoint_stall(
// TODO: Also need to reset data toggle in both directions? // TODO: Also need to reset data toggle in both directions?
} }
void usb_endpoint_reset_data_toggle(
const usb_endpoint_t* const endpoint
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if( usb_endpoint_is_in(endpoint->address) ) {
USB0_ENDPTCTRL(endpoint_number) |= USB0_ENDPTCTRL_TXR;
} else {
USB0_ENDPTCTRL(endpoint_number) |= USB0_ENDPTCTRL_RXR;
}
}
static void usb_controller_run() { static void usb_controller_run() {
USB0_USBCMD_D |= USB0_USBCMD_D_RS; USB0_USBCMD_D |= USB0_USBCMD_D_RS;
} }

View File

@ -58,6 +58,10 @@ void usb_set_address_deferred(
const uint_fast8_t address const uint_fast8_t address
); );
usb_endpoint_t* usb_endpoint_from_address(
const uint_fast8_t endpoint_address
);
void usb_endpoint_init( void usb_endpoint_init(
const usb_endpoint_t* const endpoint const usb_endpoint_t* const endpoint
); );
@ -70,6 +74,10 @@ void usb_endpoint_disable(
const usb_endpoint_t* const endpoint const usb_endpoint_t* const endpoint
); );
void usb_endpoint_reset_data_toggle(
const usb_endpoint_t* const endpoint
);
void usb_endpoint_flush( void usb_endpoint_flush(
const usb_endpoint_t* const endpoint const usb_endpoint_t* const endpoint
); );

View File

@ -333,7 +333,6 @@ static usb_request_status_t usb_standard_request_get_configuration(
} }
} }
static usb_request_status_t usb_standard_request_get_status_setup( static usb_request_status_t usb_standard_request_get_status_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint
) { ) {
@ -367,6 +366,39 @@ static usb_request_status_t usb_standard_request_get_status(
} }
} }
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_request_status_t usb_standard_request(
@ -389,6 +421,9 @@ usb_request_status_t usb_standard_request(
case USB_STANDARD_REQUEST_GET_CONFIGURATION: case USB_STANDARD_REQUEST_GET_CONFIGURATION:
return usb_standard_request_get_configuration(endpoint, stage); return usb_standard_request_get_configuration(endpoint, stage);
case USB_STANDARD_REQUEST_CLEAR_FEATURE:
return usb_standard_request_clear_feature(endpoint, stage);
default: default:
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }

View File

@ -70,6 +70,10 @@ typedef enum {
USB_STANDARD_REQUEST_SYNCH_FRAME = 12, USB_STANDARD_REQUEST_SYNCH_FRAME = 12,
} usb_standard_request_t; } usb_standard_request_t;
typedef enum {
USB_FEATURE_SELECTOR_ENDPOINT_HALT = 0,
} usb_feature_selector_t;
typedef enum { typedef enum {
USB_SETUP_REQUEST_TYPE_shift = 5, USB_SETUP_REQUEST_TYPE_shift = 5,
USB_SETUP_REQUEST_TYPE_mask = 3 << USB_SETUP_REQUEST_TYPE_shift, USB_SETUP_REQUEST_TYPE_mask = 3 << USB_SETUP_REQUEST_TYPE_shift,