//! usb_get_status. //! //! This function manages the GET STATUS request. The device, interface or //! endpoint status is returned. //! //! @warning Code:xx bytes (function code length) //! //! @param none //! //! @return none //! void usb_get_status(void) { U8 wIndex; U8 dummy; dummy = Usb_read_byte(); //!< dummy read dummy = Usb_read_byte(); //!< dummy read wIndex = Usb_read_byte(); switch(bmRequestType) { case REQUEST_DEVICE_STATUS: Usb_ack_receive_setup(); Usb_write_byte(DEVICE_STATUS); break; case REQUEST_INTERFACE_STATUS: Usb_ack_receive_setup(); Usb_write_byte(INTERFACE_STATUS); break; case REQUEST_ENDPOINT_STATUS: Usb_ack_receive_setup(); wIndex = wIndex & MSK_EP_DIR; Usb_write_byte(endpoint_status[wIndex]); break; default: Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } Usb_write_byte(0x00); Usb_send_control_in(); while( !Is_usb_receive_out() ); Usb_ack_receive_out(); }
/** * @brief This function reads one byte from the USB bus * * If one byte is present in the USB fifo, this byte is returned. If no data * is present in the USB fifo, this function waits for USB data. * * @return U8 byte received */ char uart_usb_getchar(void) { register Uchar data_rx; // Preserve the currently selected endpoint uint8_t uenum = Usb_get_selected_endpoint(); Usb_select_endpoint(VCP_RX_EP); if (!rx_counter) while (!uart_usb_test_hit()); data_rx=Usb_read_byte(); rx_counter--; if (!rx_counter) Usb_ack_receive_out(); #if USB_CDC_ACM_CONF_LOCAL_ECHO //Local echo uart_usb_putchar(data_rx); #endif USB_CDC_ACM_HOOK_RX(data_rx); // Restore previously selected endpoint UENUM = uenum; return data_rx; }
void my_uart_usb_read_from_endpoint(void){ register uint8_t data_rx; uint8_t num_to_read; num_to_read = my_uart_usb_num_to_read(); // if nothing to do, then do nothing if(num_to_read == 0) return; Usb_select_endpoint(RX_EP); // read them all while(num_to_read != 0){ // check if full if(my_uart_usb_rx_buffer.num == my_uart_usb_rx_buffer.size) break; // not full so read (this is the only thing that would make it more full data_rx = Usb_read_byte(); circ_buffer_put_byte(&my_uart_usb_rx_buffer, data_rx); num_to_read --; } // if we read the whole thing, ack if(num_to_read == 0){ Usb_select_endpoint(RX_EP); Usb_ack_receive_out(); } }
//! @breif This function checks the specific request and if known then processes it //! //! @param type corresponding at bmRequestType (see USB specification) //! @param request corresponding at bRequest (see USB specification) //! //! @return TRUE, when the request is processed //! @return FALSE, if the request is'nt know (STALL handshake is managed by the main standard request function). //! Bool usb_user_read_request(U8 type, U8 request) { U16 wInterface; U8 wValue_msb; U8 wValue_lsb; // Read wValue wValue_lsb = Usb_read_byte(); wValue_msb = Usb_read_byte(); //** Specific request from Class MassStorage if( USB_SETUP_SET_CLASS_INTER == type ) { switch( request ) { case SETUP_MASS_STORAGE_RESET: // wValue must be 0 // wIndex = Interface if( (0!=wValue_lsb) || (0!=wValue_msb) ) break; LSB(wInterface)=Usb_read_byte(); MSB(wInterface)=Usb_read_byte(); if( INTERFACE_NB != wInterface ) break; Usb_ack_receive_setup(); Usb_send_control_in(); while(!Is_usb_in_ready()); return TRUE; break; } } if( USB_SETUP_GET_CLASS_INTER == type ) { switch( request ) { case SETUP_MASS_STORAGE_GET_MAX_LUN: // wValue must be 0 // wIndex = Interface if( (0!=wValue_lsb) || (0!=wValue_msb) ) break; LSB(wInterface)=Usb_read_byte(); MSB(wInterface)=Usb_read_byte(); if( INTERFACE_NB != wInterface ) break; Usb_ack_receive_setup(); Usb_write_byte( (get_nb_lun()-1) ); Usb_send_control_in(); while(!Is_usb_in_ready()); while( !Is_usb_receive_out() ); Usb_ack_receive_out(); ms_multiple_drive = 1; return TRUE; break; } } return FALSE; // No supported request }
//! @brief This function manages hit set report request. //! void usb_hid_set_report_ouput (void) { Usb_ack_receive_setup(); Usb_send_control_in(); while(!Is_usb_receive_out()); Usb_ack_receive_out(); Usb_send_control_in(); }
//! usb_get_configuration. //! //! This function manages the GET CONFIGURATION request. The current //! configuration number is returned. //! //! @warning Code:xx bytes (function code length) //! void usb_get_configuration(void) { Usb_ack_receive_setup(); Usb_write_byte(usb_configuration_nb); Usb_send_control_in(); usb_endpoint_wait_for_receive_out(); Usb_ack_receive_out(); }
//! usb_get_configuration. //! //! This function manages the GET CONFIGURATION request. The current //! configuration number is returned. //! //! @warning Code:xx bytes (function code length) //! //! @param none //! //! @return none //! void usb_get_configuration(void) { Usb_ack_receive_setup(); Usb_write_byte(usb_configuration_nb); Usb_ack_in_ready(); while( !Is_usb_receive_out() ); Usb_ack_receive_out(); }
/** * @brief This function reads one byte from the USB bus * * If one byte is present in the USB fifo, this byte is returned. If no data * is present in the USB fifo, this function waits for USB data. * * @return U8 byte received */ char uart_usb_getchar(void) { register Uchar data_rx; Usb_select_endpoint(RX_EP); if (!rx_counter) while (!uart_usb_test_hit()); data_rx=Usb_read_byte(); rx_counter--; if (!rx_counter) Usb_ack_receive_out(); return data_rx; }
uint8_t my_uart_usb_num_to_read(void){ uint8_t num=0; if(!Is_device_enumerated()) return 0; Usb_select_endpoint(RX_EP); if (Is_usb_receive_out()){ num = Usb_byte_counter(); if (num == 0) Usb_ack_receive_out(); } return num; }
//! cdc_set_line_coding. //! //! @brief This function manages reception of line coding parameters (baudrate...). //! void cdc_set_line_coding (void) { Usb_ack_receive_setup(); while (!(Is_usb_receive_out())); LSB0(line_coding.dwDTERate) = Usb_read_byte(); LSB1(line_coding.dwDTERate) = Usb_read_byte(); LSB2(line_coding.dwDTERate) = Usb_read_byte(); LSB3(line_coding.dwDTERate) = Usb_read_byte(); line_coding.bCharFormat = Usb_read_byte(); line_coding.bParityType = Usb_read_byte(); line_coding.bDataBits = Usb_read_byte(); Usb_ack_receive_out(); Usb_send_control_in(); // send a ZLP for STATUS phase while(!(Is_usb_read_control_enabled())); }
/** * @brief This function checks if a character has been received on the USB bus. * * @return bit (true if a byte is ready to be read) */ bit uart_usb_test_hit(void) { if (!rx_counter) { // Preserve the currently selected endpoint uint8_t uenum = Usb_get_selected_endpoint(); Usb_select_endpoint(VCP_RX_EP); if (Is_usb_receive_out()) { rx_counter = Usb_byte_counter(); if (!rx_counter) Usb_ack_receive_out(); } // Restore previously selected endpoint UENUM = uenum; } return (rx_counter!=0); }
//! cdc_get_line_coding. //! //! @brief This function manages reception of line coding parameters (baudrate...). //! void cdc_get_line_coding(void) { Usb_ack_receive_setup(); Usb_write_byte(LSB0(line_coding.dwDTERate)); Usb_write_byte(LSB1(line_coding.dwDTERate)); Usb_write_byte(LSB2(line_coding.dwDTERate)); Usb_write_byte(LSB3(line_coding.dwDTERate)); Usb_write_byte(line_coding.bCharFormat); Usb_write_byte(line_coding.bParityType); Usb_write_byte(line_coding.bDataBits); Usb_send_control_in(); while(!(Is_usb_read_control_enabled())); //Usb_clear_tx_complete(); while(!Is_usb_receive_out()); Usb_ack_receive_out(); }
/** * @brief This function checks if a character has been received on the USB bus. * * @return bit (true if a byte is ready to be read) */ bit uart_usb_test_hit(void) { if(!Is_device_enumerated()) return FALSE; if (!rx_counter) { Usb_select_endpoint(RX_EP); if (Is_usb_receive_out()) { rx_counter = Usb_byte_counter(); if (!rx_counter) { Usb_ack_receive_out(); } } } return (rx_counter!=0); }
void usb_hid_set_report_feature(void) { Usb_ack_receive_setup(); Usb_send_control_in(); while(!Is_usb_receive_out()); if(Usb_read_byte()==0x55) if(Usb_read_byte()==0xAA) if(Usb_read_byte()==0x55) if(Usb_read_byte()==0xAA) { jump_bootloader=1; } Usb_ack_receive_out(); Usb_send_control_in(); while(!Is_usb_in_ready()); }
//! usb_set_interface. //! //! TThis function manages the SET_INTERFACE request. //! //! @warning Code:xx bytes (function code length) //! void usb_set_interface (void) { U8 alt_setting; U8 dummy; U8 interface; alt_setting = Usb_read_byte(); dummy = Usb_read_byte(); interface = Usb_read_byte(); if(usb_user_set_alt_interface(interface, alt_setting)) { Usb_ack_receive_setup(); Usb_send_control_in(); //!< send a ZLP for STATUS phase while(!Is_usb_in_ready()); usb_endpoint_wait_for_receive_out(); Usb_ack_receive_out(); } }
//! @brief This function manages hid get idle request. //! //! @param 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 LSB(wInterface)= Usb_read_byte(); MSB(wInterface)= Usb_read_byte(); LSB(wLength) = Usb_read_byte(); MSB(wLength) = Usb_read_byte(); Usb_ack_receive_setup(); if( wLength != 0 ) { Usb_write_byte(g_u8_report_rate); Usb_send_control_in(); } while(!Is_usb_receive_out()); Usb_ack_receive_out(); }
int USB::read(char* buf, int len) { if(!isEnumerated()) return 0; Usb_select_endpoint(EP_TEMP_OUT); if(!hasData()) return 0; U16 num = Usb_byte_counter(); if(len < num) num = len; char* ptr = buf; for(U16 i = num; i; i--) *ptr++ = Usb_read_byte(); Usb_ack_receive_out(); return num; }
//! @brief Get data report from Host //! void hid_report_out(void) { Usb_select_endpoint(EP_HID_OUT); if(Is_usb_receive_out()) { //Message Definition //Section //Instruction //Flags //Flags //datalength //Retrieve message parts unsigned char section, instruction, dataLength, flagH, flagL, i; section = Usb_read_byte(); instruction = Usb_read_byte(); flagL = Usb_read_byte(); flagH = Usb_read_byte(); dataLength = Usb_read_byte(); for(i = 0; i < HID_OUT_DATAPACKET_LENGTH; i++) //copy datapacket to global buffer hid_OUT_dataPkt[i] = Usb_read_byte(); //handle message sectionCall(section, instruction, &hid_OUT_dataPkt[0], dataLength); //ack message Usb_ack_receive_out(); } // //** Check if we received DFU mode command from host // if(jump_bootloader) // { // U32 volatile tempo; // Leds_off(); // Usb_detach(); // Detach actual generic HID application // for(tempo=0;tempo<70000;tempo++); // Wait some time before // start_boot(); // Jumping to booltoader // } }
void usb_get_string_descriptor(U8 string_type) { U16 requested_length; U8 dummy; PGM_P user_str; user_str = usb_user_get_string(string_type); if(!user_str) { usb_get_string_descriptor_sram(string_type); return; } dummy = Usb_read_byte(); //!< don't care of wIndex field dummy = Usb_read_byte(); requested_length = Usb_read_byte(); //!< read wLength requested_length |= Usb_read_byte()<<8; const U8 actual_descriptor_size = 2+strlen_P(user_str)*2; if (requested_length > actual_descriptor_size) { zlp = ((actual_descriptor_size % EP_CONTROL_LENGTH) == 0); requested_length = actual_descriptor_size; } Usb_ack_receive_setup() ; //!< clear the receive setup flag if(usb_endpoint_wait_for_read_control_enabled()!=0) { Usb_enable_stall_handshake(); return; } U8 nb_byte = 0; // Output the length if(requested_length) { Usb_write_byte(actual_descriptor_size); requested_length--; nb_byte++; } // Output the type if(requested_length) { Usb_write_byte(STRING_DESCRIPTOR); requested_length--; nb_byte++; } if(!requested_length) { Usb_send_control_in(); } while((requested_length != 0) && (!Is_usb_receive_out())) { if(usb_endpoint_wait_for_read_control_enabled()!=0) { Usb_enable_stall_handshake(); break; } while(requested_length != 0) //!< Send data until necessary { if(nb_byte==EP_CONTROL_LENGTH) { //!< Check endpoint 0 size nb_byte=0; break; } Usb_write_byte(pgm_read_byte_near((unsigned int)user_str++)); requested_length--; nb_byte++; if(requested_length) { Usb_write_byte(0); requested_length--; nb_byte++; } } Usb_send_control_in(); } //bail: if(Is_usb_receive_out()) { //! abort from Host Usb_ack_receive_out(); return; } if(zlp == TRUE) { if(usb_endpoint_wait_for_read_control_enabled()!=0) { Usb_enable_stall_handshake(); return; } Usb_send_control_in(); } usb_endpoint_wait_for_receive_out(); Usb_ack_receive_out(); }
uint8_t cdc_ecm_process(void) { static uint8_t doInit = 1; Usb_select_endpoint(RX_EP); if(!Is_usb_endpoint_enabled()) { return 0; } if (doInit) { #ifdef USB_ETH_HOOK_INIT USB_ETH_HOOK_INIT(); #endif cdc_ecm_notify_network_connection(1); cdc_ecm_notify_connection_speed_change(250000,250000); doInit = 0; if(usb_ecm_packet_filter & PACKET_TYPE_PROMISCUOUS) { #if RF230BB rf230_set_promiscuous_mode(true); #else radio_set_trx_state(RX_ON); #endif } // Select again, just to make sure. Usb_select_endpoint(RX_EP); } if(!usb_eth_is_active) { // If we aren't active, just eat the packets. if(Is_usb_read_enabled()) { Usb_ack_receive_out(); } return 0; } //Connected! Led0_on(); if(Is_usb_read_enabled()) { uint16_t bytecounter; uint16_t bytes_received = 0; U8 * buffer = uip_buf; if(!usb_eth_ready_for_next_packet()) { // Since we aren't ready for a packet yet, // just return. goto bail; } #ifdef USB_ETH_HOOK_RX_START USB_ETH_HOOK_RX_START(); #endif while((bytecounter=Usb_byte_counter_8())==CDC_ECM_DATA_ENDPOINT_SIZE) { while((bytes_received<USB_ETH_MTU) && (bytecounter--)) { *buffer++ = Usb_read_byte(); bytes_received++; } bytes_received+=bytecounter+1; //ACK previous data Usb_ack_receive_out(); //Wait for new data if(usb_endpoint_wait_for_read_enabled()!=0) { USB_ETH_HOOK_RX_ERROR("Timeout: read enabled"); goto bail; } } bytecounter = Usb_byte_counter_8(); while((bytes_received<USB_ETH_MTU) && (bytecounter--)) { *buffer++ = Usb_read_byte(); bytes_received++; } bytes_received+=bytecounter+1; //Ack final data packet Usb_ack_receive_out(); //PRINTF_P(PSTR("cdc_ecm: Got packet %d bytes long\n"),bytes_received); #ifdef USB_ETH_HOOK_RX_END USB_ETH_HOOK_RX_END(); #endif //Send data over RF or to local stack if(bytes_received<=USB_ETH_MTU) { USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,bytes_received); } else { USB_ETH_HOOK_RX_ERROR("Oversized packet"); } } bail: return 1; }
//! @brief This function manages hid get hid descriptor request. //! void hid_get_hid_descriptor(void) { U16 wLength; U8 nb_byte; bit zlp=FALSE; U16 wInterface; LSB(wInterface)=Usb_read_byte(); MSB(wInterface)=Usb_read_byte(); data_to_transfer = sizeof(usb_conf_desc.hid_mouse); pbuffer = &(usb_conf_desc.hid_mouse.bLength); LSB(wLength) = Usb_read_byte(); MSB(wLength) = Usb_read_byte(); Usb_ack_receive_setup(); if (wLength > data_to_transfer) { if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } else { zlp = FALSE; } // no need of zero length packet } else { data_to_transfer = (U8)wLength; // send only requested number of data } while((data_to_transfer != 0) && (!Is_usb_receive_out())) { while(!Is_usb_read_control_enabled()); nb_byte=0; while(data_to_transfer != 0) // Send data until necessary { if(nb_byte++==EP_CONTROL_LENGTH) // Check endpoint 0 size { break; } #ifndef __GNUC__ Usb_write_byte(*pbuffer++); #else // AVRGCC does not support point to PGM space //warning with AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++)); #endif data_to_transfer --; } Usb_send_control_in(); } if(Is_usb_receive_out()) { // abort from Host Usb_ack_receive_out(); return; } if(zlp == TRUE) { while(!Is_usb_read_control_enabled()); Usb_send_control_in(); } while(!Is_usb_receive_out()); Usb_ack_receive_out(); }
//! usb_process_request. //! //! @brief This function reads the SETUP request sent to the default control endpoint //! and calls the appropriate function. When exiting of the usb_read_request //! function, the device is ready to manage the next request. //! //! @note list of supported requests: //! GET_DESCRIPTOR //! GET_CONFIGURATION //! SET_ADDRESS //! SET_CONFIGURATION //! CLEAR_FEATURE //! SET_FEATURE //! GET_STATUS //! void usb_process_request(void) { U8 bmRequest; bmRequestType = Usb_read_byte(); bmRequest = Usb_read_byte(); switch (bmRequest) { case GET_DESCRIPTOR: if (0x80 == bmRequestType) { usb_get_descriptor(); } else goto user_read; break; case GET_CONFIGURATION: if (0x80 == bmRequestType) { usb_get_configuration(); } else goto user_read; break; case SET_ADDRESS: if (0x00 == bmRequestType) { usb_set_address(); } else goto user_read; break; case SET_CONFIGURATION: if (0x00 == bmRequestType) { usb_set_configuration(); } else goto user_read; break; case CLEAR_FEATURE: if (0x02 >= bmRequestType) { usb_clear_feature(); } else goto user_read; break; case SET_FEATURE: if (0x02 >= bmRequestType) { usb_set_feature(); } else goto user_read; break; case GET_STATUS: if ((0x7F < bmRequestType) & (0x82 >= bmRequestType)) { usb_get_status(); } else goto user_read; break; case GET_INTERFACE: if (bmRequestType == 0x81) { usb_get_interface(); } else goto user_read; break; case SET_INTERFACE: if (bmRequestType == 0x01) {usb_set_interface();} break; case SET_DESCRIPTOR: case SYNCH_FRAME: default: //!< un-supported request => call to user read request user_read: usb_user_read_request(bmRequestType, bmRequest); break; } Usb_select_endpoint(EP_CONTROL); // If the receive setup flag hasn't been cleared // by this point then we can assume that we didn't // support this request and should stall. if(Is_usb_receive_setup()) Usb_enable_stall_handshake(); // Clear some flags. Usb_ack_receive_setup(); Usb_ack_receive_out(); Usb_ack_in_ready(); }
//! @brief This function manages hit get repport request. //! void hid_get_report_descriptor(void) { U16 wLength; U8 nb_byte; bit zlp = FALSE; U16 wInterface; LSB(wInterface)=Usb_read_byte(); MSB(wInterface)=Usb_read_byte(); data_to_transfer = sizeof(usb_hid_report_descriptor); pbuffer = &(usb_hid_report_descriptor.report[0]); LSB(wLength) = Usb_read_byte(); MSB(wLength) = Usb_read_byte(); Usb_ack_receive_setup(); if (wLength > data_to_transfer) { if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } else { zlp = FALSE; } } else { data_to_transfer = (U8)wLength; // send only requested number of data } while((data_to_transfer != 0) && (!Is_usb_receive_out())) { while(!Is_usb_read_control_enabled()); nb_byte=0; while(data_to_transfer != 0) // Send data until necessary { if(nb_byte++==EP_CONTROL_LENGTH) // Check endpoint 0 size { break; } #ifndef __GNUC__ Usb_write_byte(*pbuffer++); #else // AVRGCC does not support point to PGM space Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++)); #endif data_to_transfer --; } Usb_send_control_in(); } if(Is_usb_receive_out()) { // abort from Host Usb_ack_receive_out(); return; } if(zlp == TRUE) { while(!Is_usb_read_control_enabled()); Usb_send_control_in(); } while(!Is_usb_receive_out()); Usb_ack_receive_out(); }
//! usb_get_descriptor. //! //! 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. //! //! @warning Code:xx bytes (function code length) //! void usb_get_descriptor(void) { U8 LSBwLength, MSBwLength; U8 descriptor_type ; U8 string_type ; U8 dummy; U8 byteswereread; zlp = FALSE; /* no zero length packet */ string_type = Usb_read_byte(); /* read LSB of wValue */ descriptor_type = Usb_read_byte(); /* read MSB of wValue */ byteswereread = 0; switch (descriptor_type) { case DEVICE_DESCRIPTOR: data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor); pbuffer = Usb_get_dev_desc_pointer(); break; case CONFIGURATION_DESCRIPTOR: data_to_transfer = Usb_get_conf_desc_length(string_type); //!< sizeof (usb_user_configuration_descriptor); pbuffer = Usb_get_conf_desc_pointer(string_type); break; #if 1 case STRING_DESCRIPTOR: if(string_type!=LANG_ID) { usb_get_string_descriptor(string_type); return; } #endif default: dummy = Usb_read_byte(); dummy = Usb_read_byte(); LSBwLength = Usb_read_byte(); MSBwLength = Usb_read_byte(); byteswereread=1; if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE ) { Usb_enable_stall_handshake(); //TODO:is this necessary, Win7 flaky without? Usb_ack_receive_setup(); return; } break; } if (byteswereread==0) { dummy = Usb_read_byte(); //!< don't care of wIndex field dummy = Usb_read_byte(); LSBwLength = Usb_read_byte(); //!< read wLength MSBwLength = Usb_read_byte(); } Usb_ack_receive_setup() ; //!< clear the receive setup flag if ((LSBwLength > data_to_transfer) || (MSBwLength)) { if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } else { zlp = FALSE; } //!< no need of zero length packet LSBwLength = data_to_transfer; MSBwLength = 0x00; } else { data_to_transfer = LSBwLength; //!< send only requested number of data } while((data_to_transfer != 0) && (!Is_usb_receive_out())) { U8 nb_byte = 0; if(usb_endpoint_wait_for_read_control_enabled()!=0) { Usb_enable_stall_handshake(); break; } //! Send data until necessary while(data_to_transfer != 0) { // if(Is_usb_write_enabled()) //!< Check endpoint 0 size if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size break; Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++)); data_to_transfer --; } Usb_send_control_in(); } if(Is_usb_receive_out()) { //! abort from Host Usb_ack_receive_out(); return; } if(zlp == TRUE) { if(usb_endpoint_wait_for_read_control_enabled()!=0) { Usb_enable_stall_handshake(); return; } Usb_send_control_in(); } usb_endpoint_wait_for_receive_out(); Usb_ack_receive_out(); }
//! usb_get_descriptor. //! //! 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. //! //! @warning Code:xx bytes (function code length) //! //! @param none //! //! @return none //! void usb_get_descriptor(void) { U16 wLength ; U8 descriptor_type ; U8 string_type ; U8 dummy; U8 nb_byte; zlp = FALSE; /* no zero length packet */ string_type = Usb_read_byte(); /* read LSB of wValue */ descriptor_type = Usb_read_byte(); /* read MSB of wValue */ switch (descriptor_type) { case DEVICE_DESCRIPTOR: data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor); pbuffer = Usb_get_dev_desc_pointer(); break; case CONFIGURATION_DESCRIPTOR: data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof (usb_user_configuration_descriptor); pbuffer = Usb_get_conf_desc_pointer(); break; default: if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE ) { Usb_enable_stall_handshake(); Usb_ack_receive_setup(); return; } break; } dummy = Usb_read_byte(); //!< don't care of wIndex field dummy = Usb_read_byte(); LSB(wLength) = Usb_read_byte(); //!< read wLength MSB(wLength) = Usb_read_byte(); Usb_ack_receive_setup() ; //!< clear the receive setup flag if (wLength > data_to_transfer) { if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } else { zlp = FALSE; } //!< no need of zero length packet } else { data_to_transfer = (U8)wLength; //!< send only requested number of data } while((data_to_transfer != 0) && (!Is_usb_receive_out())) { while(!Is_usb_read_control_enabled()); nb_byte=0; while(data_to_transfer != 0) //!< Send data until necessary { if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size { break; } #ifndef AVRGCC Usb_write_byte(*pbuffer++); #else // AVRGCC does not support point to PGM space #warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++)); #endif data_to_transfer --; } Usb_send_control_in(); } if(Is_usb_receive_out()) { Usb_ack_receive_out(); return; } //!< abort from Host if(zlp == TRUE) { while(!Is_usb_read_control_enabled()); Usb_send_control_in(); } while(!Is_usb_receive_out()); Usb_ack_receive_out(); }