//! This function is called by the standard USB read request function when //! the USB request is not supported. This function returns true when the //! request is processed. This function returns false if the request is not //! supported. In this case, a STALL handshake will be automatically //! sent by the standard USB read request function. //! bool usb_user_read_request(U8 type, U8 request) { Usb_read_endpoint_data(EP_CONTROL, 8); // string_type Usb_read_endpoint_data(EP_CONTROL, 8); // descriptor_type switch (request) { #if( EVK1101_CTRL_PANEL_PID==EVK1101_CTRL_PANEL_DEMO_HID_MS_PID ) case MASS_STORAGE_RESET: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return true; case GET_MAX_LUN: Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, get_nb_lun() - 1); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); while(!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); ms_multiple_drive = true; return true; #endif /* case HID_SET_REPORT: switch (descriptor_type) { case HID_REPORT_OUTPUT: Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); return true; default: break; } break; case HID_SET_IDLE: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); return true; */ default: break; } return false; }
//! This function manages the HID Get_Descriptor request. //! static void hid_get_descriptor(U8 size_of_report, const U8* p_usb_hid_report) { bool zlp; U16 wIndex; U16 wLength; zlp = false; /* no zero length packet */ data_to_transfer = size_of_report; pbuffer = p_usb_hid_report; wIndex = Usb_read_endpoint_data(EP_CONTROL, 16); wIndex = usb_format_usb_to_mcu_data(16, wIndex); wLength = Usb_read_endpoint_data(EP_CONTROL, 16); wLength = usb_format_usb_to_mcu_data(16, wLength); Usb_ack_setup_received_free(); //!< clear the setup received flag if (wLength > data_to_transfer) { zlp = !(data_to_transfer % EP_CONTROL_LENGTH); //!< zero length packet condition } else { data_to_transfer = wLength; //!< send only requested number of data bytes } Usb_ack_nak_out(EP_CONTROL); while (data_to_transfer && (!Is_usb_nak_out(EP_CONTROL))) { while( !Is_usb_control_in_ready() && !Is_usb_nak_out(EP_CONTROL) ); if( Is_usb_nak_out(EP_CONTROL) ) break; // don't clear the flag now, it will be cleared after Usb_reset_endpoint_fifo_access(EP_CONTROL); data_to_transfer = usb_write_ep_txpacket(EP_CONTROL, pbuffer, data_to_transfer, &pbuffer); if( Is_usb_nak_out(EP_CONTROL) ) break; else Usb_ack_control_in_ready_send(); //!< Send data until necessary } if ( zlp && (!Is_usb_nak_out(EP_CONTROL)) ) { while (!Is_usb_control_in_ready()); Usb_ack_control_in_ready_send(); } while (!(Is_usb_nak_out(EP_CONTROL))); Usb_ack_nak_out(EP_CONTROL); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
//! This function is called by the standard USB read request function when //! the USB request is not supported. This function returns true when the //! request is processed. This function returns false if the request is not //! supported. In this case, a STALL handshake will be automatically //! sent by the standard USB read request function. //! bool usb_user_read_request(uint8_t type, uint8_t request) { uint16_t wInterface; uint8_t wValue_msb; uint8_t wValue_lsb; wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8); wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8); //** Specific request from Class MassStorage if( USB_SETUP_SET_CLASS_INTER == type ) { switch( request ) { case MASS_STORAGE_RESET: // wValue must be 0 // wIndex = Interface if( (0!=wValue_lsb) || (0!=wValue_msb) ) break; wInterface=Usb_read_endpoint_data(EP_CONTROL, 16); if( INTERFACE_NB != wInterface ) break; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return true; } } if( USB_SETUP_GET_CLASS_INTER == type ) { switch( request ) { case GET_MAX_LUN: // wValue must be 0 // wIndex = Interface if( (0!=wValue_lsb) || (0!=wValue_msb) ) break; wInterface=Usb_read_endpoint_data(EP_CONTROL, 16); if( INTERFACE_NB != wInterface ) break; Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, get_nb_lun() - 1); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); while(!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); ms_multiple_drive = true; return true; } } return false; }
//! @brief This function manages hit set report request. //! static void usb_hid_set_report_ouput (void) { //Usb_ack_receive_setup(); Usb_ack_setup_received_free(); //Usb_send_control_in(); Usb_ack_control_in_ready_send(); //while(!Is_usb_receive_out()); while (!Is_usb_control_out_received()); //Usb_ack_receive_out(); Usb_ack_control_out_received_free(); //Usb_send_control_in(); Usb_ack_control_in_ready_send(); }
//! 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(); }
//******* Speaker control void audio_speaker_set_mute(void) { while(!Is_usb_control_out_received()) { TASKS_SCHEDULE(); } Usb_reset_endpoint_fifo_access(EP_CONTROL); b_speaker_mute=Usb_read_endpoint_data(EP_CONTROL, 8); audio_mixer_mute_audio(b_speaker_mute); if( b_speaker_mute ) { audio_mixer_dacs_set_volume_direct((uint8_t)SPEAKER_VOL_MIN); } else { audio_mixer_dacs_set_volume_direct(s16_speaker_volume); } Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); // send a ZLP while (!Is_usb_control_in_ready()) { TASKS_SCHEDULE(); } }
void audio_speaker_set_volume(void) { while(!Is_usb_control_out_received()) { TASKS_SCHEDULE(); } Usb_reset_endpoint_fifo_access(EP_CONTROL); LSB(s16_usb_speaker_volume)=Usb_read_endpoint_data(EP_CONTROL, 8); MSB(s16_usb_speaker_volume)=Usb_read_endpoint_data(EP_CONTROL, 8); // Convert USB range volume into the volume range of the application. s16_speaker_volume = volume_usb_to_appli(s16_usb_speaker_volume) ; Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); // send a ZLP // Ensures good limits of the parameter s16_speaker_volume = min( s16_speaker_volume, SPEAKER_VOL_MAX); s16_speaker_volume = max( s16_speaker_volume, SPEAKER_VOL_MIN); audio_mixer_dacs_set_volume_direct(s16_speaker_volume); while (!Is_usb_control_in_ready()) { TASKS_SCHEDULE(); } }
//! This function manages the GET INTERFACE request. //! void usb_get_interface(void) { Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); //!< send a ZLP for STATUS phase while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
void usb_hid_set_report_feature(void) { Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send();// send a ZLP while(!Is_usb_control_out_received()); if(Usb_read_endpoint_data(EP_CONTROL, 8)==0x55) if(Usb_read_endpoint_data(EP_CONTROL, 8)==0xAA) if(Usb_read_endpoint_data(EP_CONTROL, 8)==0x55) if(Usb_read_endpoint_data(EP_CONTROL, 8)==0xAA) { jump_bootloader=1; // Specific Request with 0x55AA55AA code } Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); //!< send a ZLP for STATUS phase while(!Is_usb_control_in_ready()); }
void audio_speaker_get_vol_max(void) { Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 16, Usb_format_mcu_to_usb_data(16, USB_SPEAKER_VOL_MAX)); Usb_ack_control_in_ready_send(); while(!Is_usb_control_out_received()) // send a ZLP { TASKS_SCHEDULE(); } Usb_ack_control_out_received_free(); }
//! This function manages the GET CONFIGURATION request. The current //! configuration number is returned. //! void usb_get_configuration(void) { Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, usb_configuration_nb); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
void audio_micro_get_vol_res(void) { Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 16, Usb_format_mcu_to_usb_data(16, MICRO_VOL_RES)); Usb_ack_control_in_ready_send(); while(!Is_usb_control_out_received()) // send a ZLP { TASKS_SCHEDULE(); } Usb_ack_control_out_received_free(); }
void audio_micro_get_mute(void) { Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, b_micro_mute); Usb_ack_control_in_ready_send(); while(!Is_usb_control_out_received()) // send a ZLP { TASKS_SCHEDULE(); } Usb_ack_control_out_received_free(); }
//! This function manages the SET ADDRESS request. When complete, the device //! will filter the requests using the new address. //! void usb_set_address(void) { U8 addr = Usb_read_endpoint_data(EP_CONTROL, 8); Usb_configure_address(addr); Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); //!< send a ZLP for STATUS phase while (!Is_usb_control_in_ready()); //!< waits for status phase done //!< before using the new address Usb_enable_address(); }
//! void usb_hid_set_idle (U8 u8_report_id, U8 u8_duration ) { U16 wInterface; // Get interface number to put in idle mode wInterface=Usb_read_endpoint_data(EP_CONTROL, 16); Usb_ack_setup_received_free(); if( wInterface == INTERFACE_NB ) g_u8_report_rate = u8_duration; Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); }
static void usb_hid_set_idle (uint8_t u8_report_id, uint8_t u8_duration ) { uint16_t wInterface; // Get interface number to put in idle mode wInterface=usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); Usb_ack_setup_received_free(); if( wInterface == INTERFACE_NB_KBD ) g_u8_report_rate = u8_duration; Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); }
//******* Micro control void audio_micro_set_mute(void) { while(!Is_usb_control_out_received()) { TASKS_SCHEDULE(); } Usb_reset_endpoint_fifo_access(EP_CONTROL); b_micro_mute=Usb_read_endpoint_data(EP_CONTROL, 8); Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); // send a ZLP while (!Is_usb_control_in_ready()) { TASKS_SCHEDULE(); } }
void cdc_set_line_coding (void) { Usb_ack_setup_received_free(); while(!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); LSB0(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8); LSB1(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8); LSB2(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8); LSB3(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8); line_coding.bCharFormat = Usb_read_endpoint_data(EP_CONTROL, 8); line_coding.bParityType = Usb_read_endpoint_data(EP_CONTROL, 8); line_coding.bDataBits = Usb_read_endpoint_data(EP_CONTROL, 8); Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); // Set the baudrate of the USART { static usart_options_t dbg_usart_options; uint32_t stopbits, parity; if ( line_coding.bCharFormat==0 ) stopbits = USART_1_STOPBIT; else if( line_coding.bCharFormat==1 ) stopbits = USART_1_5_STOPBITS; else stopbits = USART_2_STOPBITS; if ( line_coding.bParityType==0 ) parity = USART_NO_PARITY; else if( line_coding.bParityType==1 ) parity = USART_ODD_PARITY; else if( line_coding.bParityType==2 ) parity = USART_EVEN_PARITY; else if( line_coding.bParityType==3 ) parity = USART_MARK_PARITY; else parity = USART_SPACE_PARITY; // Options for debug USART. dbg_usart_options.baudrate = line_coding.dwDTERate; dbg_usart_options.charlength = line_coding.bDataBits; dbg_usart_options.paritytype = parity; dbg_usart_options.stopbits = stopbits; dbg_usart_options.channelmode = USART_NORMAL_CHMODE; // Initialize it in RS232 mode. usart_init_rs232(DBG_USART, &dbg_usart_options, pcl_freq_param.pba_f); // Enable Rx interrupts DBG_USART->ier = AVR32_USART_IER_RXRDY_MASK; } }
//! 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(); } } }
//! @brief This function manages hid get idle request. //! //! @param u8_report_id 0 the idle rate applies to all input reports, else only applies to the Report ID //! void usb_hid_get_idle (U8 u8_report_id) { U16 wLength; U16 wInterface; // Get interface number to put in idle mode wInterface=Usb_read_endpoint_data(EP_CONTROL, 16); wLength =Usb_read_endpoint_data(EP_CONTROL, 16); Usb_ack_setup_received_free(); if( (wLength != 0) && (wInterface == INTERFACE_NB) ) { Usb_write_endpoint_data(EP_CONTROL, 8, g_u8_report_rate); Usb_ack_control_in_ready_send(); } while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
void cdc_get_line_coding(void) { Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, LSB0(line_coding.dwDTERate)); Usb_write_endpoint_data(EP_CONTROL, 8, LSB1(line_coding.dwDTERate)); Usb_write_endpoint_data(EP_CONTROL, 8, LSB2(line_coding.dwDTERate)); Usb_write_endpoint_data(EP_CONTROL, 8, LSB3(line_coding.dwDTERate)); Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bCharFormat); Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bParityType); Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bDataBits ); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); while(!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
//! @brief This function manages hid get idle request. //! //! @param u8_report_id 0 the idle rate applies to all input reports, else only applies to the Report ID //! static void usb_hid_get_idle (uint8_t u8_report_id) { uint16_t wLength; uint16_t wInterface; // Get interface number to put in idle mode wInterface=usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); wLength =usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); Usb_ack_setup_received_free(); if( (wLength != 0) && (wInterface == INTERFACE_NB_KBD) ) { Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, g_u8_report_rate); Usb_ack_control_in_ready_send(); } while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
//! This function manages the SET CONFIGURATION request. If the selected //! configuration is valid, this function call the usb_user_endpoint_init() //! function that will configure the endpoints following the configuration //! number. //! void usb_set_configuration(void) { U8 configuration_number = Usb_read_endpoint_data(EP_CONTROL, 8); if (configuration_number <= NB_CONFIGURATION) { Usb_ack_setup_received_free(); usb_configuration_nb = configuration_number; Usb_ack_control_in_ready_send(); //!< send a ZLP for STATUS phase usb_user_endpoint_init(usb_configuration_nb); //!< endpoint configuration Usb_set_configuration_action(); } else { //!< 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(); } }
//! This function manages the GET STATUS request. The device, interface or //! endpoint status is returned. //! void usb_get_status(void) { U8 wIndex; switch (bmRequestType) { case REQUEST_DEVICE_STATUS: Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, device_status); break; case REQUEST_INTERFACE_STATUS: Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, INTERFACE_STATUS); break; case REQUEST_ENDPOINT_STATUS: Usb_read_endpoint_data(EP_CONTROL, 16); //!< dummy read (wValue) wIndex = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = Get_desc_ep_nbr(wIndex); Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, Is_usb_endpoint_stall_requested(wIndex) ); break; default: Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); }
//! This function manages the SETUP_GET_INTERFACE request. //! bool usb_get_interface (void) { U16 wInterface; U16 wValue; // Read wValue wValue = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); // wValue = Alternate Setting // wIndex = Interface wInterface=usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); if(0!=wValue) return false; Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, usb_interface_status[wInterface] ); Usb_ack_control_in_ready_send(); while( !Is_usb_control_out_received() ); Usb_ack_control_out_received_free(); return true; }
void audio_speaker_set_sample_freq(void) { uint32_t sample_freq=0; Usb_ack_setup_received_free(); while(!Is_usb_control_out_received()) { TASKS_SCHEDULE(); } Usb_reset_endpoint_fifo_access(EP_CONTROL); LSB0(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8); LSB1(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8); LSB2(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8); Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); // send a ZLP while (!Is_usb_control_in_ready()) { TASKS_SCHEDULE(); } #if (defined BOARD) && (BOARD==EVK1105) && (defined DEFAULT_DACS) && (DEFAULT_DACS==AUDIO_MIXER_DAC_AIC23B) // Disable microphone callback interrupt in order for the flush to not be blocked. // TODO: audio_mixer_dacs_flush_direct flushes Rx and Tw part of the DAC. // Should we separate them? Here, we want to flash the output only. device_audio_disable_microphone(); #endif audio_mixer_dacs_flush_direct(false); usb_stream_init( sample_freq , 2 , 16 , false ); #if (defined BOARD) && (BOARD==EVK1105) && (defined DEFAULT_DACS) && (DEFAULT_DACS==AUDIO_MIXER_DAC_AIC23B) // Enable microphone call back interrupts. device_audio_enable_microphone(); #endif }
//! 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()); }
//! This function manages the SET FEATURE request. The USB test modes are //! supported by this function. //! void usb_set_feature(void) { 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)); U16 wLength = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16)); if (wLength) goto unsupported_request; if (bmRequestType==USB_SETUP_SET_STAND_DEVICE) { #if (USB_REMOTE_WAKEUP_FEATURE == true) if (FEATURE_DEVICE_REMOTE_WAKEUP == wValue) { device_status |= USB_DEV_STATUS_REMOTEWAKEUP; remote_wakeup_feature = true; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); return; } #endif goto unsupported_request; } switch (wValue) { case FEATURE_ENDPOINT_HALT: wIndex = Get_desc_ep_nbr(wIndex); // clear direction flag if (bmRequestType != ENDPOINT_TYPE || wIndex == EP_CONTROL || !Is_usb_endpoint_enabled(wIndex)) goto unsupported_request; Usb_enable_stall_handshake(wIndex); Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); break; #if (USB_HIGH_SPEED_SUPPORT==true) case FEATURE_TEST_MODE: if (bmRequestType != DEVICE_TYPE || wIndex & 0x00FF) goto unsupported_request; switch (wIndex >> 8) { case TEST_J: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTJ_MASK); break; case TEST_K: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTK_MASK); break; case TEST_SE0_NAK: Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); break; case TEST_PACKET: { static const U8 test_packet[] = { // 00000000 * 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 01010101 * 8 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // 01110111 * 8 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, // 0, {111111S * 15}, 111111 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // S, 111111S, {0111111S * 7} 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, // 00111111, {S0111111 * 9}, S0 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E }; Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2); Usb_disable_endpoint(EP_CONTROL); Usb_unallocate_memory(EP_CONTROL); (void)Usb_configure_endpoint(EP_CONTROL, TYPE_BULK, DIRECTION_IN, 64, SINGLE_BANK); Usb_reset_endpoint(EP_CONTROL); Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTPCKT_MASK); usb_write_ep_txpacket(EP_CONTROL, &test_packet, sizeof(test_packet), NULL); Usb_send_in(EP_CONTROL); } break; case TEST_FORCE_ENABLE: // Only for downstream facing hub ports default: goto unsupported_request; } break; #endif case FEATURE_DEVICE_REMOTE_WAKEUP: default: goto unsupported_request; } return; unsupported_request: Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); }
//! This function is called by the standard USB read request function when //! the USB request is not supported. This function returns true when the //! request is processed. This function returns false if the request is not //! supported. In this case, a STALL handshake will be automatically //! sent by the standard USB read request function. //! bool usb_user_read_request(U8 type, U8 request) { U8 wValue_msb; U8 wValue_lsb; // Read wValue wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8); wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8); /* U8 descriptor_type; Usb_read_endpoint_data(EP_CONTROL, 8); // string_type descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8); */ //** Specific request from Class HID if( 0x81 == type ) // USB_SETUP_GET_STAND_INTERFACE { switch( request ) { case GET_DESCRIPTOR: switch( wValue_msb ) // Descriptor ID { #if (USB_HIGH_SPEED_SUPPORT==false) case HID_DESCRIPTOR: hid_get_descriptor( sizeof(usb_conf_desc_fs.hid) , (const U8*)&usb_conf_desc_fs.hid); return true; #else case HID_DESCRIPTOR: if( Is_usb_full_speed_mode() ) { hid_get_descriptor( sizeof(usb_conf_desc_fs.hid) , (const U8*)&usb_conf_desc_fs.hid); }else{ hid_get_descriptor( sizeof(usb_conf_desc_hs.hid_mouse) , (const U8*)&usb_conf_desc_hs.hid); } return true; #endif case HID_REPORT_DESCRIPTOR: hid_get_descriptor( sizeof(usb_hid_report_descriptor) , usb_hid_report_descriptor); return true; case HID_PHYSICAL_DESCRIPTOR: // TODO break; } break; } } if( 0x21 == type ) // USB_SETUP_SET_CLASS_INTER { switch( request ) { case HID_SET_REPORT: // The MSB wValue field specifies the Report Type // The LSB wValue field specifies the Report ID switch (wValue_msb) { case HID_REPORT_INPUT: // TODO break; case HID_REPORT_OUTPUT: Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); return true; case HID_REPORT_FEATURE: usb_hid_set_report_feature(); return true; break; } break; case HID_SET_IDLE: usb_hid_set_idle(wValue_lsb, wValue_msb); return true; case HID_SET_PROTOCOL: // TODO break; } } if( 0xA1 == type ) // USB_SETUP_GET_CLASS_INTER { switch( request ) { case HID_GET_REPORT: // TODO break; case HID_GET_IDLE: usb_hid_get_idle(wValue_lsb); return true; case HID_GET_PROTOCOL: // TODO break; } } return false; // No supported request }
void cdc_set_control_line_state (void) { Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); while (!Is_usb_control_in_ready()); }