Discard usb output before connection. Handle USB reset. 0.2
authorKeith Packard <keithp@keithp.com>
Thu, 14 May 2009 03:41:54 +0000 (20:41 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 14 May 2009 03:41:54 +0000 (20:41 -0700)
Discarding output before USB is plugged in allows threads that send output
and do other things to work without a USB connection. Unfortuantely, there
doesn't appear to be any way to detect when the USB link is disconnected,
which means that once USB is enabled, future writes will continue to block.

USB reset causes the USB interrupts to all be reconfigured back to power-on
state.

Signed-off-by: Keith Packard <keithp@keithp.com>
ao_usb.c
cc1111.h

index 69f87fc4dd17a36e1ef53cfa8324984bb9857011..315eea0828ab6fd3c5a3473f4cbe46d1730ba506 100644 (file)
--- a/ao_usb.c
+++ b/ao_usb.c
@@ -23,7 +23,20 @@ struct ao_task __xdata ao_usb_task;
 static __xdata uint16_t        ao_usb_in_bytes;
 static __xdata uint16_t        ao_usb_out_bytes;
 static __xdata uint8_t ao_usb_iif;
-static __xdata uint8_t ao_usb_oif;
+static __xdata uint8_t ao_usb_running;
+
+static void
+ao_usb_set_interrupts(void)
+{
+       /* IN interrupts on the control an IN endpoints */
+       USBIIE = (1 << AO_USB_CONTROL_EP) | (1 << AO_USB_IN_EP);
+
+       /* OUT interrupts on the OUT endpoint */
+       USBOIE = (1 << AO_USB_OUT_EP);
+
+       /* Only care about reset */
+       USBCIE = USBCIE_RSTIE;
+}
 
 /* This interrupt is shared with port 2, 
  * so when we hook that up, fix this
@@ -38,9 +51,11 @@ ao_usb_isr(void) interrupt 6
        if (ao_usb_iif & (1 << AO_USB_IN_EP))
                ao_wakeup(&ao_usb_in_bytes);
 
-       ao_usb_oif |= USBOIF;
-       if (ao_usb_oif & (1 << AO_USB_OUT_EP))
+       if (USBOIF & (1 << AO_USB_OUT_EP))
                ao_wakeup(&ao_usb_out_bytes);
+
+       if (USBCIF & USBCIF_RSTIF)
+               ao_usb_set_interrupts();
 }
 
 struct ao_usb_setup {
@@ -136,6 +151,7 @@ ao_usb_ep0_queue_byte(uint8_t a)
 void
 ao_usb_set_address(uint8_t address)
 {
+       ao_usb_running = 1;
        USBADDR = address | 0x80;
        while (USBADDR & 0x80)
                ;
@@ -318,6 +334,8 @@ ao_usb_flush(void) __critical
 void
 ao_usb_putchar(char c) __critical
 {
+       if (!ao_usb_running)
+               return;
        for (;;) {
                USBINDEX = AO_USB_IN_EP;
                if ((USBCSIL & USBCSIL_INPKT_RDY) == 0)
@@ -362,15 +380,8 @@ ao_usb_enable(void)
 
        ao_usb_set_configuration();
        
-       /* IN interrupts on the control an IN endpoints */
-       USBIIE = (1 << AO_USB_CONTROL_EP) | (1 << AO_USB_IN_EP);
+       ao_usb_set_interrupts();
 
-       /* OUT interrupts on the OUT endpoint */
-       USBOIE = (1 << AO_USB_OUT_EP);
-
-       /* Ignore control interrupts */
-       USBCIE = 0;
-       
        /* enable USB interrupts */
        IEN2 |= IEN2_USBIE;
 
index 2045c71640a490e22cda2626f541f5d1c14c5cb0..4e45146571f09c284b89566520570548f7f2c826 100644 (file)
--- a/cc1111.h
+++ b/cc1111.h
@@ -337,6 +337,12 @@ __xdata __at (0xde02) volatile uint8_t USBIIF;
 __xdata __at (0xde04) volatile uint8_t USBOIF;
 
 __xdata __at (0xde06) volatile uint8_t USBCIF;
+
+# define USBCIF_SOFIF          (1 << 3)
+# define USBCIF_RSTIF          (1 << 2)
+# define USBCIF_RESUMEIF       (1 << 1)
+# define USBCIF_SUSPENDIF      (1 << 0)
+
 __xdata __at (0xde07) volatile uint8_t USBIIE;
 
 __xdata __at (0xde09) volatile uint8_t USBOIE;