]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Output/pjrcUSB/arm/usb_dev.c
Added more CLI commands.
[kiibohd-controller.git] / Output / pjrcUSB / arm / usb_dev.c
1 #include <Lib/USBLib.h>
2 #include "usb_dev.h"
3 #include "usb_mem.h"
4
5 // buffer descriptor table
6
7 typedef struct {
8         uint32_t desc;
9         void * addr;
10 } bdt_t;
11
12 __attribute__ ((section(".usbdescriptortable"), used))
13 static bdt_t table[64];
14
15 #define BDT_OWN         0x80
16 #define BDT_DATA1       0x40
17 #define BDT_DATA0       0x00
18 #define BDT_DTS         0x08
19 #define BDT_STALL       0x04
20 #define BDT_PID(n)      (((n) >> 2) & 15)
21
22 #define BDT_DESC(count, data)   (BDT_OWN | BDT_DTS \
23                                 | ((data) ? BDT_DATA1 : BDT_DATA0) \
24                                 | ((count) << 16))
25
26 #define TX   1
27 #define RX   0
28 #define ODD  1
29 #define EVEN 0
30 #define DATA0 0
31 #define DATA1 1
32 #define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
33 #define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
34
35
36 static union {
37  struct {
38   union {
39    struct {
40         uint8_t bmRequestType;
41         uint8_t bRequest;
42    };
43         uint16_t wRequestAndType;
44   };
45         uint16_t wValue;
46         uint16_t wIndex;
47         uint16_t wLength;
48  };
49  struct {
50         uint32_t word1;
51         uint32_t word2;
52  };
53 } setup;
54
55
56 #define GET_STATUS              0
57 #define CLEAR_FEATURE           1
58 #define SET_FEATURE             3
59 #define SET_ADDRESS             5
60 #define GET_DESCRIPTOR          6
61 #define SET_DESCRIPTOR          7
62 #define GET_CONFIGURATION       8
63 #define SET_CONFIGURATION       9
64 #define GET_INTERFACE           10
65 #define SET_INTERFACE           11
66 #define SYNCH_FRAME             12
67
68 // SETUP always uses a DATA0 PID for the data field of the SETUP transaction.
69 // transactions in the data phase start with DATA1 and toggle (figure 8-12, USB1.1)
70 // Status stage uses a DATA1 PID.
71
72 static uint8_t ep0_rx0_buf[EP0_SIZE] __attribute__ ((aligned (4)));
73 static uint8_t ep0_rx1_buf[EP0_SIZE] __attribute__ ((aligned (4)));
74 static const uint8_t *ep0_tx_ptr = NULL;
75 static uint16_t ep0_tx_len;
76 static uint8_t ep0_tx_bdt_bank = 0;
77 static uint8_t ep0_tx_data_toggle = 0;
78 uint8_t usb_rx_memory_needed = 0;
79
80 volatile uint8_t usb_configuration = 0;
81 volatile uint8_t usb_reboot_timer = 0;
82
83
84 static void endpoint0_stall(void)
85 {
86         USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
87 }
88
89
90 static void endpoint0_transmit(const void *data, uint32_t len)
91 {
92 #if 0
93         serial_print("tx0:");
94         serial_phex32((uint32_t)data);
95         serial_print(",");
96         serial_phex16(len);
97         serial_print(ep0_tx_bdt_bank ? ", odd" : ", even");
98         serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n");
99 #endif
100         table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data;
101         table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
102         ep0_tx_data_toggle ^= 1;
103         ep0_tx_bdt_bank ^= 1;
104 }
105
106 static uint8_t reply_buffer[8];
107
108 static void usbdev_setup(void)
109 {
110         const uint8_t *data = NULL;
111         uint32_t datalen = 0;
112         const usb_descriptor_list_t *list;
113         uint32_t size;
114         volatile uint8_t *reg;
115         uint8_t epconf;
116         const uint8_t *cfg;
117         int i;
118
119         switch (setup.wRequestAndType) {
120           case 0x0500: // SET_ADDRESS
121                 break;
122           case 0x0900: // SET_CONFIGURATION
123                 //serial_print("configure\n");
124                 usb_configuration = setup.wValue;
125                 reg = &USB0_ENDPT1;
126                 cfg = usb_endpoint_config_table;
127                 // clear all BDT entries, free any allocated memory...
128                 for (i=4; i <= NUM_ENDPOINTS*4; i++) {
129                         if (table[i].desc & BDT_OWN) {
130                                 usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8));
131                                 table[i].desc = 0;
132                         }
133                 }
134                 usb_rx_memory_needed = 0;
135                 for (i=1; i <= NUM_ENDPOINTS; i++) {
136                         epconf = *cfg++;
137                         *reg = epconf;
138                         reg += 4;
139                         if (epconf & USB_ENDPT_EPRXEN) {
140                                 usb_packet_t *p;
141                                 p = usb_malloc();
142                                 if (p) {
143                                         table[index(i, RX, EVEN)].addr = p->buf;
144                                         table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
145                                 } else {
146                                         table[index(i, RX, EVEN)].desc = 0;
147                                         usb_rx_memory_needed++;
148                                 }
149                                 p = usb_malloc();
150                                 if (p) {
151                                         table[index(i, RX, ODD)].addr = p->buf;
152                                         table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
153                                 } else {
154                                         table[index(i, RX, ODD)].desc = 0;
155                                         usb_rx_memory_needed++;
156                                 }
157                         }
158                         table[index(i, TX, EVEN)].desc = 0;
159                         table[index(i, TX, ODD)].desc = 0;
160                 }
161                 break;
162           case 0x0880: // GET_CONFIGURATION
163                 reply_buffer[0] = usb_configuration;
164                 datalen = 1;
165                 data = reply_buffer;
166                 break;
167           case 0x0080: // GET_STATUS (device)
168                 reply_buffer[0] = 0;
169                 reply_buffer[1] = 0;
170                 datalen = 2;
171                 data = reply_buffer;
172                 break;
173           case 0x0082: // GET_STATUS (endpoint)
174                 if (setup.wIndex > NUM_ENDPOINTS) {
175                         // TODO: do we need to handle IN vs OUT here?
176                         endpoint0_stall();
177                         return;
178                 }
179                 reply_buffer[0] = 0;
180                 reply_buffer[1] = 0;
181                 if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
182                 data = reply_buffer;
183                 datalen = 2;
184                 break;
185           case 0x0102: // CLEAR_FEATURE (endpoint)
186                 i = setup.wIndex & 0x7F;
187                 if (i > NUM_ENDPOINTS || setup.wValue != 0) {
188                         // TODO: do we need to handle IN vs OUT here?
189                         endpoint0_stall();
190                         return;
191                 }
192                 (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
193                 // TODO: do we need to clear the data toggle here?
194                 break;
195           case 0x0302: // SET_FEATURE (endpoint)
196                 i = setup.wIndex & 0x7F;
197                 if (i > NUM_ENDPOINTS || setup.wValue != 0) {
198                         // TODO: do we need to handle IN vs OUT here?
199                         endpoint0_stall();
200                         return;
201                 }
202                 (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02;
203                 // TODO: do we need to clear the data toggle here?
204                 break;
205           case 0x0680: // GET_DESCRIPTOR
206           case 0x0681:
207                 //serial_print("desc:");
208                 //serial_phex16(setup.wValue);
209                 //serial_print("\n");
210                 for (list = usb_descriptor_list; 1; list++) {
211                         if (list->addr == NULL) break;
212                         //if (setup.wValue == list->wValue && 
213                         //(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) {
214                         if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
215                                 data = list->addr;
216                                 datalen = list->length;
217 #if 0
218                                 serial_print("Desc found, ");
219                                 serial_phex32((uint32_t)data);
220                                 serial_print(",");
221                                 serial_phex16(datalen);
222                                 serial_print(",");
223                                 serial_phex(data[0]);
224                                 serial_phex(data[1]);
225                                 serial_phex(data[2]);
226                                 serial_phex(data[3]);
227                                 serial_phex(data[4]);
228                                 serial_phex(data[5]);
229                                 serial_print("\n");
230 #endif
231                                 goto send;
232                         }
233                 }
234                 //serial_print("desc: not found\n");
235                 endpoint0_stall();
236                 return;
237 #if defined(CDC_STATUS_INTERFACE)
238           case 0x2221: // CDC_SET_CONTROL_LINE_STATE
239                 usb_cdc_line_rtsdtr = setup.wValue;
240                 //serial_print("set control line state\n");
241                 break;
242           case 0x2021: // CDC_SET_LINE_CODING
243                 //serial_print("set coding, waiting...\n");
244                 return;
245 #endif
246
247 // TODO: this does not work... why?
248 #if defined(KEYBOARD_INTERFACE)
249           case 0x0921: // HID SET_REPORT
250                 //serial_print(":)\n");
251                 return;
252           case 0x0A21: // HID SET_IDLE
253                 break;
254           // case 0xC940:
255 #endif
256           default:
257                 endpoint0_stall();
258                 return;
259         }
260         send:
261         //serial_print("setup send ");
262         //serial_phex32(data);
263         //serial_print(",");
264         //serial_phex16(datalen);
265         //serial_print("\n");
266
267         if (datalen > setup.wLength) datalen = setup.wLength;
268         size = datalen;
269         if (size > EP0_SIZE) size = EP0_SIZE;
270         endpoint0_transmit(data, size);
271         data += size;
272         datalen -= size;
273         if (datalen == 0 && size < EP0_SIZE) return;
274
275         size = datalen;
276         if (size > EP0_SIZE) size = EP0_SIZE;
277         endpoint0_transmit(data, size);
278         data += size;
279         datalen -= size;
280         if (datalen == 0 && size < EP0_SIZE) return;
281
282         ep0_tx_ptr = data;
283         ep0_tx_len = datalen;
284 }
285
286
287
288 //A bulk endpoint's toggle sequence is initialized to DATA0 when the endpoint
289 //experiences any configuration event (configuration events are explained in
290 //Sections 9.1.1.5 and 9.4.5).
291
292 //Configuring a device or changing an alternate setting causes all of the status
293 //and configuration values associated with endpoints in the affected interfaces
294 //to be set to their default values. This includes setting the data toggle of
295 //any endpoint using data toggles to the value DATA0.
296
297 //For endpoints using data toggle, regardless of whether an endpoint has the
298 //Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the
299 //data toggle being reinitialized to DATA0.
300
301
302
303 // #define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
304
305 static void usb_control(uint32_t stat)
306 {
307         bdt_t *b;
308         uint32_t pid, size;
309         uint8_t *buf;
310         const uint8_t *data;
311
312         b = stat2bufferdescriptor(stat);
313         pid = BDT_PID(b->desc);
314         //count = b->desc >> 16;
315         buf = b->addr;
316         //serial_print("pid:");
317         //serial_phex(pid);
318         //serial_print(", count:");
319         //serial_phex(count);
320         //serial_print("\n");
321
322         switch (pid) {
323         case 0x0D: // Setup received from host
324                 //serial_print("PID=Setup\n");
325                 //if (count != 8) ; // panic?
326                 // grab the 8 byte setup info
327                 setup.word1 = *(uint32_t *)(buf);
328                 setup.word2 = *(uint32_t *)(buf + 4);
329
330                 // give the buffer back
331                 b->desc = BDT_DESC(EP0_SIZE, DATA1);
332                 //table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1);
333                 //table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1);
334
335                 // clear any leftover pending IN transactions
336                 ep0_tx_ptr = NULL;
337                 if (ep0_tx_data_toggle) {
338                 }
339                 //if (table[index(0, TX, EVEN)].desc & 0x80) {
340                         //serial_print("leftover tx even\n");
341                 //}
342                 //if (table[index(0, TX, ODD)].desc & 0x80) {
343                         //serial_print("leftover tx odd\n");
344                 //}
345                 table[index(0, TX, EVEN)].desc = 0;
346                 table[index(0, TX, ODD)].desc = 0;
347                 // first IN after Setup is always DATA1
348                 ep0_tx_data_toggle = 1;
349
350 #if 0
351                 serial_print("bmRequestType:");
352                 serial_phex(setup.bmRequestType);
353                 serial_print(", bRequest:");
354                 serial_phex(setup.bRequest);
355                 serial_print(", wValue:");
356                 serial_phex16(setup.wValue);
357                 serial_print(", wIndex:");
358                 serial_phex16(setup.wIndex);
359                 serial_print(", len:");
360                 serial_phex16(setup.wLength);
361                 serial_print("\n");
362 #endif
363                 // actually "do" the setup request
364                 usbdev_setup();
365                 // unfreeze the USB, now that we're ready
366                 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
367                 break;
368         case 0x01:  // OUT transaction received from host
369         case 0x02:
370                 //serial_print("PID=OUT\n");
371 #ifdef CDC_STATUS_INTERFACE
372                 if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) {
373                         int i;
374                         uint8_t *dst = usb_cdc_line_coding;
375                         //serial_print("set line coding ");
376                         for (i=0; i<7; i++) {
377                                 //serial_phex(*buf);
378                                 *dst++ = *buf++;
379                         }
380                         //serial_phex32(*(uint32_t *)usb_cdc_line_coding);
381                         //serial_print("\n");
382                         // XXX - Not sure why this was casted to uint32_t... -HaaTa
383                         //if (*(uint32_t *)usb_cdc_line_coding == 134) usb_reboot_timer = 15;
384                         if (*usb_cdc_line_coding == 134) usb_reboot_timer = 15;
385                         endpoint0_transmit(NULL, 0);
386                 }
387 #endif
388 #ifdef KEYBOARD_INTERFACE
389                 if (setup.word1 == 0x02000921 && setup.word2 == ((1<<16)|KEYBOARD_INTERFACE)) {
390                         USBKeys_LEDs = buf[0];
391                         endpoint0_transmit(NULL, 0);
392                 }
393 #endif
394                 // give the buffer back
395                 b->desc = BDT_DESC(EP0_SIZE, DATA1);
396                 break;
397
398         case 0x09: // IN transaction completed to host
399                 //serial_print("PID=IN:");
400                 //serial_phex(stat);
401                 //serial_print("\n");
402
403                 // send remaining data, if any...
404                 data = ep0_tx_ptr;
405                 if (data) {
406                         size = ep0_tx_len;
407                         if (size > EP0_SIZE) size = EP0_SIZE;
408                         endpoint0_transmit(data, size);
409                         data += size;
410                         ep0_tx_len -= size;
411                         ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
412                 }
413
414                 if (setup.bRequest == 5 && setup.bmRequestType == 0) {
415                         setup.bRequest = 0;
416                         //serial_print("set address: ");
417                         //serial_phex16(setup.wValue);
418                         //serial_print("\n");
419                         USB0_ADDR = setup.wValue;
420                 }
421
422                 break;
423         //default:
424                 //serial_print("PID=unknown:");
425                 //serial_phex(pid);
426                 //serial_print("\n");
427         }
428         USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
429 }
430
431
432
433 static usb_packet_t *rx_first[NUM_ENDPOINTS];
434 static usb_packet_t *rx_last[NUM_ENDPOINTS];
435 static usb_packet_t *tx_first[NUM_ENDPOINTS];
436 static usb_packet_t *tx_last[NUM_ENDPOINTS];
437
438 static uint8_t tx_state[NUM_ENDPOINTS];
439 #define TX_STATE_BOTH_FREE_EVEN_FIRST   0
440 #define TX_STATE_BOTH_FREE_ODD_FIRST    1
441 #define TX_STATE_EVEN_FREE              2
442 #define TX_STATE_ODD_FREE               3
443 #define TX_STATE_NONE_FREE              4
444
445
446
447 usb_packet_t *usb_rx(uint32_t endpoint)
448 {
449         usb_packet_t *ret;
450         endpoint--;
451         if (endpoint >= NUM_ENDPOINTS) return NULL;
452         __disable_irq();
453         ret = rx_first[endpoint];
454         if (ret) rx_first[endpoint] = ret->next;
455         __enable_irq();
456         //serial_print("rx, epidx=");
457         //serial_phex(endpoint);
458         //serial_print(", packet=");
459         //serial_phex32(ret);
460         //serial_print("\n");
461         return ret;
462 }
463
464 static uint32_t usb_queue_byte_count(const usb_packet_t *p)
465 {
466         uint32_t count=0;
467
468         __disable_irq();
469         for ( ; p; p = p->next) {
470                 count += p->len;
471         }
472         __enable_irq();
473         return count;
474 }
475
476 uint32_t usb_rx_byte_count(uint32_t endpoint)
477 {
478         endpoint--;
479         if (endpoint >= NUM_ENDPOINTS) return 0;
480         return usb_queue_byte_count(rx_first[endpoint]);
481 }
482
483 uint32_t usb_tx_byte_count(uint32_t endpoint)
484 {
485         endpoint--;
486         if (endpoint >= NUM_ENDPOINTS) return 0;
487         return usb_queue_byte_count(tx_first[endpoint]);
488 }
489
490 uint32_t usb_tx_packet_count(uint32_t endpoint)
491 {
492         const usb_packet_t *p;
493         uint32_t count=0;
494
495         endpoint--;
496         if (endpoint >= NUM_ENDPOINTS) return 0;
497         p = tx_first[endpoint];
498         __disable_irq();
499         for ( ; p; p = p->next) count++;
500         __enable_irq();
501         return count;
502 }
503
504
505 // Called from usb_free, but only when usb_rx_memory_needed > 0, indicating
506 // receive endpoints are starving for memory.  The intention is to give
507 // endpoints needing receive memory priority over the user's code, which is
508 // likely calling usb_malloc to obtain memory for transmitting.  When the
509 // user is creating data very quickly, their consumption could starve reception
510 // without this prioritization.  The packet buffer (input) is assigned to the
511 // first endpoint needing memory.
512 //
513 void usb_rx_memory(usb_packet_t *packet)
514 {
515         unsigned int i;
516         const uint8_t *cfg;
517
518         cfg = usb_endpoint_config_table;
519         //serial_print("rx_mem:");
520         __disable_irq();
521         for (i=1; i <= NUM_ENDPOINTS; i++) {
522                 if (*cfg++ & USB_ENDPT_EPRXEN) {
523                         if (table[index(i, RX, EVEN)].desc == 0) {
524                                 table[index(i, RX, EVEN)].addr = packet->buf;
525                                 table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
526                                 usb_rx_memory_needed--;
527                                 __enable_irq();
528                                 //serial_phex(i);
529                                 //serial_print(",even\n");
530                                 return;
531                         }
532                         if (table[index(i, RX, ODD)].desc == 0) {
533                                 table[index(i, RX, ODD)].addr = packet->buf;
534                                 table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
535                                 usb_rx_memory_needed--;
536                                 __enable_irq();
537                                 //serial_phex(i);
538                                 //serial_print(",odd\n");
539                                 return;
540                         }
541                 }
542         }
543         __enable_irq();
544         // we should never reach this point.  If we get here, it means
545         // usb_rx_memory_needed was set greater than zero, but no memory
546         // was actually needed.  
547         usb_rx_memory_needed = 0;
548         usb_free(packet);
549         return;
550 }
551
552 //#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
553 //#define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
554
555 void usb_tx(uint32_t endpoint, usb_packet_t *packet)
556 {
557         bdt_t *b = &table[index(endpoint, TX, EVEN)];
558         uint8_t next;
559
560         endpoint--;
561         if (endpoint >= NUM_ENDPOINTS) return;
562         __disable_irq();
563         //serial_print("txstate=");
564         //serial_phex(tx_state[endpoint]);
565         //serial_print("\n");
566         switch (tx_state[endpoint]) {
567           case TX_STATE_BOTH_FREE_EVEN_FIRST:
568                 next = TX_STATE_ODD_FREE;
569                 break;
570           case TX_STATE_BOTH_FREE_ODD_FIRST:
571                 b++;
572                 next = TX_STATE_EVEN_FREE;
573                 break;
574           case TX_STATE_EVEN_FREE:
575                 next = TX_STATE_NONE_FREE;
576                 break;
577           case TX_STATE_ODD_FREE:
578                 b++;
579                 next = TX_STATE_NONE_FREE;
580                 break;
581           default:
582                 if (tx_first[endpoint] == NULL) {
583                         tx_first[endpoint] = packet;
584                 } else {
585                         tx_last[endpoint]->next = packet;
586                 }
587                 tx_last[endpoint] = packet;
588                 __enable_irq();
589                 return;
590         }
591         tx_state[endpoint] = next;
592         b->addr = packet->buf;
593         b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
594         __enable_irq();
595 }
596
597
598
599 void usb_device_reload()
600 {
601         asm volatile("bkpt");
602 }
603
604
605 void _reboot_Teensyduino_(void)
606 {
607         // TODO: initialize R0 with a code....
608         asm volatile("bkpt");
609 }
610
611
612
613 void usb_isr(void)
614 {
615         uint8_t status, stat, t;
616
617         //serial_print("isr");
618         //status = USB0_ISTAT;
619         //serial_phex(status);
620         //serial_print("\n");
621         restart:
622         status = USB0_ISTAT;
623
624         if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) {
625                 if (usb_configuration) {
626                         t = usb_reboot_timer;
627                         if (t) {
628                                 usb_reboot_timer = --t;
629                                 if (!t) _reboot_Teensyduino_();
630                         }
631 #ifdef CDC_DATA_INTERFACE
632                         t = usb_cdc_transmit_flush_timer;
633                         if (t) {
634                                 usb_cdc_transmit_flush_timer = --t;
635                                 if (t == 0) usb_serial_flush_callback();
636                         }
637 #endif
638                 }
639                 USB0_ISTAT = USB_INTEN_SOFTOKEN;
640         }
641
642         if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
643                 uint8_t endpoint;
644                 stat = USB0_STAT;
645                 //serial_print("token: ep=");
646                 //serial_phex(stat >> 4);
647                 //serial_print(stat & 0x08 ? ",tx" : ",rx");
648                 //serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
649                 endpoint = stat >> 4;
650                 if (endpoint == 0) {
651                         usb_control(stat);
652                 } else {
653                         bdt_t *b = stat2bufferdescriptor(stat);
654                         usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
655 #if 0
656                         serial_print("ep:");
657                         serial_phex(endpoint);
658                         serial_print(", pid:");
659                         serial_phex(BDT_PID(b->desc));
660                         serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
661                         serial_print(", count:");
662                         serial_phex(b->desc >> 16);
663                         serial_print("\n");
664 #endif
665                         endpoint--;     // endpoint is index to zero-based arrays
666
667                         if (stat & 0x08) { // transmit
668                                 usb_free(packet);
669                                 packet = tx_first[endpoint];
670                                 if (packet) {
671                                         //serial_print("tx packet\n");
672                                         tx_first[endpoint] = packet->next;
673                                         b->addr = packet->buf;
674                                         switch (tx_state[endpoint]) {
675                                           case TX_STATE_BOTH_FREE_EVEN_FIRST:
676                                                 tx_state[endpoint] = TX_STATE_ODD_FREE;
677                                                 break;
678                                           case TX_STATE_BOTH_FREE_ODD_FIRST:
679                                                 tx_state[endpoint] = TX_STATE_EVEN_FREE;
680                                                 break;
681                                           case TX_STATE_EVEN_FREE:
682                                           case TX_STATE_ODD_FREE:
683                                           default:
684                                                 tx_state[endpoint] = TX_STATE_NONE_FREE;
685                                                 break;
686                                         }
687                                         b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
688                                 } else {
689                                         //serial_print("tx no packet\n");
690                                         switch (tx_state[endpoint]) {
691                                           case TX_STATE_BOTH_FREE_EVEN_FIRST:
692                                           case TX_STATE_BOTH_FREE_ODD_FIRST:
693                                                 break;
694                                           case TX_STATE_EVEN_FREE:
695                                                 tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST;
696                                                 break;
697                                           case TX_STATE_ODD_FREE:
698                                                 tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST;
699                                                 break;
700                                           default:
701                                                 tx_state[endpoint] = ((uint32_t)b & 8) ?
702                                                   TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE;
703                                                 break;
704                                         }
705                                 }
706                         } else { // receive
707                                 packet->len = b->desc >> 16;
708                                 packet->index = 0;
709                                 packet->next = NULL;
710                                 if (rx_first[endpoint] == NULL) {
711                                         //serial_print("rx 1st, epidx=");
712                                         //serial_phex(endpoint);
713                                         //serial_print(", packet=");
714                                         //serial_phex32((uint32_t)packet);
715                                         //serial_print("\n");
716                                         rx_first[endpoint] = packet;
717                                 } else {
718                                         //serial_print("rx Nth, epidx=");
719                                         //serial_phex(endpoint);
720                                         //serial_print(", packet=");
721                                         //serial_phex32((uint32_t)packet);
722                                         //serial_print("\n");
723                                         rx_last[endpoint]->next = packet;
724                                 }
725                                 rx_last[endpoint] = packet;
726                                 // TODO: implement a per-endpoint maximum # of allocated packets
727                                 // so a flood of incoming data on 1 endpoint doesn't starve
728                                 // the others if the user isn't reading it regularly
729                                 packet = usb_malloc();
730                                 if (packet) {
731                                         b->addr = packet->buf;
732                                         b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0);
733                                 } else {
734                                         //serial_print("starving ");
735                                         //serial_phex(endpoint + 1);
736                                         //serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n");
737                                         b->desc = 0;
738                                         usb_rx_memory_needed++;
739                                 }
740                         }
741
742
743
744
745                 }
746                 USB0_ISTAT = USB_ISTAT_TOKDNE;
747                 goto restart;
748         }
749
750
751
752         if (status & USB_ISTAT_USBRST /* 01 */ ) {
753                 //serial_print("reset\n");
754
755                 // initialize BDT toggle bits
756                 USB0_CTL = USB_CTL_ODDRST;
757                 ep0_tx_bdt_bank = 0;
758
759                 // set up buffers to receive Setup and OUT packets
760                 table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0);
761                 table[index(0, RX, EVEN)].addr = ep0_rx0_buf;
762                 table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 0);
763                 table[index(0, RX, ODD)].addr = ep0_rx1_buf;
764                 table[index(0, TX, EVEN)].desc = 0;
765                 table[index(0, TX, ODD)].desc = 0;
766                 
767                 // activate endpoint 0
768                 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
769
770                 // clear all ending interrupts
771                 USB0_ERRSTAT = 0xFF;
772                 USB0_ISTAT = 0xFF;
773
774                 // set the address to zero during enumeration
775                 USB0_ADDR = 0;
776
777                 // enable other interrupts
778                 USB0_ERREN = 0xFF;
779                 USB0_INTEN = USB_INTEN_TOKDNEEN |
780                         USB_INTEN_SOFTOKEN |
781                         USB_INTEN_STALLEN |
782                         USB_INTEN_ERROREN |
783                         USB_INTEN_USBRSTEN |
784                         USB_INTEN_SLEEPEN;
785
786                 // is this necessary?
787                 USB0_CTL = USB_CTL_USBENSOFEN;
788                 return;
789         }
790
791
792         if ((status & USB_ISTAT_STALL /* 80 */ )) {
793                 //serial_print("stall:\n");
794                 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
795                 USB0_ISTAT = USB_ISTAT_STALL;
796         }
797         if ((status & USB_ISTAT_ERROR /* 02 */ )) {
798                 uint8_t err = USB0_ERRSTAT;
799                 USB0_ERRSTAT = err;
800                 //serial_print("err:");
801                 //serial_phex(err);
802                 //serial_print("\n");
803                 USB0_ISTAT = USB_ISTAT_ERROR;
804         }
805
806         if ((status & USB_ISTAT_SLEEP /* 10 */ )) {
807                 //serial_print("sleep\n");
808                 USB0_ISTAT = USB_ISTAT_SLEEP;
809         }
810
811 }
812
813
814
815 void usb_init(void)
816 {
817         int i;
818
819         //serial_begin(BAUD2DIV(115200));
820         //serial_print("usb_init\n");
821
822         for (i=0; i <= NUM_ENDPOINTS*4; i++) {
823                 table[i].desc = 0;
824                 table[i].addr = 0;
825         }
826
827         // this basically follows the flowchart in the Kinetis
828         // Quick Reference User Guide, Rev. 1, 03/2012, page 141
829
830         // assume 48 MHz clock already running
831         // SIM - enable clock
832         SIM_SCGC4 |= SIM_SCGC4_USBOTG;
833
834         // reset USB module
835         USB0_USBTRC0 = USB_USBTRC_USBRESET;
836         while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end
837
838         // set desc table base addr
839         USB0_BDTPAGE1 = ((uint32_t)table) >> 8;
840         USB0_BDTPAGE2 = ((uint32_t)table) >> 16;
841         USB0_BDTPAGE3 = ((uint32_t)table) >> 24;
842
843         // clear all ISR flags
844         USB0_ISTAT = 0xFF;
845         USB0_ERRSTAT = 0xFF;
846         USB0_OTGISTAT = 0xFF;
847
848         USB0_USBTRC0 |= 0x40; // undocumented bit
849
850         // enable USB
851         USB0_CTL = USB_CTL_USBENSOFEN;
852         USB0_USBCTRL = 0;
853
854         // enable reset interrupt
855         USB0_INTEN = USB_INTEN_USBRSTEN;
856
857         // enable interrupt in NVIC...
858         NVIC_ENABLE_IRQ(IRQ_USBOTG);
859
860         // enable d+ pullup
861         USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
862 }
863
864 // return 0 if the USB is not configured, or the configuration
865 // number selected by the HOST
866 uint8_t usb_configured(void)
867 {
868         return usb_configuration;
869 }
870