Added ENABLE_TELNET_SERVER compile time option to the Webserver project to disable...
[pub/USBasp.git] / Demos / Host / ClassDriver / MassStorageHost / MassStorageHost.c
index 0f9134f..4aa0c53 100644 (file)
@@ -1,21 +1,21 @@
 /*\r
              LUFA Library\r
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
+     Copyright (C) Dean Camera, 2010.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
+  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this \r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in \r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting \r
+  documentation, and that the name of the author not be used in \r
+  advertising or publicity pertaining to distribution of the \r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
@@ -45,13 +45,16 @@ USB_ClassInfo_MS_Host_t FlashDisk_MS_Interface =
                .Config =\r
                        {\r
                                .DataINPipeNumber       = 1,\r
                .Config =\r
                        {\r
                                .DataINPipeNumber       = 1,\r
+                               .DataINPipeDoubleBank   = false,\r
+                               \r
                                .DataOUTPipeNumber      = 2,\r
                                .DataOUTPipeNumber      = 2,\r
+                               .DataOUTPipeDoubleBank  = false,\r
                        },\r
        };\r
 \r
        \r
 /** Main program entry point. This routine configures the hardware required by the application, then\r
                        },\r
        };\r
 \r
        \r
 /** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
+ *  enters a loop to run the application tasks in sequence.\r
  */\r
 int main(void)\r
 {\r
  */\r
 int main(void)\r
 {\r
@@ -71,9 +74,8 @@ int main(void)
                                uint16_t ConfigDescriptorSize;\r
                                uint8_t  ConfigDescriptorData[512];\r
 \r
                                uint16_t ConfigDescriptorSize;\r
                                uint8_t  ConfigDescriptorData[512];\r
 \r
-                               if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||\r
-                                   (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||\r
-                                       (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))\r
+                               if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,\r
+                                                                      sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)\r
                                {\r
                                        printf("Error Retrieving Configuration Descriptor.\r\n");\r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                {\r
                                        printf("Error Retrieving Configuration Descriptor.\r\n");\r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
@@ -82,9 +84,9 @@ int main(void)
                                }\r
 \r
                                if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,\r
                                }\r
 \r
                                if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,\r
-                                                           ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)\r
+                                                          ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)\r
                                {\r
                                {\r
-                                       printf("Attached Device Not a Valid Mouse.\r\n");\r
+                                       printf("Attached Device Not a Valid Mass Storage Device.\r\n");\r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                        USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                        break;\r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                        USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                        break;\r
@@ -98,7 +100,7 @@ int main(void)
                                        break;\r
                                }\r
                                \r
                                        break;\r
                                }\r
                                \r
-                               printf("Mouse Enumerated.\r\n");\r
+                               printf("Mass Storage Device Enumerated.\r\n");\r
                                USB_HostState = HOST_STATE_Configured;\r
                                break;\r
                        case HOST_STATE_Configured:\r
                                USB_HostState = HOST_STATE_Configured;\r
                                break;\r
                        case HOST_STATE_Configured:\r
@@ -113,6 +115,8 @@ int main(void)
                                        break;\r
                                }\r
                                \r
                                        break;\r
                                }\r
                                \r
+                               printf("Total LUNs: %d - Using first LUN in device.\r\n", (MaxLUNIndex + 1));\r
+                               \r
                                if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))\r
                                {\r
                                        printf("Error resetting Mass Storage interface.\r\n");\r
                                if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))\r
                                {\r
                                        printf("Error resetting Mass Storage interface.\r\n");\r
@@ -121,10 +125,27 @@ int main(void)
                                        break;\r
                                }\r
                                \r
                                        break;\r
                                }\r
                                \r
+                               SCSI_Request_Sense_Response_t SenseData;\r
+                               if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0)\r
+                               {\r
+                                       printf("Error retrieving device sense.\r\n");\r
+                                       LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+                                       USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
+                                       break;\r
+                               }\r
+                       \r
+                               if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true))\r
+                               {\r
+                                       printf("Error setting Prevent Device Removal bit.\r\n");\r
+                                       LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+                                       USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
+                                       break;\r
+                               }\r
+\r
                                SCSI_Inquiry_Response_t InquiryData;\r
                                SCSI_Inquiry_Response_t InquiryData;\r
-                               if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, &InquiryData))\r
+                               if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData))\r
                                {\r
                                {\r
-                                       printf("Error retreiving device Inquiry data.\r\n");\r
+                                       printf("Error retrieving device Inquiry data.\r\n");\r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                        USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                        break;                          \r
                                        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                        USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                        break;                          \r
@@ -133,11 +154,16 @@ int main(void)
                                printf("Vendor \"%.8s\", Product \"%.16s\"\r\n", InquiryData.VendorID, InquiryData.ProductID);\r
                                \r
                                printf("Waiting until ready...\r\n");\r
                                printf("Vendor \"%.8s\", Product \"%.16s\"\r\n", InquiryData.VendorID, InquiryData.ProductID);\r
                                \r
                                printf("Waiting until ready...\r\n");\r
-                               bool DeviceReady;\r
 \r
 \r
-                               do\r
+                               for (;;)\r
                                {\r
                                {\r
-                                       if (MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0, &DeviceReady))\r
+                                       uint8_t ErrorCode = MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0);\r
+                                       \r
+                                       if (!(ErrorCode))\r
+                                         break;\r
+\r
+                                       /* Check if an error other than a logical command error (device busy) received */\r
+                                       if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED)\r
                                        {\r
                                                printf("Error waiting for device to be ready.\r\n");\r
                                                LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
                                        {\r
                                                printf("Error waiting for device to be ready.\r\n");\r
                                                LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
@@ -145,9 +171,8 @@ int main(void)
                                                break;\r
                                        }\r
                                }\r
                                                break;\r
                                        }\r
                                }\r
-                               while (!(DeviceReady));\r
 \r
 \r
-                               puts_P(PSTR("Retrieving Capacity... "));\r
+                               printf("Retrieving Capacity... ");\r
 \r
                                SCSI_Capacity_t DiskCapacity;\r
                                if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))\r
 \r
                                SCSI_Capacity_t DiskCapacity;\r
                                if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))\r
@@ -160,6 +185,41 @@ int main(void)
                                \r
                                printf("%lu blocks of %lu bytes.\r\n", DiskCapacity.Blocks, DiskCapacity.BlockSize);\r
 \r
                                \r
                                printf("%lu blocks of %lu bytes.\r\n", DiskCapacity.Blocks, DiskCapacity.BlockSize);\r
 \r
+                               uint8_t BlockBuffer[DiskCapacity.BlockSize];\r
+\r
+                               if (MS_Host_ReadDeviceBlocks(&FlashDisk_MS_Interface, 0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer))\r
+                               {\r
+                                       printf("Error reading device block.\r\n");\r
+                                       LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+                                       USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
+                                       break;\r
+                               }\r
+                       \r
+                               printf("\r\nContents of first block:\r\n");\r
+\r
+                               for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)\r
+                               {\r
+                                       uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];\r
+                                       \r
+                                       /* Print out the 16 bytes of the chunk in HEX format */\r
+                                       for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)\r
+                                       {\r
+                                               char CurrByte = *(ChunkPtr + ByteOffset);\r
+                                               printf_P(PSTR("%.2X "), CurrByte);\r
+                                       }\r
+                                       \r
+                                       printf("    ");\r
+\r
+                                       /* Print out the 16 bytes of the chunk in ASCII format */\r
+                                       for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)\r
+                                       {\r
+                                               char CurrByte = *(ChunkPtr + ByteOffset);\r
+                                               putchar(isprint(CurrByte) ? CurrByte : '.');\r
+                                       }\r
+                                       \r
+                                       printf("\r\n");\r
+                               }\r
+\r
                                LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
                                USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                break;\r
                                LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
                                USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
                                break;\r