Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Demos / Device / LowLevel / MassStorage / MassStorage.c
index 4b0b582..7f2d866 100644 (file)
@@ -1,21 +1,21 @@
 /*
              LUFA Library
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2010.
-              
+     Copyright (C) Dean Camera, 2011.
+
   dean [at] fourwalledcubicle [dot] com
   dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
+           www.lufa-lib.org
 */
 
 /*
 */
 
 /*
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
 
-  Permission to use, copy, modify, distribute, and sell this 
+  Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
   software and its documentation for any purpose is hereby granted
-  without fee, provided that the above copyright notice appear in 
+  without fee, provided that the above copyright notice appear in
   all copies and that both that the copyright notice and this
   all copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting 
-  documentation, and that the name of the author not be used in 
-  advertising or publicity pertaining to distribution of the 
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
 #include "MassStorage.h"
 
 /** Structure to hold the latest Command Block Wrapper issued by the host, containing a SCSI command to execute. */
 #include "MassStorage.h"
 
 /** Structure to hold the latest Command Block Wrapper issued by the host, containing a SCSI command to execute. */
-CommandBlockWrapper_t  CommandBlock;
+MS_CommandBlockWrapper_t  CommandBlock;
 
 /** Structure to hold the latest Command Status Wrapper to return to the host, containing the status of the last issued command. */
 
 /** Structure to hold the latest Command Status Wrapper to return to the host, containing the status of the last issued command. */
-CommandStatusWrapper_t CommandStatus = { .Signature = CSW_SIGNATURE };
+MS_CommandStatusWrapper_t CommandStatus = { .Signature = MS_CSW_SIGNATURE };
 
 /** Flag to asynchronously abort any in-progress data transfers upon the reception of a mass storage reset command. */
 
 /** Flag to asynchronously abort any in-progress data transfers upon the reception of a mass storage reset command. */
-volatile bool          IsMassStoreReset = false;
+volatile bool IsMassStoreReset = false;
 
 
 /** Main program entry point. This routine configures the hardware required by the application, then
 
 
 /** Main program entry point. This routine configures the hardware required by the application, then
@@ -53,7 +53,7 @@ volatile bool          IsMassStoreReset = false;
 int main(void)
 {
        SetupHardware();
 int main(void)
 {
        SetupHardware();
-       
+
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
 
@@ -89,7 +89,7 @@ void EVENT_USB_Device_Connect(void)
 {
        /* Indicate USB enumerating */
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 {
        /* Indicate USB enumerating */
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-       
+
        /* Reset the MSReset flag upon connection */
        IsMassStoreReset = false;
 }
        /* Reset the MSReset flag upon connection */
        IsMassStoreReset = false;
 }
@@ -117,43 +117,41 @@ void EVENT_USB_Device_ConfigurationChanged(void)
                                                    MASS_STORAGE_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
 
        /* Indicate endpoint configuration success or failure */
                                                    MASS_STORAGE_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
 
        /* Indicate endpoint configuration success or failure */
-       LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);                                                    
+       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)
        {
 {
        /* Process UFI specific control requests */
        switch (USB_ControlRequest.bRequest)
        {
-               case REQ_MassStorageReset:
+               case MS_REQ_MassStorageReset:
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
                        {
                                Endpoint_ClearSETUP();
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
                        {
                                Endpoint_ClearSETUP();
+                               Endpoint_ClearStatusStage();
 
                                /* Indicate that the current transfer should be aborted */
                                IsMassStoreReset = true;
 
                                /* Indicate that the current transfer should be aborted */
                                IsMassStoreReset = true;
-
-                               Endpoint_ClearStatusStage();
                        }
 
                        break;
                        }
 
                        break;
-               case REQ_GetMaxLUN:
+               case MS_REQ_GetMaxLUN:
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
                        {
                                Endpoint_ClearSETUP();
 
                                /* Indicate to the host the number of supported LUNs (virtual disks) on the device */
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
                        {
                                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_ClearIN();
-                               
                                Endpoint_ClearStatusStage();
                        }
                                Endpoint_ClearStatusStage();
                        }
-                       
+
                        break;
        }
 }
                        break;
        }
 }
@@ -174,20 +172,20 @@ void MassStorage_Task(void)
                LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 
                /* Check direction of command, select Data IN endpoint if data is from the device */
                LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 
                /* Check direction of command, select Data IN endpoint if data is from the device */
-               if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
+               if (CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
                  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
 
                /* Decode the received SCSI command, set returned status code */
                  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
 
                /* Decode the received SCSI command, set returned status code */
-               CommandStatus.Status = SCSI_DecodeSCSICommand() ? Command_Pass : Command_Fail;          
+               CommandStatus.Status = SCSI_DecodeSCSICommand() ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
 
                /* 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 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;
-               
+
                /* Stall the selected data pipe if command failed (if data is still to be transferred) */
                /* Stall the selected data pipe if command failed (if data is still to be transferred) */
-               if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
+               if ((CommandStatus.Status == MS_SCSI_COMMAND_Fail) && (CommandStatus.DataTransferResidue))
                  Endpoint_StallTransaction();
 
                /* Return command status block to the host */
                  Endpoint_StallTransaction();
 
                /* Return command status block to the host */
@@ -201,9 +199,9 @@ void MassStorage_Task(void)
        if (IsMassStoreReset)
        {
                /* Reset the data endpoint banks */
        if (IsMassStoreReset)
        {
                /* Reset the data endpoint banks */
-               Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
-               Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
-               
+               Endpoint_ResetEndpoint(MASS_STORAGE_OUT_EPNUM);
+               Endpoint_ResetEndpoint(MASS_STORAGE_IN_EPNUM);
+
                Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
                Endpoint_ClearStall();
                Endpoint_ResetDataToggle();
                Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
                Endpoint_ClearStall();
                Endpoint_ResetDataToggle();
@@ -223,48 +221,53 @@ void MassStorage_Task(void)
  */
 static bool ReadInCommandBlock(void)
 {
  */
 static bool ReadInCommandBlock(void)
 {
+       uint16_t BytesTransferred;
+
        /* Select the Data Out endpoint */
        Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
        /* Select the Data Out endpoint */
        Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-       
+
        /* Abort if no command has been sent from the host */
        if (!(Endpoint_IsOUTReceived()))
          return false;
 
        /* Read in command block header */
        /* 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 */
 
        /* Verify the command block - abort if invalid */
-       if ((CommandBlock.Signature         != CBW_SIGNATURE) ||
-           (CommandBlock.LUN               >= TOTAL_LUNS)    ||
-               (CommandBlock.Flags              & 0x1F)          ||
-               (CommandBlock.SCSICommandLength == 0)             ||
-               (CommandBlock.SCSICommandLength >  MAX_SCSI_COMMAND_LENGTH))
+       if ((CommandBlock.Signature         != MS_CBW_SIGNATURE) ||
+           (CommandBlock.LUN               >= TOTAL_LUNS)       ||
+               (CommandBlock.Flags              & 0x1F)             ||
+               (CommandBlock.SCSICommandLength == 0)                ||
+               (CommandBlock.SCSICommandLength >  sizeof(CommandBlock.SCSICommandData)))
        {
                /* Stall both data pipes until reset by host */
                Endpoint_StallTransaction();
                Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
                Endpoint_StallTransaction();
        {
                /* Stall both data pipes until reset by host */
                Endpoint_StallTransaction();
                Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
                Endpoint_StallTransaction();
-               
+
                return false;
        }
 
        /* Read in command block command data */
                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();
 
        /* Finalize the stream transfer to send the last packet */
        Endpoint_ClearOUT();
-       
+
        return true;
 }
 
        return true;
 }
 
@@ -273,6 +276,8 @@ static bool ReadInCommandBlock(void)
  */
 static void ReturnCommandStatus(void)
 {
  */
 static void ReturnCommandStatus(void)
 {
+       uint16_t BytesTransferred;
+
        /* Select the Data Out endpoint */
        Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
 
        /* Select the Data Out endpoint */
        Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
 
@@ -294,28 +299,17 @@ static void ReturnCommandStatus(void)
                if (IsMassStoreReset)
                  return;
        }
                if (IsMassStoreReset)
                  return;
        }
-       
+
        /* Write the CSW to the endpoint */
        /* Write the CSW to the endpoint */
-       Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus),
-                                 StreamCallback_AbortOnMassStoreReset);
+       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;
+       }
        
        
-       /* 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();
 }
        /* 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;
-}