Пример #1
0
/* Returns true if the configuration value changed */
static int
set_configuration()
{
  notify_user(USB_EVENT_CONFIG);
  if (usb_configuration_value != LOW_BYTE(usb_setup_buffer.wValue)) {
    usb_configuration_value = LOW_BYTE(usb_setup_buffer.wValue);
    usb_arch_set_configuration(usb_configuration_value);
    usb_send_ctrl_status();
    return 1;
  } else {
    usb_send_ctrl_status();
    return 0;
  }
}
Пример #2
0
static void
handle_blit(uint8_t *data, unsigned int length)
{
  int x;
  int y;
  struct BlitReport *blit;
  uint8_t *p;
  if (length < sizeof(struct BlitReport)) {
    usb_error_stall();
    return;
  }
  blit = (struct BlitReport*)data;
  printf("Blit: (%d,%d) - (%d,%d)\n",blit->x1,blit->y1,blit->x2,blit->y2);
  if (sizeof(struct BlitReport) 
      + (((blit->x2-blit->x1) * (blit->y2-blit->y1) - 1) 
	 * sizeof(blit->pixels[0])) > length) {
    printf("Not enough blit data\n");
    usb_error_stall();
    return;
  }
  if (blit->x2 > SIZE_X || blit->x1 > blit->x2
      || blit->y2 > SIZE_Y || blit->y1 > blit->y2) {
    printf("Illegal rect\n");
    usb_error_stall();
    return;
  }
  p = (uint8_t*)&blit->pixels;
  for(y = blit->y1; y < blit->y2; y++) {
    for(x = blit->x1; x < blit->x2; x++) {
      ws2812_encode_rgb(ws_buffer + x + y * SIZE_X, p[0], p[1], p[2]);
      p += 3;
    }
  }
  usb_send_ctrl_status();
}
Пример #3
0
static unsigned int
handle_hid_requests()
{
  printf("HID request %02x %02x\n", usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest);
  switch(usb_setup_buffer.bmRequestType) {
  case 0x81:
    switch(usb_setup_buffer.bRequest) {
    case GET_DESCRIPTOR:
      printf("Get HID report decriptor\n");
      if (usb_setup_buffer.wValue == 0x2200 
	  && usb_setup_buffer.wLength >= sizeof(HID_REPORT_DESCRIPTOR_BLOCK)) {
	usb_send_ctrl_response((const uint8_t*)&HID_REPORT_DESCRIPTOR_BLOCK,
			       sizeof(HID_REPORT_DESCRIPTOR_BLOCK));
	return 1;
      } else if (usb_setup_buffer.wValue == 0x2100
		 && usb_setup_buffer.wLength >= sizeof(HID_DESCRIPTOR_BLOCK)) {
	usb_send_ctrl_response((const uint8_t*)&HID_DESCRIPTOR_BLOCK,
			       sizeof(HID_DESCRIPTOR_BLOCK));
	return 1;
      }
      return 0;
    }
    break;
  case 0x21:
    switch(usb_setup_buffer.bRequest) {
    case SET_IDLE:
      if (usb_setup_buffer.wLength == 0) {
	if ((usb_setup_buffer.wValue & 0xff) < 4) {
	  idle_rate[usb_setup_buffer.wValue & 0xff] =
	    usb_setup_buffer.wValue>>8;
	  printf("Dur: %d, id: %d\n", 
		 usb_setup_buffer.wValue>>8,
		 usb_setup_buffer.wValue & 0xff);
	}
	usb_send_ctrl_status();
	return 1;
      }
      break;
    case SET_REPORT:
      {
	unsigned int len = usb_setup_buffer.wLength;
	if (len > sizeof(blit_buffer))
          len = sizeof(blit_buffer);
        usb_get_ctrl_data(blit_buffer, len,
                          handle_blit);
	printf("Got blit report: %d\n",len);
	return 1;
      }
      break;
    }
    break;
  case 0xa1:
    switch(usb_setup_buffer.bRequest) {
    case GET_REPORT:
      printf("GET_REPORT\n");
      if (usb_setup_buffer.wValue == 0x0301 
	  && usb_setup_buffer.wLength >= sizeof(display_report)) {
	usb_send_ctrl_response((const uint8_t*)&display_report,
			       sizeof(display_report));
	return 1;
      }
      return 0;
    case GET_IDLE:
      if (usb_setup_buffer.wValue < 4) {
	usb_send_ctrl_response((const uint8_t*)
			       &idle_rate[usb_setup_buffer.wValue],
			       sizeof(uint8_t));
	return 1;
      }
      return 0;
    }
    break;
  }
Пример #4
0
PROCESS_THREAD(usb_process, ev , data)
{
  PROCESS_BEGIN();
  PRINTF("USB process started\r\n");
  while(1) {
    PROCESS_WAIT_EVENT();
    if (ev == PROCESS_EVENT_EXIT) break;
    if (ev == PROCESS_EVENT_POLL) {
      unsigned int events = usb_arch_get_global_events();
      if (events) {
	if (events & USB_EVENT_RESET) {
	  submit_setup();
	  usb_configuration_value = 0;
	  notify_user(USB_EVENT_RESET);
	}
	if (events & USB_EVENT_SUSPEND) {
	  notify_user(USB_EVENT_SUSPEND);
	}
	if (events & USB_EVENT_RESUME) {
	  notify_user(USB_EVENT_RESUME);
	}
	
      }
      events = usb_get_ep_events(0);
      if (events) {
	if ((events & USB_EP_EVENT_NOTIFICATION)
	    && !(ctrl_buffer.flags & USB_BUFFER_SUBMITTED)) {
	  /* PRINTF("Endpoint 0\r\n"); */
	  if (ctrl_buffer.flags & USB_BUFFER_FAILED) {
	    /* Something went wrong with the buffer, just wait for a
	       new SETUP packet */
	    PRINTF("Discarded\r\n");
	    submit_setup();
	  } else if (ctrl_buffer.flags & USB_BUFFER_SETUP) {
	    struct USBRequestHandlerHook *hook = usb_request_handler_hooks;

	    PRINTF("Setup\r\n");
#if 0
	    {
	    unsigned int i;
	    for (i = 0; i< 8; i++) PRINTF(" %02x", ((unsigned char*)&usb_setup_buffer)[i]);
	    PRINTF("\r\n");
	    }
#endif	    
	    while(hook) {
	      const struct USBRequestHandler *handler = hook->handler;
	      /* Check if the handler matches the request */
	      if (((handler->request_type ^ usb_setup_buffer.bmRequestType)
		   & handler->request_type_mask) == 0
		  && ((handler->request ^ usb_setup_buffer.bRequest)
		      & handler->request_mask) == 0) {
		if (handler->handler_func()) break;
	      }
	      hook = hook->next;
	    }
	    if (!hook) {
	      /* No handler found */
	      usb_error_stall();
	      PRINTF("Unhandled setup: %02x %02x %04x %04x %04x\r\n",
		     usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest,
		     usb_setup_buffer.wValue, usb_setup_buffer.wIndex,
		     usb_setup_buffer.wLength);
	    }
	    /* Check if any handler stalled the pipe, if so prepare for
	       next setup */
	    if (error_stall) {
	      error_stall = 0;
	      submit_setup();
	    }
	  } else {
	    if (ctrl_buffer.id == IN_ID) {
	      /* Receive status stage */
	      PRINTF("Status OUT\r\n");
	      ctrl_buffer.flags =  USB_BUFFER_NOTIFY;
	      ctrl_buffer.next = NULL;
	      ctrl_buffer.data = NULL;
	      ctrl_buffer.left = 0;
	      ctrl_buffer.id = STATUS_OUT_ID;
	      usb_submit_recv_buffer(0,&ctrl_buffer);
	    } else if (ctrl_buffer.id == STATUS_OUT_ID) {
	      PRINTF("Status OUT done\r\n");
	      submit_setup();
	    } else if (ctrl_buffer.id == STATUS_IN_ID) {
	      PRINTF("Status IN done\r\n");
	      if (usb_flags & USB_FLAG_ADDRESS_PENDING) {
		while(usb_send_pending(0));
		usb_arch_set_address(LOW_BYTE(usb_setup_buffer.wValue));
		usb_flags &= ~USB_FLAG_ADDRESS_PENDING;
	      }
	      submit_setup();
	    } else if (ctrl_buffer.id == OUT_ID) {
	      PRINTF("OUT\r\n");
	      if (data_callback) {
		data_callback(ctrl_data, ctrl_data_len- ctrl_buffer.left);
	      } else {
		usb_send_ctrl_status();
	      }
	    }
	  }
	}
      }
    }
  }
  PROCESS_END();
}
Пример #5
0
static unsigned int
handle_standard_requests()
{
  switch(usb_setup_buffer.bmRequestType) {
  case 0x80: /* standard device IN requests */
    switch(usb_setup_buffer.bRequest) {
    case GET_DESCRIPTOR:
      switch (HIGH_BYTE(usb_setup_buffer.wValue)) {
      case DEVICE:
	get_device_descriptor();
	break;
      case CONFIGURATION:
	get_configuration_descriptor();
	break;
      case STRING:
	get_string_descriptor();
	break;
      default:
	/* Unknown descriptor */
	return 0;
      }
      break;
    case GET_CONFIGURATION:
      get_configuration();
      break;
    case GET_STATUS:
      get_device_status();
      break;
    case GET_INTERFACE:
      get_interface();
      break;
    default:
      return 0;
    }
    break;
  case 0x81: /* standard interface IN requests */
    switch(usb_setup_buffer.bRequest) {
    case GET_STATUS:
      get_interface_status();
      break;
#ifdef HID_ENABLED
      case GET_DESCRIPTOR:
	switch (USB_setup_buffer.wValue.byte.high) {
	case REPORT:
	  get_report_descriptor();
	  break;
	}
	break;
#endif	
    default:
      return 0;
    }
    break;
  case 0x82: /* standard endpoint IN requests */
    switch(usb_setup_buffer.bRequest) {
    case GET_STATUS:
      get_endpoint_status();
      break;
    default:
      return 0;
    }
    break;
  case 0x00: /* standard device OUT requests */
    switch(usb_setup_buffer.bRequest) {
    case SET_ADDRESS:
      PRINTF("Address: %d\r\n", LOW_BYTE(usb_setup_buffer.wValue));
      usb_flags |= USB_FLAG_ADDRESS_PENDING;
      /* The actual setting of the address is done when the status packet
	 is sent. */
      usb_send_ctrl_status();
      break;
#if SETABLE_STRING_DESCRIPTORS > 0
    case SET_DESCRIPTOR:
      if (usb_setup_buffer.wValue.byte.high == STRING) {
	set_string_descriptor();
      } else {
	return 0;
      }
      break;
#endif
    case SET_CONFIGURATION:
      if (set_configuration()) {
#if 0
	config_msg.data.config = LOW_BYTE(usb_setup_buffer.wValue);
	notify_user(&config_msg);
#endif
      }
      break;
    default:
      return 0;
    }
    break;
  case 0x01: /* standard interface OUT requests */
    switch(usb_setup_buffer.bRequest) {
    case SET_INTERFACE:
      /* Change interface here if we support more than one */
      usb_send_ctrl_status();
      break;
    default:
      return 0;
    }
    break;
  case 0x02: /* standard endpoint OUT requests */
    switch(usb_setup_buffer.bRequest) {
    case SET_FEATURE:
    case CLEAR_FEATURE:
      if (usb_setup_buffer.wValue == ENDPOINT_HALT_FEATURE) {
	usb_arch_halt_endpoint(usb_setup_buffer.wIndex, usb_setup_buffer.bRequest== SET_FEATURE);
	usb_send_ctrl_status();
      } else {
	usb_error_stall();
      }
      break;
    default:
      return 0;
    }
    break;
#ifdef HID_ENABLED
  case 0xa1: /* class specific interface IN request*/
    switch(USB_setup_buffer.bRequest) {
    case GET_HID_REPORT:
      PRINTF("Get report\r\n");
      send_ctrl_response((code u_int8_t*)&zero_byte,
			   sizeof(zero_byte));
      break;
    case GET_HID_IDLE:
      PRINTF("Get idle\r\n");
      send_ctrl_response((code u_int8_t*)&zero_byte,
			 sizeof(zero_byte));
      break;
    default:
      return 0;
      }
    break;
  case 0x21: /* class specific interface OUT request*/
    switch(USB_setup_buffer.bRequest) {
    case SET_HID_IDLE:
      PRINTF("Set idle\r\n");
      send_ctrl_status();
      break;
    default:
      return 0;
    }
    break;
#endif
  default:
    return 0;
  }
  return 1;
}