]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Output/pjrcUSB/arm/usb_dev.c
Fixing Mac OSX freeze on wake-up bug
[kiibohd-controller.git] / Output / pjrcUSB / arm / usb_dev.c
1 /* Teensyduino Core Library
2  * http://www.pjrc.com/teensy/
3  * Copyright (c) 2013 PJRC.COM, LLC.
4  * Modifications by Jacob Alexander (2013-2014)
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * 1. The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * 2. If the Software is incorporated into a build system that allows
18  * selection among a list of target devices, then similar target
19  * devices manufactured by PJRC.COM must be included in the list of
20  * target devices and selectable in the same manner.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29  * SOFTWARE.
30  */
31
32 // ----- Includes -----
33
34 // Project Includes
35 #include <Lib/OutputLib.h>
36 #include <print.h>
37
38 // Local Includes
39 #include "usb_dev.h"
40 #include "usb_mem.h"
41
42
43
44 // ----- Defines -----
45
46 // DEBUG Mode
47 // XXX - Only use when using usbMuxUart Module
48 // Delay causes issues initializing more than 1 hid device (i.e. NKRO keyboard)
49 //#define UART_DEBUG 1
50 // Debug Unknown USB requests, usually what you want to debug USB issues
51 //#define UART_DEBUG_UNKNOWN 1
52
53
54 #define TX_STATE_BOTH_FREE_EVEN_FIRST   0
55 #define TX_STATE_BOTH_FREE_ODD_FIRST    1
56 #define TX_STATE_EVEN_FREE              2
57 #define TX_STATE_ODD_FREE               3
58 #define TX_STATE_NONE_FREE_EVEN_FIRST   4
59 #define TX_STATE_NONE_FREE_ODD_FIRST    5
60
61 #define BDT_OWN         0x80
62 #define BDT_DATA1       0x40
63 #define BDT_DATA0       0x00
64 #define BDT_DTS         0x08
65 #define BDT_STALL       0x04
66
67 #define TX    1
68 #define RX    0
69 #define ODD   1
70 #define EVEN  0
71 #define DATA0 0
72 #define DATA1 1
73
74
75 #define GET_STATUS              0
76 #define CLEAR_FEATURE           1
77 #define SET_FEATURE             3
78 #define SET_ADDRESS             5
79 #define GET_DESCRIPTOR          6
80 #define SET_DESCRIPTOR          7
81 #define GET_CONFIGURATION       8
82 #define SET_CONFIGURATION       9
83 #define GET_INTERFACE           10
84 #define SET_INTERFACE           11
85 #define SYNCH_FRAME             12
86
87 #define TX_STATE_BOTH_FREE_EVEN_FIRST   0
88 #define TX_STATE_BOTH_FREE_ODD_FIRST    1
89 #define TX_STATE_EVEN_FREE              2
90 #define TX_STATE_ODD_FREE               3
91 #define TX_STATE_NONE_FREE              4
92
93
94
95
96
97 // ----- Macros -----
98
99 #define BDT_PID(n)      (((n) >> 2) & 15)
100
101 #define BDT_DESC(count, data)   (BDT_OWN | BDT_DTS \
102                                 | ((data) ? BDT_DATA1 : BDT_DATA0) \
103                                 | ((count) << 16))
104
105 #define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
106 #define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
107
108
109
110 // ----- Structs -----
111
112 // buffer descriptor table
113
114 typedef struct {
115         uint32_t desc;
116         void * addr;
117 } bdt_t;
118
119 static union {
120         struct {
121                 union {
122                         struct {
123                                 uint8_t bmRequestType;
124                                 uint8_t bRequest;
125                         };
126                         uint16_t wRequestAndType;
127                 };
128                 uint16_t wValue;
129                 uint16_t wIndex;
130                 uint16_t wLength;
131         };
132         struct {
133                 uint32_t word1;
134                 uint32_t word2;
135         };
136 } setup;
137
138
139
140 // ----- Variables -----
141
142 __attribute__ ((section(".usbdescriptortable"), used))
143 static bdt_t table[ (NUM_ENDPOINTS + 1) * 4 ];
144
145 static usb_packet_t *rx_first  [ NUM_ENDPOINTS ];
146 static usb_packet_t *rx_last   [ NUM_ENDPOINTS ];
147 static usb_packet_t *tx_first  [ NUM_ENDPOINTS ];
148 static usb_packet_t *tx_last   [ NUM_ENDPOINTS ];
149 uint16_t usb_rx_byte_count_data[ NUM_ENDPOINTS ];
150
151 static uint8_t tx_state[NUM_ENDPOINTS];
152
153 // SETUP always uses a DATA0 PID for the data field of the SETUP transaction.
154 // transactions in the data phase start with DATA1 and toggle (figure 8-12, USB1.1)
155 // Status stage uses a DATA1 PID.
156
157 static uint8_t ep0_rx0_buf[EP0_SIZE] __attribute__ ((aligned (4)));
158 static uint8_t ep0_rx1_buf[EP0_SIZE] __attribute__ ((aligned (4)));
159 static const uint8_t *ep0_tx_ptr = NULL;
160 static uint16_t ep0_tx_len;
161 static uint8_t ep0_tx_bdt_bank = 0;
162 static uint8_t ep0_tx_data_toggle = 0;
163 uint8_t usb_rx_memory_needed = 0;
164
165 volatile uint8_t usb_configuration = 0;
166 volatile uint8_t usb_reboot_timer = 0;
167
168 static uint8_t reply_buffer[8];
169
170
171
172 // ----- Functions -----
173
174 static void endpoint0_stall()
175 {
176         USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
177 }
178
179 static void endpoint0_transmit( const void *data, uint32_t len )
180 {
181         table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data;
182         table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
183         ep0_tx_data_toggle ^= 1;
184         ep0_tx_bdt_bank ^= 1;
185 }
186
187 static void usb_setup()
188 {
189         const uint8_t *data = NULL;
190         uint32_t datalen = 0;
191         const usb_descriptor_list_t *list;
192         uint32_t size;
193         volatile uint8_t *reg;
194         uint8_t epconf;
195         const uint8_t *cfg;
196         int i;
197
198         switch ( setup.wRequestAndType )
199         {
200         case 0x0500: // SET_ADDRESS
201                 break;
202         case 0x0900: // SET_CONFIGURATION
203                 #ifdef UART_DEBUG
204                 print("CONFIGURE - ");
205                 #endif
206                 usb_configuration = setup.wValue;
207                 reg = &USB0_ENDPT1;
208                 cfg = usb_endpoint_config_table;
209                 // clear all BDT entries, free any allocated memory...
210                 for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ )
211                 {
212                         if ( table[i].desc & BDT_OWN )
213                         {
214                                 usb_free( (usb_packet_t *)((uint8_t *)(table[ i ].addr) - 8) );
215                         }
216                 }
217                 // free all queued packets
218                 for ( i = 0; i < NUM_ENDPOINTS; i++ )
219                 {
220                         usb_packet_t *p, *n;
221                         p = rx_first[i];
222                         while ( p )
223                         {
224                                 n = p->next;
225                                 usb_free(p);
226                                 p = n;
227                         }
228                         rx_first[ i ] = NULL;
229                         rx_last[ i ] = NULL;
230                         p = tx_first[i];
231                         while (p)
232                         {
233                                 n = p->next;
234                                 usb_free(p);
235                                 p = n;
236                         }
237                         tx_first[ i ] = NULL;
238                         tx_last[ i ] = NULL;
239                         usb_rx_byte_count_data[i] = 0;
240
241                         switch ( tx_state[ i ] )
242                         {
243                         case TX_STATE_EVEN_FREE:
244                         case TX_STATE_NONE_FREE_EVEN_FIRST:
245                                 tx_state[ i ] = TX_STATE_BOTH_FREE_EVEN_FIRST;
246                                 break;
247                         case TX_STATE_ODD_FREE:
248                         case TX_STATE_NONE_FREE_ODD_FIRST:
249                                 tx_state[ i ] = TX_STATE_BOTH_FREE_ODD_FIRST;
250                                 break;
251                         default:
252                                 break;
253                         }
254                 }
255                 usb_rx_memory_needed = 0;
256                 for ( i = 1; i <= NUM_ENDPOINTS; i++ )
257                 {
258                         epconf = *cfg++;
259                         *reg = epconf;
260                         reg += 4;
261                         if ( epconf & USB_ENDPT_EPRXEN )
262                         {
263                                 usb_packet_t *p;
264                                 p = usb_malloc();
265                                 if ( p )
266                                 {
267                                         table[ index( i, RX, EVEN ) ].addr = p->buf;
268                                         table[ index( i, RX, EVEN ) ].desc = BDT_DESC( 64, 0 );
269                                 }
270                                 else
271                                 {
272                                         table[ index( i, RX, EVEN ) ].desc = 0;
273                                         usb_rx_memory_needed++;
274                                 }
275                                 p = usb_malloc();
276                                 if ( p )
277                                 {
278                                         table[ index( i, RX, ODD ) ].addr = p->buf;
279                                         table[ index( i, RX, ODD ) ].desc = BDT_DESC( 64, 1 );
280                                 }
281                                 else
282                                 {
283                                         table[ index( i, RX, ODD ) ].desc = 0;
284                                         usb_rx_memory_needed++;
285                                 }
286                         }
287                         table[ index( i, TX, EVEN ) ].desc = 0;
288                         table[ index( i, TX, ODD ) ].desc = 0;
289                 }
290                 break;
291         case 0x0880: // GET_CONFIGURATION
292                 reply_buffer[0] = usb_configuration;
293                 datalen = 1;
294                 data = reply_buffer;
295                 break;
296         case 0x0080: // GET_STATUS (device)
297                 reply_buffer[0] = 0;
298                 reply_buffer[1] = 0;
299                 datalen = 2;
300                 data = reply_buffer;
301                 break;
302         case 0x0082: // GET_STATUS (endpoint)
303                 if (setup.wIndex > NUM_ENDPOINTS)
304                 {
305                         // TODO: do we need to handle IN vs OUT here?
306                         endpoint0_stall();
307                         return;
308                 }
309                 reply_buffer[0] = 0;
310                 reply_buffer[1] = 0;
311                 if ( *(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02 )
312                         reply_buffer[0] = 1;
313                 data = reply_buffer;
314                 datalen = 2;
315                 break;
316         case 0x0102: // CLEAR_FEATURE (endpoint)
317                 i = setup.wIndex & 0x7F;
318                 if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
319                 {
320                         endpoint0_stall();
321                         return;
322                 }
323                 //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
324                 // TODO: do we need to clear the data toggle here?
325                 //break;
326
327                 // FIXME: Clearing causes keyboard to freeze, likely an invalid clear
328                 // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa
329                 endpoint0_stall();
330                 return;
331         case 0x0302: // SET_FEATURE (endpoint)
332                 i = setup.wIndex & 0x7F;
333                 if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
334                 {
335                         // TODO: do we need to handle IN vs OUT here?
336                         endpoint0_stall();
337                         return;
338                 }
339                 (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02;
340                 // TODO: do we need to clear the data toggle here?
341                 break;
342         case 0x0680: // GET_DESCRIPTOR
343         case 0x0681:
344                 #ifdef UART_DEBUG
345                 print("desc:");
346                 printHex( setup.wValue );
347                 print( NL );
348                 #endif
349                 for ( list = usb_descriptor_list; 1; list++ )
350                 {
351                         if ( list->addr == NULL )
352                                 break;
353                         if ( setup.wValue == list->wValue && setup.wIndex == list->wIndex )
354                         {
355                                 data = list->addr;
356                                 if ( (setup.wValue >> 8) == 3 )
357                                 {
358                                         // for string descriptors, use the descriptor's
359                                         // length field, allowing runtime configured
360                                         // length.
361                                         datalen = *(list->addr);
362                                 }
363                                 else
364                                 {
365                                         datalen = list->length;
366                                 }
367                                 #if UART_DEBUG
368                                 print("Desc found, ");
369                                 printHex32( (uint32_t)data );
370                                 print(",");
371                                 printHex( datalen );
372                                 print(",");
373                                 printHex_op( data[0], 2 );
374                                 printHex_op( data[1], 2 );
375                                 printHex_op( data[2], 2 );
376                                 printHex_op( data[3], 2 );
377                                 printHex_op( data[4], 2 );
378                                 printHex_op( data[5], 2 );
379                                 print( NL );
380                                 #endif
381                                 goto send;
382                         }
383                 }
384                 #ifdef UART_DEBUG
385                 print( "desc: not found" NL );
386                 #endif
387                 endpoint0_stall();
388                 return;
389
390         case 0x2221: // CDC_SET_CONTROL_LINE_STATE
391                 usb_cdc_line_rtsdtr = setup.wValue;
392                 //serial_print("set control line state\n");
393                 endpoint0_stall();
394                 return;
395
396         case 0x21A1: // CDC_GET_LINE_CODING
397                 data = (uint8_t*)usb_cdc_line_coding;
398                 datalen = sizeof( usb_cdc_line_coding );
399                 goto send;
400
401         case 0x2021: // CDC_SET_LINE_CODING
402                 // XXX Needed?
403                 //serial_print("set coding, waiting...\n");
404                 endpoint0_stall();
405                 return; // Cannot stall here (causes issues)
406
407         case 0x0921: // HID SET_REPORT
408                 #ifdef UART_DEBUG
409                 print("SET_REPORT - ");
410                 printHex( setup.wValue );
411                 print(" - ");
412                 printHex( setup.wValue & 0xFF );
413                 print( NL );
414                 #endif
415                 USBKeys_LEDs = setup.wValue & 0xFF;
416                 endpoint0_stall();
417                 return;
418
419         case 0x01A1: // HID GET_REPORT
420                 #ifdef UART_DEBUG
421                 print("GET_REPORT - ");
422                 printHex( USBKeys_LEDs );
423                 print(NL);
424                 #endif
425                 data = (uint8_t*)&USBKeys_LEDs;
426                 datalen = 1;
427                 goto send;
428
429         case 0x0A21: // HID SET_IDLE
430                 #ifdef UART_DEBUG
431                 print("SET_IDLE - ");
432                 printHex( setup.wValue );
433                 print(NL);
434                 #endif
435                 USBKeys_Idle_Config = (setup.wValue >> 8);
436                 USBKeys_Idle_Count = 0;
437                 endpoint0_stall();
438                 return;
439
440         case 0x0B21: // HID SET_PROTOCOL
441                 #ifdef UART_DEBUG
442                 print("SET_PROTOCOL - ");
443                 printHex( setup.wValue );
444                 print(" - ");
445                 printHex( setup.wValue & 0xFF );
446                 print(NL);
447                 #endif
448                 USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode
449                 endpoint0_stall();
450                 return;
451
452         // case 0xC940:
453         default:
454                 #ifdef UART_DEBUG_UNKNOWN
455                 print("UNKNOWN");
456                 #endif
457                 endpoint0_stall();
458                 return;
459         }
460
461 send:
462         #ifdef UART_DEBUG
463         print("setup send ");
464         printHex32((uint32_t)data);
465         print(",");
466         printHex(datalen);
467         print(NL);
468         #endif
469
470         if ( datalen > setup.wLength )
471                 datalen = setup.wLength;
472
473         size = datalen;
474         if ( size > EP0_SIZE )
475                 size = EP0_SIZE;
476
477         endpoint0_transmit(data, size);
478         data += size;
479         datalen -= size;
480
481         // See if transmit has finished
482         if ( datalen == 0 && size < EP0_SIZE )
483                 return;
484
485         size = datalen;
486         if ( size > EP0_SIZE )
487                 size = EP0_SIZE;
488         endpoint0_transmit(data, size);
489         data += size;
490         datalen -= size;
491
492         // See if transmit has finished
493         if ( datalen == 0 && size < EP0_SIZE )
494                 return;
495
496         // Save rest of transfer for later? XXX
497         ep0_tx_ptr = data;
498         ep0_tx_len = datalen;
499 }
500
501
502 //A bulk endpoint's toggle sequence is initialized to DATA0 when the endpoint
503 //experiences any configuration event (configuration events are explained in
504 //Sections 9.1.1.5 and 9.4.5).
505
506 //Configuring a device or changing an alternate setting causes all of the status
507 //and configuration values associated with endpoints in the affected interfaces
508 //to be set to their default values. This includes setting the data toggle of
509 //any endpoint using data toggles to the value DATA0.
510
511 //For endpoints using data toggle, regardless of whether an endpoint has the
512 //Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the
513 //data toggle being reinitialized to DATA0.
514
515 static void usb_control( uint32_t stat )
516 {
517         #ifdef UART_DEBUG
518         print("CONTROL - ");
519         #endif
520         bdt_t *b;
521         uint32_t pid, size;
522         uint8_t *buf;
523         const uint8_t *data;
524
525         b = stat2bufferdescriptor( stat );
526         pid = BDT_PID( b->desc );
527         buf = b->addr;
528         #ifdef UART_DEBUG
529         print("pid:");
530         printHex(pid);
531         print(", count:");
532         printHex32(b->desc);
533         print(" - ");
534         #endif
535
536         switch (pid)
537         {
538         case 0x0D: // Setup received from host
539                 //serial_print("PID=Setup\n");
540                 //if (count != 8) ; // panic?
541                 // grab the 8 byte setup info
542                 setup.word1 = *(uint32_t *)(buf);
543                 setup.word2 = *(uint32_t *)(buf + 4);
544
545                 // give the buffer back
546                 b->desc = BDT_DESC( EP0_SIZE, DATA1 );
547                 //table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1);
548                 //table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1);
549
550                 // clear any leftover pending IN transactions
551                 ep0_tx_ptr = NULL;
552                 if ( ep0_tx_data_toggle )
553                 {
554                 }
555                 //if (table[index(0, TX, EVEN)].desc & 0x80) {
556                         //serial_print("leftover tx even\n");
557                 //}
558                 //if (table[index(0, TX, ODD)].desc & 0x80) {
559                         //serial_print("leftover tx odd\n");
560                 //}
561                 table[index(0, TX, EVEN)].desc = 0;
562                 table[index(0, TX, ODD)].desc = 0;
563                 // first IN after Setup is always DATA1
564                 ep0_tx_data_toggle = 1;
565
566                 #ifdef UART_DEBUG_UNKNOWN
567                 print("bmRequestType:");
568                 printHex(setup.bmRequestType);
569                 print(", bRequest:");
570                 printHex(setup.bRequest);
571                 print(", wValue:");
572                 printHex(setup.wValue);
573                 print(", wIndex:");
574                 printHex(setup.wIndex);
575                 print(", len:");
576                 printHex(setup.wLength);
577                 print(NL);
578                 #endif
579                 // actually "do" the setup request
580                 usb_setup();
581                 // unfreeze the USB, now that we're ready
582                 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
583                 break;
584         case 0x01:  // OUT transaction received from host
585         case 0x02:
586                 #ifdef UART_DEBUG
587                 print("PID=OUT"NL);
588                 #endif
589                 // CDC Interface
590                 if ( setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/ )
591                 {
592                         int i;
593                         uint8_t *dst = (uint8_t *)usb_cdc_line_coding;
594                         //serial_print("set line coding ");
595                         for ( i = 0; i < 7; i++ )
596                         {
597                                 //serial_phex(*buf);
598                                 *dst++ = *buf++;
599                         }
600                         //serial_phex32(usb_cdc_line_coding[0]);
601                         //serial_print("\n");
602                         if ( usb_cdc_line_coding[0] == 134 )
603                                 usb_reboot_timer = 15;
604                         endpoint0_transmit( NULL, 0 );
605                 }
606
607                 // Keyboard Interface
608                 if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | KEYBOARD_INTERFACE ) )
609                 {
610                         USBKeys_LEDs = buf[0];
611                         endpoint0_transmit( NULL, 0 );
612                 }
613                 // NKRO Keyboard Interface
614                 if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | NKRO_KEYBOARD_INTERFACE ) )
615                 {
616                         USBKeys_LEDs = buf[0];
617                         endpoint0_transmit( NULL, 0 );
618                 }
619
620                 // give the buffer back
621                 b->desc = BDT_DESC( EP0_SIZE, DATA1 );
622                 break;
623
624         case 0x09: // IN transaction completed to host
625                 #ifdef UART_DEBUG
626                 print("PID=IN:");
627                 printHex(stat);
628                 print(NL);
629                 #endif
630
631                 // send remaining data, if any...
632                 data = ep0_tx_ptr;
633                 if ( data )
634                 {
635                         size = ep0_tx_len;
636                         if (size > EP0_SIZE) size = EP0_SIZE;
637                         endpoint0_transmit(data, size);
638                         data += size;
639                         ep0_tx_len -= size;
640                         ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
641                 }
642
643                 if ( setup.bRequest == 5 && setup.bmRequestType == 0 )
644                 {
645                         setup.bRequest = 0;
646                         #ifdef UART_DEBUG
647                         print("set address: ");
648                         printHex(setup.wValue);
649                         print(NL);
650                         #endif
651                         USB0_ADDR = setup.wValue;
652                 }
653
654                 break;
655         default:
656                 #ifdef UART_DEBUG
657                 print("PID=unknown:");
658                 printHex(pid);
659                 print(NL);
660                 #endif
661                 break;
662         }
663         USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
664 }
665
666 usb_packet_t *usb_rx( uint32_t endpoint )
667 {
668         //print("USB RX");
669         usb_packet_t *ret;
670         endpoint--;
671         if ( endpoint >= NUM_ENDPOINTS )
672                 return NULL;
673         __disable_irq();
674         ret = rx_first[endpoint];
675         if ( ret )
676                 rx_first[ endpoint ] = ret->next;
677         usb_rx_byte_count_data[ endpoint ] -= ret->len;
678         __enable_irq();
679         //serial_print("rx, epidx=");
680         //serial_phex(endpoint);
681         //serial_print(", packet=");
682         //serial_phex32(ret);
683         //serial_print("\n");
684         return ret;
685 }
686
687 static uint32_t usb_queue_byte_count( const usb_packet_t *p )
688 {
689         uint32_t count=0;
690
691         __disable_irq();
692         for ( ; p; p = p->next )
693         {
694                 count += p->len;
695         }
696         __enable_irq();
697         return count;
698 }
699
700 uint32_t usb_tx_byte_count( uint32_t endpoint )
701 {
702         endpoint--;
703         if ( endpoint >= NUM_ENDPOINTS )
704                 return 0;
705         return usb_queue_byte_count( tx_first[ endpoint ] );
706 }
707
708 uint32_t usb_tx_packet_count( uint32_t endpoint )
709 {
710         const usb_packet_t *p;
711         uint32_t count=0;
712
713         endpoint--;
714         if ( endpoint >= NUM_ENDPOINTS )
715                 return 0;
716         __disable_irq();
717         for ( p = tx_first[ endpoint ]; p; p = p->next )
718                 count++;
719         __enable_irq();
720         return count;
721 }
722
723
724 // Called from usb_free, but only when usb_rx_memory_needed > 0, indicating
725 // receive endpoints are starving for memory.  The intention is to give
726 // endpoints needing receive memory priority over the user's code, which is
727 // likely calling usb_malloc to obtain memory for transmitting.  When the
728 // user is creating data very quickly, their consumption could starve reception
729 // without this prioritization.  The packet buffer (input) is assigned to the
730 // first endpoint needing memory.
731 //
732 void usb_rx_memory( usb_packet_t *packet )
733 {
734         //print("USB RX MEMORY");
735         unsigned int i;
736         const uint8_t *cfg;
737
738         cfg = usb_endpoint_config_table;
739         //serial_print("rx_mem:");
740         __disable_irq();
741         for ( i = 1; i <= NUM_ENDPOINTS; i++ )
742         {
743                 if ( *cfg++ & USB_ENDPT_EPRXEN )
744                 {
745                         if ( table[ index( i, RX, EVEN ) ].desc == 0 )
746                         {
747                                 table[ index( i, RX, EVEN ) ].addr = packet->buf;
748                                 table[ index( i, RX, EVEN ) ].desc = BDT_DESC( 64, 0 );
749                                 usb_rx_memory_needed--;
750                                 __enable_irq();
751                                 //serial_phex(i);
752                                 //serial_print(",even\n");
753                                 return;
754                         }
755                         if ( table[ index( i, RX, ODD ) ].desc == 0 )
756                         {
757                                 table[ index( i, RX, ODD ) ].addr = packet->buf;
758                                 table[ index( i, RX, ODD ) ].desc = BDT_DESC( 64, 1 );
759                                 usb_rx_memory_needed--;
760                                 __enable_irq();
761                                 //serial_phex(i);
762                                 //serial_print(",odd\n");
763                                 return;
764                         }
765                 }
766         }
767         __enable_irq();
768         // we should never reach this point.  If we get here, it means
769         // usb_rx_memory_needed was set greater than zero, but no memory
770         // was actually needed.
771         usb_rx_memory_needed = 0;
772         usb_free( packet );
773         return;
774 }
775
776 //#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
777 //#define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
778
779 void usb_tx( uint32_t endpoint, usb_packet_t *packet )
780 {
781         bdt_t *b = &table[ index( endpoint, TX, EVEN ) ];
782         uint8_t next;
783
784         endpoint--;
785         if ( endpoint >= NUM_ENDPOINTS )
786                 return;
787         __disable_irq();
788         //serial_print("txstate=");
789         //serial_phex(tx_state[ endpoint ]);
790         //serial_print("\n");
791         switch ( tx_state[ endpoint ] )
792         {
793         case TX_STATE_BOTH_FREE_EVEN_FIRST:
794                 next = TX_STATE_ODD_FREE;
795                 break;
796         case TX_STATE_BOTH_FREE_ODD_FIRST:
797                 b++;
798                 next = TX_STATE_EVEN_FREE;
799                 break;
800         case TX_STATE_EVEN_FREE:
801                 next = TX_STATE_NONE_FREE_ODD_FIRST;
802                 break;
803         case TX_STATE_ODD_FREE:
804                 b++;
805                 next = TX_STATE_NONE_FREE_EVEN_FIRST;
806                 break;
807         default:
808                 if (tx_first[ endpoint ] == NULL)
809                 {
810                         tx_first[ endpoint ] = packet;
811                 }
812                 else
813                 {
814                         tx_last[ endpoint ]->next = packet;
815                 }
816                 tx_last[ endpoint ] = packet;
817                 __enable_irq();
818                 return;
819         }
820
821         tx_state[ endpoint ] = next;
822         b->addr = packet->buf;
823         b->desc = BDT_DESC( packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0 );
824         __enable_irq();
825 }
826
827
828 void usb_device_reload()
829 {
830 // MCHCK
831 #if defined(_mk20dx128vlf5_)
832
833         // MCHCK Kiibohd Variant
834         // Check to see if PTA3 (has a pull-up) is connected to GND (usually via jumper)
835         // Only allow reload if the jumper is present (security)
836         GPIOA_PDDR &= ~(1<<3); // Input
837         PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up
838
839         // Check for jumper
840         if ( GPIOA_PDIR & (1<<3) )
841         {
842                 print( NL );
843                 warn_print("Security jumper not present, cancelling firmware reload...");
844                 info_msg("Replace jumper on middle 2 pins, or manually press the firmware reload button.");
845         }
846         else
847         {
848                 // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode
849                 for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ )
850                         (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ];
851                 SOFTWARE_RESET();
852         }
853
854 // Teensy 3.0 and 3.1
855 #else
856         asm volatile("bkpt");
857 #endif
858 }
859
860
861 void usb_isr()
862 {
863         uint8_t status, stat, t;
864
865         //serial_print("isr");
866         //status = USB0_ISTAT;
867         //serial_phex(status);
868         //serial_print("\n");
869 restart:
870         status = USB0_ISTAT;
871         /*
872         print("USB ISR STATUS: ");
873         printHex( status );
874         print( NL );
875         */
876
877         if ( (status & USB_INTEN_SOFTOKEN /* 04 */ ) )
878         {
879                 if ( usb_configuration )
880                 {
881                         t = usb_reboot_timer;
882                         if ( t )
883                         {
884                                 usb_reboot_timer = --t;
885                                 if ( !t )
886                                         usb_device_reload();
887                         }
888
889                         // CDC Interface
890                         t = usb_cdc_transmit_flush_timer;
891                         if ( t )
892                         {
893                                 usb_cdc_transmit_flush_timer = --t;
894                                 if ( t == 0 )
895                                         usb_serial_flush_callback();
896                         }
897
898                 }
899                 USB0_ISTAT = USB_INTEN_SOFTOKEN;
900         }
901
902         if ( (status & USB_ISTAT_TOKDNE /* 08 */ ) )
903         {
904                 uint8_t endpoint;
905                 stat = USB0_STAT;
906                 //serial_print("token: ep=");
907                 //serial_phex(stat >> 4);
908                 //serial_print(stat & 0x08 ? ",tx" : ",rx");
909                 //serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
910                 endpoint = stat >> 4;
911                 if ( endpoint == 0 )
912                 {
913                         usb_control( stat );
914                 }
915                 else
916                 {
917                         bdt_t *b = stat2bufferdescriptor(stat);
918                         usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
919 #if 0
920                         serial_print("ep:");
921                         serial_phex(endpoint);
922                         serial_print(", pid:");
923                         serial_phex(BDT_PID(b->desc));
924                         serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
925                         serial_print(", count:");
926                         serial_phex(b->desc >> 16);
927                         serial_print("\n");
928 #endif
929                         endpoint--;     // endpoint is index to zero-based arrays
930
931                         if ( stat & 0x08 )
932                         { // transmit
933                                 usb_free( packet );
934                                 packet = tx_first[ endpoint ];
935                                 if ( packet )
936                                 {
937                                         //serial_print("tx packet\n");
938                                         tx_first[endpoint] = packet->next;
939                                         b->addr = packet->buf;
940                                         switch ( tx_state[ endpoint ] )
941                                         {
942                                         case TX_STATE_BOTH_FREE_EVEN_FIRST:
943                                                 tx_state[ endpoint ] = TX_STATE_ODD_FREE;
944                                                 break;
945                                         case TX_STATE_BOTH_FREE_ODD_FIRST:
946                                                 tx_state[ endpoint ] = TX_STATE_EVEN_FREE;
947                                                 break;
948                                         case TX_STATE_EVEN_FREE:
949                                                 tx_state[ endpoint ] = TX_STATE_NONE_FREE_ODD_FIRST;
950                                                 break;
951                                         case TX_STATE_ODD_FREE:
952                                                 tx_state[ endpoint ] = TX_STATE_NONE_FREE_EVEN_FIRST;
953                                                 break;
954                                         default:
955                                                 break;
956                                         }
957                                         b->desc = BDT_DESC( packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0 );
958                                 } else {
959                                         //serial_print("tx no packet\n");
960                                         switch ( tx_state[ endpoint ] )
961                                         {
962                                         case TX_STATE_BOTH_FREE_EVEN_FIRST:
963                                         case TX_STATE_BOTH_FREE_ODD_FIRST:
964                                                 break;
965                                         case TX_STATE_EVEN_FREE:
966                                                 tx_state[ endpoint ] = TX_STATE_BOTH_FREE_EVEN_FIRST;
967                                                 break;
968                                         case TX_STATE_ODD_FREE:
969                                                 tx_state[ endpoint ] = TX_STATE_BOTH_FREE_ODD_FIRST;
970                                                 break;
971                                         default:
972                                                 tx_state[ endpoint ] = ((uint32_t)b & 8)
973                                                   ? TX_STATE_ODD_FREE
974                                                   : TX_STATE_EVEN_FREE;
975                                                 break;
976                                         }
977                                 }
978                         }
979                         else
980                         { // receive
981                                 packet->len = b->desc >> 16;
982                                 if ( packet->len > 0 )
983                                 {
984                                         packet->index = 0;
985                                         packet->next = NULL;
986                                         if ( rx_first[ endpoint ] == NULL )
987                                         {
988                                                 //serial_print("rx 1st, epidx=");
989                                                 //serial_phex(endpoint);
990                                                 //serial_print(", packet=");
991                                                 //serial_phex32((uint32_t)packet);
992                                                 //serial_print("\n");
993                                                 rx_first[ endpoint ] = packet;
994                                         }
995                                         else
996                                         {
997                                                 //serial_print("rx Nth, epidx=");
998                                                 //serial_phex(endpoint);
999                                                 //serial_print(", packet=");
1000                                                 //serial_phex32((uint32_t)packet);
1001                                                 //serial_print("\n");
1002                                                 rx_last[ endpoint ]->next = packet;
1003                                         }
1004                                         rx_last[ endpoint ] = packet;
1005                                         usb_rx_byte_count_data[ endpoint ] += packet->len;
1006                                         // TODO: implement a per-endpoint maximum # of allocated packets
1007                                         // so a flood of incoming data on 1 endpoint doesn't starve
1008                                         // the others if the user isn't reading it regularly
1009                                         packet = usb_malloc();
1010                                         if ( packet )
1011                                         {
1012                                                 b->addr = packet->buf;
1013                                                 b->desc = BDT_DESC( 64, ((uint32_t)b & 8) ? DATA1 : DATA0 );
1014                                         }
1015                                         else
1016                                         {
1017                                                 //serial_print("starving ");
1018                                                 //serial_phex(endpoint + 1);
1019                                                 //serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n");
1020                                                 b->desc = 0;
1021                                                 usb_rx_memory_needed++;
1022                                         }
1023                                 }
1024                                 else
1025                                 {
1026                                         b->desc = BDT_DESC( 64, ((uint32_t)b & 8) ? DATA1 : DATA0 );
1027                                 }
1028                         }
1029
1030
1031
1032
1033                 }
1034                 USB0_ISTAT = USB_ISTAT_TOKDNE;
1035                 goto restart;
1036         }
1037
1038
1039         if ( status & USB_ISTAT_USBRST /* 01 */ )
1040         {
1041                 //serial_print("reset\n");
1042
1043                 // initialize BDT toggle bits
1044                 USB0_CTL = USB_CTL_ODDRST;
1045                 ep0_tx_bdt_bank = 0;
1046
1047                 // set up buffers to receive Setup and OUT packets
1048                 table[index( 0, RX, EVEN ) ].desc = BDT_DESC( EP0_SIZE, 0 );
1049                 table[index( 0, RX, EVEN ) ].addr = ep0_rx0_buf;
1050                 table[index( 0, RX, ODD ) ].desc = BDT_DESC( EP0_SIZE, 0 );
1051                 table[index( 0, RX, ODD ) ].addr = ep0_rx1_buf;
1052                 table[index( 0, TX, EVEN ) ].desc = 0;
1053                 table[index( 0, TX, ODD ) ].desc = 0;
1054
1055                 // activate endpoint 0
1056                 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
1057
1058                 // clear all ending interrupts
1059                 USB0_ERRSTAT = 0xFF;
1060                 USB0_ISTAT = 0xFF;
1061
1062                 // set the address to zero during enumeration
1063                 USB0_ADDR = 0;
1064
1065                 // enable other interrupts
1066                 USB0_ERREN = 0xFF;
1067                 USB0_INTEN = USB_INTEN_TOKDNEEN |
1068                         USB_INTEN_SOFTOKEN |
1069                         USB_INTEN_STALLEN |
1070                         USB_INTEN_ERROREN |
1071                         USB_INTEN_USBRSTEN |
1072                         USB_INTEN_SLEEPEN;
1073
1074                 // is this necessary?
1075                 USB0_CTL = USB_CTL_USBENSOFEN;
1076                 return;
1077         }
1078
1079
1080         if ( (status & USB_ISTAT_STALL /* 80 */ ) )
1081         {
1082                 //serial_print("stall:\n");
1083                 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
1084                 USB0_ISTAT = USB_ISTAT_STALL;
1085         }
1086         if ( (status & USB_ISTAT_ERROR /* 02 */ ) )
1087         {
1088                 uint8_t err = USB0_ERRSTAT;
1089                 USB0_ERRSTAT = err;
1090                 //serial_print("err:");
1091                 //serial_phex(err);
1092                 //serial_print("\n");
1093                 USB0_ISTAT = USB_ISTAT_ERROR;
1094         }
1095
1096         if ( (status & USB_ISTAT_SLEEP /* 10 */ ) )
1097         {
1098                 //serial_print("sleep\n");
1099                 USB0_ISTAT = USB_ISTAT_SLEEP;
1100         }
1101 }
1102
1103
1104
1105 uint8_t usb_init()
1106 {
1107         #ifdef UART_DEBUG
1108         print("USB INIT"NL);
1109         #endif
1110
1111         // If no USB cable is attached, do not initialize usb
1112         // XXX Test -HaaTa
1113         //if ( USB0_OTGISTAT & USB_OTGSTAT_ID )
1114         //      return 0;
1115
1116         // Clear out endpoints table
1117         for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ )
1118         {
1119                 table[i].desc = 0;
1120                 table[i].addr = 0;
1121         }
1122
1123         // this basically follows the flowchart in the Kinetis
1124         // Quick Reference User Guide, Rev. 1, 03/2012, page 141
1125
1126         // assume 48 MHz clock already running
1127         // SIM - enable clock
1128         SIM_SCGC4 |= SIM_SCGC4_USBOTG;
1129
1130         // reset USB module
1131         USB0_USBTRC0 = USB_USBTRC_USBRESET;
1132         while ( (USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0 ); // wait for reset to end
1133
1134         // set desc table base addr
1135         USB0_BDTPAGE1 = ((uint32_t)table) >> 8;
1136         USB0_BDTPAGE2 = ((uint32_t)table) >> 16;
1137         USB0_BDTPAGE3 = ((uint32_t)table) >> 24;
1138
1139         // clear all ISR flags
1140         USB0_ISTAT = 0xFF;
1141         USB0_ERRSTAT = 0xFF;
1142         USB0_OTGISTAT = 0xFF;
1143
1144         USB0_USBTRC0 |= 0x40; // undocumented bit
1145
1146         // enable USB
1147         USB0_CTL = USB_CTL_USBENSOFEN;
1148         USB0_USBCTRL = 0;
1149
1150         // enable reset interrupt
1151         USB0_INTEN = USB_INTEN_USBRSTEN;
1152
1153         // enable interrupt in NVIC...
1154         NVIC_SET_PRIORITY( IRQ_USBOTG, 112 );
1155         NVIC_ENABLE_IRQ( IRQ_USBOTG );
1156
1157         // enable d+ pullup
1158         USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
1159
1160         return 1;
1161 }
1162
1163 // return 0 if the USB is not configured, or the configuration
1164 // number selected by the HOST
1165 uint8_t usb_configured()
1166 {
1167         return usb_configuration;
1168 }
1169