8 #include <descriptors.h>
9 #include <string-descriptors.h>
13 #define PRINTF(...) printf(__VA_ARGS__)
19 struct USB_request_st usb_setup_buffer;
20 static USBBuffer ctrl_buffer;
25 #define STATUS_OUT_ID 4
26 #define STATUS_IN_ID 5
28 static uint16_t usb_device_status;
29 static uint8_t usb_configuration_value;
31 static struct USBRequestHandlerHook *usb_request_handler_hooks =
NULL;
33 static const unsigned char zero_byte = 0;
34 static const unsigned short zero_word = 0;
36 static unsigned char usb_flags = 0;
37 #define USB_FLAG_ADDRESS_PENDING 0x01
39 static struct process *global_user_event_pocess =
NULL;
40 static unsigned int global_user_events = 0;
43 usb_set_global_event_process(
struct process *p)
45 global_user_event_pocess = p;
48 usb_get_global_events(
void)
50 unsigned int e = global_user_events;
51 global_user_events = 0;
56 notify_user(
unsigned int e)
58 global_user_events |= e;
59 if (global_user_event_pocess) {
65 usb_send_ctrl_response(
const uint8_t *data,
unsigned int len)
67 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED)
return;
68 if (len >= usb_setup_buffer.wLength) {
69 len = usb_setup_buffer.wLength;
71 ctrl_buffer.flags = USB_BUFFER_NOTIFY | USB_BUFFER_IN;
72 if (len < usb_setup_buffer.wLength) {
73 ctrl_buffer.flags |= USB_BUFFER_SHORT_END;
75 ctrl_buffer.next =
NULL;
76 ctrl_buffer.data = (uint8_t*)data;
77 ctrl_buffer.left = len;
78 ctrl_buffer.id = IN_ID;
79 usb_submit_xmit_buffer(0,&ctrl_buffer);
82 static uint8_t error_stall = 0;
88 usb_arch_control_stall(0);
92 usb_send_ctrl_status()
94 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED)
return;
95 ctrl_buffer.flags = USB_BUFFER_NOTIFY | USB_BUFFER_IN;
96 ctrl_buffer.next =
NULL;
97 ctrl_buffer.data =
NULL;
99 ctrl_buffer.id = STATUS_IN_ID;
100 usb_submit_xmit_buffer(0,&ctrl_buffer);
103 static usb_ctrl_data_callback data_callback =
NULL;
104 static uint8_t *ctrl_data =
NULL;
105 static unsigned int ctrl_data_len = 0;
107 usb_get_ctrl_data(uint8_t *data,
unsigned int length,
108 usb_ctrl_data_callback cb)
110 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED)
return;
111 PRINTF(
"usb_get_ctrl_data: %d\n",length);
114 ctrl_data_len = length;
115 ctrl_buffer.flags = USB_BUFFER_NOTIFY;
116 ctrl_buffer.next =
NULL;
117 ctrl_buffer.data = data;
118 ctrl_buffer.left = length;
119 ctrl_buffer.id = OUT_ID;
120 usb_submit_recv_buffer(0,&ctrl_buffer);
126 usb_set_user_process(
struct process *p)
133 get_device_descriptor()
135 usb_send_ctrl_response((
unsigned char*)&device_descriptor,
sizeof(device_descriptor));
139 get_string_descriptor()
142 if (
LOW_BYTE(usb_setup_buffer.wValue) == 0) {
143 usb_send_ctrl_response((
const unsigned char*)string_languages->lang_descr,
144 string_languages->lang_descr->bLength);
146 const struct usb_st_string_descriptor *descriptor;
148 const struct usb_st_string_descriptor *
const *table;
149 const struct usb_st_string_language_map *map;
150 if (
LOW_BYTE(usb_setup_buffer.wValue) > string_languages->max_index) {
154 l = string_languages->num_lang;
155 map = string_languages->map;
156 table = map->descriptors;
158 if (map->lang_id == usb_setup_buffer.wIndex) {
159 table = map->descriptors;
165 PRINTF(
"Lang id %04x = table %p\n", usb_setup_buffer.wIndex, (
void*)table);
166 descriptor = table[
LOW_BYTE(usb_setup_buffer.wValue) - 1];
167 usb_send_ctrl_response((
const unsigned char*)descriptor,
168 descriptor->bLength);
171 const struct usb_st_string_descriptor *descriptor;
172 descriptor = (
struct usb_st_string_descriptor*)
173 usb_class_get_string_descriptor(usb_setup_buffer.wIndex,
179 usb_send_ctrl_response((
const unsigned char*)descriptor,
180 descriptor->bLength);
185 get_configuration_descriptor()
187 usb_send_ctrl_response((
unsigned char*)configuration_head,
188 configuration_head->wTotalLength);
194 usb_send_ctrl_response((
unsigned char*)&usb_configuration_value,
195 sizeof(usb_configuration_value));
202 notify_user(USB_EVENT_CONFIG);
203 if (usb_configuration_value !=
LOW_BYTE(usb_setup_buffer.wValue)) {
204 usb_configuration_value =
LOW_BYTE(usb_setup_buffer.wValue);
205 usb_arch_set_configuration(usb_configuration_value);
206 usb_send_ctrl_status();
209 usb_send_ctrl_status();
217 PRINTF(
"get_device_status\n");
218 usb_send_ctrl_response((
const unsigned char*)&usb_device_status,
219 sizeof(usb_device_status));
223 get_endpoint_status()
225 static uint16_t status;
226 PRINTF(
"get_endpoint_status\n");
227 if ((usb_setup_buffer.wIndex & 0x7f) == 0) {
228 usb_send_ctrl_response((
const unsigned char*)&zero_word,
231 status = usb_arch_get_ep_status(usb_setup_buffer.wIndex);
232 usb_send_ctrl_response((uint8_t*)&status,
sizeof(status));
237 get_interface_status()
239 PRINTF(
"get_interface_status\n");
240 usb_send_ctrl_response((
const unsigned char*)&zero_word,
247 PRINTF(
"get_interface\n");
248 if (usb_configuration_value == 0) usb_error_stall();
250 usb_send_ctrl_response(&zero_byte,
257 handle_standard_requests()
259 switch(usb_setup_buffer.bmRequestType) {
261 switch(usb_setup_buffer.bRequest) {
263 switch (
HIGH_BYTE(usb_setup_buffer.wValue)) {
265 get_device_descriptor();
268 get_configuration_descriptor();
271 get_string_descriptor();
278 case GET_CONFIGURATION:
292 switch(usb_setup_buffer.bRequest) {
294 get_interface_status();
298 switch (USB_setup_buffer.wValue.byte.high) {
300 get_report_descriptor();
310 switch(usb_setup_buffer.bRequest) {
312 get_endpoint_status();
319 switch(usb_setup_buffer.bRequest) {
321 PRINTF(
"Address: %d\n",
LOW_BYTE(usb_setup_buffer.wValue));
322 usb_flags |= USB_FLAG_ADDRESS_PENDING;
325 usb_send_ctrl_status();
327 #if SETABLE_STRING_DESCRIPTORS > 0
329 if (usb_setup_buffer.wValue.byte.high == STRING) {
330 set_string_descriptor();
336 case SET_CONFIGURATION:
337 if (set_configuration()) {
339 config_msg.data.config =
LOW_BYTE(usb_setup_buffer.wValue);
340 notify_user(&config_msg);
349 switch(usb_setup_buffer.bRequest) {
352 usb_send_ctrl_status();
359 switch(usb_setup_buffer.bRequest) {
362 if (usb_setup_buffer.wValue == ENDPOINT_HALT_FEATURE) {
363 usb_arch_halt_endpoint(usb_setup_buffer.wIndex, usb_setup_buffer.bRequest==
SET_FEATURE);
364 usb_send_ctrl_status();
375 switch(USB_setup_buffer.bRequest) {
377 PRINTF(
"Get report\n");
378 send_ctrl_response((code u_int8_t*)&zero_byte,
382 PRINTF(
"Get idle\n");
383 send_ctrl_response((code u_int8_t*)&zero_byte,
391 switch(USB_setup_buffer.bRequest) {
393 PRINTF(
"Set idle\n");
407 static const struct USBRequestHandler standard_request_handler =
411 handle_standard_requests
414 static struct USBRequestHandlerHook standard_request_hook =
417 &standard_request_handler
423 ctrl_buffer.next =
NULL;
424 ctrl_buffer.data = (uint8_t*)&usb_setup_buffer;
425 ctrl_buffer.left =
sizeof(usb_setup_buffer);
426 ctrl_buffer.flags = (USB_BUFFER_PACKET_END | USB_BUFFER_SETUP
427 | USB_BUFFER_NOTIFY);
428 ctrl_buffer.id = SETUP_ID;
429 usb_submit_recv_buffer(0, &ctrl_buffer);
437 PRINTF(
"USB process started\n");
440 if (ev == PROCESS_EVENT_EXIT)
break;
441 if (ev == PROCESS_EVENT_POLL) {
442 unsigned int events = usb_arch_get_global_events();
444 if (events & USB_EVENT_RESET) {
446 usb_configuration_value = 0;
447 notify_user(USB_EVENT_RESET);
449 if (events & USB_EVENT_SUSPEND) {
450 notify_user(USB_EVENT_SUSPEND);
452 if (events & USB_EVENT_RESUME) {
453 notify_user(USB_EVENT_RESUME);
457 events = usb_get_ep_events(0);
459 if ((events & USB_EP_EVENT_NOTIFICATION)
460 && !(ctrl_buffer.flags & USB_BUFFER_SUBMITTED)) {
462 if (ctrl_buffer.flags & USB_BUFFER_FAILED) {
465 PRINTF(
"Discarded\n");
467 }
else if (ctrl_buffer.flags & USB_BUFFER_SETUP) {
468 struct USBRequestHandlerHook *hook = usb_request_handler_hooks;
473 for (i = 0; i< 8; i++) PRINTF(
" %02x", ((
unsigned char*)&usb_setup_buffer)[i]);
478 const struct USBRequestHandler *handler = hook->handler;
480 if (((handler->request_type ^ usb_setup_buffer.bmRequestType)
481 & handler->request_type_mask) == 0
482 && ((handler->request ^ usb_setup_buffer.bRequest)
483 & handler->request_mask) == 0) {
484 if (handler->handler_func())
break;
491 PRINTF(
"Unhandled setup: %02x %02x %04x %04x %04x\n",
492 usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest,
493 usb_setup_buffer.wValue, usb_setup_buffer.wIndex,
494 usb_setup_buffer.wLength);
503 if (ctrl_buffer.id == IN_ID) {
505 PRINTF(
"Status OUT\n");
506 ctrl_buffer.flags = USB_BUFFER_NOTIFY;
507 ctrl_buffer.next =
NULL;
508 ctrl_buffer.data =
NULL;
509 ctrl_buffer.left = 0;
510 ctrl_buffer.id = STATUS_OUT_ID;
511 usb_submit_recv_buffer(0,&ctrl_buffer);
512 }
else if (ctrl_buffer.id == STATUS_OUT_ID) {
513 PRINTF(
"Status OUT done\n");
515 }
else if (ctrl_buffer.id == STATUS_IN_ID) {
516 PRINTF(
"Status IN done\n");
517 if (usb_flags & USB_FLAG_ADDRESS_PENDING) {
518 while(usb_send_pending(0));
519 usb_arch_set_address(
LOW_BYTE(usb_setup_buffer.wValue));
520 usb_flags &= ~USB_FLAG_ADDRESS_PENDING;
523 }
else if (ctrl_buffer.id == OUT_ID) {
526 data_callback(ctrl_data, ctrl_data_len- ctrl_buffer.left);
528 usb_send_ctrl_status();
545 usb_arch_set_global_event_process(&usb_process);
546 usb_set_ep_event_process(0, &usb_process);
548 usb_register_request_handler(&standard_request_hook);
552 usb_register_request_handler(
struct USBRequestHandlerHook *hook)
554 struct USBRequestHandlerHook **prevp = &usb_request_handler_hooks;
557 prevp = &(*prevp)->next;
565 usb_prepend_request_handler(
struct USBRequestHandlerHook *hook)
567 hook->next = usb_request_handler_hooks;
568 usb_request_handler_hooks = hook;
573 usb_get_current_configuration(
void)
575 return usb_configuration_value;
579 usb_setup_bulk_endpoint(
unsigned char addr)
581 usb_arch_setup_bulk_endpoint(addr);
585 usb_setup_interrupt_endpoint(
unsigned char addr)
587 usb_arch_setup_interrupt_endpoint(addr);
591 usb_disable_endpoint(uint8_t addr)
593 usb_arch_discard_all_buffers(addr);
594 usb_arch_disable_endpoint(addr);
598 usb_discard_all_buffers(uint8_t addr)
600 usb_arch_discard_all_buffers(addr);
606 usb_arch_halt_endpoint(addr, halt);
610 usb_send_pending(uint8_t addr)
612 return usb_arch_send_pending(addr);