/** 
  * @brief This function transmits a ram buffer content to the USB.
  * This function is mode efficient in term of USB bandwith transfer.
  * 
  * @param U8 *buffer : the pointer to the RAM buffer to be sent 
  * @param data_to_send : the number of data to be sent
  */
void uart_usb_send_buffer(U8 *buffer, U8 nb_data)
{
  U8 zlp;

  if(!Is_device_enumerated())
    return;
   
  // Compute if zlp required
  if(nb_data%TX_EP_SIZE) 
    zlp=FALSE;
  else 
    zlp=TRUE;
   
  Usb_select_endpoint(TX_EP);
  while (nb_data)
  {
    while(Is_usb_write_enabled()==FALSE); // Wait Endpoint ready
    while(Is_usb_write_enabled() && nb_data)
    {
      Usb_write_byte(*buffer);
      buffer++;
      nb_data--;
    }
    Usb_ack_in_ready();
  }
  if(zlp)
  {
    while(Is_usb_write_enabled()==FALSE); // Wait Endpoint ready
    Usb_ack_in_ready();
  }
}
// this function should be continuously called
void my_uart_usb_send_to_endpoint(void){
  static uint8_t zlp=FALSE; /* zero load packet */
  static uint8_t local_buffer[TX_EP_SIZE];
  uint16_t num_read;
  bit ret;
  if(!Is_device_enumerated())
    return;


  // make atomic, this will be fixed by interrupts
  Usb_select_endpoint(TX_EP);
  if(Is_usb_write_enabled()==FALSE) // Only if endpoint ready
    return;

  if(line_status.DTR == 0){
    Usb_ack_in_ready();
    return;
  }


  // we send in chunks of TX_EP_SIZE 
  num_read = TX_EP_SIZE;
  ret = circ_buffer_get_nbytes(&my_uart_usb_tx_buffer, local_buffer, &num_read);
  if(num_read == 0 && zlp == TRUE){
    Usb_ack_in_ready();
    zlp = FALSE;
    Usb_disable_in_ready_interrupt(); // Nothing left to send, disable this until next time
    return;
  }
  // if we got exactly TX_EP_SIZE bytes, we should send zlp the next time if we send 0
  if(ret == PASS){
    zlp = TRUE;
    //Usb_enable_in_ready_interrupt(); // We don't need to do this since this is inside an interrupt.
  }
  else{ // this is the second pass and we didn't get a full TX_EP_SIZE bytes so the buffer is not full
    zlp = FALSE;
  }

  // write to the endpoint
  uint16_t nb_data = 0;
  Usb_select_endpoint(TX_EP);
  while(nb_data < num_read)
  {
    Usb_write_byte(local_buffer[nb_data]);
    nb_data++;
  }
  Usb_ack_in_ready();

  cdc_update_serial_state(); // I really do not know what this does, it could have been an old artifact from usart usb

//  if(usb_request_break_generation == TRUE)
//   usb_request_break_generation = FALSE;
}
Beispiel #3
0
uint8_t
ecm_send(uint8_t * senddata, uint16_t sendlen, uint8_t led) {
	U8 byte_in_packet = 0;

	//Send Data
	Usb_select_endpoint(TX_EP);

	if(usb_endpoint_wait_for_write_enabled()!=0) {
		USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
		return 0;
	}

#ifdef USB_ETH_HOOK_TX_START
	USB_ETH_HOOK_TX_START();
#endif

	//Send packet
	while(sendlen) {
		Usb_write_byte(*senddata);
		senddata++;
		sendlen--;
		byte_in_packet++;
		
		//If endpoint is full, send data in
		//And then wait for data to transfer
		if (!Is_usb_write_enabled()) {
			Usb_ack_in_ready();

			if(usb_endpoint_wait_for_write_enabled()!=0) {
				USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
				return 0;
			}
			byte_in_packet=0;
		}

	}

	//Send last data in - also handles sending a ZLP if needed
	Usb_ack_in_ready();

#ifdef USB_ETH_HOOK_TX_END
	USB_ETH_HOOK_TX_END();
#endif

    //Wait for ready
	if(usb_endpoint_wait_for_IN_ready()!=0) {
		USB_ETH_HOOK_TX_ERROR("Timeout: IN ready");
		return 0;
	}

	return 1;
}
Beispiel #4
0
//! Task which links mouse events with the USB HID mouse device
//!
void mouse_task(void)
{
   if(Is_usb_vbus_low())
   {
      Setup_power_down_mode();
      Sleep_instruction();
   }

   if(!Is_device_enumerated())
      return;  // Device not ready

#if (USB_LOW_SPEED_DEVICE==DISABLE)
   // The SOF is used to schedule the task at the same frequency that Endpoint Interrupt frequency
   // This check allow to win a CPU time
   if(g_u8_cpt_sof<NB_IDLE_POLLING_SOF)
      return;  // Wait a delay
   g_u8_cpt_sof=0;
#endif

   if(!g_b_send_report)
   {
      // No report sending on going, then check mouse event to eventualy fill a new report
      if(is_mouse_event())
      {
         // Enable sending of report
         g_b_send_report      = TRUE;
      }
   }

   if((!g_b_send_report)&&(!g_b_send_ack_report))
      return;  // No report and ack to send

   //** A report or ack must be send
   Usb_select_endpoint(EP_MOUSE_IN);
   if(!Is_usb_write_enabled())
      return;  // Endpoint no free

   Led0_on();
   if( g_b_send_report )
   {
      g_b_send_report      = FALSE;
      // Send an ack after a "clic" report only
      g_b_send_ack_report = (0!=g_hid_mouse_report[0]);
   }
   else
   {
      Hid_mouse_report_reset();     // Reset report to have a ack report
      g_b_send_ack_report  = FALSE;
   }
   // Send report
   Usb_write_byte(g_hid_mouse_report[0]);
   Usb_write_byte(g_hid_mouse_report[1]);
   Usb_write_byte(g_hid_mouse_report[2]);
   Usb_write_byte(g_hid_mouse_report[3]);
   Usb_ack_in_ready();
   Led0_off();
}
Beispiel #5
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();
}
Beispiel #6
0
int USB::write(char* buf, int len)
{
  if(!isEnumerated())
    return 0;

  Usb_select_endpoint(EP_TEMP_IN);

  //if(!canSend())
  //  return 0;

  char* ptr = buf;
  for(int i = 0; i<len; i++)
    Usb_write_byte(*ptr++);
  for(int i; i<EP_IN_LENGTH_TEMP1; i++)
    Usb_write_byte(0);
  Usb_ack_in_ready();

  return len;
}
//! 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();
}