comparison Output/pjrcUSB/arm/usb_dev.c @ 368:06a54d582bf8

FIxing Media Keys and general USB compatibilty - Media keys tested working on Linux/Windows/Mac (use Consumer control) - Fixed enumeration delays - Fixed virtual serial port configuration issues - Fixed GET_REPORT and SET_REPORT - Added intial descriptors and endpoints for Mouse and Joystick devices - Split out the consumer and system control endpoint - Added more fault debugging messages - Added interface names to endpoints (visible in Windows Device Manager) - Added KLL define for keyboard locale
author Jacob Alexander <haata@kiibohd.com>
date Wed, 19 Aug 2015 00:01:15 -0700
parents 136e47478441
children 39e338a6733d
comparison
equal deleted inserted replaced
367:8a6c2d410ad9 368:06a54d582bf8
171 171
172 // ----- Functions ----- 172 // ----- Functions -----
173 173
174 static void endpoint0_stall() 174 static void endpoint0_stall()
175 { 175 {
176 #ifdef UART_DEBUG_UNKNOWN
177 print("STALL" NL );
178 #endif
176 USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; 179 USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
177 } 180 }
178 181
179 static void endpoint0_transmit( const void *data, uint32_t len ) 182 static void endpoint0_transmit( const void *data, uint32_t len )
180 { 183 {
196 int i; 199 int i;
197 200
198 switch ( setup.wRequestAndType ) 201 switch ( setup.wRequestAndType )
199 { 202 {
200 case 0x0500: // SET_ADDRESS 203 case 0x0500: // SET_ADDRESS
201 break; 204 goto send;
205
202 case 0x0900: // SET_CONFIGURATION 206 case 0x0900: // SET_CONFIGURATION
203 #ifdef UART_DEBUG 207 #ifdef UART_DEBUG
204 print("CONFIGURE - "); 208 print("CONFIGURE - ");
205 #endif 209 #endif
206 usb_configuration = setup.wValue; 210 usb_configuration = setup.wValue;
286 } 290 }
287 } 291 }
288 table[ index( i, TX, EVEN ) ].desc = 0; 292 table[ index( i, TX, EVEN ) ].desc = 0;
289 table[ index( i, TX, ODD ) ].desc = 0; 293 table[ index( i, TX, ODD ) ].desc = 0;
290 } 294 }
291 break; 295 goto send;
296
292 case 0x0880: // GET_CONFIGURATION 297 case 0x0880: // GET_CONFIGURATION
293 reply_buffer[0] = usb_configuration; 298 reply_buffer[0] = usb_configuration;
294 datalen = 1; 299 datalen = 1;
295 data = reply_buffer; 300 data = reply_buffer;
296 break; 301 goto send;
302
297 case 0x0080: // GET_STATUS (device) 303 case 0x0080: // GET_STATUS (device)
298 reply_buffer[0] = 0; 304 reply_buffer[0] = 0;
299 reply_buffer[1] = 0; 305 reply_buffer[1] = 0;
300 datalen = 2; 306 datalen = 2;
301 data = reply_buffer; 307 data = reply_buffer;
302 break; 308 goto send;
309
303 case 0x0082: // GET_STATUS (endpoint) 310 case 0x0082: // GET_STATUS (endpoint)
304 if ( setup.wIndex > NUM_ENDPOINTS ) 311 if ( setup.wIndex > NUM_ENDPOINTS )
305 { 312 {
306 // TODO: do we need to handle IN vs OUT here? 313 // TODO: do we need to handle IN vs OUT here?
307 endpoint0_stall(); 314 endpoint0_stall();
311 reply_buffer[1] = 0; 318 reply_buffer[1] = 0;
312 if ( *(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02 ) 319 if ( *(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02 )
313 reply_buffer[0] = 1; 320 reply_buffer[0] = 1;
314 data = reply_buffer; 321 data = reply_buffer;
315 datalen = 2; 322 datalen = 2;
316 break; 323 goto send;
324
317 case 0x0100: // CLEAR_FEATURE (device) 325 case 0x0100: // CLEAR_FEATURE (device)
318 case 0x0101: // CLEAR_FEATURE (interface) 326 case 0x0101: // CLEAR_FEATURE (interface)
319 // TODO: Currently ignoring, perhaps useful? -HaaTa 327 // TODO: Currently ignoring, perhaps useful? -HaaTa
328 warn_print("CLEAR_FEATURE - Device/Interface");
320 endpoint0_stall(); 329 endpoint0_stall();
321 return; 330 return;
331
322 case 0x0102: // CLEAR_FEATURE (interface) 332 case 0x0102: // CLEAR_FEATURE (interface)
323 i = setup.wIndex & 0x7F; 333 i = setup.wIndex & 0x7F;
324 if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) 334 if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
325 { 335 {
326 endpoint0_stall(); 336 endpoint0_stall();
327 return; 337 return;
328 } 338 }
339 warn_print("CLEAR_FEATURE - Interface");
329 //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; 340 //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
330 // TODO: do we need to clear the data toggle here? 341 // TODO: do we need to clear the data toggle here?
331 //break; 342 //break;
332 343
333 // FIXME: Clearing causes keyboard to freeze, likely an invalid clear 344 // FIXME: Clearing causes keyboard to freeze, likely an invalid clear
334 // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa 345 // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa
335 endpoint0_stall(); 346 endpoint0_stall();
336 return; 347 return;
348
337 case 0x0300: // SET_FEATURE (device) 349 case 0x0300: // SET_FEATURE (device)
338 case 0x0301: // SET_FEATURE (interface) 350 case 0x0301: // SET_FEATURE (interface)
339 // TODO: Currently ignoring, perhaps useful? -HaaTa 351 // TODO: Currently ignoring, perhaps useful? -HaaTa
352 warn_print("SET_FEATURE");
340 endpoint0_stall(); 353 endpoint0_stall();
341 return; 354 return;
355
342 case 0x0302: // SET_FEATURE (endpoint) 356 case 0x0302: // SET_FEATURE (endpoint)
343 i = setup.wIndex & 0x7F; 357 i = setup.wIndex & 0x7F;
344 if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) 358 if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
345 { 359 {
346 // TODO: do we need to handle IN vs OUT here? 360 // TODO: do we need to handle IN vs OUT here?
347 endpoint0_stall(); 361 endpoint0_stall();
348 return; 362 return;
349 } 363 }
350 (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; 364 (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02;
351 // TODO: do we need to clear the data toggle here? 365 // TODO: do we need to clear the data toggle here?
352 break; 366 goto send;
367
353 case 0x0680: // GET_DESCRIPTOR 368 case 0x0680: // GET_DESCRIPTOR
354 case 0x0681: 369 case 0x0681:
355 #ifdef UART_DEBUG 370 #ifdef UART_DEBUG
356 print("desc:"); 371 print("desc:");
357 printHex( setup.wValue ); 372 printHex( setup.wValue );
399 return; 414 return;
400 415
401 case 0x2221: // CDC_SET_CONTROL_LINE_STATE 416 case 0x2221: // CDC_SET_CONTROL_LINE_STATE
402 usb_cdc_line_rtsdtr = setup.wValue; 417 usb_cdc_line_rtsdtr = setup.wValue;
403 //serial_print("set control line state\n"); 418 //serial_print("set control line state\n");
404 endpoint0_stall(); 419 goto send;
405 return;
406 420
407 case 0x21A1: // CDC_GET_LINE_CODING 421 case 0x21A1: // CDC_GET_LINE_CODING
408 data = (uint8_t*)usb_cdc_line_coding; 422 data = (uint8_t*)usb_cdc_line_coding;
409 datalen = sizeof( usb_cdc_line_coding ); 423 datalen = sizeof( usb_cdc_line_coding );
410 goto send; 424 goto send;
411 425
412 case 0x2021: // CDC_SET_LINE_CODING 426 case 0x2021: // CDC_SET_LINE_CODING
413 // XXX Needed? 427 // XXX Needed?
414 //serial_print("set coding, waiting...\n"); 428 //serial_print("set coding, waiting...\n");
415 endpoint0_stall(); 429 return;
416 return; // Cannot stall here (causes issues)
417 430
418 case 0x0921: // HID SET_REPORT 431 case 0x0921: // HID SET_REPORT
419 #ifdef UART_DEBUG 432 #ifdef UART_DEBUG
420 print("SET_REPORT - "); 433 warn_msg("SET_REPORT - ");
421 printHex( setup.wValue ); 434 printHex( setup.wValue );
422 print(" - "); 435 print(" - ");
423 printHex( setup.wValue & 0xFF ); 436 printHex( setup.wValue & 0xFF );
424 print( NL ); 437 print( NL );
425 #endif 438 #endif
426 USBKeys_LEDs = setup.wValue & 0xFF; 439 USBKeys_LEDs = setup.wValue & 0xFF;
440
441 // Must be stall for some reason... -HaaTa
427 endpoint0_stall(); 442 endpoint0_stall();
428 return; 443 return;
429 444
430 case 0x01A1: // HID GET_REPORT 445 case 0x01A1: // HID GET_REPORT
431 #ifdef UART_DEBUG 446 #ifdef UART_DEBUG
432 print("GET_REPORT - "); 447 print("GET_REPORT - ");
433 printHex( USBKeys_LEDs ); 448 printHex( setup.wIndex );
434 print(NL); 449 print(NL);
435 #endif 450 #endif
436 data = (uint8_t*)&USBKeys_LEDs; 451 // Search through descriptors returning necessary info
437 datalen = 1; 452 for ( list = usb_descriptor_list; 1; list++ )
438 goto send; 453 {
454 if ( list->addr == NULL )
455 break;
456 if ( list->wValue != 0x2200 )
457 continue;
458 if ( setup.wIndex == list->wIndex )
459 {
460 data = list->addr;
461 datalen = list->length;
462 goto send;
463 }
464 }
465 endpoint0_stall();
466 return;
439 467
440 case 0x0A21: // HID SET_IDLE 468 case 0x0A21: // HID SET_IDLE
441 #ifdef UART_DEBUG 469 #ifdef UART_DEBUG
442 print("SET_IDLE - "); 470 print("SET_IDLE - ");
443 printHex( setup.wValue ); 471 printHex( setup.wValue );
444 print(NL); 472 print(NL);
445 #endif 473 #endif
446 USBKeys_Idle_Config = (setup.wValue >> 8); 474 USBKeys_Idle_Config = (setup.wValue >> 8);
447 USBKeys_Idle_Count = 0; 475 USBKeys_Idle_Count = 0;
448 endpoint0_stall(); 476 goto send;
449 return;
450 477
451 case 0x0B21: // HID SET_PROTOCOL 478 case 0x0B21: // HID SET_PROTOCOL
452 #ifdef UART_DEBUG 479 #ifdef UART_DEBUG
453 print("SET_PROTOCOL - "); 480 print("SET_PROTOCOL - ");
454 printHex( setup.wValue ); 481 printHex( setup.wValue );
455 print(" - "); 482 print(" - ");
456 printHex( setup.wValue & 0xFF ); 483 printHex( setup.wValue & 0xFF );
457 print(NL); 484 print(NL);
458 #endif 485 #endif
459 USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode 486 USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode
460 endpoint0_stall(); 487 goto send;
461 return;
462 488
463 // case 0xC940: 489 // case 0xC940:
464 default: 490 default:
465 #ifdef UART_DEBUG_UNKNOWN 491 #ifdef UART_DEBUG_UNKNOWN
466 print("UNKNOWN"); 492 print("UNKNOWN");
470 } 496 }
471 497
472 send: 498 send:
473 #ifdef UART_DEBUG 499 #ifdef UART_DEBUG
474 print("setup send "); 500 print("setup send ");
475 printHex32((uint32_t)data); 501 printHex32( (uint32_t)data );
476 print(","); 502 print(",");
477 printHex(datalen); 503 for ( uint8_t c = 0; c < datalen; c++ )
478 print(NL); 504 {
505 printHex( data[c] );
506 print(" ");
507 }
508 print(",");
509 printHex( datalen );
510 print( NL );
479 #endif 511 #endif
480 512
481 if ( datalen > setup.wLength ) 513 if ( datalen > setup.wLength )
482 datalen = setup.wLength; 514 datalen = setup.wLength;
483 515
590 // actually "do" the setup request 622 // actually "do" the setup request
591 usb_setup(); 623 usb_setup();
592 // unfreeze the USB, now that we're ready 624 // unfreeze the USB, now that we're ready
593 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit 625 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
594 break; 626 break;
627
595 case 0x01: // OUT transaction received from host 628 case 0x01: // OUT transaction received from host
596 case 0x02: 629 case 0x02:
597 #ifdef UART_DEBUG 630 #ifdef UART_DEBUG
598 print("PID=OUT"NL); 631 print("PID=OUT"NL);
599 #endif 632 #endif
661 #endif 694 #endif
662 USB0_ADDR = setup.wValue; 695 USB0_ADDR = setup.wValue;
663 } 696 }
664 697
665 break; 698 break;
699
666 default: 700 default:
667 #ifdef UART_DEBUG 701 #ifdef UART_DEBUG
668 print("PID=unknown:"); 702 print("PID=unknown:");
669 printHex(pid); 703 printHex(pid);
670 print(NL); 704 print(NL);