Contiki 2.6
|
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; /* Truncate if too long */ 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; /* Use first table if language not found */ 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 /* Returns true if the configuration value changed */ 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: /* standard device IN requests */ 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 /* Unknown descriptor */ 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: /* standard interface IN requests */ 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: /* standard endpoint IN requests */ 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: /* standard device OUT requests */ 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 /* The actual setting of the address is done when the status packet 00324 is sent. */ 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: /* standard interface OUT requests */ 00349 switch(usb_setup_buffer.bRequest) { 00350 case SET_INTERFACE: 00351 /* Change interface here if we support more than one */ 00352 usb_send_ctrl_status(); 00353 break; 00354 default: 00355 return 0; 00356 } 00357 break; 00358 case 0x02: /* standard endpoint OUT requests */ 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: /* class specific interface IN request*/ 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: /* class specific interface OUT request*/ 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 /* PRINTF("Endpoint 0\n"); */ 00462 if (ctrl_buffer.flags & USB_BUFFER_FAILED) { 00463 /* Something went wrong with the buffer, just wait for a 00464 new SETUP packet */ 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 /* Check if the handler matches the request */ 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 /* No handler found */ 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 /* Check if any handler stalled the pipe, if so prepare for 00497 next setup */ 00498 if (error_stall) { 00499 error_stall = 0; 00500 submit_setup(); 00501 } 00502 } else { 00503 if (ctrl_buffer.id == IN_ID) { 00504 /* Receive status stage */ 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 /* Find last hook */ 00556 while(*prevp) { 00557 prevp = &(*prevp)->next; 00558 } 00559 /* Add last */ 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