00001 #include <usb-core.h>
00002 #include <usb.h>
00003 #include <usb-arch.h>
00004 #include <usb-api.h>
00005 #include <stdio.h>
00006 #include <sys/process.h>
00007 #include <stdio.h>
00008 #include <descriptors.h>
00009 #include <string-descriptors.h>
00010
00011 #define DEBUG
00012 #ifdef DEBUG
00013 #define PRINTF(...) printf(__VA_ARGS__)
00014 #else
00015 #define PRINTF(...)
00016 #endif
00017
00018
00019 struct USB_request_st usb_setup_buffer;
00020 static USBBuffer ctrl_buffer;
00021
00022 #define SETUP_ID 1
00023 #define OUT_ID 2
00024 #define IN_ID 3
00025 #define STATUS_OUT_ID 4
00026 #define STATUS_IN_ID 5
00027
00028 static uint16_t usb_device_status;
00029 static uint8_t usb_configuration_value;
00030
00031 static struct USBRequestHandlerHook *usb_request_handler_hooks = NULL;
00032
00033 static const unsigned char zero_byte = 0;
00034 static const unsigned short zero_word = 0;
00035
00036 static unsigned char usb_flags = 0;
00037 #define USB_FLAG_ADDRESS_PENDING 0x01
00038
00039 static struct process *global_user_event_pocess = NULL;
00040 static unsigned int global_user_events = 0;
00041
00042 void
00043 usb_set_global_event_process(struct process *p)
00044 {
00045 global_user_event_pocess = p;
00046 }
00047 unsigned int
00048 usb_get_global_events(void)
00049 {
00050 unsigned int e = global_user_events;
00051 global_user_events = 0;
00052 return e;
00053 }
00054
00055 static void
00056 notify_user(unsigned int e)
00057 {
00058 global_user_events |= e;
00059 if (global_user_event_pocess) {
00060 process_poll(global_user_event_pocess);
00061 }
00062 }
00063
00064 void
00065 usb_send_ctrl_response(const uint8_t *data, unsigned int len)
00066 {
00067 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED) return;
00068 if (len >= usb_setup_buffer.wLength) {
00069 len = usb_setup_buffer.wLength;
00070 }
00071 ctrl_buffer.flags = USB_BUFFER_NOTIFY | USB_BUFFER_IN;
00072 if (len < usb_setup_buffer.wLength) {
00073 ctrl_buffer.flags |= USB_BUFFER_SHORT_END;
00074 }
00075 ctrl_buffer.next = NULL;
00076 ctrl_buffer.data = (uint8_t*)data;
00077 ctrl_buffer.left = len;
00078 ctrl_buffer.id = IN_ID;
00079 usb_submit_xmit_buffer(0,&ctrl_buffer);
00080 }
00081
00082 static uint8_t error_stall = 0;
00083
00084 void
00085 usb_error_stall()
00086 {
00087 error_stall = 1;
00088 usb_arch_control_stall(0);
00089 }
00090
00091 void
00092 usb_send_ctrl_status()
00093 {
00094 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED) return;
00095 ctrl_buffer.flags = USB_BUFFER_NOTIFY | USB_BUFFER_IN;
00096 ctrl_buffer.next = NULL;
00097 ctrl_buffer.data = NULL;
00098 ctrl_buffer.left = 0;
00099 ctrl_buffer.id = STATUS_IN_ID;
00100 usb_submit_xmit_buffer(0,&ctrl_buffer);
00101 }
00102
00103 static usb_ctrl_data_callback data_callback = NULL;
00104 static uint8_t *ctrl_data = NULL;
00105 static unsigned int ctrl_data_len = 0;
00106 void
00107 usb_get_ctrl_data(uint8_t *data, unsigned int length,
00108 usb_ctrl_data_callback cb)
00109 {
00110 if (ctrl_buffer.flags & USB_BUFFER_SUBMITTED) return;
00111 PRINTF("usb_get_ctrl_data: %d\n",length);
00112 data_callback = cb;
00113 ctrl_data = data;
00114 ctrl_data_len = length;
00115 ctrl_buffer.flags = USB_BUFFER_NOTIFY;
00116 ctrl_buffer.next = NULL;
00117 ctrl_buffer.data = data;
00118 ctrl_buffer.left = length;
00119 ctrl_buffer.id = OUT_ID;
00120 usb_submit_recv_buffer(0,&ctrl_buffer);
00121 }
00122
00123 #if 0
00124
00125 void
00126 usb_set_user_process(struct process *p)
00127 {
00128 user_process = p;
00129 }
00130 #endif
00131
00132 static void
00133 get_device_descriptor()
00134 {
00135 usb_send_ctrl_response((unsigned char*)&device_descriptor, sizeof(device_descriptor));
00136 }
00137
00138 static void
00139 get_string_descriptor()
00140 {
00141 #if OLD_STRING_DESCR
00142 if (LOW_BYTE(usb_setup_buffer.wValue) == 0) {
00143 usb_send_ctrl_response((const unsigned char*)string_languages->lang_descr,
00144 string_languages->lang_descr->bLength);
00145 } else {
00146 const struct usb_st_string_descriptor *descriptor;
00147 unsigned char l;
00148 const struct usb_st_string_descriptor * const *table;
00149 const struct usb_st_string_language_map *map;
00150 if (LOW_BYTE(usb_setup_buffer.wValue) > string_languages->max_index) {
00151 usb_error_stall();
00152 return;
00153 }
00154 l = string_languages->num_lang;
00155 map = string_languages->map;
00156 table = map->descriptors;
00157 while (l > 0) {
00158 if (map->lang_id == usb_setup_buffer.wIndex) {
00159 table = map->descriptors;
00160 break;
00161 }
00162 map++;
00163 l--;
00164 }
00165 PRINTF("Lang id %04x = table %p\n", usb_setup_buffer.wIndex, (void*)table);
00166 descriptor = table[LOW_BYTE(usb_setup_buffer.wValue) - 1];
00167 usb_send_ctrl_response((const unsigned char*)descriptor,
00168 descriptor->bLength);
00169 }
00170 #else
00171 const struct usb_st_string_descriptor *descriptor;
00172 descriptor = (struct usb_st_string_descriptor*)
00173 usb_class_get_string_descriptor(usb_setup_buffer.wIndex,
00174 LOW_BYTE(usb_setup_buffer.wValue));
00175 if (!descriptor) {
00176 usb_error_stall();
00177 return;
00178 }
00179 usb_send_ctrl_response((const unsigned char*)descriptor,
00180 descriptor->bLength);
00181 #endif
00182 }
00183
00184 static void
00185 get_configuration_descriptor()
00186 {
00187 usb_send_ctrl_response((unsigned char*)configuration_head,
00188 configuration_head->wTotalLength);
00189 }
00190
00191 static void
00192 get_configuration()
00193 {
00194 usb_send_ctrl_response((unsigned char*)&usb_configuration_value,
00195 sizeof(usb_configuration_value));
00196 }
00197
00198
00199 static int
00200 set_configuration()
00201 {
00202 notify_user(USB_EVENT_CONFIG);
00203 if (usb_configuration_value != LOW_BYTE(usb_setup_buffer.wValue)) {
00204 usb_configuration_value = LOW_BYTE(usb_setup_buffer.wValue);
00205 usb_arch_set_configuration(usb_configuration_value);
00206 usb_send_ctrl_status();
00207 return 1;
00208 } else {
00209 usb_send_ctrl_status();
00210 return 0;
00211 }
00212 }
00213
00214 static void
00215 get_device_status()
00216 {
00217 PRINTF("get_device_status\n");
00218 usb_send_ctrl_response((const unsigned char*)&usb_device_status,
00219 sizeof(usb_device_status));
00220 }
00221
00222 static void
00223 get_endpoint_status()
00224 {
00225 static uint16_t status;
00226 PRINTF("get_endpoint_status\n");
00227 if ((usb_setup_buffer.wIndex & 0x7f) == 0) {
00228 usb_send_ctrl_response((const unsigned char*)&zero_word,
00229 sizeof(zero_word));
00230 } else {
00231 status = usb_arch_get_ep_status(usb_setup_buffer.wIndex);
00232 usb_send_ctrl_response((uint8_t*)&status, sizeof(status));
00233 }
00234 }
00235
00236 static void
00237 get_interface_status()
00238 {
00239 PRINTF("get_interface_status\n");
00240 usb_send_ctrl_response((const unsigned char*)&zero_word,
00241 sizeof(zero_word));
00242 }
00243
00244 static void
00245 get_interface()
00246 {
00247 PRINTF("get_interface\n");
00248 if (usb_configuration_value == 0) usb_error_stall();
00249 else {
00250 usb_send_ctrl_response(&zero_byte,
00251 sizeof(zero_byte));
00252 }
00253 }
00254
00255
00256 static unsigned int
00257 handle_standard_requests()
00258 {
00259 switch(usb_setup_buffer.bmRequestType) {
00260 case 0x80:
00261 switch(usb_setup_buffer.bRequest) {
00262 case GET_DESCRIPTOR:
00263 switch (HIGH_BYTE(usb_setup_buffer.wValue)) {
00264 case DEVICE:
00265 get_device_descriptor();
00266 break;
00267 case CONFIGURATION:
00268 get_configuration_descriptor();
00269 break;
00270 case STRING:
00271 get_string_descriptor();
00272 break;
00273 default:
00274
00275 return 0;
00276 }
00277 break;
00278 case GET_CONFIGURATION:
00279 get_configuration();
00280 break;
00281 case GET_STATUS:
00282 get_device_status();
00283 break;
00284 case GET_INTERFACE:
00285 get_interface();
00286 break;
00287 default:
00288 return 0;
00289 }
00290 break;
00291 case 0x81:
00292 switch(usb_setup_buffer.bRequest) {
00293 case GET_STATUS:
00294 get_interface_status();
00295 break;
00296 #ifdef HID_ENABLED
00297 case GET_DESCRIPTOR:
00298 switch (USB_setup_buffer.wValue.byte.high) {
00299 case REPORT:
00300 get_report_descriptor();
00301 break;
00302 }
00303 break;
00304 #endif
00305 default:
00306 return 0;
00307 }
00308 break;
00309 case 0x82:
00310 switch(usb_setup_buffer.bRequest) {
00311 case GET_STATUS:
00312 get_endpoint_status();
00313 break;
00314 default:
00315 return 0;
00316 }
00317 break;
00318 case 0x00:
00319 switch(usb_setup_buffer.bRequest) {
00320 case SET_ADDRESS:
00321 PRINTF("Address: %d\n", LOW_BYTE(usb_setup_buffer.wValue));
00322 usb_flags |= USB_FLAG_ADDRESS_PENDING;
00323
00324
00325 usb_send_ctrl_status();
00326 break;
00327 #if SETABLE_STRING_DESCRIPTORS > 0
00328 case SET_DESCRIPTOR:
00329 if (usb_setup_buffer.wValue.byte.high == STRING) {
00330 set_string_descriptor();
00331 } else {
00332 return 0;
00333 }
00334 break;
00335 #endif
00336 case SET_CONFIGURATION:
00337 if (set_configuration()) {
00338 #if 0
00339 config_msg.data.config = LOW_BYTE(usb_setup_buffer.wValue);
00340 notify_user(&config_msg);
00341 #endif
00342 }
00343 break;
00344 default:
00345 return 0;
00346 }
00347 break;
00348 case 0x01:
00349 switch(usb_setup_buffer.bRequest) {
00350 case SET_INTERFACE:
00351
00352 usb_send_ctrl_status();
00353 break;
00354 default:
00355 return 0;
00356 }
00357 break;
00358 case 0x02:
00359 switch(usb_setup_buffer.bRequest) {
00360 case SET_FEATURE:
00361 case CLEAR_FEATURE:
00362 if (usb_setup_buffer.wValue == ENDPOINT_HALT_FEATURE) {
00363 usb_arch_halt_endpoint(usb_setup_buffer.wIndex, usb_setup_buffer.bRequest== SET_FEATURE);
00364 usb_send_ctrl_status();
00365 } else {
00366 usb_error_stall();
00367 }
00368 break;
00369 default:
00370 return 0;
00371 }
00372 break;
00373 #ifdef HID_ENABLED
00374 case 0xa1:
00375 switch(USB_setup_buffer.bRequest) {
00376 case GET_HID_REPORT:
00377 PRINTF("Get report\n");
00378 send_ctrl_response((code u_int8_t*)&zero_byte,
00379 sizeof(zero_byte));
00380 break;
00381 case GET_HID_IDLE:
00382 PRINTF("Get idle\n");
00383 send_ctrl_response((code u_int8_t*)&zero_byte,
00384 sizeof(zero_byte));
00385 break;
00386 default:
00387 return 0;
00388 }
00389 break;
00390 case 0x21:
00391 switch(USB_setup_buffer.bRequest) {
00392 case SET_HID_IDLE:
00393 PRINTF("Set idle\n");
00394 send_ctrl_status();
00395 break;
00396 default:
00397 return 0;
00398 }
00399 break;
00400 #endif
00401 default:
00402 return 0;
00403 }
00404 return 1;
00405 }
00406
00407 static const struct USBRequestHandler standard_request_handler =
00408 {
00409 0x00, 0x60,
00410 0x00, 0x00,
00411 handle_standard_requests
00412 };
00413
00414 static struct USBRequestHandlerHook standard_request_hook =
00415 {
00416 NULL,
00417 &standard_request_handler
00418 };
00419
00420 static void
00421 submit_setup(void)
00422 {
00423 ctrl_buffer.next = NULL;
00424 ctrl_buffer.data = (uint8_t*)&usb_setup_buffer;
00425 ctrl_buffer.left = sizeof(usb_setup_buffer);
00426 ctrl_buffer.flags = (USB_BUFFER_PACKET_END | USB_BUFFER_SETUP
00427 | USB_BUFFER_NOTIFY);
00428 ctrl_buffer.id = SETUP_ID;
00429 usb_submit_recv_buffer(0, &ctrl_buffer);
00430 }
00431
00432 PROCESS(usb_process, "USB");
00433
00434 PROCESS_THREAD(usb_process, ev , data)
00435 {
00436 PROCESS_BEGIN();
00437 PRINTF("USB process started\n");
00438 while(1) {
00439 PROCESS_WAIT_EVENT();
00440 if (ev == PROCESS_EVENT_EXIT) break;
00441 if (ev == PROCESS_EVENT_POLL) {
00442 unsigned int events = usb_arch_get_global_events();
00443 if (events) {
00444 if (events & USB_EVENT_RESET) {
00445 submit_setup();
00446 usb_configuration_value = 0;
00447 notify_user(USB_EVENT_RESET);
00448 }
00449 if (events & USB_EVENT_SUSPEND) {
00450 notify_user(USB_EVENT_SUSPEND);
00451 }
00452 if (events & USB_EVENT_RESUME) {
00453 notify_user(USB_EVENT_RESUME);
00454 }
00455
00456 }
00457 events = usb_get_ep_events(0);
00458 if (events) {
00459 if ((events & USB_EP_EVENT_NOTIFICATION)
00460 && !(ctrl_buffer.flags & USB_BUFFER_SUBMITTED)) {
00461
00462 if (ctrl_buffer.flags & USB_BUFFER_FAILED) {
00463
00464
00465 PRINTF("Discarded\n");
00466 submit_setup();
00467 } else if (ctrl_buffer.flags & USB_BUFFER_SETUP) {
00468 struct USBRequestHandlerHook *hook = usb_request_handler_hooks;
00469
00470 PRINTF("Setup\n");
00471 {
00472 unsigned int i;
00473 for (i = 0; i< 8; i++) PRINTF(" %02x", ((unsigned char*)&usb_setup_buffer)[i]);
00474 PRINTF("\n");
00475 }
00476
00477 while(hook) {
00478 const struct USBRequestHandler *handler = hook->handler;
00479
00480 if (((handler->request_type ^ usb_setup_buffer.bmRequestType)
00481 & handler->request_type_mask) == 0
00482 && ((handler->request ^ usb_setup_buffer.bRequest)
00483 & handler->request_mask) == 0) {
00484 if (handler->handler_func()) break;
00485 }
00486 hook = hook->next;
00487 }
00488 if (!hook) {
00489
00490 usb_error_stall();
00491 PRINTF("Unhandled setup: %02x %02x %04x %04x %04x\n",
00492 usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest,
00493 usb_setup_buffer.wValue, usb_setup_buffer.wIndex,
00494 usb_setup_buffer.wLength);
00495 }
00496
00497
00498 if (error_stall) {
00499 error_stall = 0;
00500 submit_setup();
00501 }
00502 } else {
00503 if (ctrl_buffer.id == IN_ID) {
00504
00505 PRINTF("Status OUT\n");
00506 ctrl_buffer.flags = USB_BUFFER_NOTIFY;
00507 ctrl_buffer.next = NULL;
00508 ctrl_buffer.data = NULL;
00509 ctrl_buffer.left = 0;
00510 ctrl_buffer.id = STATUS_OUT_ID;
00511 usb_submit_recv_buffer(0,&ctrl_buffer);
00512 } else if (ctrl_buffer.id == STATUS_OUT_ID) {
00513 PRINTF("Status OUT done\n");
00514 submit_setup();
00515 } else if (ctrl_buffer.id == STATUS_IN_ID) {
00516 PRINTF("Status IN done\n");
00517 if (usb_flags & USB_FLAG_ADDRESS_PENDING) {
00518 while(usb_send_pending(0));
00519 usb_arch_set_address(LOW_BYTE(usb_setup_buffer.wValue));
00520 usb_flags &= ~USB_FLAG_ADDRESS_PENDING;
00521 }
00522 submit_setup();
00523 } else if (ctrl_buffer.id == OUT_ID) {
00524 PRINTF("OUT\n");
00525 if (data_callback) {
00526 data_callback(ctrl_data, ctrl_data_len- ctrl_buffer.left);
00527 } else {
00528 usb_send_ctrl_status();
00529 }
00530 }
00531 }
00532 }
00533 }
00534 }
00535 }
00536 PROCESS_END();
00537 }
00538
00539
00540 void
00541 usb_setup(void)
00542 {
00543 usb_arch_setup();
00544 process_start(&usb_process, NULL);
00545 usb_arch_set_global_event_process(&usb_process);
00546 usb_set_ep_event_process(0, &usb_process);
00547
00548 usb_register_request_handler(&standard_request_hook);
00549 }
00550
00551 void
00552 usb_register_request_handler(struct USBRequestHandlerHook *hook)
00553 {
00554 struct USBRequestHandlerHook **prevp = &usb_request_handler_hooks;
00555
00556 while(*prevp) {
00557 prevp = &(*prevp)->next;
00558 }
00559
00560 *prevp = hook;
00561 hook->next = NULL;
00562 }
00563
00564 void
00565 usb_prepend_request_handler(struct USBRequestHandlerHook *hook)
00566 {
00567 hook->next = usb_request_handler_hooks;
00568 usb_request_handler_hooks = hook;
00569 }
00570
00571
00572 unsigned int
00573 usb_get_current_configuration(void)
00574 {
00575 return usb_configuration_value;
00576 }
00577
00578 void
00579 usb_setup_bulk_endpoint(unsigned char addr)
00580 {
00581 usb_arch_setup_bulk_endpoint(addr);
00582 }
00583
00584 void
00585 usb_setup_interrupt_endpoint(unsigned char addr)
00586 {
00587 usb_arch_setup_interrupt_endpoint(addr);
00588 }
00589
00590 void
00591 usb_disable_endpoint(uint8_t addr)
00592 {
00593 usb_arch_discard_all_buffers(addr);
00594 usb_arch_disable_endpoint(addr);
00595 }
00596
00597 void
00598 usb_discard_all_buffers(uint8_t addr)
00599 {
00600 usb_arch_discard_all_buffers(addr);
00601 }
00602
00603 void
00604 usb_halt_endpoint(uint8_t addr, int halt)
00605 {
00606 usb_arch_halt_endpoint(addr, halt);
00607 }
00608
00609 int
00610 usb_send_pending(uint8_t addr)
00611 {
00612 return usb_arch_send_pending(addr);
00613 }
00614