X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/cb779e3d7d32d7c43e0a45bb526de0a04135b0c7..5ce60f25e68ef73e01c06409b31b75cfbac9ee3f:/Demos/Device/LowLevel/MassStorage/MassStorage.c diff --git a/Demos/Device/LowLevel/MassStorage/MassStorage.c b/Demos/Device/LowLevel/MassStorage/MassStorage.c index 33eac7a46..0e8e1083b 100644 --- a/Demos/Device/LowLevel/MassStorage/MassStorage.c +++ b/Demos/Device/LowLevel/MassStorage/MassStorage.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2010. + Copyright (C) Dean Camera, 2012. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -80,6 +80,13 @@ void SetupHardware(void) Dataflash_Init(); USB_Init(); + /* Check if the Dataflash is working, abort if not */ + if (!(DataflashManager_CheckDataflashOperation())) + { + LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + for(;;); + } + /* Clear Dataflash sector protections, if enabled */ DataflashManager_ResetDataflashProtections(); } @@ -111,20 +118,18 @@ void EVENT_USB_Device_ConfigurationChanged(void) bool ConfigSuccess = true; /* Setup Mass Storage Data Endpoints */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(MASS_STORAGE_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN, - MASS_STORAGE_IO_EPSIZE, ENDPOINT_BANK_SINGLE); - ConfigSuccess &= Endpoint_ConfigureEndpoint(MASS_STORAGE_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT, - MASS_STORAGE_IO_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= Endpoint_ConfigureEndpoint(MASS_STORAGE_IN_EPADDR, EP_TYPE_BULK, MASS_STORAGE_IO_EPSIZE, 1); + ConfigSuccess &= Endpoint_ConfigureEndpoint(MASS_STORAGE_OUT_EPADDR, EP_TYPE_BULK, MASS_STORAGE_IO_EPSIZE, 1); /* Indicate endpoint configuration success or failure */ LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); } -/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific - * control requests that are not handled internally by the USB library (including the Mass Storage class-specific - * requests) so that they can be handled appropriately for the application. +/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to + * the device from the USB host before passing along unhandled control requests to the library for processing + * internally. */ -void EVENT_USB_Device_UnhandledControlRequest(void) +void EVENT_USB_Device_ControlRequest(void) { /* Process UFI specific control requests */ switch (USB_ControlRequest.bRequest) @@ -146,7 +151,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearSETUP(); /* Indicate to the host the number of supported LUNs (virtual disks) on the device */ - Endpoint_Write_Byte(TOTAL_LUNS - 1); + Endpoint_Write_8(TOTAL_LUNS - 1); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); @@ -173,7 +178,7 @@ void MassStorage_Task(void) /* Check direction of command, select Data IN endpoint if data is from the device */ if (CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN) - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPADDR); /* Decode the received SCSI command, set returned status code */ CommandStatus.Status = SCSI_DecodeSCSICommand() ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail; @@ -199,13 +204,13 @@ void MassStorage_Task(void) if (IsMassStoreReset) { /* Reset the data endpoint banks */ - Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM); - Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM); + Endpoint_ResetEndpoint(MASS_STORAGE_OUT_EPADDR); + Endpoint_ResetEndpoint(MASS_STORAGE_IN_EPADDR); - Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPADDR); Endpoint_ClearStall(); Endpoint_ResetDataToggle(); - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPADDR); Endpoint_ClearStall(); Endpoint_ResetDataToggle(); @@ -221,20 +226,24 @@ void MassStorage_Task(void) */ static bool ReadInCommandBlock(void) { + uint16_t BytesTransferred; + /* Select the Data Out endpoint */ - Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPADDR); /* Abort if no command has been sent from the host */ if (!(Endpoint_IsOUTReceived())) return false; /* Read in command block header */ - Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)), - StreamCallback_AbortOnMassStoreReset); - - /* Check if the current command is being aborted by the host */ - if (IsMassStoreReset) - return false; + BytesTransferred = 0; + while (Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)), + &BytesTransferred) == ENDPOINT_RWSTREAM_IncompleteTransfer) + { + /* Check if the current command is being aborted by the host */ + if (IsMassStoreReset) + return false; + } /* Verify the command block - abort if invalid */ if ((CommandBlock.Signature != MS_CBW_SIGNATURE) || @@ -245,20 +254,21 @@ static bool ReadInCommandBlock(void) { /* Stall both data pipes until reset by host */ Endpoint_StallTransaction(); - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPADDR); Endpoint_StallTransaction(); return false; } /* Read in command block command data */ - Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData, - CommandBlock.SCSICommandLength, - StreamCallback_AbortOnMassStoreReset); - - /* Check if the current command is being aborted by the host */ - if (IsMassStoreReset) - return false; + BytesTransferred = 0; + while (Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData, CommandBlock.SCSICommandLength, + &BytesTransferred) == ENDPOINT_RWSTREAM_IncompleteTransfer) + { + /* Check if the current command is being aborted by the host */ + if (IsMassStoreReset) + return false; + } /* Finalize the stream transfer to send the last packet */ Endpoint_ClearOUT(); @@ -271,8 +281,10 @@ static bool ReadInCommandBlock(void) */ static void ReturnCommandStatus(void) { + uint16_t BytesTransferred; + /* Select the Data Out endpoint */ - Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPADDR); /* While data pipe is stalled, wait until the host issues a control request to clear the stall */ while (Endpoint_IsStalled()) @@ -283,7 +295,7 @@ static void ReturnCommandStatus(void) } /* Select the Data In endpoint */ - Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); + Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPADDR); /* While data pipe is stalled, wait until the host issues a control request to clear the stall */ while (Endpoint_IsStalled()) @@ -294,27 +306,16 @@ static void ReturnCommandStatus(void) } /* Write the CSW to the endpoint */ - Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus), - StreamCallback_AbortOnMassStoreReset); - - /* Check if the current command is being aborted by the host */ - if (IsMassStoreReset) - return; + BytesTransferred = 0; + while (Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus), + &BytesTransferred) == ENDPOINT_RWSTREAM_IncompleteTransfer) + { + /* Check if the current command is being aborted by the host */ + if (IsMassStoreReset) + return; + } /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); } -/** Stream callback function for the Endpoint stream read and write functions. This callback will abort the current stream transfer - * if a Mass Storage Reset request has been issued to the control endpoint. - */ -uint8_t StreamCallback_AbortOnMassStoreReset(void) -{ - /* Abort if a Mass Storage reset command was received */ - if (IsMassStoreReset) - return STREAMCALLBACK_Abort; - - /* Continue with the current stream operation */ - return STREAMCALLBACK_Continue; -} -