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)];
}
static usb_endpoint_t* usb_endpoint_from_address(
usb_endpoint_t* usb_endpoint_from_address(
const uint_fast8_t endpoint_address
) {
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?
}
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() {
USB0_USBCMD_D |= USB0_USBCMD_D_RS;
}

View File

@ -58,6 +58,10 @@ void usb_set_address_deferred(
const uint_fast8_t address
);
usb_endpoint_t* usb_endpoint_from_address(
const uint_fast8_t endpoint_address
);
void usb_endpoint_init(
const usb_endpoint_t* const endpoint
);
@ -70,6 +74,10 @@ void usb_endpoint_disable(
const usb_endpoint_t* const endpoint
);
void usb_endpoint_reset_data_toggle(
const usb_endpoint_t* const endpoint
);
void usb_endpoint_flush(
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(
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(
@ -389,6 +421,9 @@ usb_request_status_t usb_standard_request(
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;
}

View File

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