Example #1
0
//! 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();
}
Example #2
0
/** 
  * @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();
  }
}
Example #4
0
//! @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
}
Example #5
0
//! @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();
}
Example #7
0
//! 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;
}
Example #10
0
//! 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()));
}
Example #11
0
/** 
  * @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);
}
Example #12
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();
	}

}
Example #16
0
//! @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();
}
Example #17
0
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();
}
Example #20
0
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;
}
Example #21
0
//! @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();
}
Example #25
0
//! 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();
}