//! 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(); }
//******* 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 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 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; }
//! 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; } }
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 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(); }
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 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 }
//! This function manages the GET DESCRIPTOR request. The device descriptor, //! the configuration descriptor and the device qualifier are supported. All //! other descriptors must be supported by the usb_user_get_descriptor //! function. //! Only 1 configuration is supported. //! void usb_get_descriptor(void) { Bool zlp; U16 wLength; U8 descriptor_type; U8 string_type; Union32 temp; zlp = FALSE; /* no zero length packet */ string_type = Usb_read_endpoint_data(EP_CONTROL, 8); /* read LSB of wValue */ descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8); /* read MSB of wValue */ switch (descriptor_type) { case DEVICE_DESCRIPTOR: data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof(usb_dev_desc); pbuffer = Usb_get_dev_desc_pointer(); break; case CONFIGURATION_DESCRIPTOR: data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof(usb_conf_desc); pbuffer = Usb_get_conf_desc_pointer(); break; default: if (!usb_user_get_descriptor(descriptor_type, string_type)) { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } break; } temp.u32 = Usb_read_endpoint_data(EP_CONTROL, 32); //!< read wIndex and wLength with a 32-bit access //!< since this access is aligned with a 32-bit //!< boundary from the beginning of the endpoint wLength = usb_format_usb_to_mcu_data(16, temp.u16[1]); //!< ignore wIndex, keep and format 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 { // No need to test ZLP sending since we send the exact number of bytes as // expected by the host. data_to_transfer = (U8)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 manages the SET INTERFACE request. //! void usb_set_interface(void) { Usb_ack_setup_received_free(); Usb_ack_control_in_ready_send(); //!< send a ZLP for STATUS phase while (!Is_usb_control_in_ready()); }
//! 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 uac2_user_read_request(U8 type, U8 request) { int i; // Read wValue // why are these file statics? wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8); wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8); wIndex = 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)); if (type == IN_CL_INTERFACE || type == OUT_CL_INTERFACE){ // process Class Specific Interface // request for AUDIO interfaces if (wIndex == DSC_INTERFACE_AS){ // Audio Streaming Interface if (type == IN_CL_INTERFACE){ // get controls if (wValue_msb == AUDIO_AS_VAL_ALT_SETTINGS && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, 0x01); Usb_write_endpoint_data(EP_CONTROL, 8, 0b00000011); // alt 0 and 1 valid Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, usb_alternate_setting); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_AS_AUDIO_DATA_FORMAT && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, 0x01); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); // only PCM format Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else return FALSE; } else if (type == OUT_CL_INTERFACE){ // set controls if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); usb_alternate_setting = Usb_read_endpoint_data(EP_CONTROL, 8); usb_alternate_setting_changed = TRUE; Usb_ack_control_out_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 return FALSE; } } // end OUT_CL_INTERFACE } // end DSC_INTERFACE_AS if (wIndex == DSC_INTERFACE_AS_OUT){ // Playback Audio Streaming Interface if (type == IN_CL_INTERFACE){ // get controls if (wValue_msb == AUDIO_AS_VAL_ALT_SETTINGS && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, 0x01); Usb_write_endpoint_data(EP_CONTROL, 8, 0b00000011); // alt 0 and 1 valid Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, usb_alternate_setting_out); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_AS_AUDIO_DATA_FORMAT && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, 0x01); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); // only PCM format Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else return FALSE; } else if (type == OUT_CL_INTERFACE){ // set controls if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); usb_alternate_setting_out = Usb_read_endpoint_data(EP_CONTROL, 8); usb_alternate_setting_out_changed = TRUE; Usb_ack_control_out_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 return FALSE; } } // end OUT_CL_INTERFACE } // end DSC_INTERFACE_AS_OUT if ( (wIndex % 256) == DSC_INTERFACE_AUDIO){// low byte wIndex is Interface number // high byte is for EntityID if (type == IN_CL_INTERFACE){ // get controls switch (wIndex /256){ case CSD_ID_1: if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[3]); // 0x0000bb80 is 48khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[2]); // 0x00017700 is 96khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[1]); // 0x0002ee00 is 192khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[0]); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_CS_CONTROL_CLOCK_VALID && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, TRUE); // always valid // temp hack to give total # of bytes requested for (i = 0; i < (wLength - 1); i++) 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(); return TRUE; } else if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_RANGE){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); // give total # of bytes requested for (i = 0; i < (wLength); i++){ if (FEATURE_DAC_ES9022) Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_1[i]); else Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_2[i]); } Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else return FALSE; case CSD_ID_2: if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[3]); // 0x0000bb80 is 48khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[2]); // 0x00017700 is 96khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[1]); // 0x0002ee00 is 192khz Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[0]); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else if (wValue_msb == AUDIO_CS_CONTROL_CLOCK_VALID && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, TRUE); // always valid // temp hack to give total # of bytes requested for (i = 0; i < (wLength - 1); i++) 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(); return TRUE; } else if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_RANGE){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); // give total # of bytes requested for (i = 0; i < (wLength); i++) Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_2[i]); // LED_Toggle(LED0); Usb_ack_control_in_ready_send(); while (!Is_usb_control_out_received()); Usb_ack_control_out_received_free(); return TRUE; } else return FALSE; case CSX_ID: if (wValue_msb == AUDIO_CX_CLOCK_SELECTOR && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, clock_selected); // temp hack to give total # of bytes requested for (i = 0; i < (wLength - 1); i++) 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(); return TRUE; } else return FALSE; case MIC_FEATURE_UNIT_ID: if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, mute); // temp hack to give total # of bytes requested for (i = 0; i < (wLength - 1); i++) 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(); return TRUE; } else return FALSE; case SPK_FEATURE_UNIT_ID: if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); Usb_write_endpoint_data(EP_CONTROL, 8, spk_mute); // temp hack to give total # of bytes requested for (i = 0; i < (wLength - 1); i++) 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(); return TRUE; } else return FALSE; case INPUT_TERMINAL_ID: if (wValue_msb == AUDIO_TE_CONTROL_CS_CLUSTER && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); if (usb_alternate_setting == 1) { Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_NB_CHANNELS); Usb_write_endpoint_data(EP_CONTROL, 8, (U8) INPUT_TERMINAL_CHANNEL_CONF); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_STRING_DESC); } else { // zero's at startup alt setting 0 Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); 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(); return TRUE; } else return FALSE; case SPK_INPUT_TERMINAL_ID: if (wValue_msb == AUDIO_TE_CONTROL_CS_CLUSTER && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); Usb_reset_endpoint_fifo_access(EP_CONTROL); if (usb_alternate_setting_out == 1) { Usb_write_endpoint_data(EP_CONTROL, 8, SPK_INPUT_TERMINAL_NB_CHANNELS); Usb_write_endpoint_data(EP_CONTROL, 8, (U8) SPK_INPUT_TERMINAL_CHANNEL_CONF); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_STRING_DESC); } else { // zero's at startup alt setting 0 Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); Usb_write_endpoint_data(EP_CONTROL, 8, 0x00); 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(); return TRUE; } else return FALSE; default: return FALSE; } // end switch EntityID } else if (type == OUT_CL_INTERFACE){ // set controls switch (wIndex /256){ case CSD_ID_1: // set CUR freq case CSD_ID_2: if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); current_freq.freq_bytes[3]=Usb_read_endpoint_data(EP_CONTROL, 8); // read 4 bytes freq to set current_freq.freq_bytes[2]=Usb_read_endpoint_data(EP_CONTROL, 8); current_freq.freq_bytes[1]=Usb_read_endpoint_data(EP_CONTROL, 8); current_freq.freq_bytes[0]=Usb_read_endpoint_data(EP_CONTROL, 8); freq_changed = TRUE; Usb_ack_control_out_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 return TRUE; } else return FALSE; case CSX_ID: if (wValue_msb == AUDIO_CX_CLOCK_SELECTOR && wValue_lsb == 0 && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); clock_selected = Usb_read_endpoint_data(EP_CONTROL, 8); clock_changed = TRUE; Usb_ack_control_out_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 if (clock_selected < 1 || clock_selected > CSX_INPUT_PINS) clock_selected = 1; return TRUE; } else return FALSE; case MIC_FEATURE_UNIT_ID: if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); mute = Usb_read_endpoint_data(EP_CONTROL, 8); Usb_ack_control_out_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 return TRUE; } else return FALSE; case SPK_FEATURE_UNIT_ID: if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE && request == AUDIO_CS_REQUEST_CUR){ Usb_ack_setup_received_free(); while (!Is_usb_control_out_received()); Usb_reset_endpoint_fifo_access(EP_CONTROL); spk_mute = Usb_read_endpoint_data(EP_CONTROL, 8); Usb_ack_control_out_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 return TRUE; } else return FALSE; default: return FALSE; } } // end OUT_CL_INTERFACE } // end Audio Control Interface } // end CL_INTERFACE 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()); }
//! This function manages the GET DESCRIPTOR request. The device descriptor, //! the configuration descriptor and the device qualifier are supported. All //! other descriptors must be supported by the usb_user_get_descriptor //! function. //! Only 1 configuration is supported. //! void usb_get_descriptor(void) { bool zlp; U16 wLength; U8 descriptor_type; U8 string_type; Union32 temp; #if (USB_HIGH_SPEED_SUPPORT==true) bool b_first_data = true; #endif zlp = false; /* no zero length packet */ string_type = Usb_read_endpoint_data(EP_CONTROL, 8); /* read LSB of wValue */ descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8); /* read MSB of wValue */ switch (descriptor_type) { case DEVICE_DESCRIPTOR: data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof(usb_dev_desc); pbuffer = Usb_get_dev_desc_pointer(); break; #if (USB_HIGH_SPEED_SUPPORT==false) case CONFIGURATION_DESCRIPTOR: data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof(usb_conf_desc); pbuffer = Usb_get_conf_desc_pointer(); break; #else case CONFIGURATION_DESCRIPTOR: 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(); } break; case OTHER_SPEED_CONFIGURATION_DESCRIPTOR: 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(); } break; case DEVICE_QUALIFIER_DESCRIPTOR: data_to_transfer = Usb_get_qualifier_desc_length(); //!< sizeof(usb_qualifier_desc); pbuffer = Usb_get_qualifier_desc_pointer(); break; #endif default: if (!usb_user_get_descriptor(descriptor_type, string_type)) { Usb_enable_stall_handshake(EP_CONTROL); Usb_ack_setup_received_free(); return; } break; } temp.u32 = Usb_read_endpoint_data(EP_CONTROL, 32); //!< read wIndex and wLength with a 32-bit access //!< since this access is aligned with a 32-bit //!< boundary from the beginning of the endpoint wLength = usb_format_usb_to_mcu_data(16, temp.u16[1]); //!< ignore wIndex, keep and format 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 { // No need to test ZLP sending since we send the exact number of bytes as // expected by the host. 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); #if (USB_HIGH_SPEED_SUPPORT==true) // To support other descriptors like OTHER_SPEED_CONFIGURATION_DESCRIPTOR if( b_first_data ) { b_first_data = false; if( 0!= data_to_transfer ) { usb_write_ep_txpacket(EP_CONTROL, pbuffer, 1, &pbuffer); data_to_transfer--; } if( 0!= data_to_transfer ) { usb_write_ep_txpacket(EP_CONTROL, &descriptor_type, 1, NULL); pbuffer = ((const U8*)pbuffer)+1; data_to_transfer--; } } #endif if( 0!= data_to_transfer ) { data_to_transfer = usb_write_ep_txpacket(EP_CONTROL, pbuffer, data_to_transfer, &pbuffer); } if (Is_usb_nak_out(EP_CONTROL)) break; 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 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(); }