altos/telescience: Add more header dependencies
[fw/altos] / src / avr / ao_usb_avr.c
1 /*
2  * Copyright © 2011 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19 #include "ao_usb.h"
20
21 #define USB_DEBUG 0
22
23 #if USB_DEBUG
24 #define debug(format, args...)  printf(format, ## args)
25 #else
26 #define debug(format, args...)
27 #endif
28
29 struct ao_task __xdata ao_usb_task;
30
31 struct ao_usb_setup {
32         uint8_t         dir_type_recip;
33         uint8_t         request;
34         uint16_t        value;
35         uint16_t        index;
36         uint16_t        length;
37 } __xdata ao_usb_setup;
38
39 static __xdata uint8_t  ao_usb_ep0_state;
40 static const uint8_t * __xdata ao_usb_ep0_in_data;
41 static __xdata uint8_t  ao_usb_ep0_in_len;
42 static __xdata uint8_t  ao_usb_ep0_in_pending;
43 static __xdata uint8_t  ao_usb_addr_pending;
44 static __xdata uint8_t  ao_usb_ep0_in_buf[2];
45 static __xdata uint8_t  ao_usb_ep0_out_len;
46 static __xdata uint8_t *__xdata ao_usb_ep0_out_data;
47
48 static __xdata uint8_t  ao_usb_in_flushed;
49 static __xdata uint8_t  ao_usb_running;
50 static __xdata uint8_t  ao_usb_configuration;
51 static __xdata uint8_t  ueienx_0;
52
53 void
54 ao_usb_set_address(uint8_t address)
55 {
56         UDADDR = (0 << ADDEN) | address;
57         ao_usb_addr_pending = 1;
58 }
59
60 #define EP_SIZE(s)      ((s) == 64 ? 0x30 :     \
61                         ((s) == 32 ? 0x20 :     \
62                         ((s) == 16 ? 0x10 :     \
63                                      0x00)))
64
65 static void
66 ao_usb_dump_ep(uint8_t ep)
67 {
68         UENUM = ep;
69         debug ("EP %d: UECONX %02x UECFG0X %02x UECFG1X %02x UEIENX %02x UESTA0X %02x UESTA1X %02X\n",
70                 ep, UECONX, UECFG0X, UECFG1X, UEIENX, UESTA0X, UESTA1X);
71 }
72
73 static void
74 ao_usb_set_ep0(void)
75 {
76         debug ("set_ep0\n");
77         /* Set the CONTROL max packet size, single buffered */
78         UENUM = 0;
79         UECONX = (1 << EPEN);                                   /* Enable */
80
81         UECFG0X = ((0 << EPTYPE0) |                             /* Control */
82                    (0 << EPDIR));                               /* Out (ish) */
83
84         UECFG1X = (EP_SIZE(AO_USB_CONTROL_SIZE) |               /* Size */
85                    (0 << EPBK0) |                               /* Single bank */
86                    (1 << ALLOC));
87
88         ueienx_0 = ((1 << RXSTPE) |                             /* Enable SETUP interrupt */
89                     (1 << RXOUTE));                             /* Enable OUT interrupt */
90
91 //      ao_usb_dump_ep(0);
92         ao_usb_addr_pending = 0;
93 }
94
95 static void
96 ao_usb_set_configuration(void)
97 {
98         /* Set the IN max packet size, double buffered */
99         UENUM = AO_USB_IN_EP;
100         UECONX = (1 << EPEN);                                   /* Enable */
101
102         UECFG0X = ((2 << EPTYPE0) |                             /* Bulk */
103                    (1 << EPDIR));                               /* In */
104
105         UECFG1X = (EP_SIZE(AO_USB_IN_SIZE) |                    /* Size */
106                    (1 << EPBK0) |                               /* Double bank */
107                    (1 << ALLOC));                               /* Allocate */
108
109 #if 0
110         UEIENX = ((1 << TXINE));                                /* Enable IN complete interrupt */
111 #endif
112
113         ao_usb_dump_ep(AO_USB_IN_EP);
114
115         /* Set the OUT max packet size, double buffered */
116         UENUM = AO_USB_OUT_EP;
117         UECONX |= (1 << EPEN);                                  /* Enable */
118
119         UECFG0X = ((2 << EPTYPE0) |                             /* Bulk */
120                    (0 << EPDIR));                               /* Out */
121
122         UECFG1X = (EP_SIZE(AO_USB_OUT_SIZE) |                   /* Size */
123                    (1 << EPBK0) |                               /* Double bank */
124                    (1 << ALLOC));                               /* Allocate */
125
126         UEIENX = ((1 << RXOUTE));                               /* Enable OUT complete interrupt */
127
128         ao_usb_dump_ep(AO_USB_OUT_EP);
129         ao_usb_running = 1;
130 }
131
132 ISR(USB_GEN_vect)
133 {
134         ao_wakeup(&ao_usb_task);
135 }
136
137
138 __xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
139
140 /* Walk through the list of descriptors and find a match
141  */
142 static void
143 ao_usb_get_descriptor(uint16_t value)
144 {
145         const uint8_t           *__xdata descriptor;
146         __xdata uint8_t         type = value >> 8;
147         __xdata uint8_t         index = value;
148
149         descriptor = ao_usb_descriptors;
150         while (descriptor[0] != 0) {
151                 if (descriptor[1] == type && index-- == 0) {
152                         if (type == AO_USB_DESC_CONFIGURATION)
153                                 ao_usb_ep0_in_len = descriptor[2];
154                         else
155                                 ao_usb_ep0_in_len = descriptor[0];
156                         ao_usb_ep0_in_data = descriptor;
157                         break;
158                 }
159                 descriptor += descriptor[0];
160         }
161 }
162
163 static void
164 ao_usb_ep0_set_in_pending(uint8_t in_pending)
165 {
166         ao_usb_ep0_in_pending = in_pending;
167
168         if (in_pending)
169                 ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE) | (1 << TXINE));      /* Enable IN interrupt */
170 }
171
172 /* Send an IN data packet */
173 static void
174 ao_usb_ep0_flush(void)
175 {
176         __xdata uint8_t this_len;
177
178         cli();
179         UENUM = 0;
180         if (!(UEINTX & (1 << TXINI))) {
181                 debug("EP0 not accepting IN data\n");
182                 ao_usb_ep0_set_in_pending(1);
183         } else {
184                 this_len = ao_usb_ep0_in_len;
185                 if (this_len > AO_USB_CONTROL_SIZE)
186                         this_len = AO_USB_CONTROL_SIZE;
187
188                 ao_usb_ep0_in_len -= this_len;
189
190                 /* Set IN interrupt enable */
191                 if (ao_usb_ep0_in_len == 0 && this_len != AO_USB_CONTROL_SIZE)
192                         ao_usb_ep0_set_in_pending(0);
193                 else
194                         ao_usb_ep0_set_in_pending(1);
195
196                 debug ("Flush EP0 len %d:", this_len);
197                 while (this_len--) {
198                         uint8_t c = *ao_usb_ep0_in_data++;
199                         debug(" %02x", c);
200                         UEDATX = c;
201                 }
202                 debug ("\n");
203
204                 /* Clear the TXINI bit to send the packet */
205                 UEINTX &= ~(1 << TXINI);
206         }
207         sei();
208 }
209
210 /* Read data from the ep0 OUT fifo */
211 static void
212 ao_usb_ep0_fill(uint8_t len, uint8_t ack)
213 {
214         if (len > ao_usb_ep0_out_len)
215                 len = ao_usb_ep0_out_len;
216         ao_usb_ep0_out_len -= len;
217
218 //      debug ("EP0 UEINTX %02x UEBCLX %d UEBCHX %d\n",
219 //              UEINTX, UEBCLX, UEBCHX);
220         /* Pull all of the data out of the packet */
221         debug ("Fill EP0 len %d:", len);
222         UENUM = 0;
223         while (len--) {
224                 uint8_t c = UEDATX;
225                 *ao_usb_ep0_out_data++ = c;
226                 debug (" %02x", c);
227         }
228         debug ("\n");
229
230         /* ACK the packet */
231         UEINTX &= ~ack;
232 }
233
234 void
235 ao_usb_ep0_queue_byte(uint8_t a)
236 {
237         ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a;
238 }
239
240 static void
241 ao_usb_ep0_setup(void)
242 {
243         /* Pull the setup packet out of the fifo */
244         ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_setup;
245         ao_usb_ep0_out_len = 8;
246         ao_usb_ep0_fill(8, (1 << RXSTPI) | (1 << RXOUTI) | (1 << TXINI));
247         if (ao_usb_ep0_out_len != 0) {
248                 debug ("invalid setup packet length\n");
249                 return;
250         }
251
252         /* Figure out how to ACK the setup packet */
253         if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) {
254                 if (ao_usb_setup.length)
255                         ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
256                 else
257                         ao_usb_ep0_state = AO_USB_EP0_IDLE;
258         } else {
259                 if (ao_usb_setup.length)
260                         ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
261                 else
262                         ao_usb_ep0_state = AO_USB_EP0_IDLE;
263         }
264 /*
265         UENUM = 0;
266         if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
267                 USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
268         else
269                 USBCS0 = USBCS0_CLR_OUTPKT_RDY;
270 */
271
272         ao_usb_ep0_in_data = ao_usb_ep0_in_buf;
273         ao_usb_ep0_in_len = 0;
274         switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) {
275         case AO_USB_TYPE_STANDARD:
276                 debug ("Standard setup packet\n");
277                 switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) {
278                 case AO_USB_RECIP_DEVICE:
279                         debug ("Device setup packet\n");
280                         switch(ao_usb_setup.request) {
281                         case AO_USB_REQ_GET_STATUS:
282                                 debug ("get status\n");
283                                 ao_usb_ep0_queue_byte(0);
284                                 ao_usb_ep0_queue_byte(0);
285                                 break;
286                         case AO_USB_REQ_SET_ADDRESS:
287                                 debug ("set address %d\n", ao_usb_setup.value);
288                                 ao_usb_set_address(ao_usb_setup.value);
289                                 break;
290                         case AO_USB_REQ_GET_DESCRIPTOR:
291                                 debug ("get descriptor %d\n", ao_usb_setup.value);
292                                 ao_usb_get_descriptor(ao_usb_setup.value);
293                                 break;
294                         case AO_USB_REQ_GET_CONFIGURATION:
295                                 debug ("get configuration %d\n", ao_usb_configuration);
296                                 ao_usb_ep0_queue_byte(ao_usb_configuration);
297                                 break;
298                         case AO_USB_REQ_SET_CONFIGURATION:
299                                 ao_usb_configuration = ao_usb_setup.value;
300                                 debug ("set configuration %d\n", ao_usb_configuration);
301                                 ao_usb_set_configuration();
302                                 break;
303                         }
304                         break;
305                 case AO_USB_RECIP_INTERFACE:
306 #ifndef AVR
307                         #pragma disable_warning 110
308 #endif
309                         debug ("Interface setup packet\n");
310                         switch(ao_usb_setup.request) {
311                         case AO_USB_REQ_GET_STATUS:
312                                 ao_usb_ep0_queue_byte(0);
313                                 ao_usb_ep0_queue_byte(0);
314                                 break;
315                         case AO_USB_REQ_GET_INTERFACE:
316                                 ao_usb_ep0_queue_byte(0);
317                                 break;
318                         case AO_USB_REQ_SET_INTERFACE:
319                                 break;
320                         }
321                         break;
322                 case AO_USB_RECIP_ENDPOINT:
323                         debug ("Endpoint setup packet\n");
324                         switch(ao_usb_setup.request) {
325                         case AO_USB_REQ_GET_STATUS:
326                                 ao_usb_ep0_queue_byte(0);
327                                 ao_usb_ep0_queue_byte(0);
328                                 break;
329                         }
330                         break;
331                 }
332                 break;
333         case AO_USB_TYPE_CLASS:
334                 debug ("Class setup packet\n");
335                 switch (ao_usb_setup.request) {
336                 case SET_LINE_CODING:
337                         debug ("set line coding\n");
338                         ao_usb_ep0_out_len = 7;
339                         ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding;
340                         break;
341                 case GET_LINE_CODING:
342                         debug ("get line coding\n");
343                         ao_usb_ep0_in_len = 7;
344                         ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding;
345                         break;
346                 case SET_CONTROL_LINE_STATE:
347                         break;
348                 }
349                 break;
350         }
351         if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
352                 if (ao_usb_setup.length < ao_usb_ep0_in_len)
353                         ao_usb_ep0_in_len = ao_usb_setup.length;
354                 debug ("Start ep0 in delivery %d\n", ao_usb_ep0_in_len);
355                 ao_usb_ep0_set_in_pending(1);
356         }
357 }
358
359 /* End point 0 receives all of the control messages. */
360 static void
361 ao_usb_ep0(void)
362 {
363         uint8_t intx, udint;
364
365         debug ("usb task started\n");
366         ao_usb_ep0_state = AO_USB_EP0_IDLE;
367         for (;;) {
368                 cli();
369                 for (;;) {
370                         udint = UDINT;
371                         UDINT = 0;
372 //                      debug ("UDINT %02x\n", udint);
373                         if (udint & (1 << EORSTI)) {
374                                 ao_usb_configuration = 0;
375                                 ao_usb_set_ep0();
376                         }
377                         UENUM = 0;
378                         intx = UEINTX;
379 //                      debug ("UEINTX %02x\n", intx);
380                         if (intx & ((1 << RXSTPI) | (1 << RXOUTI)))
381                                 break;
382                         if ((intx & (1 << TXINI))) {
383                                 if (ao_usb_ep0_in_pending)
384                                         break;
385                                 else
386                                 {
387                                         if (ao_usb_addr_pending) {
388                                                 UDADDR |= (1 << ADDEN);
389                                                 ao_usb_addr_pending = 0;
390                                         }
391                                         ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE));     /* Disable IN interrupt */
392                                 }
393                         }
394 //                      debug ("usb task sleeping...\n");
395                         UENUM = 0;
396                         UEIENX = ueienx_0;
397                         ao_sleep(&ao_usb_task);
398                 }
399                 sei();
400 //              debug ("UEINTX for ep0 is %02x\n", intx);
401                 if (intx & (1 << RXSTPI)) {
402                         ao_usb_ep0_setup();
403                 }
404                 if (intx & (1 << RXOUTI)) {
405                         ao_usb_ep0_fill(UEBCLX, (1 << RXOUTI));
406                         ao_usb_ep0_set_in_pending(1);
407                 }
408                 if (intx & (1 << TXINI) && ao_usb_ep0_in_pending) {
409                         debug ("continue sending ep0 IN data\n");
410                         ao_usb_ep0_flush();
411                 }
412         }
413 }
414
415 /* Wait for a free IN buffer */
416 static void
417 ao_usb_in_wait(void)
418 {
419         for (;;) {
420                 /* Check if the current buffer is writable */
421                 UENUM = AO_USB_IN_EP;
422                 if (UEINTX & (1 << RWAL))
423                         break;
424
425                 cli();
426                 /* Wait for an IN buffer to be ready */
427                 for (;;) {
428                         UENUM = AO_USB_IN_EP;
429                         if ((UEINTX & (1 << TXINI)))
430                                 break;
431                         UEIENX = (1 << TXINE);
432                         ao_sleep(&ao_usb_in_flushed);
433                 }
434                 /* Ack the interrupt */
435                 UEINTX &= ~(1 << TXINI);
436                 sei();
437         }
438 }
439
440 /* Queue the current IN buffer for transmission */
441 static void
442 ao_usb_in_send(void)
443 {
444         UENUM = AO_USB_IN_EP;
445         UEINTX &= ~(1 << FIFOCON);
446 }
447
448 void
449 ao_usb_flush(void) __critical
450 {
451         if (!ao_usb_running)
452                 return;
453
454         /* Anytime we've sent a character since
455          * the last time we flushed, we'll need
456          * to send a packet -- the only other time
457          * we would send a packet is when that
458          * packet was full, in which case we now
459          * want to send an empty packet
460          */
461         if (!ao_usb_in_flushed) {
462                 ao_usb_in_flushed = 1;
463                 ao_usb_in_wait();
464                 ao_usb_in_send();
465         }
466 }
467
468 void
469 ao_usb_putchar(char c) __critical __reentrant
470 {
471         if (!ao_usb_running)
472                 return;
473
474         ao_usb_in_wait();
475
476         /* Queue a byte */
477         UENUM = AO_USB_IN_EP;
478         UEDATX = c;
479
480         /* Send the packet when full */
481         if ((UEINTX & (1 << RWAL)) == 0)
482                 ao_usb_in_send();
483         ao_usb_in_flushed = 0;
484 }
485
486 static char
487 _ao_usb_pollchar(void)
488 {
489         char c;
490         uint8_t intx;
491
492         if (!ao_usb_running)
493                 return AO_READ_AGAIN;
494
495         for (;;) {
496                 UENUM = AO_USB_OUT_EP;
497                 intx = UEINTX;
498                 debug("usb_pollchar UEINTX %02d\n", intx);
499                 if (intx & (1 << RWAL))
500                         break;
501
502                 if (intx & (1 << FIFOCON)) {
503                         /* Ack the last packet */
504                         UEINTX = (uint8_t) ~(1 << FIFOCON);
505                 }
506
507                 /* Check to see if a packet has arrived */
508                 if ((intx & (1 << RXOUTI)) == 0) {
509                         UENUM = AO_USB_OUT_EP;
510                         UEIENX = (1 << RXOUTE);
511                         return AO_READ_AGAIN;
512                 }
513
514                 /* Ack the interrupt */
515                 UEINTX = ~(1 << RXOUTI);
516         }
517
518         /* Pull a character out of the fifo */
519         c = UEDATX;
520         return c;
521 }
522
523 char
524 ao_usb_pollchar(void)
525 {
526         char    c;
527         cli();
528         c = _ao_usb_pollchar();
529         sei();
530         return c;
531 }
532
533 char
534 ao_usb_getchar(void) __critical
535 {
536         char    c;
537
538         cli();
539         while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN)
540                 ao_sleep(&ao_stdin_ready);
541         sei();
542         return c;
543 }
544
545 uint16_t        control_count;
546 uint16_t        in_count;
547 uint16_t        out_count;
548
549 /* Endpoint interrupt */
550 ISR(USB_COM_vect)
551 {
552         uint8_t old_num = UENUM;
553         uint8_t i = UEINT;
554
555 #ifdef AO_LED_RED
556         ao_led_toggle(AO_LED_RED);
557 #endif
558         UEINT = 0;
559         if (i & (1 << 0)) {
560                 UENUM = 0;
561                 UEIENX = 0;
562                 ao_wakeup(&ao_usb_task);
563                 ++control_count;
564         }
565         if (i & (1 << AO_USB_IN_EP)) {
566                 UENUM = AO_USB_IN_EP;
567                 UEIENX = 0;
568                 ao_wakeup(&ao_usb_in_flushed);
569                 in_count++;
570         }
571         if (i & (1 << AO_USB_OUT_EP)) {
572                 UENUM = AO_USB_OUT_EP;
573                 UEIENX = 0;
574                 ao_wakeup(&ao_stdin_ready);
575                 ++out_count;
576         }
577         UENUM = old_num;
578 }
579
580 #if AVR_VCC_5V
581 #define AO_PAD_REGULATOR_INIT   (1 << UVREGE)   /* Turn on pad regulator */
582 #endif
583 #if AVR_VCC_3V3
584 /* TeleScience V0.1 has a hardware bug -- UVcc is hooked up, but UCap is not
585  * Make this work by running power through UVcc to the USB system
586  */
587 #define AO_PAD_REGULATOR_INIT   (1 << UVREGE)   /* Turn off pad regulator */
588 #endif
589
590 #if AVR_CLOCK == 16000000UL
591 #define AO_USB_PLL_INPUT_PRESCALER      (1 << PINDIV)   /* Divide 16MHz clock by 2 */
592 #endif
593 #if AVR_CLOCK == 8000000UL
594 #define AO_USB_PLL_INPUT_PRESCALER      0               /* Don't divide clock */
595 #endif
596
597 void
598 ao_usb_disable(void)
599 {
600         /* Unplug from the bus */
601         UDCON = (1 << DETACH);
602
603         /* Disable the interface */
604         USBCON = 0;
605
606         /* Disable the PLL */
607         PLLCSR = 0;
608
609         /* Turn off the pad regulator */
610         UHWCON = 0;
611 }
612
613 #define AO_USB_CON ((1 << USBE) |       /* USB enable */ \
614                     (0 << RSTCPU) |     /* do not reset CPU */  \
615                     (0 << LSM) |        /* Full speed mode */   \
616                     (0 << RMWKUP))      /* no remote wake-up */ \
617
618 void
619 ao_usb_enable(void)
620 {
621         /* Configure pad regulator */
622         UHWCON = AO_PAD_REGULATOR_INIT;
623
624         /* Enable USB device, but freeze the clocks until initialized */
625         USBCON = AO_USB_CON | (1 <<FRZCLK);
626
627         /* Enable PLL with appropriate divider */
628         PLLCSR = AO_USB_PLL_INPUT_PRESCALER | (1 << PLLE);
629
630         /* Wait for PLL to lock */
631         loop_until_bit_is_set(PLLCSR, (1 << PLOCK));
632
633         /* Enable USB, enable the VBUS pad */
634         USBCON = AO_USB_CON | (1 << OTGPADE);
635
636         /* Enable global interrupts */
637         UDIEN = (1 << EORSTE);          /* End of reset interrupt */
638
639         ao_usb_configuration = 0;
640
641         debug ("ao_usb_enable\n");
642
643         debug ("UHWCON %02x USBCON %02x PLLCSR %02x UDIEN %02x\n",
644                UHWCON, USBCON, PLLCSR, UDIEN);
645         UDCON = (0 << DETACH);  /* Clear the DETACH bit to plug into the bus */
646 }
647
648 #if USB_DEBUG
649 struct ao_task __xdata ao_usb_echo_task;
650
651 static void
652 ao_usb_echo(void)
653 {
654         char    c;
655
656         for (;;) {
657                 c = ao_usb_getchar();
658                 ao_usb_putchar(c);
659                 ao_usb_flush();
660         }
661 }
662 #endif
663
664 static void
665 ao_usb_irq(void)
666 {
667         printf ("control: %d out: %d in: %d\n",
668                 control_count, out_count, in_count);
669 }
670
671 __code struct ao_cmds ao_usb_cmds[] = {
672         { ao_usb_irq, "i\0Show USB interrupt counts" },
673         { 0, NULL }
674 };
675
676 void
677 ao_usb_init(void)
678 {
679         ao_usb_enable();
680
681         debug ("ao_usb_init\n");
682         ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
683 #if USB_DEBUG
684         ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
685 #endif
686         ao_cmd_register(&ao_usb_cmds[0]);
687         ao_add_stdio(ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
688 }