From e071f3897a0946c6be1e1b5e1f78eda8dcbf6fc7 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 21 Jul 2009 13:31:21 +0000 Subject: [PATCH] Added new USB_DeviceState variable to keep track of the current Device mode USB state. Added new Endpoint_ClearStatusStage() convenience function to assist with the status stages of control transfers. Removed vague USB_IsConnected global - test USB_DeviceState or USB_HostState explicitly to gain previous functionality. Removed USB_IsSuspended global - test USB_DeviceState against DEVICE_STATE_Suspended instead. Fixed possible enumeration errors from spinloops which may fail to exit if the USB connection is severed before the exit condition becomes true. --- Bootloaders/CDC/BootloaderCDC.c | 47 +++++--- Bootloaders/DFU/BootloaderDFU.c | 79 +++++++------ Bootloaders/TeensyHID/TeensyHID.c | 6 +- .../MassStorage/Lib/DataflashManager.c | 24 +++- .../ClassDriver/USBtoSerial/USBtoSerial.c | 2 +- Demos/Device/Incomplete/Sideshow/Sideshow.c | 2 +- Demos/Device/LowLevel/AudioInput/AudioInput.c | 6 +- .../Device/LowLevel/AudioOutput/AudioOutput.c | 6 +- Demos/Device/LowLevel/CDC/CDC.c | 51 +++++---- Demos/Device/LowLevel/DualCDC/DualCDC.c | 39 ++++--- Demos/Device/LowLevel/GenericHID/GenericHID.c | 14 ++- Demos/Device/LowLevel/Joystick/Joystick.c | 2 +- Demos/Device/LowLevel/Keyboard/Keyboard.c | 28 ++--- .../LowLevel/KeyboardMouse/KeyboardMouse.c | 14 ++- Demos/Device/LowLevel/MIDI/MIDI.c | 2 +- .../MassStorage/Lib/DataflashManager.c | 26 ++++- .../Device/LowLevel/MassStorage/MassStorage.c | 108 +++++++++--------- Demos/Device/LowLevel/Mouse/Mouse.c | 18 +-- .../LowLevel/RNDISEthernet/RNDISEthernet.c | 2 +- .../Device/LowLevel/USBtoSerial/USBtoSerial.c | 27 +++-- .../BluetoothHost/Lib/BluetoothHCICommands.c | 49 ++++++-- .../BluetoothHost/Lib/BluetoothStack.c | 2 +- Demos/Host/LowLevel/CDCHost/CDCHost.c | 9 +- .../LowLevel/GenericHIDHost/GenericHIDHost.c | 7 +- .../Host/LowLevel/KeyboardHost/KeyboardHost.c | 7 +- .../KeyboardHostWithParser.c | 7 +- .../MassStorageHost/Lib/MassStoreCommands.c | 8 +- .../MassStorageHost/MassStorageHost.c | 23 ++-- Demos/Host/LowLevel/MouseHost/MouseHost.c | 9 +- .../MouseHostWithParser/MouseHostWithParser.c | 9 +- .../PrinterHost/Lib/PrinterCommands.c | 6 +- Demos/Host/LowLevel/PrinterHost/PrinterHost.c | 9 +- .../StillImageHost/Lib/StillImageCommands.c | 9 +- .../LowLevel/StillImageHost/StillImageHost.c | 11 +- LUFA/Drivers/USB/Class/Device/Audio.c | 3 +- LUFA/Drivers/USB/Class/Device/CDC.c | 27 +++-- LUFA/Drivers/USB/Class/Device/HID.c | 14 +-- LUFA/Drivers/USB/Class/Device/MIDI.c | 4 +- LUFA/Drivers/USB/Class/Device/MassStorage.c | 11 +- LUFA/Drivers/USB/Class/Device/RNDIS.c | 2 +- LUFA/Drivers/USB/HighLevel/Events.h | 4 +- LUFA/Drivers/USB/HighLevel/USBInterrupt.c | 52 ++++----- LUFA/Drivers/USB/HighLevel/USBTask.c | 8 +- LUFA/Drivers/USB/HighLevel/USBTask.h | 61 ++++------ LUFA/Drivers/USB/LowLevel/DevChapter9.c | 40 ++++++- LUFA/Drivers/USB/LowLevel/Device.h | 31 ++++- LUFA/Drivers/USB/LowLevel/Endpoint.c | 26 ++++- LUFA/Drivers/USB/LowLevel/Endpoint.h | 45 +++++++- LUFA/Drivers/USB/LowLevel/Host.c | 27 ++--- LUFA/Drivers/USB/LowLevel/Host.h | 26 ++--- LUFA/Drivers/USB/LowLevel/LowLevel.c | 25 ++-- LUFA/Drivers/USB/LowLevel/Pipe.c | 2 +- .../Template/Template_Endpoint_Control_R.c | 9 +- .../Template/Template_Endpoint_Control_W.c | 19 ++- LUFA/ManPages/ChangeLog.txt | 6 + LUFA/ManPages/CompileTimeTokens.txt | 2 +- LUFA/ManPages/MigrationInformation.txt | 8 +- Projects/MissileLauncher/MissileLauncher.c | 3 - 58 files changed, 663 insertions(+), 460 deletions(-) diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index d875b842dd..cbcfd7e6c7 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -165,9 +165,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -176,16 +174,18 @@ void EVENT_USB_UnhandledControlPacket(void) { Endpoint_ClearSETUP(); - while (!(Endpoint_IsOUTReceived())); - + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + for (uint8_t i = 0; i < sizeof(LineCoding); i++) *(LineCodingData++) = Endpoint_Read_Byte(); Endpoint_ClearOUT(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -194,9 +194,7 @@ void EVENT_USB_UnhandledControlPacket(void) { Endpoint_ClearSETUP(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -333,7 +331,12 @@ static uint8_t FetchNextCommandByte(void) while (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearOUT(); - while (!(Endpoint_IsOUTReceived())); + + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return 0; + } } /* Fetch the next byte from the OUT endpoint */ @@ -354,7 +357,12 @@ static void WriteNextResponseByte(const uint8_t Response) if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); - while (!(Endpoint_IsINReady())); + + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Write the next byte to the OUT endpoint */ @@ -563,12 +571,21 @@ void CDC_Task(void) /* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */ if (IsEndpointFull) { - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + Endpoint_ClearIN(); } /* Wait until the data has been sent to the host */ - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Select the OUT endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPNUM); diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index 2086a91d20..f9c8195f37 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -177,7 +177,11 @@ void EVENT_USB_UnhandledControlPacket(void) /* If the request has a data stage, load it into the command struct */ if (SentCommand.DataSize) { - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* First byte of the data stage is the DNLOAD request's command */ SentCommand.Command = Endpoint_Read_Byte(); @@ -235,7 +239,12 @@ void EVENT_USB_UnhandledControlPacket(void) if (!(Endpoint_BytesInEndpoint())) { Endpoint_ClearOUT(); - while (!(Endpoint_IsOUTReceived())); + + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Write the next word into the current flash page */ @@ -279,7 +288,12 @@ void EVENT_USB_UnhandledControlPacket(void) if (!(Endpoint_BytesInEndpoint())) { Endpoint_ClearOUT(); - while (!(Endpoint_IsOUTReceived())); + + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Read the byte from the USB interface and write to to the EEPROM */ @@ -297,16 +311,18 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearOUT(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); - + Endpoint_ClearStatusStage(); + break; case DFU_UPLOAD: Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); - + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + if (DFU_State != dfuUPLOAD_IDLE) { if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank Check @@ -343,7 +359,12 @@ void EVENT_USB_UnhandledControlPacket(void) if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE) { Endpoint_ClearIN(); - while (!(Endpoint_IsINReady())); + + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Read the flash word and send it via USB to the host */ @@ -368,7 +389,12 @@ void EVENT_USB_UnhandledControlPacket(void) if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE) { Endpoint_ClearIN(); - while (!(Endpoint_IsINReady())); + + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Read the EEPROM byte and send it via USB to the host */ @@ -385,10 +411,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); - + Endpoint_ClearStatusStage(); break; case DFU_GETSTATUS: Endpoint_ClearSETUP(); @@ -408,10 +431,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); - + Endpoint_ClearStatusStage(); break; case DFU_CLRSTATUS: Endpoint_ClearSETUP(); @@ -419,10 +439,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Reset the status value variable to the default OK status */ DFU_Status = OK; - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); - + Endpoint_ClearStatusStage(); break; case DFU_GETSTATE: Endpoint_ClearSETUP(); @@ -432,21 +449,15 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); - + Endpoint_ClearStatusStage(); break; case DFU_ABORT: Endpoint_ClearSETUP(); /* Reset the current state variable to the default idle state */ DFU_State = dfuIDLE; - - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); break; } } @@ -465,7 +476,11 @@ static void DiscardFillerBytes(uint8_t NumberOfBytes) Endpoint_ClearOUT(); /* Wait until next data packet received */ - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } else { diff --git a/Bootloaders/TeensyHID/TeensyHID.c b/Bootloaders/TeensyHID/TeensyHID.c index 12d5c0de84..eed709783d 100644 --- a/Bootloaders/TeensyHID/TeensyHID.c +++ b/Bootloaders/TeensyHID/TeensyHID.c @@ -119,7 +119,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Wait until the command (report) has been sent by the host */ while (!(Endpoint_IsOUTReceived())); - + /* Read in the write destination address */ uint16_t PageAddress = Endpoint_Read_Word_LE(); @@ -158,9 +158,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearOUT(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; diff --git a/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c b/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c index 1c584e71c3..5f12d02b43 100644 --- a/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c +++ b/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c @@ -69,7 +69,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co Dataflash_SendAddressBytes(0, CurrDFPageByte); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } while (TotalBlocks) { @@ -85,7 +89,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co Endpoint_ClearOUT(); /* Wait until the host has sent another packet */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ @@ -197,7 +205,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con Dataflash_SendByte(0x00); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } while (TotalBlocks) { @@ -213,7 +225,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con Endpoint_ClearIN(); /* Wait until the endpoint is ready for more data */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ diff --git a/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c b/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c index ac63f0f9fc..89537066c6 100644 --- a/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c +++ b/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c @@ -152,7 +152,7 @@ void EVENT_USB_UnhandledControlPacket(void) */ ISR(USART1_RX_vect, ISR_BLOCK) { - if (USB_IsConnected) + if (USB_DeviceState == DEVICE_STATE_Configured) Buffer_StoreElement(&Tx_Buffer, UDR1); } diff --git a/Demos/Device/Incomplete/Sideshow/Sideshow.c b/Demos/Device/Incomplete/Sideshow/Sideshow.c index cc8bd51c38..d67fae03fb 100644 --- a/Demos/Device/Incomplete/Sideshow/Sideshow.c +++ b/Demos/Device/Incomplete/Sideshow/Sideshow.c @@ -142,7 +142,7 @@ void EVENT_USB_UnhandledControlPacket(void) void SideShow_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Select the SideShow data out endpoint */ diff --git a/Demos/Device/LowLevel/AudioInput/AudioInput.c b/Demos/Device/LowLevel/AudioInput/AudioInput.c index 5656b05d10..bf790169dd 100644 --- a/Demos/Device/LowLevel/AudioInput/AudioInput.c +++ b/Demos/Device/LowLevel/AudioInput/AudioInput.c @@ -139,9 +139,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */ StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -152,7 +150,7 @@ void EVENT_USB_UnhandledControlPacket(void) void USB_Audio_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check to see if the streaming interface is selected, if not the host is not receiving audio */ diff --git a/Demos/Device/LowLevel/AudioOutput/AudioOutput.c b/Demos/Device/LowLevel/AudioOutput/AudioOutput.c index 6d22009dcc..89c4446bcc 100644 --- a/Demos/Device/LowLevel/AudioOutput/AudioOutput.c +++ b/Demos/Device/LowLevel/AudioOutput/AudioOutput.c @@ -166,9 +166,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */ StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -181,7 +179,7 @@ void EVENT_USB_UnhandledControlPacket(void) void USB_Audio_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check to see if the streaming interface is selected, if not the host is not receiving audio */ diff --git a/Demos/Device/LowLevel/CDC/CDC.c b/Demos/Device/LowLevel/CDC/CDC.c index d8263b11f7..e63257dbdc 100644 --- a/Demos/Device/LowLevel/CDC/CDC.c +++ b/Demos/Device/LowLevel/CDC/CDC.c @@ -56,12 +56,15 @@ CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600, */ static int CDC_putchar (char c, FILE *stream) -{ - if (!(USB_IsConnected)) - return -1; - +{ Endpoint_SelectEndpoint(CDC_TX_EPNUM); - while (!(Endpoint_IsReadWriteAllowed())); + + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState != DEVICE_STATE_Configured) + return -1; + } + Endpoint_Write_Byte(c); Endpoint_ClearIN(); @@ -76,10 +79,11 @@ static int CDC_getchar (FILE *stream) for (;;) { - if (!(USB_IsConnected)) - return -1; - - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState != DEVICE_STATE_Configured) + return -1; + } if (!(Endpoint_BytesInEndpoint())) { @@ -229,9 +233,7 @@ void EVENT_USB_UnhandledControlPacket(void) CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code: */ - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -244,18 +246,17 @@ void CDC_Task(void) char* ReportString = NULL; uint8_t JoyStatus_LCL = Joystick_GetStatus(); static bool ActionSent = false; - - char* JoystickStrings[] = - { - "Joystick Up\r\n", - "Joystick Down\r\n", - "Joystick Left\r\n", - "Joystick Right\r\n", - "Joystick Pressed\r\n", - }; + char* JoystickStrings[] = + { + "Joystick Up\r\n", + "Joystick Down\r\n", + "Joystick Left\r\n", + "Joystick Right\r\n", + "Joystick Pressed\r\n", + }; /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; #if 0 @@ -319,7 +320,11 @@ void CDC_Task(void) if (IsFull) { /* Wait until the endpoint is ready for another packet */ - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Send an empty packet to ensure that the host does not buffer data sent to it */ Endpoint_ClearIN(); diff --git a/Demos/Device/LowLevel/DualCDC/DualCDC.c b/Demos/Device/LowLevel/DualCDC/DualCDC.c index 862945e631..dd278d5353 100644 --- a/Demos/Device/LowLevel/DualCDC/DualCDC.c +++ b/Demos/Device/LowLevel/DualCDC/DualCDC.c @@ -211,9 +211,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Acknowledge the SETUP packet, ready for data transfer */ Endpoint_ClearSETUP(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -228,20 +226,19 @@ void CDC1_Task(void) char* ReportString = NULL; uint8_t JoyStatus_LCL = Joystick_GetStatus(); static bool ActionSent = false; - + char* JoystickStrings[] = + { + "Joystick Up\r\n", + "Joystick Down\r\n", + "Joystick Left\r\n", + "Joystick Right\r\n", + "Joystick Pressed\r\n", + }; + /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; - char* JoystickStrings[] = - { - "Joystick Up\r\n", - "Joystick Down\r\n", - "Joystick Left\r\n", - "Joystick Right\r\n", - "Joystick Pressed\r\n", - }; - /* Determine if a joystick action has occurred */ if (JoyStatus_LCL & JOY_UP) ReportString = JoystickStrings[0]; @@ -273,7 +270,11 @@ void CDC1_Task(void) Endpoint_ClearIN(); /* Wait until the endpoint is ready for another packet */ - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Send an empty packet to ensure that the host does not buffer data sent to it */ Endpoint_ClearIN(); @@ -293,7 +294,7 @@ void CDC1_Task(void) void CDC2_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Select the Serial Rx Endpoint */ @@ -324,7 +325,11 @@ void CDC2_Task(void) Endpoint_ClearIN(); /* Wait until the endpoint is ready for the next packet */ - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Send an empty packet to prevent host buffering */ Endpoint_ClearIN(); diff --git a/Demos/Device/LowLevel/GenericHID/GenericHID.c b/Demos/Device/LowLevel/GenericHID/GenericHID.c index 5c6d1ee470..34c991f12f 100644 --- a/Demos/Device/LowLevel/GenericHID/GenericHID.c +++ b/Demos/Device/LowLevel/GenericHID/GenericHID.c @@ -148,7 +148,11 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearSETUP(); /* Wait until the generic report has been sent by the host */ - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData)); @@ -158,7 +162,11 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearOUT(); /* Wait until the host is ready to receive the request confirmation */ - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Handshake the request by sending an empty IN packet */ Endpoint_ClearIN(); @@ -203,7 +211,7 @@ void CreateGenericHIDReport(uint8_t* DataArray) void HID_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM); diff --git a/Demos/Device/LowLevel/Joystick/Joystick.c b/Demos/Device/LowLevel/Joystick/Joystick.c index e117475376..db2415e4bc 100644 --- a/Demos/Device/LowLevel/Joystick/Joystick.c +++ b/Demos/Device/LowLevel/Joystick/Joystick.c @@ -182,7 +182,7 @@ bool GetNextReport(USB_JoystickReport_Data_t* ReportData) void HID_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Select the Joystick Report Endpoint */ diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.c b/Demos/Device/LowLevel/Keyboard/Keyboard.c index 9950484bae..e27b22827f 100644 --- a/Demos/Device/LowLevel/Keyboard/Keyboard.c +++ b/Demos/Device/LowLevel/Keyboard/Keyboard.c @@ -172,7 +172,11 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearSETUP(); /* Wait until the LED report has been sent by the host */ - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Read in the LED report from the host */ uint8_t LEDStatus = Endpoint_Read_Byte(); @@ -183,9 +187,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Clear the endpoint data */ Endpoint_ClearOUT(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -200,9 +202,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Send the flag to the host */ Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -214,9 +214,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Set or clear the flag depending on what the host indicates that the current Protocol should be */ UsingReportProtocol = (USB_ControlRequest.wValue != 0); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -228,9 +226,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Get idle period in MSB, IdleCount must be multiplied by 4 to get number of milliseconds */ IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -245,9 +241,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Send the flag to the host */ Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -378,7 +372,7 @@ void ReceiveNextReport(void) void HID_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Send the next keypress report to the host */ diff --git a/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c b/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c index c60f08f9c5..7d486e16e3 100644 --- a/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c +++ b/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c @@ -174,7 +174,11 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearSETUP(); /* Wait until the LED report has been sent by the host */ - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Read in the LED report from the host */ uint8_t LEDStatus = Endpoint_Read_Byte(); @@ -195,9 +199,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Clear the endpoint data */ Endpoint_ClearOUT(); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -213,7 +215,7 @@ void Keyboard_HID_Task(void) uint8_t JoyStatus_LCL = Joystick_GetStatus(); /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check if board button is not pressed, if so mouse mode enabled */ @@ -284,7 +286,7 @@ void Mouse_HID_Task(void) uint8_t JoyStatus_LCL = Joystick_GetStatus(); /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check if board button is pressed, if so mouse mode enabled */ diff --git a/Demos/Device/LowLevel/MIDI/MIDI.c b/Demos/Device/LowLevel/MIDI/MIDI.c index 954cbcbf64..8aed527dbe 100644 --- a/Demos/Device/LowLevel/MIDI/MIDI.c +++ b/Demos/Device/LowLevel/MIDI/MIDI.c @@ -117,7 +117,7 @@ void MIDI_Task(void) static uint8_t PrevJoystickStatus; /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM); diff --git a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c index fdc91dd5d8..2bd03c98d9 100644 --- a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c +++ b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c @@ -68,8 +68,12 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo Dataflash_SendAddressBytes(0, CurrDFPageByte); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); - + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + while (TotalBlocks) { uint8_t BytesInBlockDiv16 = 0; @@ -84,7 +88,11 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo Endpoint_ClearOUT(); /* Wait until the host has sent another packet */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ @@ -195,7 +203,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc Dataflash_SendByte(0x00); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } while (TotalBlocks) { @@ -211,7 +223,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc Endpoint_ClearIN(); /* Wait until the endpoint is ready for more data */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ diff --git a/Demos/Device/LowLevel/MassStorage/MassStorage.c b/Demos/Device/LowLevel/MassStorage/MassStorage.c index 2c80fc595e..01d27f043a 100644 --- a/Demos/Device/LowLevel/MassStorage/MassStorage.c +++ b/Demos/Device/LowLevel/MassStorage/MassStorage.c @@ -142,9 +142,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Indicate that the current transfer should be aborted */ IsMassStoreReset = true; - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -158,9 +156,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -172,67 +168,67 @@ void EVENT_USB_UnhandledControlPacket(void) */ void MassStorage_Task(void) { - /* Check if the USB System is connected to a Host */ - if (USB_IsConnected) + /* Device must be connected and configured for the task to run */ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + /* Select the Data Out Endpoint */ + Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); + + /* Check to see if a command from the host has been issued */ + if (Endpoint_IsReadWriteAllowed()) { - /* Select the Data Out Endpoint */ - Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); - - /* Check to see if a command from the host has been issued */ - if (Endpoint_IsReadWriteAllowed()) - { - /* Indicate busy */ - LEDs_SetAllLEDs(LEDMASK_USB_BUSY); + /* Indicate busy */ + LEDs_SetAllLEDs(LEDMASK_USB_BUSY); - /* Process sent command block from the host */ - if (ReadInCommandBlock()) - { - /* Check direction of command, select Data IN endpoint if data is from the device */ - if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN) - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + /* Process sent command block from the host */ + if (ReadInCommandBlock()) + { + /* Check direction of command, select Data IN endpoint if data is from the device */ + if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN) + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); - /* Decode the received SCSI command */ - SCSI_DecodeSCSICommand(); + /* Decode the received SCSI command */ + SCSI_DecodeSCSICommand(); - /* Load in the CBW tag into the CSW to link them together */ - CommandStatus.Tag = CommandBlock.Tag; + /* Load in the CBW tag into the CSW to link them together */ + CommandStatus.Tag = CommandBlock.Tag; - /* Load in the data residue counter into the CSW */ - CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength; + /* Load in the data residue counter into the CSW */ + CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength; - /* Stall the selected data pipe if command failed (if data is still to be transferred) */ - if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue)) - Endpoint_StallTransaction(); + /* Stall the selected data pipe if command failed (if data is still to be transferred) */ + if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue)) + Endpoint_StallTransaction(); - /* Return command status block to the host */ - ReturnCommandStatus(); - - /* Check if a Mass Storage Reset occurred */ - if (IsMassStoreReset) - { - /* Reset the data endpoint banks */ - Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM); - Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM); - - Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); - Endpoint_ClearStall(); - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); - Endpoint_ClearStall(); - } - - /* Indicate ready */ - LEDs_SetAllLEDs(LEDMASK_USB_READY); - } - else + /* Return command status block to the host */ + ReturnCommandStatus(); + + /* Check if a Mass Storage Reset occurred */ + if (IsMassStoreReset) { - /* Indicate error reading in the command block from the host */ - LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + /* Reset the data endpoint banks */ + Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM); + Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM); + + Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); + Endpoint_ClearStall(); + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + Endpoint_ClearStall(); } - } - /* Clear the abort transfer flag */ - IsMassStoreReset = false; + /* Indicate ready */ + LEDs_SetAllLEDs(LEDMASK_USB_READY); + } + else + { + /* Indicate error reading in the command block from the host */ + LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + } } + + /* Clear the abort transfer flag */ + IsMassStoreReset = false; } /** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block diff --git a/Demos/Device/LowLevel/Mouse/Mouse.c b/Demos/Device/LowLevel/Mouse/Mouse.c index febb36450c..d15f688d64 100644 --- a/Demos/Device/LowLevel/Mouse/Mouse.c +++ b/Demos/Device/LowLevel/Mouse/Mouse.c @@ -172,9 +172,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Send the flag to the host */ Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -186,9 +184,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Set or clear the flag depending on what the host indicates that the current Protocol should be */ UsingReportProtocol = (USB_ControlRequest.wValue != 0); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -200,9 +196,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Get idle period in MSB, must multiply by 4 to get the duration in milliseconds */ IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -217,9 +211,7 @@ void EVENT_USB_UnhandledControlPacket(void) /* Send the flag to the host */ Endpoint_ClearIN(); - /* Acknowledge status stage */ - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -314,7 +306,7 @@ void SendNextReport(void) void Mouse_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Send the next mouse report to the host */ diff --git a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c index 1c0e0304cc..ca38c24d60 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c +++ b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c @@ -285,7 +285,7 @@ void Ethernet_Task(void) Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */ /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check if a frame has been written to the IN frame buffer */ diff --git a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c index 9160dd1073..af963b1fc5 100644 --- a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c +++ b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c @@ -192,9 +192,7 @@ void EVENT_USB_UnhandledControlPacket(void) CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code: */ - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -205,7 +203,7 @@ void EVENT_USB_UnhandledControlPacket(void) void CDC_Task(void) { /* Device must be connected and configured for the task to run */ - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; #if 0 @@ -264,7 +262,11 @@ void CDC_Task(void) if (Tx_Buffer.Elements) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } /* Write the bytes from the buffer to the endpoint while space is available */ while (Tx_Buffer.Elements && Endpoint_IsReadWriteAllowed()) @@ -284,8 +286,12 @@ void CDC_Task(void) if (IsFull && !(Tx_Buffer.Elements)) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ - while (!(Endpoint_IsReadWriteAllowed())); - + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + /* Send an empty packet to terminate the transfer */ Endpoint_ClearIN(); } @@ -298,11 +304,8 @@ void CDC_Task(void) ISR(USART1_RX_vect, ISR_BLOCK) { /* Only store received characters if the USB interface is connected */ - if (USB_IsConnected) - { - /* Character received, store it into the buffer */ - Buffer_StoreElement(&Tx_Buffer, UDR1); - } + if (USB_DeviceState != DEVICE_STATE_Configured) + Buffer_StoreElement(&Tx_Buffer, UDR1); } /** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */ diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c index ddd159ef75..54291bf752 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c @@ -114,7 +114,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -133,7 +138,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -155,7 +165,12 @@ void Bluetooth_ProcessHCICommands(void) EventMask[3], EventMask[2], EventMask[1], EventMask[0]); do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -176,7 +191,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -195,7 +215,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -215,7 +240,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_HostState == HOST_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); @@ -366,7 +396,12 @@ void Bluetooth_ProcessHCICommands(void) do { - while (!(Bluetooth_GetNextHCIEventHeader())); + while (!(Bluetooth_GetNextHCIEventHeader())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + Bluetooth_DiscardRemainingHCIEventParameters(); } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE); diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c index e2659102e4..628fa217cb 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c @@ -41,7 +41,7 @@ Bluetooth_Device_t Bluetooth_DeviceConfiguration ATTR_WEAK = void Bluetooth_Stack_Task(void) { - if (!(USB_IsConnected) || (USB_HostState != HOST_STATE_Ready)) + if (USB_HostState != HOST_STATE_Configured) Bluetooth_HCIProcessingState = Bluetooth_Init; Bluetooth_ProcessHCICommands(); diff --git a/Demos/Host/LowLevel/CDCHost/CDCHost.c b/Demos/Host/LowLevel/CDCHost/CDCHost.c index a3cde7826c..e20fa2cfcc 100644 --- a/Demos/Host/LowLevel/CDCHost/CDCHost.c +++ b/Demos/Host/LowLevel/CDCHost/CDCHost.c @@ -164,15 +164,12 @@ void CDC_Host_Task(void) USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } - + + puts_P(PSTR("CDC Device Enumerated.\r\n")); + USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - puts_P(PSTR("CDC Device Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; - break; - case HOST_STATE_Ready: /* Select and the data IN pipe */ Pipe_SelectPipe(CDC_DATAPIPE_IN); Pipe_Unfreeze(); diff --git a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c index 3a055c8209..d360643332 100644 --- a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c +++ b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c @@ -266,14 +266,11 @@ void HID_Host_Task(void) break; } + puts_P(PSTR("HID Device Enumerated.\r\n")); + USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - puts_P(PSTR("HID Device Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; - break; - case HOST_STATE_Ready: ReadNextReport(); break; diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c index c2d8dd4a63..273cd71751 100644 --- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c +++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c @@ -230,9 +230,6 @@ void Keyboard_HID_Task(void) break; } - USB_HostState = HOST_STATE_Configured; - break; - case HOST_STATE_Configured: /* HID class request to set the keyboard protocol to the Boot Protocol */ USB_ControlRequest = (USB_Request_Header_t) { @@ -262,9 +259,9 @@ void Keyboard_HID_Task(void) puts_P(PSTR("Keyboard Enumerated.\r\n")); - USB_HostState = HOST_STATE_Ready; + USB_HostState = HOST_STATE_Configured; break; - case HOST_STATE_Ready: + case HOST_STATE_Configured: /* If a report has been received, read and process it */ ReadNextReport(); diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c index dc1707bd0c..eee1755bf7 100644 --- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c +++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c @@ -166,9 +166,6 @@ void Keyboard_HID_Task(void) break; } - USB_HostState = HOST_STATE_Configured; - break; - case HOST_STATE_Configured: puts_P(PSTR("Processing HID Report.\r\n")); /* Get and process the device's first HID report descriptor */ @@ -187,9 +184,9 @@ void Keyboard_HID_Task(void) puts_P(PSTR("Keyboard Enumerated.\r\n")); - USB_HostState = HOST_STATE_Ready; + USB_HostState = HOST_STATE_Configured; break; - case HOST_STATE_Ready: + case HOST_STATE_Configured: /* Select and unfreeze keyboard data pipe */ Pipe_SelectPipe(KEYBOARD_DATAPIPE); Pipe_Unfreeze(); diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index 7ee7de1382..d0518df1f0 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -154,7 +154,7 @@ static uint8_t MassStore_WaitForDataReceived(void) } /* Check to see if the device was disconnected, if so exit function */ - if (!(USB_IsConnected)) + if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; }; @@ -206,7 +206,11 @@ static uint8_t MassStore_SendReceiveData(void* BufferPtr) /* Acknowledge the packet */ Pipe_ClearOUT(); - while (!(Pipe_IsOUTReady())); + while (!(Pipe_IsOUTReady())) + { + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } } /* Freeze used pipe after use */ diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c index 1adec5bcf4..6cfe669f6b 100644 --- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c +++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c @@ -171,14 +171,11 @@ void MassStorage_Task(void) break; } + puts_P(PSTR("Mass Storage Disk Enumerated.\r\n")); + USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - puts_P(PSTR("Mass Storage Disk Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; - break; - case HOST_STATE_Ready: /* Indicate device busy via the status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); @@ -241,7 +238,11 @@ void MassStorage_Task(void) { Serial_TxByte('.'); - if ((ErrorCode = MassStore_TestUnitReady(0)) != 0) + /* Abort if device removed */ + if (USB_HostState == HOST_STATE_Unattached) + break; + + if ((ErrorCode = MassStore_TestUnitReady(0)) != PIPE_RWSTREAM_NoError) { ShowDiskReadError(PSTR("Test Unit Ready"), false, ErrorCode); @@ -249,11 +250,7 @@ void MassStorage_Task(void) break; } } - while ((SCSICommandStatus.Status != Command_Pass) && USB_IsConnected); - - /* Abort if device removed */ - if (!(USB_IsConnected)) - break; + while (SCSICommandStatus.Status != Command_Pass); puts_P(PSTR("\r\nRetrieving Capacity... ")); @@ -320,7 +317,7 @@ void MassStorage_Task(void) while (!(Buttons_GetStatus() & BUTTONS_BUTTON1)) { /* Abort if device removed */ - if (!(USB_IsConnected)) + if (USB_HostState == HOST_STATE_Unattached) break; } @@ -346,7 +343,7 @@ void MassStorage_Task(void) } /* Abort if device removed */ - if (!(USB_IsConnected)) + if (USB_HostState == HOST_STATE_Unattached) break; } diff --git a/Demos/Host/LowLevel/MouseHost/MouseHost.c b/Demos/Host/LowLevel/MouseHost/MouseHost.c index 5340aa11fb..b98f4bf968 100644 --- a/Demos/Host/LowLevel/MouseHost/MouseHost.c +++ b/Demos/Host/LowLevel/MouseHost/MouseHost.c @@ -226,9 +226,6 @@ void Mouse_HID_Task(void) break; } - USB_HostState = HOST_STATE_Configured; - break; - case HOST_STATE_Configured: /* HID class request to set the mouse protocol to the Boot Protocol */ USB_ControlRequest = (USB_Request_Header_t) { @@ -257,10 +254,10 @@ void Mouse_HID_Task(void) } puts_P(PSTR("Mouse Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; + + USB_HostState = HOST_STATE_Configured; break; - case HOST_STATE_Ready: + case HOST_STATE_Configured: /* If a report has been received, read and process it */ ReadNextReport(); diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c index 42865e515e..63fce0dcb6 100644 --- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c +++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c @@ -166,9 +166,6 @@ void Mouse_HID_Task(void) break; } - USB_HostState = HOST_STATE_Configured; - break; - case HOST_STATE_Configured: puts_P(PSTR("Processing HID Report.\r\n")); /* Get and process the device's first HID report descriptor */ @@ -186,10 +183,10 @@ void Mouse_HID_Task(void) } puts_P(PSTR("Mouse Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; + + USB_HostState = HOST_STATE_Configured; break; - case HOST_STATE_Ready: + case HOST_STATE_Configured: /* Select and unfreeze mouse data pipe */ Pipe_SelectPipe(MOUSE_DATAPIPE); Pipe_Unfreeze(); diff --git a/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c b/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c index 4c88bb4f26..cb051cdf11 100644 --- a/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c +++ b/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c @@ -54,7 +54,11 @@ uint8_t Printer_SendData(Printer_Data_t* PrinterCommands) return ErrorCode; Pipe_ClearOUT(); - while (!(Pipe_IsOUTReady())); + while (!(Pipe_IsOUTReady())) + { + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } Pipe_Freeze(); diff --git a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c index 3b145a63da..bbda0c24b5 100644 --- a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c +++ b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c @@ -195,9 +195,6 @@ void USB_Printer_Host(void) } } - USB_HostState = HOST_STATE_Configured; - break; - case HOST_STATE_Configured: puts_P(PSTR("Retrieving Device ID...\r\n")); char DeviceIDString[256]; @@ -217,10 +214,10 @@ void USB_Printer_Host(void) printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString); puts_P(PSTR("Printer Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; + + USB_HostState = HOST_STATE_Configured; break; - case HOST_STATE_Ready: + case HOST_STATE_Configured: /* Indicate device busy via the status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); diff --git a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c index e0d71a0591..970df4f879 100644 --- a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c +++ b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c @@ -152,12 +152,9 @@ uint8_t SImage_RecieveBlockHeader(void) } /* Check to see if the device was disconnected, if so exit function */ - if (!(USB_IsConnected)) - { - /* Return error code */ - return PIPE_RWSTREAM_DeviceDisconnected; - } - }; + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } /* Freeze OUT pipe after use */ Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE); diff --git a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c index 5cfaf46bed..ca0771a94b 100644 --- a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c +++ b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c @@ -166,14 +166,11 @@ void StillImage_Task(void) break; } + puts_P(PSTR("Still Image Device Enumerated.\r\n")); + USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - puts_P(PSTR("Still Image Device Enumerated.\r\n")); - - USB_HostState = HOST_STATE_Ready; - break; - case HOST_STATE_Ready: /* Indicate device busy via the status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); @@ -331,9 +328,7 @@ void StillImage_Task(void) /* Indicate device no longer busy */ LEDs_SetAllLEDs(LEDMASK_USB_READY); - /* Wait until USB device disconnected */ - while (USB_IsConnected); - + USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } } diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c index d117bedf68..116921e6ef 100644 --- a/LUFA/Drivers/USB/Class/Device/Audio.c +++ b/LUFA/Drivers/USB/Class/Device/Audio.c @@ -50,8 +50,7 @@ void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_Device_t* const Audio AudioInterfaceInfo->State.InterfaceEnabled = (USB_ControlRequest.wValue != 0); - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c index 12b55938c4..237e1dd2fa 100644 --- a/LUFA/Drivers/USB/Class/Device/CDC.c +++ b/LUFA/Drivers/USB/Class/Device/CDC.c @@ -78,8 +78,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_Device_t* CDCInterfaceInf EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -114,7 +113,7 @@ bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) { - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber); @@ -125,7 +124,12 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); - while (!(Endpoint_IsReadWriteAllowed())); + + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } Endpoint_ClearIN(); @@ -133,7 +137,7 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber); @@ -142,7 +146,7 @@ void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, c void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber); @@ -150,7 +154,12 @@ void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, con if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); - while (!(Endpoint_IsReadWriteAllowed())); + + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } Endpoint_Write_Byte(Data); @@ -165,7 +174,7 @@ uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterface uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return 0; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber); @@ -180,7 +189,7 @@ uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo) void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber); diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c index 4a6295ab0c..f292c633e7 100644 --- a/LUFA/Drivers/USB/Class/Device/HID.c +++ b/LUFA/Drivers/USB/Class/Device/HID.c @@ -88,8 +88,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol); Endpoint_ClearIN(); - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -100,8 +99,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf HIDInterfaceInfo->State.UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000); - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -115,8 +113,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } } @@ -129,8 +126,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2); Endpoint_ClearIN(); - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -152,7 +148,7 @@ bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfac void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) { - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber); diff --git a/LUFA/Drivers/USB/Class/Device/MIDI.c b/LUFA/Drivers/USB/Class/Device/MIDI.c index da33bdb610..3643275955 100644 --- a/LUFA/Drivers/USB/Class/Device/MIDI.c +++ b/LUFA/Drivers/USB/Class/Device/MIDI.c @@ -70,7 +70,7 @@ void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber); @@ -84,7 +84,7 @@ void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfac bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event) { - if (!(USB_IsConnected)) + if (USB_DeviceState != DEVICE_STATE_Configured) return false; Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber); diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c index f7f3fd9f23..9f8688c1df 100644 --- a/LUFA/Drivers/USB/Class/Device/MassStorage.c +++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c @@ -53,8 +53,7 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* const MSInterface MSInterfaceInfo->State.IsMassStoreReset = true; - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -63,12 +62,10 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* const MSInterface { Endpoint_ClearSETUP(); - Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1); - + Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1); Endpoint_ClearIN(); - while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); } break; @@ -96,7 +93,7 @@ bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceIn void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber); diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c index 0d35ee6b40..37771c646f 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDIS.c +++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c @@ -138,7 +138,7 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISIn void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) { - if (!(USB_IsConnected) || !(USB_ConfigurationNumber)) + if (USB_DeviceState != DEVICE_STATE_Configured) return; RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h index 2df0dda08d..4042d46703 100644 --- a/LUFA/Drivers/USB/HighLevel/Events.h +++ b/LUFA/Drivers/USB/HighLevel/Events.h @@ -98,7 +98,7 @@ * which is not always accurate (host may suspend the bus while still connected). If the actual connection state * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by * passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection - * and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually. + * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. * * \see USBTask.h for more information on the USB management task and reducing CPU usage. */ @@ -116,7 +116,7 @@ * which is not always accurate (host may suspend the bus while still connected). If the actual connection state * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by * passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection - * and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually. + * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. * * \see USBTask.h for more information on the USB management task and reducing CPU usage. */ diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c index c240bef6ea..5edefa9967 100644 --- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c +++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c @@ -78,19 +78,17 @@ ISR(USB_GEN_vect, ISR_BLOCK) { EVENT_USB_VBUSConnect(); - if (USB_IsConnected) + if (USB_DeviceState != DEVICE_STATE_Unattached) EVENT_USB_Disconnect(); USB_ResetInterface(); - - USB_IsConnected = true; + USB_DeviceState = DEVICE_STATE_Powered; EVENT_USB_Connect(); } else { - USB_IsConnected = false; - + USB_DeviceState = DEVICE_STATE_Unattached; EVENT_USB_Disconnect(); USB_Detach(); @@ -117,16 +115,12 @@ ISR(USB_GEN_vect, ISR_BLOCK) if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); - USB_IsSuspended = true; - - EVENT_USB_Suspend(); - #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) - if (USB_IsConnected) - { - USB_IsConnected = false; - EVENT_USB_Disconnect(); - } + USB_DeviceState = DEVICE_STATE_Unattached; + EVENT_USB_Disconnect(); + #else + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Suspend(); #endif } @@ -146,22 +140,19 @@ ISR(USB_GEN_vect, ISR_BLOCK) USB_INT_Enable(USB_INT_SUSPEND); #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) - if (!(USB_IsConnected)) - { - USB_IsConnected = true; - EVENT_USB_Connect(); - } + USB_DeviceState = DEVICE_STATE_Powered; + EVENT_USB_Connect(); + #else + USB_DeviceState = DEVICE_STATE_Configured; + EVENT_USB_WakeUp(); #endif - - USB_IsSuspended = false; - - EVENT_USB_WakeUp(); } if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) { USB_INT_Clear(USB_INT_EORSTI); + USB_DeviceState = DEVICE_STATE_Default; USB_ConfigurationNumber = 0; USB_INT_Clear(USB_INT_SUSPEND); @@ -217,7 +208,7 @@ ISR(USB_GEN_vect, ISR_BLOCK) USB_INT_Enable(USB_INT_DDISCI); - USB_HostState = HOST_STATE_Attached; + USB_HostState = HOST_STATE_Powered; } if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) @@ -227,7 +218,7 @@ ISR(USB_GEN_vect, ISR_BLOCK) EVENT_USB_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); EVENT_USB_DeviceUnattached(); - if (USB_IsConnected) + if (USB_HostState != HOST_STATE_Unattached) EVENT_USB_Disconnect(); USB_ResetInterface(); @@ -239,13 +230,16 @@ ISR(USB_GEN_vect, ISR_BLOCK) { USB_INT_Clear(USB_INT_IDTI); - if (USB_IsConnected) - { - if (USB_CurrentMode == USB_MODE_HOST) - EVENT_USB_DeviceUnattached(); + if (USB_DeviceState != DEVICE_STATE_Unattached) + EVENT_USB_Disconnect(); + if (USB_HostState != HOST_STATE_Unattached) + { EVENT_USB_Disconnect(); + EVENT_USB_DeviceUnattached(); } + + EVENT_USB_Disconnect(); EVENT_USB_UIDChange(); diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c index 894171f246..500a697bcf 100644 --- a/LUFA/Drivers/USB/HighLevel/USBTask.c +++ b/LUFA/Drivers/USB/HighLevel/USBTask.c @@ -33,8 +33,6 @@ #define INCLUDE_FROM_USBTASK_C #include "USBTask.h" -volatile bool USB_IsSuspended; -volatile bool USB_IsConnected; volatile bool USB_IsInitialized; USB_Request_Header_t USB_ControlRequest; @@ -42,6 +40,10 @@ USB_Request_Header_t USB_ControlRequest; volatile uint8_t USB_HostState; #endif +#if defined(USB_CAN_BE_DEVICE) +volatile uint8_t USB_DeviceState; +#endif + void USB_USBTask(void) { #if defined(USB_HOST_ONLY) @@ -59,7 +61,7 @@ void USB_USBTask(void) #if defined(USB_CAN_BE_DEVICE) static void USB_DeviceTask(void) { - if (USB_IsConnected) + if (USB_DeviceState != DEVICE_STATE_Unattached) { uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h index 2a9bf19535..12acb11951 100644 --- a/LUFA/Drivers/USB/HighLevel/USBTask.h +++ b/LUFA/Drivers/USB/HighLevel/USBTask.h @@ -55,23 +55,6 @@ /* Public Interface - May be used in end-application: */ /* Global Variables: */ - /** Indicates if the USB interface is currently connected to a host if in device mode, or to a - * device while running in host mode. - * - * \note This variable should be treated as read-only in the user application, and never manually - * changed in value. - * - * \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller. - * this means that the current connection state is derived from the bus suspension and wake up events by default, - * which is not always accurate (host may suspend the bus while still connected). If the actual connection state - * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by - * passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection - * and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually. - * - * \ingroup Group_USBManagement - */ - extern volatile bool USB_IsConnected; - /** Indicates if the USB interface is currently initialized but not necessarily connected to a host * or device (i.e. if \ref USB_Init() has been run). If this is false, all other library globals are invalid. * @@ -90,39 +73,43 @@ */ extern USB_Request_Header_t USB_ControlRequest; - #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) - /** Indicates if the USB interface is currently suspended by the host when in device mode. When suspended, - * the device should consume minimal power, and cannot communicate to the host. If Remote Wakeup is - * supported by the device and \ref USB_RemoteWakeupEnabled is true, suspension can be terminated by the device - * by issuing a Remote Wakeup request. - * - * \note This global is only present if the user application can be a USB device. - * - * \note This variable should be treated as read-only in the user application, and never manually - * changed in value. - * - * \ingroup Group_Device - */ - extern volatile bool USB_IsSuspended; - #endif - #if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) /** Indicates the current host state machine state. When in host mode, this indicates the state - * via one of the values of the \ref USB_Host_States_t enum values in Host.h. + * via one of the values of the \ref USB_Host_States_t enum values. * * This value may be altered by the user application to implement the \ref HOST_STATE_Addressed, - * \ref HOST_STATE_Configured, \ref HOST_STATE_Ready and \ref HOST_STATE_Suspended states which - * are not implemented by the library. + * \ref HOST_STATE_Configured and \ref HOST_STATE_Suspended states which are not implemented by + * the library. * * \note This global is only present if the user application can be a USB host. * - * \see \ref USB_Host_States_t for a list of possible host states + * \see \ref USB_Host_States_t for a list of possible device states * * \ingroup Group_Host */ extern volatile uint8_t USB_HostState; #endif + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + /** Indicates the current device state machine state. When in device mode, this indicates the state + * via one of the values of the \ref USB_Device_States_t enum values. + * + * This value should not be altered by the user application as it is handled automatically by the + * library. The only exception to this rule is if the NO_LIMITED_CONTROLLER_CONNECT token is used + * (see \ref EVENT_USB_Connect() and \ref EVENT_USB_Disconnect() events). + * + * \note This global is only present if the user application can be a USB device. + * + * \note This variable should be treated as read-only in the user application, and never manually + * changed in value except in the circumstances outlined above. + * + * \see \ref USB_Device_States_t for a list of possible device states + * + * \ingroup Group_Device + */ + extern volatile uint8_t USB_DeviceState; + #endif + /* Function Prototypes: */ /** This is the main USB management task. The USB driver requires that this task be executed * continuously when the USB system is active (device attached in host mode, or attached to a host diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.c b/LUFA/Drivers/USB/LowLevel/DevChapter9.c index 10dce7298d..8de4bd6a82 100644 --- a/LUFA/Drivers/USB/LowLevel/DevChapter9.c +++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.c @@ -117,13 +117,22 @@ void USB_Device_ProcessControlPacket(void) static void USB_Device_SetAddress(void) { + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + Endpoint_ClearSETUP(); Endpoint_ClearIN(); - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + UDADDR = ((1 << ADDEN) | DeviceAddress); - UDADDR = ((1 << ADDEN) | ((uint8_t)USB_ControlRequest.wValue & 0x7F)); + if (DeviceAddress) + USB_DeviceState = DEVICE_STATE_Addressed; return; } @@ -185,8 +194,17 @@ static void USB_Device_SetConfiguration(void) Endpoint_ClearIN(); - if (!(AlreadyConfigured) && USB_ConfigurationNumber) - EVENT_USB_DeviceEnumerationComplete(); + if (USB_ConfigurationNumber) + { + USB_DeviceState = DEVICE_STATE_Configured; + + if (!(AlreadyConfigured)) + EVENT_USB_DeviceEnumerationComplete(); + } + else + { + USB_DeviceState = DEVICE_STATE_Addressed; + } EVENT_USB_ConfigurationChanged(); } @@ -199,7 +217,12 @@ void USB_Device_GetConfiguration(void) Endpoint_ClearIN(); - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + Endpoint_ClearOUT(); } @@ -332,7 +355,12 @@ static void USB_Device_GetStatus(void) Endpoint_ClearIN(); - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + Endpoint_ClearOUT(); } diff --git a/LUFA/Drivers/USB/LowLevel/Device.h b/LUFA/Drivers/USB/LowLevel/Device.h index 975d09a79e..e162a59801 100644 --- a/LUFA/Drivers/USB/LowLevel/Device.h +++ b/LUFA/Drivers/USB/LowLevel/Device.h @@ -118,7 +118,36 @@ #define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false) #endif - + + /* Type Defines: */ + enum USB_Device_States_t + { + DEVICE_STATE_Unattached = 0, /**< Internally implemented by the library. This state indicates + * that the device is not currently connected to a host. + */ + DEVICE_STATE_Powered = 1, /**< Internally implemented by the library. This state indicates + * that the device is connected to a host, but enumeration has not + * yet begun. + */ + DEVICE_STATE_Default = 2, /**< Internally implemented by the library. This state indicates + * that the device's USB bus has been reset by the host and it is + * now waiting for the host to begin the enumeration process. + */ + DEVICE_STATE_Addressed = 3, /**< Internally implemented by the library. This state indicates + * that the device has been addressed by the USB Host, but is not + * yet configured. + */ + DEVICE_STATE_Configured = 4, /**< May be implemented by the user project. This state indicates + * that the device has been enumerated by the host and is ready + * for USB communications to begin. + */ + DEVICE_STATE_Suspended = 5, /**< May be implemented by the user project. This state indicates + * that the USB bus has been suspended by the host, and the device + * should power down to a minimal power level until the bus is + * resumed. + */ + }; + /* Function Prototypes: */ /** Function to retrieve a given descriptor's size and memory location from the given descriptor type value, * index and language ID. This function MUST be overridden in the user application (added with full, identical diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c index f9db9cd224..e4d01404dd 100644 --- a/LUFA/Drivers/USB/LowLevel/Endpoint.c +++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c @@ -71,6 +71,30 @@ void Endpoint_ClearEndpoints(void) } } +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + } +} + #if !defined(CONTROL_ONLY_DEVICE) uint8_t Endpoint_WaitUntilReady(void) { @@ -93,7 +117,7 @@ uint8_t Endpoint_WaitUntilReady(void) return ENDPOINT_READYWAIT_NoError; } - if (!(USB_IsConnected)) + if (USB_DeviceState == DEVICE_STATE_Unattached) return ENDPOINT_READYWAIT_DeviceDisconnected; else if (Endpoint_IsStalled()) return ENDPOINT_READYWAIT_EndpointStalled; diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.h b/LUFA/Drivers/USB/LowLevel/Endpoint.h index 2caea8343a..a9ec122a27 100644 --- a/LUFA/Drivers/USB/LowLevel/Endpoint.h +++ b/LUFA/Drivers/USB/LowLevel/Endpoint.h @@ -431,14 +431,14 @@ ENDPOINT_RWSTREAM_EndpointStalled = 1, /**< The endpoint was stalled during the stream * transfer by the host or device. */ - ENDPOINT_RWSTREAM_DeviceDisconnected = 1, /**< Device was disconnected from the host during + ENDPOINT_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during * the transfer. */ - ENDPOINT_RWSTREAM_Timeout = 2, /**< The host failed to accept or send the next packet + ENDPOINT_RWSTREAM_Timeout = 3, /**< The host failed to accept or send the next packet * within the software timeout period set by the * \ref USB_STREAM_TIMEOUT_MS macro. */ - ENDPOINT_RWSTREAM_CallbackAborted = 3, /**< Indicates that the stream's callback function + ENDPOINT_RWSTREAM_CallbackAborted = 4, /**< Indicates that the stream's callback function * aborted the transfer early. */ }; @@ -451,6 +451,9 @@ { ENDPOINT_RWCSTREAM_NoError = 0, /**< Command completed successfully, no error. */ ENDPOINT_RWCSTREAM_HostAborted = 1, /**< The aborted the transfer prematurely. */ + ENDPOINT_RWCSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during + * the transfer. + */ }; /* Inline Functions: */ @@ -726,6 +729,12 @@ * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. */ uint8_t Endpoint_WaitUntilReady(void); + + /** Completes the status stage of a control transfer on a CONTROL type endpoint automatically, + * with respect to the data direction. This is a convenience function which can be used to + * simplify user control request handling. + */ + void Endpoint_ClearStatusStage(void); /** Reads and discards the given number of bytes from the endpoint from the given buffer, * discarding fully read packets from the host as needed. The last packet is not automatically @@ -922,6 +931,9 @@ * in both failure and success states; the user is responsible for manually clearing the setup OUT to * finalize the transfer via the \ref Endpoint_ClearOUT() macro. * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * * \note This routine should only be used on CONTROL type endpoints. * * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained @@ -937,6 +949,9 @@ uint8_t Endpoint_Write_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note This routine should only be used on CONTROL type endpoints. * @@ -953,6 +968,9 @@ uint8_t Endpoint_Write_Control_EStream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. * @@ -975,6 +993,9 @@ * in both failure and success states; the user is responsible for manually clearing the setup OUT to * finalize the transfer via the \ref Endpoint_ClearOUT() macro. * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * * \note This routine should only be used on CONTROL type endpoints. * * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained @@ -990,6 +1011,9 @@ uint8_t Endpoint_Write_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note This routine should only be used on CONTROL type endpoints. * @@ -1006,6 +1030,9 @@ uint8_t Endpoint_Write_Control_EStream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. * @@ -1028,6 +1055,9 @@ * automatically sent after success or failure states; the user is responsible for manually sending the * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * * \note This routine should only be used on CONTROL type endpoints. * * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained @@ -1043,6 +1073,9 @@ uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note This routine should only be used on CONTROL type endpoints. * @@ -1063,6 +1096,9 @@ * automatically sent after success or failure states; the user is responsible for manually sending the * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * * \note This routine should only be used on CONTROL type endpoints. * * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained @@ -1078,6 +1114,9 @@ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. * * \note This routine should only be used on CONTROL type endpoints. * diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c index efe4baeeb2..ae7525bee7 100644 --- a/LUFA/Drivers/USB/LowLevel/Host.c +++ b/LUFA/Drivers/USB/LowLevel/Host.c @@ -60,12 +60,12 @@ void USB_Host_ProcessNextHostState(void) } break; - case HOST_STATE_Attached: + case HOST_STATE_Powered: WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; - USB_HostState = HOST_STATE_Attached_WaitForDeviceSettle; + USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; break; - case HOST_STATE_Attached_WaitForDeviceSettle: + case HOST_STATE_Powered_WaitForDeviceSettle: #if HOST_DEVICE_SETTLE_DELAY_MS > 0 _delay_ms(1); @@ -77,14 +77,14 @@ void USB_Host_ProcessNextHostState(void) USB_Host_VBUS_Auto_Enable(); USB_Host_VBUS_Auto_On(); - USB_HostState = HOST_STATE_Attached_WaitForConnect; + USB_HostState = HOST_STATE_Powered_WaitForConnect; } #else - USB_HostState = HOST_STATE_Attached_WaitForConnect; + USB_HostState = HOST_STATE_Powered_WaitForConnect; #endif break; - case HOST_STATE_Attached_WaitForConnect: + case HOST_STATE_Powered_WaitForConnect: if (USB_INT_HasOccurred(USB_INT_DCONNI)) { USB_INT_Clear(USB_INT_DCONNI); @@ -93,22 +93,21 @@ void USB_Host_ProcessNextHostState(void) USB_INT_Clear(USB_INT_VBERRI); USB_INT_Enable(USB_INT_VBERRI); - USB_IsConnected = true; EVENT_USB_Connect(); USB_Host_ResumeBus(); Pipe_ClearPipes(); - HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset); + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); } break; - case HOST_STATE_Attached_DoReset: + case HOST_STATE_Powered_DoReset: USB_Host_ResetDevice(); - HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered); + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); break; - case HOST_STATE_Powered: + case HOST_STATE_Powered_ConfigPipe: Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE); @@ -199,9 +198,7 @@ void USB_Host_ProcessNextHostState(void) USB_Host_VBUS_Auto_Off(); EVENT_USB_DeviceUnattached(); - - if (USB_IsConnected) - EVENT_USB_Disconnect(); + EVENT_USB_Disconnect(); USB_ResetInterface(); } @@ -222,7 +219,7 @@ uint8_t USB_Host_WaitMS(uint8_t MS) MS--; } - if ((USB_IsConnected == false) || (USB_CurrentMode == USB_MODE_DEVICE)) + if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode == USB_MODE_DEVICE)) { ErrorCode = HOST_WAITERROR_DeviceDisconnect; diff --git a/LUFA/Drivers/USB/LowLevel/Host.h b/LUFA/Drivers/USB/LowLevel/Host.h index 88634fdae0..a602cee771 100644 --- a/LUFA/Drivers/USB/LowLevel/Host.h +++ b/LUFA/Drivers/USB/LowLevel/Host.h @@ -241,32 +241,32 @@ * * \note Do not manually change to this state in the user code. */ - HOST_STATE_Attached = 3, /**< Internally implemented by the library. This state indicates + HOST_STATE_Powered = 3, /**< Internally implemented by the library. This state indicates * that a device has been attached, and the library's internals * are being configured to begin the enumeration process. * * \note Do not manually change to this state in the user code. */ - HOST_STATE_Attached_WaitForDeviceSettle = 4, /**< Internally implemented by the library. This state indicates + HOST_STATE_Powered_WaitForDeviceSettle = 4, /**< Internally implemented by the library. This state indicates * that the stack is waiting for the initial settling period to * elapse before beginning the enumeration process. * * \note Do not manually change to this state in the user code. */ - HOST_STATE_Attached_WaitForConnect = 5, /**< Internally implemented by the library. This state indicates + HOST_STATE_Powered_WaitForConnect = 5, /**< Internally implemented by the library. This state indicates * that the stack is waiting for a connection event from the USB * controller to indicate a valid USB device has been attached to * the bus and is ready to be enumerated. * * \note Do not manually change to this state in the user code. */ - HOST_STATE_Attached_DoReset = 6, /**< Internally implemented by the library. This state indicates + HOST_STATE_Powered_DoReset = 6, /**< Internally implemented by the library. This state indicates * that a valid USB device has been attached, and that it is * will now be reset to ensure it is ready for enumeration. * * \note Do not manually change to this state in the user code. */ - HOST_STATE_Powered = 7, /**< Internally implemented by the library. This state indicates + HOST_STATE_Powered_ConfigPipe = 7, /**< Internally implemented by the library. This state indicates * that the attached device is currently powered and reset, and * that the control pipe is now being configured by the stack. * @@ -301,20 +301,12 @@ * retrieval and processing of the device descriptor) should also * be placed in this state. */ - HOST_STATE_Configured = 12, /**< May be implemented by the user project. This state should - * implement any extra device configuration (such as the setting of - * class-specific parameters) before normal communication is begun - * in the HOST_STATE_Ready state. - */ - HOST_STATE_Ready = 13, /**< May be implemented by the user project. This state should - * contain the main communications with the attached device. From this - * this state the host state machine should be changed to either - * HOST_STATE_Suspended (after the bus is manually suspended using the - * USB_Host_SuspendBus() macro) or HOST_STATE_WaitForDeviceRemoval as - * needed. + HOST_STATE_Configured = 12, /**< May be implemented by the user project. This state should implement the + * actual work performed on the attached device and changed to the + * HOST_STATE_Suspended or HOST_STATE_WaitForDeviceRemoval states as needed. */ HOST_STATE_Suspended = 15, /**< May be implemented by the user project. This state should be maintained - * while the bus is suspended, and changed to either the HOST_STATE_Ready + * while the bus is suspended, and changed to either the HOST_STATE_Configured * (after resuming the bus with the USB_Host_ResumeBus() macro) or the * HOST_STATE_WaitForDeviceRemoval states as needed. */ diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.c b/LUFA/Drivers/USB/LowLevel/LowLevel.c index 4fcf4fcabe..cd7fa891d0 100644 --- a/LUFA/Drivers/USB/LowLevel/LowLevel.c +++ b/LUFA/Drivers/USB/LowLevel/LowLevel.c @@ -110,15 +110,21 @@ void USB_Init( void USB_ShutDown(void) { - if (USB_IsConnected) + #if defined(USB_CAN_BE_DEVICE) + if (USB_DeviceState != DEVICE_STATE_Unattached) + EVENT_USB_Disconnect(); + #endif + + #if defined(USB_CAN_BE_HOST) + if (USB_HostState != HOST_STATE_Unattached) EVENT_USB_Disconnect(); + #endif USB_Detach(); USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); - USB_IsConnected = false; USB_IsInitialized = false; #if defined(USB_CAN_BE_HOST) @@ -126,7 +132,10 @@ void USB_ShutDown(void) #endif #if defined(USB_CAN_BE_DEVICE) - USB_ConfigurationNumber = 0; + USB_DeviceState = DEVICE_STATE_Unattached; + USB_ConfigurationNumber = 0; + USB_RemoteWakeupEnabled = false; + USB_CurrentlySelfPowered = false; #endif #if defined(CAN_BE_BOTH) @@ -149,16 +158,14 @@ void USB_ResetInterface(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); - - USB_IsConnected = false; - + #if defined(USB_CAN_BE_HOST) - USB_HostState = HOST_STATE_Unattached; + USB_HostState = HOST_STATE_Unattached; #endif - + #if defined(USB_CAN_BE_DEVICE) + USB_DeviceState = DEVICE_STATE_Unattached; USB_ConfigurationNumber = 0; - USB_IsSuspended = false; USB_RemoteWakeupEnabled = false; USB_CurrentlySelfPowered = false; #endif diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c index 3fb30a2f79..7d3e87602e 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.c +++ b/LUFA/Drivers/USB/LowLevel/Pipe.c @@ -93,7 +93,7 @@ uint8_t Pipe_WaitUntilReady(void) if (Pipe_IsStalled()) return PIPE_READYWAIT_PipeStalled; - else if (!(USB_IsConnected)) + else if (USB_HostState == HOST_STATE_Unattached) return PIPE_READYWAIT_DeviceDisconnected; if (USB_INT_HasOccurred(USB_INT_HSOFI)) diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c index d66edafd6c..b85705c226 100644 --- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c +++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c @@ -14,9 +14,16 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) Endpoint_ClearOUT(); } + + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; } - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + } return ENDPOINT_RWCSTREAM_NoError; } diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c index 2796c64255..43a9f3d42c 100644 --- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c +++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c @@ -8,7 +8,11 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) while (Length && !(Endpoint_IsOUTReceived())) { - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + } while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) { @@ -25,11 +29,20 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) if (LastPacketFull) { - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + } + Endpoint_ClearIN(); } - while (!(Endpoint_IsOUTReceived())); + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + } return ENDPOINT_RWCSTREAM_NoError; } diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 0c51940edc..b2500b0c4a 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -29,6 +29,8 @@ * - Added new USE_FLASH_DESCRIPTORS and TOTAL_NUM_CONFIGURATIONS compile time options * - Added support for the new ATMEGA32U2, ATMEGA16U2 and ATMEGA8U2 AVR models * - Added new PrinterHost demo (thanks to John Andrews) + * - Added new USB_DeviceState variable to keep track of the current Device mode USB state + * - Added new Endpoint_ClearStatusStage() convenience function to assist with the status stages of control transfers * * Changed: * - Deprecated psuedo-scheduler and removed dynamic memory allocator from the library (first no longer needed and second unused) @@ -47,6 +49,8 @@ * descriptor is located can be specified. This means that descriptors can now be located in multiple memory spaces within a device. * - Host mode demos now use sane terminal escape codes, so that text is always readable and events/program output is visually distinguished * from oneanother using foreground colours + * - Removed vague USB_IsConnected global - test USB_DeviceState or USB_HostState explicitly to gain previous functionality + * - Removed USB_IsSuspended global - test USB_DeviceState against DEVICE_STATE_Suspended instead * * Fixed: * - Changed bootloaders to use FLASHEND rather than the existence of RAMPZ to determine if far FLASH pointers are needed to fix @@ -91,6 +95,8 @@ * LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs * - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure * - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt + * - Fixed possible enumeration errors from spinloops which may fail to exit if the USB connection is severed before the exit condition + * becomes true * * * \section Sec_ChangeLog090510 Version 090510 diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt index 2d9ec7a95e..f11dff2e1b 100644 --- a/LUFA/ManPages/CompileTimeTokens.txt +++ b/LUFA/ManPages/CompileTimeTokens.txt @@ -157,7 +157,7 @@ * On the smaller USB AVRs, the USB controller lacks VBUS events to determine the physical connection state of the USB bus to a host. In lieu of * VBUS events, the library attempts to determine the connection state via the bus suspension and wake up events instead. This however may be * slightly inaccurate due to the possibility of the host suspending the bus while the device is still connected. If accurate connection status is - * required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_IsConnected global + * required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_DeviceState global * can be accurately set and the USB_Connect and USB_Disconnect events manually raised by the RAISE_EVENT macro. When defined, this token disables * the library's auto-detection of the connection state by the aforementioned suspension and wake up events. * diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index 945406d61a..5ea8d9c166 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -19,17 +19,23 @@ * - The "Dynamic Memory Block Allocator" has been removed, as it was unused in (and unrelated to) the LUFA library and never * used in user applications. The library is available from the author's website for those wishing to still use it in their * applications. + * - The USB_IsConnected global has been removed, as it is too vague for general use. Test \ref USB_DeviceState or \ref USB_HostState + * explicitly to ensure the device is in the desired state instead. * * Host Mode * - The HIDParser.c module has moved from LUFA/Drivers/USB/Class/ to LUFA/Drivers/USB/Class/Host/. - * - The USB_GetDeviceConfigDescriptor() function now requires the desired configuration index within the device as its first + * - The \ref USB_GetDeviceConfigDescriptor() function now requires the desired configuration index within the device as its first * parameter, to add support for multi-configuration devices. Existing code should use a configuration index of 1 to indicate the * first configuration descriptor within the device. + * - The non-standard "Ready" host state has been removed. Existing \ref HOST_STATE_Configured code should be moved to the end of + * the existing \ref HOST_STATE_Addressed state, and the existing HOST_STATE_Ready state code should be moved to the \ref HOST_STATE_Configured + * state. * * Device Mode * - The \ref CALLBACK_USB_GetDescriptor() function now takes an extra parameter to specify the descriptor's memory space so that * descriptors in mixed memory spaces can be used. The previous functionality can be returned by defining the USE_FLASH_DESCRIPTORS * token in the project makefile to fix all descriptors into FLASH space and remove the extra function parameter. + * - Removed USB_IsSuspended - test \ref USB_DeviceState against \ref DEVICE_STATE_Suspended instead. * * * \section Sec_Migration090605 Migrating from 090510 to 090605 diff --git a/Projects/MissileLauncher/MissileLauncher.c b/Projects/MissileLauncher/MissileLauncher.c index 88902cf2e7..1ae37044f6 100644 --- a/Projects/MissileLauncher/MissileLauncher.c +++ b/Projects/MissileLauncher/MissileLauncher.c @@ -337,9 +337,6 @@ void HID_Host_Task(void) USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - USB_HostState = HOST_STATE_Ready; - break; - case HOST_STATE_Ready: DiscardNextReport(); break;