//! @brief This function selects (and resets) the interface alternate setting //! //! @param wInterface Interface selected //! @param alternate_setting alternate setting selected //! void usb_user_interface_reset(U16 wInterface, U8 alternate_setting) { // default setting selected = reset data toggle if( INTERFACE_NB == wInterface ) { // Interface Mass Storage Usb_select_endpoint(EP_MS_IN); Usb_disable_stall_handshake(); Usb_reset_endpoint(EP_MS_IN); Usb_reset_data_toggle(); Usb_select_endpoint(EP_MS_OUT); Usb_disable_stall_handshake(); Usb_reset_endpoint(EP_MS_OUT); Usb_reset_data_toggle(); } }
//! usb_clear_feature. //! //! This function manages the SET FEATURE request. //! //! @warning Code:xx bytes (function code length) //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; U8 dummy; if (bmRequestType == ZERO_TYPE) { return; } else if (bmRequestType == INTERFACE_TYPE) { return; } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_byte(); dummy = Usb_read_byte(); //!< dummy read if (wValue == FEATURE_ENDPOINT_HALT) { wIndex = (Usb_read_byte() & MSK_EP_DIR); Usb_select_endpoint(wIndex); if(Is_usb_endpoint_enabled()) { if(wIndex != EP_CONTROL) { Usb_disable_stall_handshake(); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(); } Usb_select_endpoint(EP_CONTROL); endpoint_status[wIndex] = 0x00; Usb_ack_receive_setup(); Usb_send_control_in(); } else { return; } } else { return; } } }
//! This function manages the CLEAR FEATURE request. //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; switch (bmRequestType) { #if (USB_REMOTE_WAKEUP_FEATURE == true) case USB_SETUP_SET_STAND_DEVICE: wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue != FEATURE_DEVICE_REMOTE_WAKEUP) break; // Invalid request device_status &= ~USB_DEV_STATUS_REMOTEWAKEUP; remote_wakeup_feature = false; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; #endif case USB_SETUP_SET_STAND_INTERFACE: break; case USB_SETUP_SET_STAND_ENDPOINT: wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue != FEATURE_ENDPOINT_HALT) break; Usb_read_endpoint_data(EP_CONTROL, 8); //!< dummy read (MSB of wValue) wIndex = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = Get_desc_ep_nbr(wIndex); if (!Is_usb_endpoint_enabled(wIndex)) break; if (wIndex != EP_CONTROL) { Usb_disable_stall_handshake(wIndex); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(wIndex); } Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; default: break; } Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); }
//! This function manages the CLEAR FEATURE request. //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; if (bmRequestType == DEVICE_TYPE || bmRequestType == INTERFACE_TYPE) { //!< keep that order (set StallRq/clear RxSetup) or a //!< OUT request following the SETUP may be acknowledged Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_endpoint_data(EP_CONTROL, 8); if (wValue == FEATURE_ENDPOINT_HALT) { Usb_read_endpoint_data(EP_CONTROL, 8); //!< dummy read (MSB of wValue) wIndex = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = Get_desc_ep_nbr(wIndex); if (Is_usb_endpoint_enabled(wIndex)) { if (wIndex != EP_CONTROL) { Usb_disable_stall_handshake(wIndex); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(wIndex); } endpoint_status[wIndex] = 0; // Halt feature flag Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); } else { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } } else { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); } } }
//! This function manages the SET INTERFACE request. //! void usb_set_interface(void) { U8 u8_i; // wValue = Alternate Setting // wIndex = Interface U16 wValue = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); U16 wIndex = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); Usb_ack_setup_received_free(); // Get descriptor #if (USB_HIGH_SPEED_SUPPORT==true) if( Is_usb_full_speed_mode() ) { data_to_transfer = Usb_get_conf_desc_fs_length(); //!< sizeof(usb_conf_desc_fs); pbuffer = Usb_get_conf_desc_fs_pointer(); }else{ data_to_transfer = Usb_get_conf_desc_hs_length(); //!< sizeof(usb_conf_desc_hs); pbuffer = Usb_get_conf_desc_hs_pointer(); } #else data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof(usb_conf_desc); pbuffer = Usb_get_conf_desc_pointer(); #endif //** Scan descriptor //* Find configuration selected if( usb_configuration_nb == 0 ) { // No configuration selected then no interface enable Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } u8_i = usb_configuration_nb; while( u8_i != 0 ) { if( CONFIGURATION_DESCRIPTOR != ((S_usb_configuration_descriptor*)pbuffer)->bDescriptorType ) { data_to_transfer -= ((S_usb_configuration_descriptor*)pbuffer)->bLength; pbuffer = (U8*)pbuffer + ((S_usb_configuration_descriptor*)pbuffer)->bLength; continue; } u8_i--; if( u8_i != 0 ) { data_to_transfer -= ((S_usb_configuration_descriptor*)pbuffer)->wTotalLength; pbuffer = (U8*)pbuffer + ((S_usb_configuration_descriptor*)pbuffer)->wTotalLength; } } // Find interface selected if( wIndex >= ((S_usb_configuration_descriptor*)pbuffer)->bNumInterfaces ) { // Interface number unknown Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } while( 1 ) { if( data_to_transfer <= ((S_usb_interface_descriptor*)pbuffer)->bLength ) { // Interface unknown Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } data_to_transfer -= ((S_usb_interface_descriptor*)pbuffer)->bLength; pbuffer = (U8*)pbuffer + ((S_usb_interface_descriptor*)pbuffer)->bLength; if( INTERFACE_DESCRIPTOR != ((S_usb_interface_descriptor*)pbuffer)->bDescriptorType ) continue; if( wIndex != ((S_usb_interface_descriptor*)pbuffer)->bInterfaceNumber ) continue; if( wValue != ((S_usb_interface_descriptor*)pbuffer)->bAlternateSetting ) continue; usb_interface_status[wIndex] = wValue; break; } //* Find endpoints of interface and reset it while( 1 ) { if( data_to_transfer <= ((S_usb_endpoint_descriptor*)pbuffer)->bLength ) break; // End of interface data_to_transfer -= ((S_usb_endpoint_descriptor*)pbuffer)->bLength; pbuffer = (U8*)pbuffer + ((S_usb_endpoint_descriptor*)pbuffer)->bLength; if( INTERFACE_DESCRIPTOR == ((S_usb_endpoint_descriptor*)pbuffer)->bDescriptorType ) break; // End of interface if( ENDPOINT_DESCRIPTOR == ((S_usb_endpoint_descriptor*)pbuffer)->bDescriptorType ) { // Reset endpoint u8_i = ((S_usb_endpoint_descriptor*)pbuffer)->bEndpointAddress & (~MSK_EP_DIR); Usb_disable_stall_handshake(u8_i); Usb_reset_endpoint(u8_i); Usb_reset_data_toggle(u8_i); } } // send a ZLP for STATUS phase Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); }
//! usb_clear_feature. //! //! This function manages the SET FEATURE request. //! //! @warning Code:xx bytes (function code length) //! //! @param none //! //! @return none //! void usb_clear_feature(void) { U8 wValue; U8 wIndex; U8 dummy; if (bmRequestType == ZERO_TYPE) { //!< keep that order (set StallRq/clear RxSetup) or a //!< OUT request following the SETUP may be acknowledged Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } else if (bmRequestType == INTERFACE_TYPE) { //!< keep that order (set StallRq/clear RxSetup) or a //!< OUT request following the SETUP may be acknowledged Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } else if (bmRequestType == ENDPOINT_TYPE) { wValue = Usb_read_byte(); dummy = Usb_read_byte(); //!< dummy read if (wValue == FEATURE_ENDPOINT_HALT) { wIndex = (Usb_read_byte() & MSK_EP_DIR); Usb_select_endpoint(wIndex); if(Is_usb_endpoint_enabled()) { if(wIndex != EP_CONTROL) { Usb_disable_stall_handshake(); Usb_reset_endpoint(wIndex); Usb_reset_data_toggle(); } Usb_select_endpoint(EP_CONTROL); endpoint_status[wIndex] = 0x00; Usb_ack_receive_setup(); Usb_send_control_in(); } else { Usb_select_endpoint(EP_CONTROL); Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } } else { Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } } }