/*---------------------------------------------------------------------------*/ static void queue_rx_urb(void) { data_rx_urb.flags = USB_BUFFER_PACKET_END; data_rx_urb.flags |= USB_BUFFER_NOTIFY; data_rx_urb.data = usb_rx_data; data_rx_urb.left = RX_BUFFER_SIZE; data_rx_urb.next = NULL; usb_submit_recv_buffer(EPOUT, &data_rx_urb); }
static void submit_setup(void) { ctrl_buffer.next = NULL; ctrl_buffer.data = (uint8_t*)&usb_setup_buffer; ctrl_buffer.left = sizeof(usb_setup_buffer); ctrl_buffer.flags = (USB_BUFFER_PACKET_END | USB_BUFFER_SETUP | USB_BUFFER_NOTIFY); ctrl_buffer.id = SETUP_ID; usb_submit_recv_buffer(0, &ctrl_buffer); }
void usb_get_ctrl_data(uint8_t *data, unsigned int length, usb_ctrl_data_callback cb) { if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED) return; PRINTF("usb_get_ctrl_data: %d\r\n",length); data_callback = cb; ctrl_data = data; ctrl_data_len = length; ctrl_buffer.flags = USB_BUFFER_NOTIFY; ctrl_buffer.next = NULL; ctrl_buffer.data = data; ctrl_buffer.left = length; ctrl_buffer.id = OUT_ID; usb_submit_recv_buffer(0,&ctrl_buffer); }
PROCESS_THREAD(usb_eth_process, ev , data) { PROCESS_BEGIN(); usb_register_request_handler(&cdc_eth_request_hook); usb_setup(); usb_set_ep_event_process(DATA_OUT, process_current); usb_set_global_event_process(process_current); uip_fw_default(&usbethif); uip_setethaddr(default_uip_ethaddr); uip_arp_init(); while(1) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_EXIT) break; if (ev == PROCESS_EVENT_POLL) { unsigned int events = usb_get_global_events(); if (events) { if (events & USB_EVENT_CONFIG) { if (usb_get_current_configuration() != 0) { printf("Configured\n"); usb_setup_bulk_endpoint(DATA_IN); usb_setup_bulk_endpoint(DATA_OUT); usb_setup_interrupt_endpoint(INTERRUPT_IN); init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); #if 0 { static const uint8_t foo[4] = {0x12,0x34,0x56,0x78}; xmit_buffer[0].next = NULL; xmit_buffer[0].left = sizeof(foo); xmit_buffer[0].flags = USB_BUFFER_SHORT_END; xmit_buffer[0].data = &foo; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); } #endif } else { usb_disable_endpoint(DATA_IN); usb_disable_endpoint(DATA_OUT); usb_disable_endpoint(INTERRUPT_IN); } } } events = usb_get_ep_events(DATA_OUT); if (events & USB_EP_EVENT_NOTIFICATION) { uip_len = sizeof(recv_data) - recv_buffer.left; /* printf("Received: %d bytes\n", uip_len); */ memcpy(uip_buf, recv_data, uip_len); #if UIP_CONF_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); tcpip_input(); } else #endif /* UIP_CONF_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if (uip_len > 0) { memcpy(xmit_data, uip_buf, uip_len); xmit_buffer[0].next = NULL; xmit_buffer[0].data = xmit_data; xmit_buffer[0].left = uip_len; xmit_buffer[0].flags = USB_BUFFER_SHORT_END; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); /* printf("Sent: %d bytes\n", uip_len); */ } } init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); } } } PROCESS_END(); }
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(); }