altos: Do not release interrupts from any pollchar function
[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                         debug ("Interface setup packet\n");
307                         switch(ao_usb_setup.request) {
308                         case AO_USB_REQ_GET_STATUS:
309                                 ao_usb_ep0_queue_byte(0);
310                                 ao_usb_ep0_queue_byte(0);
311                                 break;
312                         case AO_USB_REQ_GET_INTERFACE:
313                                 ao_usb_ep0_queue_byte(0);
314                                 break;
315                         case AO_USB_REQ_SET_INTERFACE:
316                                 break;
317                         }
318                         break;
319                 case AO_USB_RECIP_ENDPOINT:
320                         debug ("Endpoint setup packet\n");
321                         switch(ao_usb_setup.request) {
322                         case AO_USB_REQ_GET_STATUS:
323                                 ao_usb_ep0_queue_byte(0);
324                                 ao_usb_ep0_queue_byte(0);
325                                 break;
326                         }
327                         break;
328                 }
329                 break;
330         case AO_USB_TYPE_CLASS:
331                 debug ("Class setup packet\n");
332                 switch (ao_usb_setup.request) {
333                 case AO_USB_SET_LINE_CODING:
334                         debug ("set line coding\n");
335                         ao_usb_ep0_out_len = 7;
336                         ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding;
337                         break;
338                 case AO_USB_GET_LINE_CODING:
339                         debug ("get line coding\n");
340                         ao_usb_ep0_in_len = 7;
341                         ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding;
342                         break;
343                 case AO_USB_SET_CONTROL_LINE_STATE:
344                         break;
345                 }
346                 break;
347         }
348         if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
349                 if (ao_usb_setup.length < ao_usb_ep0_in_len)
350                         ao_usb_ep0_in_len = ao_usb_setup.length;
351                 debug ("Start ep0 in delivery %d\n", ao_usb_ep0_in_len);
352                 ao_usb_ep0_set_in_pending(1);
353         }
354 }
355
356 /* End point 0 receives all of the control messages. */
357 static void
358 ao_usb_ep0(void)
359 {
360         uint8_t intx, udint;
361
362         debug ("usb task started\n");
363         ao_usb_ep0_state = AO_USB_EP0_IDLE;
364         for (;;) {
365                 cli();
366                 for (;;) {
367                         udint = UDINT;
368                         UDINT = 0;
369 //                      debug ("UDINT %02x\n", udint);
370                         if (udint & (1 << EORSTI)) {
371                                 ao_usb_configuration = 0;
372                                 ao_usb_set_ep0();
373                         }
374                         UENUM = 0;
375                         intx = UEINTX;
376 //                      debug ("UEINTX %02x\n", intx);
377                         if (intx & ((1 << RXSTPI) | (1 << RXOUTI)))
378                                 break;
379                         if ((intx & (1 << TXINI))) {
380                                 if (ao_usb_ep0_in_pending)
381                                         break;
382                                 else
383                                 {
384                                         if (ao_usb_addr_pending) {
385                                                 UDADDR |= (1 << ADDEN);
386                                                 ao_usb_addr_pending = 0;
387                                         }
388                                         ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE));     /* Disable IN interrupt */
389                                 }
390                         }
391 //                      debug ("usb task sleeping...\n");
392                         UENUM = 0;
393                         UEIENX = ueienx_0;
394                         ao_sleep(&ao_usb_task);
395                 }
396                 sei();
397 //              debug ("UEINTX for ep0 is %02x\n", intx);
398                 if (intx & (1 << RXSTPI)) {
399                         ao_usb_ep0_setup();
400                 }
401                 if (intx & (1 << RXOUTI)) {
402                         ao_usb_ep0_fill(UEBCLX, (1 << RXOUTI));
403                         ao_usb_ep0_set_in_pending(1);
404                 }
405                 if (intx & (1 << TXINI) && ao_usb_ep0_in_pending) {
406                         debug ("continue sending ep0 IN data\n");
407                         ao_usb_ep0_flush();
408                 }
409         }
410 }
411
412 /* Wait for a free IN buffer */
413 static void
414 _ao_usb_in_wait(void)
415 {
416         for (;;) {
417                 /* Check if the current buffer is writable */
418                 UENUM = AO_USB_IN_EP;
419                 if (UEINTX & (1 << RWAL))
420                         break;
421
422                 /* Wait for an IN buffer to be ready */
423                 for (;;) {
424                         UENUM = AO_USB_IN_EP;
425                         if ((UEINTX & (1 << TXINI)))
426                                 break;
427                         UEIENX = (1 << TXINE);
428                         ao_sleep(&ao_usb_in_flushed);
429                 }
430                 /* Ack the interrupt */
431                 UEINTX &= ~(1 << TXINI);
432         }
433 }
434
435 /* Queue the current IN buffer for transmission */
436 static void
437 _ao_usb_in_send(void)
438 {
439         UENUM = AO_USB_IN_EP;
440         UEINTX &= ~(1 << FIFOCON);
441 }
442
443 void
444 ao_usb_flush(void)
445 {
446         if (!ao_usb_running)
447                 return;
448
449         ao_arch_block_interrupts();
450         /* Anytime we've sent a character since
451          * the last time we flushed, we'll need
452          * to send a packet -- the only other time
453          * we would send a packet is when that
454          * packet was full, in which case we now
455          * want to send an empty packet
456          */
457         if (!ao_usb_in_flushed) {
458                 ao_usb_in_flushed = 1;
459                 _ao_usb_in_wait();
460                 _ao_usb_in_send();
461         }
462         ao_arch_release_interrupts();
463 }
464
465 void
466 ao_usb_putchar(char c)
467 {
468         if (!ao_usb_running)
469                 return;
470
471         ao_arch_block_interrupts();
472         _ao_usb_in_wait();
473
474         /* Queue a byte */
475         UENUM = AO_USB_IN_EP;
476         UEDATX = c;
477
478         /* Send the packet when full */
479         if ((UEINTX & (1 << RWAL)) == 0)
480                 _ao_usb_in_send();
481         ao_usb_in_flushed = 0;
482         ao_arch_release_interrupts();
483 }
484
485 int
486 _ao_usb_pollchar(void)
487 {
488         uint8_t c;
489         uint8_t intx;
490
491         if (!ao_usb_running)
492                 return AO_READ_AGAIN;
493
494         for (;;) {
495                 UENUM = AO_USB_OUT_EP;
496                 intx = UEINTX;
497                 debug("usb_pollchar UEINTX %02d\n", intx);
498                 if (intx & (1 << RWAL))
499                         break;
500
501                 if (intx & (1 << FIFOCON)) {
502                         /* Ack the last packet */
503                         UEINTX = (uint8_t) ~(1 << FIFOCON);
504                 }
505
506                 /* Check to see if a packet has arrived */
507                 if ((intx & (1 << RXOUTI)) == 0) {
508                         UENUM = AO_USB_OUT_EP;
509                         UEIENX = (1 << RXOUTE);
510                         return AO_READ_AGAIN;
511                 }
512
513                 /* Ack the interrupt */
514                 UEINTX = ~(1 << RXOUTI);
515         }
516
517         /* Pull a character out of the fifo */
518         c = UEDATX;
519         return c;
520 }
521
522 char
523 ao_usb_getchar(void)
524 {
525         int     c;
526
527         ao_arch_block_interrupts();
528         while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN)
529                 ao_sleep(&ao_stdin_ready);
530         ao_arch_release_interrupts();
531         return c;
532 }
533
534 uint16_t        control_count;
535 uint16_t        in_count;
536 uint16_t        out_count;
537
538 /* Endpoint interrupt */
539 ISR(USB_COM_vect)
540 {
541         uint8_t old_num = UENUM;
542         uint8_t i = UEINT;
543
544 #ifdef AO_LED_RED
545         ao_led_toggle(AO_LED_RED);
546 #endif
547         UEINT = 0;
548         if (i & (1 << 0)) {
549                 UENUM = 0;
550                 UEIENX = 0;
551                 ao_wakeup(&ao_usb_task);
552                 ++control_count;
553         }
554         if (i & (1 << AO_USB_IN_EP)) {
555                 UENUM = AO_USB_IN_EP;
556                 UEIENX = 0;
557                 ao_wakeup(&ao_usb_in_flushed);
558                 in_count++;
559         }
560         if (i & (1 << AO_USB_OUT_EP)) {
561                 UENUM = AO_USB_OUT_EP;
562                 UEIENX = 0;
563                 ao_wakeup(&ao_stdin_ready);
564                 ++out_count;
565         }
566         UENUM = old_num;
567 }
568
569 #if AVR_VCC_5V
570 #define AO_PAD_REGULATOR_INIT   (1 << UVREGE)   /* Turn on pad regulator */
571 #endif
572 #if AVR_VCC_3V3
573 /* TeleScience V0.1 has a hardware bug -- UVcc is hooked up, but UCap is not
574  * Make this work by running power through UVcc to the USB system
575  */
576 #define AO_PAD_REGULATOR_INIT   (1 << UVREGE)   /* Turn off pad regulator */
577 #endif
578
579 #if AVR_CLOCK == 16000000UL
580 #define AO_USB_PLL_INPUT_PRESCALER      (1 << PINDIV)   /* Divide 16MHz clock by 2 */
581 #endif
582 #if AVR_CLOCK == 8000000UL
583 #define AO_USB_PLL_INPUT_PRESCALER      0               /* Don't divide clock */
584 #endif
585
586 void
587 ao_usb_disable(void)
588 {
589         /* Unplug from the bus */
590         UDCON = (1 << DETACH);
591
592         /* Disable the interface */
593         USBCON = 0;
594
595         /* Disable the PLL */
596         PLLCSR = 0;
597
598         /* Turn off the pad regulator */
599         UHWCON = 0;
600 }
601
602 #define AO_USB_CON ((1 << USBE) |       /* USB enable */ \
603                     (0 << RSTCPU) |     /* do not reset CPU */  \
604                     (0 << LSM) |        /* Full speed mode */   \
605                     (0 << RMWKUP))      /* no remote wake-up */ \
606
607 void
608 ao_usb_enable(void)
609 {
610         /* Configure pad regulator */
611         UHWCON = AO_PAD_REGULATOR_INIT;
612
613         /* Enable USB device, but freeze the clocks until initialized */
614         USBCON = AO_USB_CON | (1 <<FRZCLK);
615
616         /* Enable PLL with appropriate divider */
617         PLLCSR = AO_USB_PLL_INPUT_PRESCALER | (1 << PLLE);
618
619         /* Wait for PLL to lock */
620         loop_until_bit_is_set(PLLCSR, (1 << PLOCK));
621
622         /* Enable USB, enable the VBUS pad */
623         USBCON = AO_USB_CON | (1 << OTGPADE);
624
625         /* Enable global interrupts */
626         UDIEN = (1 << EORSTE);          /* End of reset interrupt */
627
628         ao_usb_configuration = 0;
629
630         debug ("ao_usb_enable\n");
631
632         debug ("UHWCON %02x USBCON %02x PLLCSR %02x UDIEN %02x\n",
633                UHWCON, USBCON, PLLCSR, UDIEN);
634         UDCON = (0 << DETACH);  /* Clear the DETACH bit to plug into the bus */
635 }
636
637 #if USB_DEBUG
638 struct ao_task __xdata ao_usb_echo_task;
639
640 static void
641 ao_usb_echo(void)
642 {
643         char    c;
644
645         for (;;) {
646                 c = ao_usb_getchar();
647                 ao_usb_putchar(c);
648                 ao_usb_flush();
649         }
650 }
651 #endif
652
653 void
654 ao_usb_init(void)
655 {
656         ao_usb_enable();
657
658         debug ("ao_usb_init\n");
659         ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
660 #if USB_DEBUG
661         ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
662 #endif
663         ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
664 }