📄 usbs.c
字号:
(*endpoint->start_tx_fn)(endpoint);}voidusbs_start(usbs_control_endpoint* endpoint){ CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied"); CYG_CHECK_FUNC_PTR( endpoint->start_fn, "The USB endpoint should have a start function"); (*endpoint->start_fn)(endpoint);}cyg_boolusbs_rx_endpoint_halted(usbs_rx_endpoint* endpoint){ CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied"); return endpoint->halted;}cyg_boolusbs_tx_endpoint_halted(usbs_tx_endpoint* endpoint){ CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied"); return endpoint->halted;}voidusbs_set_rx_endpoint_halted(usbs_rx_endpoint* endpoint, cyg_bool halted){ CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied"); CYG_CHECK_FUNC_PTR( endpoint->set_halted_fn, "The USB endpoint should have a set-halted function"); (*endpoint->set_halted_fn)(endpoint, halted);}voidusbs_set_tx_endpoint_halted(usbs_tx_endpoint* endpoint, cyg_bool halted){ CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied"); CYG_CHECK_FUNC_PTR( endpoint->set_halted_fn, "The USB endpoint should have a set-halted function"); (*endpoint->set_halted_fn)(endpoint, halted);}voidusbs_start_rx_endpoint_wait(usbs_rx_endpoint* endpoint, void (*callback_fn)(void*, int), void* callback_data){ endpoint->buffer = (unsigned char*) 0; endpoint->buffer_size = 0; endpoint->complete_fn = callback_fn; endpoint->complete_data = callback_data; (*endpoint->start_rx_fn)(endpoint);}voidusbs_start_tx_endpoint_wait(usbs_tx_endpoint* endpoint, void (*callback_fn)(void*, int), void* callback_data){ endpoint->buffer = (unsigned char*) 0; endpoint->buffer_size = 0; endpoint->complete_fn = callback_fn; endpoint->complete_data = callback_data; (*endpoint->start_tx_fn)(endpoint);}// ----------------------------------------------------------------------------// Handling of standard control messages. This will be invoked by// a USB device driver, usually at DSR level, to process any control// messages that cannot be handled by the hardware itself and that// have also not been handled by the application-specific handler// (if any).//// Because this function can run at DSR level performance is important.//// The various standard control messages are affected as follows://// clear-feature: nothing can be done here about device requests to// disable remote-wakeup or about endpoint halt requests. It appears// to be legal to clear no features on an interface.//// get-configuration: if the device is not configured a single byte 0// should be returned. Otherwise this code assumes only one configuration// is supported and its id can be extracted from the enumeration data.// For more complicated devices get-configuration has to be handled// at a higher-level.//// get-descriptor: this is the big one. It is used to obtain// the enumeration data. An auxiliary refill function is needed.//// get-interface: this can be used to identify the current variant// for a given interface within a configuration. For simple devices// there will be only interface, 0. For anything more complicated// higher level code will have to take care of the request.//// get-status. Much the same as clear-feature.//// set-address. Must be handled at the device driver level.//// set-configuration: a value of 0 is used to deconfigure the device,// which can be handled here. Otherwise this code assumes that only// a single configuration is supported and enables that. For anything// more complicated higher-level code has to handle this request.//// set-descriptor: used to update the enumeration data. This is not// supported here, although higher-level code can choose to do so.//// set-feature. See clear-feature and get-status.//// set-interface. Variant interfaces are not supported by the// base code so this request has to be handled at a higher level.//// synch-frame. This is only relevant for isochronous transfers// which are not yet supported, and anyway it is not clear what// could be done about these requests here.// This refill function handles GET_DESCRIPTOR requests for a// configuration. For details of the control_buffer usage see// the relevant code in the main callback.static voidusbs_configuration_descriptor_refill(usbs_control_endpoint* endpoint){ usb_devreq* req = (usb_devreq*) endpoint->control_buffer; int length = (req->length_hi << 8) | req->length_lo; int sent = (req->index_hi << 8) | req->index_lo; int current_interface = req->type; int last_interface = req->request; int current_endpoint = req->value_lo; int last_endpoint = req->value_hi; cyg_bool done = false; if (current_endpoint == last_endpoint) { // The next transfer should be a single interface - unless we have already finished. if (current_interface == last_interface) { done = true; } else { endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->interfaces[current_interface]); if (USB_INTERFACE_DESCRIPTOR_LENGTH >= (length - sent)) { endpoint->buffer_size = length - sent; done = true; } else { endpoint->buffer_size = USB_INTERFACE_DESCRIPTOR_LENGTH; sent += USB_INTERFACE_DESCRIPTOR_LENGTH; // Note that an interface with zero endpoints is ok. We'll just move // to the next interface in the next call. last_endpoint = current_endpoint + endpoint->enumeration_data->interfaces[current_interface].number_endpoints; current_interface++; } } } else { // The next transfer should be a single endpoint. The // endpoints are actually contiguous array elements // but may not be packed, so they have to be transferred // one at a time. endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->endpoints[current_endpoint]); if ((sent + USB_ENDPOINT_DESCRIPTOR_LENGTH) >= length) { endpoint->buffer_size = length - sent; done = true; } else { endpoint->buffer_size = USB_ENDPOINT_DESCRIPTOR_LENGTH; current_endpoint ++; } } if (done) { endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0; } else { req->type = (unsigned char) current_interface; req->value_lo = (unsigned char) current_endpoint; req->value_hi = (unsigned char) last_endpoint; req->index_hi = (unsigned char) (sent >> 8); req->index_lo = (unsigned char) (sent & 0x00FF); }}usbs_control_returnusbs_handle_standard_control(usbs_control_endpoint* endpoint){ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN; usb_devreq* req = (usb_devreq*) endpoint->control_buffer; int length; int direction; int recipient; length = (req->length_hi << 8) | req->length_lo; direction = req->type & USB_DEVREQ_DIRECTION_MASK; recipient = req->type & USB_DEVREQ_RECIPIENT_MASK; if (USB_DEVREQ_CLEAR_FEATURE == req->request) { if (USB_DEVREQ_RECIPIENT_INTERFACE == recipient) { // The host should expect no data back, the device must // be configured, and there are no defined features to clear. if ((0 == length) && (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK)) && (0 == req->value_lo)) { int interface_id = req->index_lo; CYG_ASSERT( 1 == endpoint->enumeration_data->total_number_interfaces, \ "Higher level code should have handled this request"); if (interface_id == endpoint->enumeration_data->interfaces[0].interface_id) { result = USBS_CONTROL_RETURN_HANDLED; } else { result = USBS_CONTROL_RETURN_STALL; } } else { result = USBS_CONTROL_RETURN_STALL; } } } else if (USB_DEVREQ_GET_CONFIGURATION == req->request) { // Return a single byte 0 if the device is not currently // configured. Otherwise assume a single configuration // in the enumeration data and return its id. if ((1 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) { if (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK)) { CYG_ASSERT( 1 == endpoint->enumeration_data->device.number_configurations, \ "Higher level code should have handled this request"); endpoint->control_buffer[0] = endpoint->enumeration_data->configurations[0].configuration_id; } else { endpoint->control_buffer[0] = 0; } endpoint->buffer = endpoint->control_buffer; endpoint->buffer_size = 1; endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0; endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0; result = USBS_CONTROL_RETURN_HANDLED; } else { result = USBS_CONTROL_RETURN_STALL; } } else if (USB_DEVREQ_GET_DESCRIPTOR == req->request) { // The descriptor type is in value_hi. The descriptor index // is in value_lo.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -