From e071f3897a0946c6be1e1b5e1f78eda8dcbf6fc7 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 21 Jul 2009 13:31:21 +0000 Subject: 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. --- .../LowLevel/MassStorage/Lib/DataflashManager.c | 26 ++++- Demos/Device/LowLevel/MassStorage/MassStorage.c | 108 ++++++++++----------- 2 files changed, 73 insertions(+), 61 deletions(-) (limited to 'Demos/Device/LowLevel/MassStorage') diff --git a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c index fdc91dd5d..2bd03c98d 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 2c80fc595..01d27f043 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 -- cgit v1.2.3