diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 9de5b70..27059b5 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -171,6 +171,8 @@ static uint8_t reply_buffer[8]; static uint8_t power_neg_delay; static uint32_t power_neg_time; +static uint8_t usb_dev_sleep = 0; + // ----- Functions ----- @@ -977,6 +979,16 @@ void usb_rx_memory( usb_packet_t *packet ) void usb_tx( uint32_t endpoint, usb_packet_t *packet ) { + // If we have been sleeping, try to wake up host + if ( usb_dev_sleep ) + { + // Force wake-up for 10 ms + // According to the USB Spec a device must hold resume for at least 1 ms but no more than 15 ms + USB0_CTL |= USB_CTL_RESUME; + delay(10); + USB0_CTL &= ~(USB_CTL_RESUME); + } + // Since we are transmitting data, USB will be brought out of sleep/suspend // if it's in that state // Use the currently set descriptor value @@ -1257,6 +1269,7 @@ restart: USB_INTEN_STALLEN | USB_INTEN_ERROREN | USB_INTEN_USBRSTEN | + USB_INTEN_RESUMEEN | USB_INTEN_SLEEPEN; // is this necessary? @@ -1285,9 +1298,19 @@ restart: // The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms if ( (status & USB_ISTAT_SLEEP /* 10 */ ) ) { - info_print("Host has requested USB sleep/suspend state"); + //info_print("Host has requested USB sleep/suspend state"); Output_update_usb_current( 100 ); // Set to 100 mA - USB0_ISTAT = USB_ISTAT_SLEEP; + usb_dev_sleep = 1; + USB0_ISTAT |= USB_ISTAT_SLEEP; + } + + // On USB Resume, unset the usb_dev_sleep so we don't keep sending resume signals + if ( (status & USB_ISTAT_RESUME /* 20 */ ) ) + { + //info_print("Host has woken-up/resumed from sleep/suspend state"); + Output_update_usb_current( *usb_bMaxPower * 2 ); + usb_dev_sleep = 0; + USB0_ISTAT |= USB_ISTAT_RESUME; } } @@ -1346,6 +1369,9 @@ uint8_t usb_init() // Do not check for power negotiation delay until Get Configuration Descriptor power_neg_delay = 0; + // During initialization host isn't sleeping + usb_dev_sleep = 0; + return 1; } diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index d362bb3..040ef25 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -127,6 +127,7 @@ void usb_keyboard_send() { transmit_previous_timeout = 1; warn_print("USB Transmit Timeout..."); + USBKeys_Changed = USBKeyChangeState_None; // Indicate packet lost return; } yield(); diff --git a/Output/pjrcUSB/arm/usb_mouse.c b/Output/pjrcUSB/arm/usb_mouse.c index 5de7712..c72eed5 100644 --- a/Output/pjrcUSB/arm/usb_mouse.c +++ b/Output/pjrcUSB/arm/usb_mouse.c @@ -163,6 +163,12 @@ void usb_mouse_send() { transmit_previous_timeout = 1; warn_print("USB Transmit Timeout..."); + + // Clear status and state + USBMouse_Buttons = 0; + USBMouse_Relative_x = 0; + USBMouse_Relative_y = 0; + USBMouse_Changed = 0; return; } yield(); diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 39ee0b0..082c42b 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -713,10 +713,12 @@ void Output_update_usb_current( unsigned int current ) // Update USB current Output_USBCurrent_Available = current; + /* XXX Affects sleep states due to USB messages unsigned int total_current = Output_current_available(); info_msg("USB Available Current Changed. Total Available: "); printInt32( total_current ); print(" mA" NL); + */ // Send new total current to the Scan Modules Scan_currentChange( Output_current_available() ); diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 6aa07e9..00fbff6 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -734,10 +734,12 @@ void Output_update_usb_current( unsigned int current ) // Update USB current Output_USBCurrent_Available = current; + /* XXX Affects sleep states due to USB messages unsigned int total_current = Output_current_available(); info_msg("USB Available Current Changed. Total Available: "); printInt32( total_current ); print(" mA" NL); + */ // Send new total current to the Scan Modules Scan_currentChange( Output_current_available() );