Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.

This commit is contained in:
Dean Camera 2010-05-08 03:12:14 +00:00
parent e331b531c6
commit 071e02c6b6
839 changed files with 274562 additions and 274562 deletions

View file

@ -1,166 +1,166 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
* needed to communication with an attached USB device. Descriptors are special computer-readable structures
* which the host requests upon device enumeration, to determine the device's capabilities and functions.
*/
#include "ConfigDescriptor.h"
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This
* routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate
* with compatible devices.
*
* This routine searches for a MSD interface descriptor containing bulk IN and OUT data endpoints.
*
* \return An error code from the \ref MassStorageHost_GetConfigDescriptorDataCodes_t enum.
*/
uint8_t ProcessConfigurationDescriptor(void)
{
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
{
case HOST_GETCONFIG_Successful:
break;
case HOST_GETCONFIG_InvalidData:
return InvalidConfigDataReturned;
case HOST_GETCONFIG_BuffOverflow:
return DescriptorTooLarge;
default:
return ControlError;
}
/* Get the mass storage interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoInterfaceFound;
}
/* Get the IN and OUT data endpoints for the mass storage interface */
while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE)))
{
/* Fetch the next bulk endpoint from the current mass storage interface */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk IN or bulk OUT endpoint, set appropriate globals */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_OUT_PIPE);
}
}
/* Valid data found, return success */
return SuccessfulConfigRead;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Interface descriptor of the correct Mass Storage Class, Subclass and Protocol values.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextMSInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Check the descriptor class and protocol, break out if correct class/protocol interface found */
if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == MASS_STORE_CLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == MASS_STORE_SUBCLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == MASS_STORE_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Bulk Endpoint descriptor of the correct MSD interface, aborting the search if
* another interface descriptor is found before the next endpoint.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextMSInterfaceBulkDataEndpoint(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
/* Check the endpoint type, break out if correct BULK type endpoint found */
if (EndpointType == EP_TYPE_BULK)
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
* needed to communication with an attached USB device. Descriptors are special computer-readable structures
* which the host requests upon device enumeration, to determine the device's capabilities and functions.
*/
#include "ConfigDescriptor.h"
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This
* routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate
* with compatible devices.
*
* This routine searches for a MSD interface descriptor containing bulk IN and OUT data endpoints.
*
* \return An error code from the \ref MassStorageHost_GetConfigDescriptorDataCodes_t enum.
*/
uint8_t ProcessConfigurationDescriptor(void)
{
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
{
case HOST_GETCONFIG_Successful:
break;
case HOST_GETCONFIG_InvalidData:
return InvalidConfigDataReturned;
case HOST_GETCONFIG_BuffOverflow:
return DescriptorTooLarge;
default:
return ControlError;
}
/* Get the mass storage interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoInterfaceFound;
}
/* Get the IN and OUT data endpoints for the mass storage interface */
while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE)))
{
/* Fetch the next bulk endpoint from the current mass storage interface */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk IN or bulk OUT endpoint, set appropriate globals */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_OUT_PIPE);
}
}
/* Valid data found, return success */
return SuccessfulConfigRead;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Interface descriptor of the correct Mass Storage Class, Subclass and Protocol values.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextMSInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Check the descriptor class and protocol, break out if correct class/protocol interface found */
if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == MASS_STORE_CLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == MASS_STORE_SUBCLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == MASS_STORE_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Bulk Endpoint descriptor of the correct MSD interface, aborting the search if
* another interface descriptor is found before the next endpoint.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextMSInterfaceBulkDataEndpoint(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
/* Check the endpoint type, break out if correct BULK type endpoint found */
if (EndpointType == EP_TYPE_BULK)
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}

View file

@ -1,72 +1,72 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for ConfigDescriptor.c.
*/
#ifndef _CONFIGDESCRIPTOR_H_
#define _CONFIGDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "MassStorageHost.h"
/* Macros: */
/** Interface Class value for the Mass Storage Device class */
#define MASS_STORE_CLASS 0x08
/** Interface Class value for the Mass Storage Device subclass */
#define MASS_STORE_SUBCLASS 0x06
/** Interface Protocol value for the Bulk Only transport protocol */
#define MASS_STORE_PROTOCOL 0x50
/* Enums: */
/** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */
enum MassStorageHost_GetConfigDescriptorDataCodes_t
{
SuccessfulConfigRead = 0, /**< Configuration Descriptor was processed successfully */
ControlError = 1, /**< A control request to the device failed to complete successfully */
DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
NoInterfaceFound = 4, /**< A compatible MSD interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< The correct MSD endpoint descriptors were not found in the device's MSD interface */
};
/* Function Prototypes: */
uint8_t ProcessConfigurationDescriptor(void);
uint8_t DComp_NextMSInterface(void* CurrentDescriptor);
uint8_t DComp_NextMSInterfaceBulkDataEndpoint(void* CurrentDescriptor);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for ConfigDescriptor.c.
*/
#ifndef _CONFIGDESCRIPTOR_H_
#define _CONFIGDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "MassStorageHost.h"
/* Macros: */
/** Interface Class value for the Mass Storage Device class */
#define MASS_STORE_CLASS 0x08
/** Interface Class value for the Mass Storage Device subclass */
#define MASS_STORE_SUBCLASS 0x06
/** Interface Protocol value for the Bulk Only transport protocol */
#define MASS_STORE_PROTOCOL 0x50
/* Enums: */
/** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */
enum MassStorageHost_GetConfigDescriptorDataCodes_t
{
SuccessfulConfigRead = 0, /**< Configuration Descriptor was processed successfully */
ControlError = 1, /**< A control request to the device failed to complete successfully */
DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
NoInterfaceFound = 4, /**< A compatible MSD interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< The correct MSD endpoint descriptors were not found in the device's MSD interface */
};
/* Function Prototypes: */
uint8_t ProcessConfigurationDescriptor(void);
uint8_t DComp_NextMSInterface(void* CurrentDescriptor);
uint8_t DComp_NextMSInterfaceBulkDataEndpoint(void* CurrentDescriptor);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,209 +1,209 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for MassStoreCommands.c.
*/
#ifndef _MASS_STORE_COMMANDS_H_
#define _MASS_STORE_COMMANDS_H_
/* Includes: */
#include <avr/io.h>
#include "MassStorageHost.h"
#include "SCSI_Codes.h"
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
/** Class specific request to reset the Mass Storage interface of the attached device */
#define REQ_MassStorageReset 0xFF
/** Class specific request to retrieve the maximum Logical Unit Number (LUN) index of the attached device */
#define REQ_GetMaxLUN 0xFE
/** Command Block Wrapper signature byte, for verification of valid CBW blocks */
#define CBW_SIGNATURE 0x43425355UL
/** Command Static Wrapper signature byte, for verification of valid CSW blocks */
#define CSW_SIGNATURE 0x53425355UL
/** Data direction mask for the Flags field of a CBW, indicating Host-to-Device transfer direction */
#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
/** Data direction mask for the Flags field of a CBW, indicating Device-to-Host transfer direction */
#define COMMAND_DIRECTION_DATA_IN (1 << 7)
/** Timeout period between the issuing of a CBW to a device, and the reception of the first packet */
#define COMMAND_DATA_TIMEOUT_MS 10000
/** Pipe number of the Mass Storage data IN pipe */
#define MASS_STORE_DATA_IN_PIPE 1
/** Pipe number of the Mass Storage data OUT pipe */
#define MASS_STORE_DATA_OUT_PIPE 2
/** Additional error code for Mass Storage functions when a device returns a logical command failure */
#define MASS_STORE_SCSI_COMMAND_FAILED 0xC0
/* Type defines: */
/** Type define for a Mass Storage class Command Block Wrapper, used to wrap SCSI
* commands for transport over the USB bulk endpoints to the device.
*/
typedef struct
{
uint32_t Signature; /**< Command block signature, always equal to CBW_SIGNATURE */
uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW (filled automatically) */
uint32_t DataTransferLength; /**< Length of data to transfer, following the CBW */
uint8_t Flags; /**< Block flags, equal to one of the COMMAND_DIRECTION_DATA_* macros */
uint8_t LUN; /**< Logical Unit Number the CBW is addressed to in the device */
uint8_t SCSICommandLength; /**< Length of the SCSI command in the CBW */
uint8_t SCSICommandData[16]; /**< SCSI command to issue to the device */
} CommandBlockWrapper_t;
/** Type define for a Mass Storage class Command Status Wrapper, used to wrap SCSI
* responses for transport over the USB bulk endpoints from the device.
*/
typedef struct
{
uint32_t Signature; /**< Command status signature, always equal to CSW_SIGNATURE */
uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */
uint32_t DataTransferResidue; /**< Length of data not transferred */
uint8_t Status; /**< Command status, a value from the MassStorageHost_CommandStatusCodes_t enum */
} CommandStatusWrapper_t;
/** Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/** SCSI capacity structure, to hold the total capacity of the device in both the number
* of blocks in the current LUN, and the size of each block. This structure is filled by
* the device when the MassStore_ReadCapacity() function is called.
*/
typedef struct
{
uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */
uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */
} SCSI_Capacity_t;
/* Enums: */
/** CSW status return codes, indicating the overall status of the issued CBW */
enum MassStorageHost_CommandStatusCodes_t
{
Command_Pass = 0, /**< Command completed successfully */
Command_Fail = 1, /**< Command failed to complete successfully */
Phase_Error = 2 /**< Phase error while processing the issued command */
};
/* Function Prototypes: */
#if defined(INCLUDE_FROM_MASSSTORE_COMMANDS_C)
static uint8_t MassStore_SendCommand(CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr);
static uint8_t MassStore_WaitForDataReceived(void);
static uint8_t MassStore_SendReceiveData(CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t MassStore_GetReturnedStatus(CommandStatusWrapper_t* SCSICommandStatus) ATTR_NON_NULL_PTR_ARG(1);
#endif
uint8_t MassStore_MassStorageReset(void);
uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);
uint8_t MassStore_RequestSense(const uint8_t LUNIndex, SCSI_Request_Sense_Response_t* const SensePtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_Inquiry(const uint8_t LUNIndex, SCSI_Inquiry_Response_t* const InquiryPtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);
uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);
uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex);
uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for MassStoreCommands.c.
*/
#ifndef _MASS_STORE_COMMANDS_H_
#define _MASS_STORE_COMMANDS_H_
/* Includes: */
#include <avr/io.h>
#include "MassStorageHost.h"
#include "SCSI_Codes.h"
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
/** Class specific request to reset the Mass Storage interface of the attached device */
#define REQ_MassStorageReset 0xFF
/** Class specific request to retrieve the maximum Logical Unit Number (LUN) index of the attached device */
#define REQ_GetMaxLUN 0xFE
/** Command Block Wrapper signature byte, for verification of valid CBW blocks */
#define CBW_SIGNATURE 0x43425355UL
/** Command Static Wrapper signature byte, for verification of valid CSW blocks */
#define CSW_SIGNATURE 0x53425355UL
/** Data direction mask for the Flags field of a CBW, indicating Host-to-Device transfer direction */
#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
/** Data direction mask for the Flags field of a CBW, indicating Device-to-Host transfer direction */
#define COMMAND_DIRECTION_DATA_IN (1 << 7)
/** Timeout period between the issuing of a CBW to a device, and the reception of the first packet */
#define COMMAND_DATA_TIMEOUT_MS 10000
/** Pipe number of the Mass Storage data IN pipe */
#define MASS_STORE_DATA_IN_PIPE 1
/** Pipe number of the Mass Storage data OUT pipe */
#define MASS_STORE_DATA_OUT_PIPE 2
/** Additional error code for Mass Storage functions when a device returns a logical command failure */
#define MASS_STORE_SCSI_COMMAND_FAILED 0xC0
/* Type defines: */
/** Type define for a Mass Storage class Command Block Wrapper, used to wrap SCSI
* commands for transport over the USB bulk endpoints to the device.
*/
typedef struct
{
uint32_t Signature; /**< Command block signature, always equal to CBW_SIGNATURE */
uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW (filled automatically) */
uint32_t DataTransferLength; /**< Length of data to transfer, following the CBW */
uint8_t Flags; /**< Block flags, equal to one of the COMMAND_DIRECTION_DATA_* macros */
uint8_t LUN; /**< Logical Unit Number the CBW is addressed to in the device */
uint8_t SCSICommandLength; /**< Length of the SCSI command in the CBW */
uint8_t SCSICommandData[16]; /**< SCSI command to issue to the device */
} CommandBlockWrapper_t;
/** Type define for a Mass Storage class Command Status Wrapper, used to wrap SCSI
* responses for transport over the USB bulk endpoints from the device.
*/
typedef struct
{
uint32_t Signature; /**< Command status signature, always equal to CSW_SIGNATURE */
uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */
uint32_t DataTransferResidue; /**< Length of data not transferred */
uint8_t Status; /**< Command status, a value from the MassStorageHost_CommandStatusCodes_t enum */
} CommandStatusWrapper_t;
/** Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/** SCSI capacity structure, to hold the total capacity of the device in both the number
* of blocks in the current LUN, and the size of each block. This structure is filled by
* the device when the MassStore_ReadCapacity() function is called.
*/
typedef struct
{
uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */
uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */
} SCSI_Capacity_t;
/* Enums: */
/** CSW status return codes, indicating the overall status of the issued CBW */
enum MassStorageHost_CommandStatusCodes_t
{
Command_Pass = 0, /**< Command completed successfully */
Command_Fail = 1, /**< Command failed to complete successfully */
Phase_Error = 2 /**< Phase error while processing the issued command */
};
/* Function Prototypes: */
#if defined(INCLUDE_FROM_MASSSTORE_COMMANDS_C)
static uint8_t MassStore_SendCommand(CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr);
static uint8_t MassStore_WaitForDataReceived(void);
static uint8_t MassStore_SendReceiveData(CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t MassStore_GetReturnedStatus(CommandStatusWrapper_t* SCSICommandStatus) ATTR_NON_NULL_PTR_ARG(1);
#endif
uint8_t MassStore_MassStorageReset(void);
uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);
uint8_t MassStore_RequestSense(const uint8_t LUNIndex, SCSI_Request_Sense_Response_t* const SensePtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_Inquiry(const uint8_t LUNIndex, SCSI_Inquiry_Response_t* const InquiryPtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);
uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);
uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)
ATTR_NON_NULL_PTR_ARG(2);
uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex);
uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval);
#endif

View file

@ -1,85 +1,85 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header containing macros for possible SCSI commands and SENSE data. Refer to
* the SCSI standard documentation for more information on each SCSI command and
* the SENSE data.
*/
#ifndef _SCSI_CODES_H_
#define _SCSI_CODES_H_
/* Macros: */
#define SCSI_CMD_INQUIRY 0x12
#define SCSI_CMD_REQUEST_SENSE 0x03
#define SCSI_CMD_TEST_UNIT_READY 0x00
#define SCSI_CMD_READ_CAPACITY_10 0x25
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_CMD_WRITE_10 0x2A
#define SCSI_CMD_READ_10 0x28
#define SCSI_CMD_WRITE_6 0x0A
#define SCSI_CMD_READ_6 0x08
#define SCSI_CMD_VERIFY_10 0x2F
#define SCSI_CMD_MODE_SENSE_6 0x1A
#define SCSI_CMD_MODE_SENSE_10 0x5A
#define SCSI_SENSE_KEY_GOOD 0x00
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
#define SCSI_SENSE_KEY_NOT_READY 0x02
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
#define SCSI_ASENSE_FORMAT_ERROR 0x31
#define SCSI_ASENSE_INVALID_COMMAND 0x20
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header containing macros for possible SCSI commands and SENSE data. Refer to
* the SCSI standard documentation for more information on each SCSI command and
* the SENSE data.
*/
#ifndef _SCSI_CODES_H_
#define _SCSI_CODES_H_
/* Macros: */
#define SCSI_CMD_INQUIRY 0x12
#define SCSI_CMD_REQUEST_SENSE 0x03
#define SCSI_CMD_TEST_UNIT_READY 0x00
#define SCSI_CMD_READ_CAPACITY_10 0x25
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_CMD_WRITE_10 0x2A
#define SCSI_CMD_READ_10 0x28
#define SCSI_CMD_WRITE_6 0x0A
#define SCSI_CMD_READ_6 0x08
#define SCSI_CMD_VERIFY_10 0x2F
#define SCSI_CMD_MODE_SENSE_6 0x1A
#define SCSI_CMD_MODE_SENSE_10 0x5A
#define SCSI_SENSE_KEY_GOOD 0x00
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
#define SCSI_SENSE_KEY_NOT_READY 0x02
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
#define SCSI_ASENSE_FORMAT_ERROR 0x31
#define SCSI_ASENSE_INVALID_COMMAND 0x20
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
#endif

View file

@ -1,394 +1,394 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the MassStorageHost demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#include "MassStorageHost.h"
/** Index of the highest available LUN (Logical Unit) in the attached Mass Storage Device */
uint8_t MassStore_MaxLUNIndex;
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "Mass Storage Host Demo running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
MassStorage_Task();
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
SerialStream_Init(9600, false);
LEDs_Init();
Buttons_Init();
USB_Init();
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_ShutDown();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Task to set the configuration of the attached device after it has been enumerated, and to read in blocks from
* the device and print them to the serial port.
*/
void MassStorage_Task(void)
{
uint8_t ErrorCode;
switch (USB_HostState)
{
case HOST_STATE_Addressed:
puts_P(PSTR("Getting Config Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
{
if (ErrorCode == ControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
{
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
/* Indicate device busy via the status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
/* Send the request, display error and wait for device detach if request fails */
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Print number of LUNs detected in the attached device */
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
/* Reset the Mass Storage device interface, ready for use */
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Get sense data from the device - many devices will not accept any other commands until the sense data
* is read - both on start-up and after a failed command */
SCSI_Request_Sense_Response_t SenseData;
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
{
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Set the prevent removal flag for the device, allowing it to be accessed */
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
{
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Get inquiry data from the device */
SCSI_Inquiry_Response_t InquiryData;
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
{
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Print vendor and product names of attached device */
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
/* Wait until disk ready */
puts_P(PSTR("Waiting until ready.."));
for (;;)
{
Serial_TxByte('.');
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
/* Check to see if the attached device is ready for new commands */
ErrorCode = MassStore_TestUnitReady(0);
/* If attached device is ready, abort the loop */
if (!(ErrorCode))
break;
/* If an error other than a logical command failure (indicating device busy) returned, abort */
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
{
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
}
puts_P(PSTR("\r\nRetrieving Capacity... "));
/* Create new structure for the disk's capacity in blocks and block size */
SCSI_Capacity_t DiskCapacity;
/* Retrieve disk capacity */
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
{
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Display the disk capacity in blocks * block size bytes */
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
/* Create a new buffer capable of holding a single block from the device */
uint8_t BlockBuffer[DiskCapacity.BlockSize];
/* Read in the first 512 byte block from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("\r\nContents of first block:\r\n"));
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
{
/* Pointer to the start of the current 16-byte chunk in the read block of data */
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
/* Print out the 16 bytes of the chunk in HEX format */
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
{
char CurrByte = *(ChunkPtr + ByteOffset);
printf_P(PSTR("%.2X "), CurrByte);
}
puts_P(PSTR(" "));
/* Print out the 16 bytes of the chunk in ASCII format */
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
{
char CurrByte = *(ChunkPtr + ByteOffset);
putchar(isprint(CurrByte) ? CurrByte : '.');
}
puts_P(PSTR("\r\n"));
}
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
/* Wait for the board button to be pressed */
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
{
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
}
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
/* Print out the entire disk contents in ASCII format */
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
{
/* Read in the next block of data from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Send the ASCII data in the read in block to the serial port */
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
{
char CurrByte = BlockBuffer[Byte];
putchar(isprint(CurrByte) ? CurrByte : '.');
}
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
}
/* Indicate device no longer busy */
LEDs_SetAllLEDs(LEDMASK_USB_READY);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
}
/** Indicates that a communication error has occurred with the attached Mass Storage Device,
* printing error codes to the serial port and waiting until the device is removed before
* continuing.
*
* \param[in] CommandString ASCII string located in PROGMEM space indicating what operation failed
* \param[in] ErrorCode Error code of the function which failed to complete successfully
*/
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode)
{
if (ErrorCode == MASS_STORE_SCSI_COMMAND_FAILED)
{
/* Display the error code */
printf_P(PSTR(ESC_FG_RED "SCSI command error (%S).\r\n"), CommandString);
}
else
{
/* Display the error code */
printf_P(PSTR(ESC_FG_RED "Command error (%S).\r\n"), CommandString);
printf_P(PSTR(" -- Error Code: %d" ESC_FG_WHITE), ErrorCode);
}
Pipe_Freeze();
/* Indicate device error via the status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the MassStorageHost demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#include "MassStorageHost.h"
/** Index of the highest available LUN (Logical Unit) in the attached Mass Storage Device */
uint8_t MassStore_MaxLUNIndex;
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "Mass Storage Host Demo running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
MassStorage_Task();
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
SerialStream_Init(9600, false);
LEDs_Init();
Buttons_Init();
USB_Init();
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_ShutDown();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Task to set the configuration of the attached device after it has been enumerated, and to read in blocks from
* the device and print them to the serial port.
*/
void MassStorage_Task(void)
{
uint8_t ErrorCode;
switch (USB_HostState)
{
case HOST_STATE_Addressed:
puts_P(PSTR("Getting Config Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
{
if (ErrorCode == ControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
{
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
/* Indicate device busy via the status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
/* Send the request, display error and wait for device detach if request fails */
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Print number of LUNs detected in the attached device */
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
/* Reset the Mass Storage device interface, ready for use */
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Get sense data from the device - many devices will not accept any other commands until the sense data
* is read - both on start-up and after a failed command */
SCSI_Request_Sense_Response_t SenseData;
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
{
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Set the prevent removal flag for the device, allowing it to be accessed */
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
{
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Get inquiry data from the device */
SCSI_Inquiry_Response_t InquiryData;
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
{
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Print vendor and product names of attached device */
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
/* Wait until disk ready */
puts_P(PSTR("Waiting until ready.."));
for (;;)
{
Serial_TxByte('.');
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
/* Check to see if the attached device is ready for new commands */
ErrorCode = MassStore_TestUnitReady(0);
/* If attached device is ready, abort the loop */
if (!(ErrorCode))
break;
/* If an error other than a logical command failure (indicating device busy) returned, abort */
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
{
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
}
puts_P(PSTR("\r\nRetrieving Capacity... "));
/* Create new structure for the disk's capacity in blocks and block size */
SCSI_Capacity_t DiskCapacity;
/* Retrieve disk capacity */
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
{
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Display the disk capacity in blocks * block size bytes */
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
/* Create a new buffer capable of holding a single block from the device */
uint8_t BlockBuffer[DiskCapacity.BlockSize];
/* Read in the first 512 byte block from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("\r\nContents of first block:\r\n"));
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
{
/* Pointer to the start of the current 16-byte chunk in the read block of data */
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
/* Print out the 16 bytes of the chunk in HEX format */
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
{
char CurrByte = *(ChunkPtr + ByteOffset);
printf_P(PSTR("%.2X "), CurrByte);
}
puts_P(PSTR(" "));
/* Print out the 16 bytes of the chunk in ASCII format */
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
{
char CurrByte = *(ChunkPtr + ByteOffset);
putchar(isprint(CurrByte) ? CurrByte : '.');
}
puts_P(PSTR("\r\n"));
}
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
/* Wait for the board button to be pressed */
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
{
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
}
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
/* Print out the entire disk contents in ASCII format */
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
{
/* Read in the next block of data from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Send the ASCII data in the read in block to the serial port */
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
{
char CurrByte = BlockBuffer[Byte];
putchar(isprint(CurrByte) ? CurrByte : '.');
}
/* Abort if device removed */
if (USB_HostState == HOST_STATE_Unattached)
break;
}
/* Indicate device no longer busy */
LEDs_SetAllLEDs(LEDMASK_USB_READY);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
}
/** Indicates that a communication error has occurred with the attached Mass Storage Device,
* printing error codes to the serial port and waiting until the device is removed before
* continuing.
*
* \param[in] CommandString ASCII string located in PROGMEM space indicating what operation failed
* \param[in] ErrorCode Error code of the function which failed to complete successfully
*/
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode)
{
if (ErrorCode == MASS_STORE_SCSI_COMMAND_FAILED)
{
/* Display the error code */
printf_P(PSTR(ESC_FG_RED "SCSI command error (%S).\r\n"), CommandString);
}
else
{
/* Display the error code */
printf_P(PSTR(ESC_FG_RED "Command error (%S).\r\n"), CommandString);
printf_P(PSTR(" -- Error Code: %d" ESC_FG_WHITE), ErrorCode);
}
Pipe_Freeze();
/* Indicate device error via the status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}

View file

@ -1,88 +1,88 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for MassStoreHost.c.
*/
#ifndef _MASS_STORE_HOST_H_
#define _MASS_STORE_HOST_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ConfigDescriptor.h"
#include "Lib/MassStoreCommands.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
/* Function Prototypes: */
void MassStorage_Task(void);
void SetupHardware(void);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 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
without fee, provided that the above copyright notice appear in
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
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for MassStoreHost.c.
*/
#ifndef _MASS_STORE_HOST_H_
#define _MASS_STORE_HOST_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ConfigDescriptor.h"
#include "Lib/MassStoreCommands.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
/* Function Prototypes: */
void MassStorage_Task(void);
void SetupHardware(void);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode);
#endif

View file

@ -1,67 +1,67 @@
/** \file
*
* This file contains special DoxyGen information for the generation of the main page and other special
* documentation pages. It is not a project source file.
*/
/** \mainpage Mass Storage Host Demo
*
* \section SSec_Compat Demo Compatibility:
*
* The following list indicates what microcontrollers are compatible with this demo.
*
* - Series 7 USB AVRs
*
* \section SSec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this demo.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host</td>
* </tr>
* <tr>
* <td><b>USB Class:</b></td>
* <td>Mass Storage Device</td>
* </tr>
* <tr>
* <td><b>USB Subclass:</b></td>
* <td>Bulk Only</td>
* </tr>
* <tr>
* <td><b>Relevant Standards:</b></td>
* <td>USBIF Mass Storage Standard \n
* USB Bulk-Only Transport Standard \n
* SCSI Primary Commands Specification \n
* SCSI Block Commands Specification</td>
* </tr>
* <tr>
* <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td>
* </tr>
* </table>
*
* \section SSec_Description Project Description:
*
* Mass Storage host demonstration application. This gives a simple reference
* application for implementing a USB Mass Storage host, for USB storage devices
* using the standard Mass Storage USB profile.
*
* The first 512 bytes (boot sector) of an attached disk's memory will be dumped
* out of the serial port in HEX and ASCII form when it is attached to the AT90USB1287
* AVR. The device will then wait for HWB to be pressed, whereupon the entire ASCII contents
* of the disk will be dumped to the serial port.
*
* \section SSec_Options Project Options
*
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
*
* <table>
* <tr>
* <td>
* None
* </td>
* </tr>
* </table>
/** \file
*
* This file contains special DoxyGen information for the generation of the main page and other special
* documentation pages. It is not a project source file.
*/
/** \mainpage Mass Storage Host Demo
*
* \section SSec_Compat Demo Compatibility:
*
* The following list indicates what microcontrollers are compatible with this demo.
*
* - Series 7 USB AVRs
*
* \section SSec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this demo.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host</td>
* </tr>
* <tr>
* <td><b>USB Class:</b></td>
* <td>Mass Storage Device</td>
* </tr>
* <tr>
* <td><b>USB Subclass:</b></td>
* <td>Bulk Only</td>
* </tr>
* <tr>
* <td><b>Relevant Standards:</b></td>
* <td>USBIF Mass Storage Standard \n
* USB Bulk-Only Transport Standard \n
* SCSI Primary Commands Specification \n
* SCSI Block Commands Specification</td>
* </tr>
* <tr>
* <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td>
* </tr>
* </table>
*
* \section SSec_Description Project Description:
*
* Mass Storage host demonstration application. This gives a simple reference
* application for implementing a USB Mass Storage host, for USB storage devices
* using the standard Mass Storage USB profile.
*
* The first 512 bytes (boot sector) of an attached disk's memory will be dumped
* out of the serial port in HEX and ASCII form when it is attached to the AT90USB1287
* AVR. The device will then wait for HWB to be pressed, whereupon the entire ASCII contents
* of the disk will be dumped to the serial port.
*
* \section SSec_Options Project Options
*
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
*
* <table>
* <tr>
* <td>
* None
* </td>
* </tr>
* </table>
*/

File diff suppressed because it is too large Load diff