mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Add the start of a new Mass Storage class bootloader.
This commit is contained in:
		
							parent
							
								
									57071dea22
								
							
						
					
					
						commit
						64f17a679f
					
				
							
								
								
									
										93
									
								
								Bootloaders/Incomplete/MassStorage/Config/LUFAConfig.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Bootloaders/Incomplete/MassStorage/Config/LUFAConfig.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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
 | ||||||
|  |  *  \brief LUFA Library Configuration Header File | ||||||
|  |  * | ||||||
|  |  *  This header file is used to configure LUFA's compile time options, | ||||||
|  |  *  as an alternative to the compile time constants supplied through | ||||||
|  |  *  a makefile. | ||||||
|  |  * | ||||||
|  |  *  For information on what each token does, refer to the LUFA | ||||||
|  |  *  manual section "Summary of Compile Tokens". | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _LUFA_CONFIG_H_ | ||||||
|  | #define _LUFA_CONFIG_H_ | ||||||
|  | 
 | ||||||
|  | 	#if (ARCH == ARCH_AVR8) | ||||||
|  | 
 | ||||||
|  | 		/* Non-USB Related Configuration Tokens: */ | ||||||
|  | //		#define DISABLE_TERMINAL_CODES
 | ||||||
|  | 
 | ||||||
|  | 		/* USB Class Driver Related Tokens: */ | ||||||
|  | //		#define HID_HOST_BOOT_PROTOCOL_ONLY
 | ||||||
|  | //		#define HID_STATETABLE_STACK_DEPTH       {Insert Value Here}
 | ||||||
|  | //		#define HID_USAGE_STACK_DEPTH            {Insert Value Here}
 | ||||||
|  | //		#define HID_MAX_COLLECTIONS              {Insert Value Here}
 | ||||||
|  | //		#define HID_MAX_REPORTITEMS              {Insert Value Here}
 | ||||||
|  | //		#define HID_MAX_REPORT_IDS               {Insert Value Here}
 | ||||||
|  | //		#define NO_CLASS_DRIVER_AUTOFLUSH
 | ||||||
|  | 
 | ||||||
|  | 		/* General USB Driver Related Tokens: */ | ||||||
|  | //		#define ORDERED_EP_CONFIG
 | ||||||
|  | 		#define USE_STATIC_OPTIONS               (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) | ||||||
|  | 		#define USB_DEVICE_ONLY | ||||||
|  | //		#define USB_HOST_ONLY
 | ||||||
|  | //		#define USB_STREAM_TIMEOUT_MS            {Insert Value Here}
 | ||||||
|  | //		#define NO_LIMITED_CONTROLLER_CONNECT
 | ||||||
|  | //		#define NO_SOF_EVENTS
 | ||||||
|  | 
 | ||||||
|  | 		/* USB Device Mode Driver Related Tokens: */ | ||||||
|  | 		#define USE_RAM_DESCRIPTORS | ||||||
|  | //		#define USE_FLASH_DESCRIPTORS
 | ||||||
|  | //		#define USE_EEPROM_DESCRIPTORS
 | ||||||
|  | //		#define NO_INTERNAL_SERIAL
 | ||||||
|  | 		#define FIXED_CONTROL_ENDPOINT_SIZE      8 | ||||||
|  | //		#define DEVICE_STATE_AS_GPIOR            {Insert Value Here}
 | ||||||
|  | 		#define FIXED_NUM_CONFIGURATIONS         1 | ||||||
|  | //		#define CONTROL_ONLY_DEVICE
 | ||||||
|  | 		#define INTERRUPT_CONTROL_ENDPOINT | ||||||
|  | //		#define NO_DEVICE_REMOTE_WAKEUP
 | ||||||
|  | //		#define NO_DEVICE_SELF_POWER
 | ||||||
|  | 
 | ||||||
|  | 		/* USB Host Mode Driver Related Tokens: */ | ||||||
|  | //		#define HOST_STATE_AS_GPIOR              {Insert Value Here}
 | ||||||
|  | //		#define USB_HOST_TIMEOUT_MS              {Insert Value Here}
 | ||||||
|  | //		#define HOST_DEVICE_SETTLE_DELAY_MS	     {Insert Value Here}
 | ||||||
|  | //		#define NO_AUTO_VBUS_MANAGEMENT
 | ||||||
|  | //		#define INVERTED_VBUS_ENABLE_LINE
 | ||||||
|  | 
 | ||||||
|  | 	#else | ||||||
|  | 
 | ||||||
|  | 		#error Unsupported architecture for this LUFA configuration file. | ||||||
|  | 
 | ||||||
|  | 	#endif | ||||||
|  | #endif | ||||||
							
								
								
									
										209
									
								
								Bootloaders/Incomplete/MassStorage/Descriptors.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								Bootloaders/Incomplete/MassStorage/Descriptors.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,209 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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 Descriptors, for library use when in USB device mode. Descriptors are special | ||||||
|  |  *  computer-readable structures which the host requests upon device enumeration, to determine | ||||||
|  |  *  the device's capabilities and functions. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "Descriptors.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
 | ||||||
|  |  *  device characteristics, including the supported USB version, control endpoint size and the | ||||||
|  |  *  number of device configurations. The descriptor is read out by the USB host when the enumeration | ||||||
|  |  *  process begins. | ||||||
|  |  */ | ||||||
|  | const USB_Descriptor_Device_t DeviceDescriptor = | ||||||
|  | { | ||||||
|  | 	.Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | ||||||
|  | 
 | ||||||
|  | 	.USBSpecification       = VERSION_BCD(01.10), | ||||||
|  | 	.Class                  = USB_CSCP_NoDeviceClass, | ||||||
|  | 	.SubClass               = USB_CSCP_NoDeviceSubclass, | ||||||
|  | 	.Protocol               = USB_CSCP_NoDeviceProtocol, | ||||||
|  | 
 | ||||||
|  | 	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE, | ||||||
|  | 
 | ||||||
|  | 	.VendorID               = 0x03EB, | ||||||
|  | 	.ProductID              = 0x2045, | ||||||
|  | 	.ReleaseNumber          = VERSION_BCD(00.01), | ||||||
|  | 
 | ||||||
|  | 	.ManufacturerStrIndex   = 0x01, | ||||||
|  | 	.ProductStrIndex        = 0x02, | ||||||
|  | 	.SerialNumStrIndex      = USE_INTERNAL_SERIAL, | ||||||
|  | 
 | ||||||
|  | 	.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
 | ||||||
|  |  *  of the device in one of its supported configurations, including information about any device interfaces | ||||||
|  |  *  and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | ||||||
|  |  *  a configuration so that the host may correctly communicate with the USB device. | ||||||
|  |  */ | ||||||
|  | const USB_Descriptor_Configuration_t ConfigurationDescriptor = | ||||||
|  | { | ||||||
|  | 	.Config = | ||||||
|  | 		{ | ||||||
|  | 			.Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | ||||||
|  | 
 | ||||||
|  | 			.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | ||||||
|  | 			.TotalInterfaces        = 1, | ||||||
|  | 
 | ||||||
|  | 			.ConfigurationNumber    = 1, | ||||||
|  | 			.ConfigurationStrIndex  = NO_DESCRIPTOR, | ||||||
|  | 
 | ||||||
|  | 			.ConfigAttributes       = USB_CONFIG_ATTR_RESERVED, | ||||||
|  | 
 | ||||||
|  | 			.MaxPowerConsumption    = USB_CONFIG_POWER_MA(100) | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 	.MS_Interface = | ||||||
|  | 		{ | ||||||
|  | 			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | ||||||
|  | 
 | ||||||
|  | 			.InterfaceNumber        = 0, | ||||||
|  | 			.AlternateSetting       = 0, | ||||||
|  | 
 | ||||||
|  | 			.TotalEndpoints         = 2, | ||||||
|  | 
 | ||||||
|  | 			.Class                  = MS_CSCP_MassStorageClass, | ||||||
|  | 			.SubClass               = MS_CSCP_SCSITransparentSubclass, | ||||||
|  | 			.Protocol               = MS_CSCP_BulkOnlyTransportProtocol, | ||||||
|  | 
 | ||||||
|  | 			.InterfaceStrIndex      = NO_DESCRIPTOR | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 	.MS_DataInEndpoint = | ||||||
|  | 		{ | ||||||
|  | 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | ||||||
|  | 
 | ||||||
|  | 			.EndpointAddress        = MASS_STORAGE_IN_EPADDR, | ||||||
|  | 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | ||||||
|  | 			.EndpointSize           = MASS_STORAGE_IO_EPSIZE, | ||||||
|  | 			.PollingIntervalMS      = 0x05 | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 	.MS_DataOutEndpoint = | ||||||
|  | 		{ | ||||||
|  | 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | ||||||
|  | 
 | ||||||
|  | 			.EndpointAddress        = MASS_STORAGE_OUT_EPADDR, | ||||||
|  | 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | ||||||
|  | 			.EndpointSize           = MASS_STORAGE_IO_EPSIZE, | ||||||
|  | 			.PollingIntervalMS      = 0x05 | ||||||
|  | 		} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
 | ||||||
|  |  *  the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate | ||||||
|  |  *  via the language ID table available at USB.org what languages the device supports for its string descriptors. | ||||||
|  |  */ | ||||||
|  | const USB_Descriptor_String_t LanguageString = | ||||||
|  | { | ||||||
|  | 	.Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, | ||||||
|  | 
 | ||||||
|  | 	.UnicodeString          = {LANGUAGE_ID_ENG} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
 | ||||||
|  |  *  form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | ||||||
|  |  *  Descriptor. | ||||||
|  |  */ | ||||||
|  | const USB_Descriptor_String_t ManufacturerString = | ||||||
|  | { | ||||||
|  | 	.Header                 = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, | ||||||
|  | 
 | ||||||
|  | 	.UnicodeString          = L"Dean Camera" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
 | ||||||
|  |  *  and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | ||||||
|  |  *  Descriptor. | ||||||
|  |  */ | ||||||
|  | const USB_Descriptor_String_t ProductString = | ||||||
|  | { | ||||||
|  | 	.Header                 = {.Size = USB_STRING_LEN(15), .Type = DTYPE_String}, | ||||||
|  | 
 | ||||||
|  | 	.UnicodeString          = L"LUFA Bootloader" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
 | ||||||
|  |  *  documentation) by the application code so that the address and size of a requested descriptor can be given | ||||||
|  |  *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | ||||||
|  |  *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | ||||||
|  |  *  USB host. | ||||||
|  |  */ | ||||||
|  | uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||||
|  |                                     const uint8_t wIndex, | ||||||
|  |                                     const void** const DescriptorAddress) | ||||||
|  | { | ||||||
|  | 	const uint8_t  DescriptorType   = (wValue >> 8); | ||||||
|  | 	const uint8_t  DescriptorNumber = (wValue & 0xFF); | ||||||
|  | 
 | ||||||
|  | 	const void* Address = NULL; | ||||||
|  | 	uint16_t    Size    = NO_DESCRIPTOR; | ||||||
|  | 
 | ||||||
|  | 	switch (DescriptorType) | ||||||
|  | 	{ | ||||||
|  | 		case DTYPE_Device: | ||||||
|  | 			Address = &DeviceDescriptor; | ||||||
|  | 			Size    = sizeof(USB_Descriptor_Device_t); | ||||||
|  | 			break; | ||||||
|  | 		case DTYPE_Configuration: | ||||||
|  | 			Address = &ConfigurationDescriptor; | ||||||
|  | 			Size    = sizeof(USB_Descriptor_Configuration_t); | ||||||
|  | 			break; | ||||||
|  | 		case DTYPE_String: | ||||||
|  | 			switch (DescriptorNumber) | ||||||
|  | 			{ | ||||||
|  | 				case 0x00: | ||||||
|  | 					Address = &LanguageString; | ||||||
|  | 					Size    = pgm_read_byte(&LanguageString.Header.Size); | ||||||
|  | 					break; | ||||||
|  | 				case 0x01: | ||||||
|  | 					Address = &ManufacturerString; | ||||||
|  | 					Size    = pgm_read_byte(&ManufacturerString.Header.Size); | ||||||
|  | 					break; | ||||||
|  | 				case 0x02: | ||||||
|  | 					Address = &ProductString; | ||||||
|  | 					Size    = pgm_read_byte(&ProductString.Header.Size); | ||||||
|  | 					break; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*DescriptorAddress = Address; | ||||||
|  | 	return Size; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										76
									
								
								Bootloaders/Incomplete/MassStorage/Descriptors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Bootloaders/Incomplete/MassStorage/Descriptors.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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 Descriptors.c. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _DESCRIPTORS_H_ | ||||||
|  | #define _DESCRIPTORS_H_ | ||||||
|  | 
 | ||||||
|  | 	/* Includes: */ | ||||||
|  | 		#include <avr/pgmspace.h> | ||||||
|  | 
 | ||||||
|  | 		#include <LUFA/Drivers/USB/USB.h> | ||||||
|  | 
 | ||||||
|  | 	/* Macros: */ | ||||||
|  | 		/** Endpoint address of the Mass Storage device-to-host data IN endpoint. */ | ||||||
|  | 		#define MASS_STORAGE_IN_EPADDR         (ENDPOINT_DIR_IN  | 3) | ||||||
|  | 
 | ||||||
|  | 		/** Endpoint address of the Mass Storage host-to-device data OUT endpoint. */ | ||||||
|  | 		#define MASS_STORAGE_OUT_EPADDR        (ENDPOINT_DIR_OUT | 4) | ||||||
|  | 
 | ||||||
|  | 		/** Size in bytes of the Mass Storage data endpoints. */ | ||||||
|  | 		#define MASS_STORAGE_IO_EPSIZE         64 | ||||||
|  | 
 | ||||||
|  | 	/* Type Defines: */ | ||||||
|  | 		/** Type define for the device configuration descriptor structure. This must be defined in the
 | ||||||
|  | 		 *  application code, as the configuration descriptor contains several sub-descriptors which | ||||||
|  | 		 *  vary between devices, and which describe the device's usage to the host. | ||||||
|  | 		 */ | ||||||
|  | 		typedef struct | ||||||
|  | 		{ | ||||||
|  | 			USB_Descriptor_Configuration_Header_t Config; | ||||||
|  | 
 | ||||||
|  | 			// Mass Storage Interface
 | ||||||
|  | 			USB_Descriptor_Interface_t            MS_Interface; | ||||||
|  | 			USB_Descriptor_Endpoint_t             MS_DataInEndpoint; | ||||||
|  | 			USB_Descriptor_Endpoint_t             MS_DataOutEndpoint; | ||||||
|  | 		} USB_Descriptor_Configuration_t; | ||||||
|  | 
 | ||||||
|  | 	/* Function Prototypes: */ | ||||||
|  | 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||||
|  | 		                                    const uint8_t wIndex, | ||||||
|  | 		                                    const void** const DescriptorAddress) | ||||||
|  | 		                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
							
								
								
									
										321
									
								
								Bootloaders/Incomplete/MassStorage/Lib/SCSI.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								Bootloaders/Incomplete/MassStorage/Lib/SCSI.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,321 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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
 | ||||||
|  |  * | ||||||
|  |  *  SCSI command processing routines, for SCSI commands issued by the host. Mass Storage | ||||||
|  |  *  devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information, | ||||||
|  |  *  which wrap around standard SCSI device commands for controlling the actual storage medium. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define  INCLUDE_FROM_SCSI_C | ||||||
|  | #include "SCSI.h" | ||||||
|  | 
 | ||||||
|  | /** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
 | ||||||
|  |  *  features and capabilities. | ||||||
|  |  */ | ||||||
|  | static const SCSI_Inquiry_Response_t InquiryData = | ||||||
|  | 	{ | ||||||
|  | 		.DeviceType          = DEVICE_TYPE_BLOCK, | ||||||
|  | 		.PeripheralQualifier = 0, | ||||||
|  | 
 | ||||||
|  | 		.Removable           = true, | ||||||
|  | 
 | ||||||
|  | 		.Version             = 0, | ||||||
|  | 
 | ||||||
|  | 		.ResponseDataFormat  = 2, | ||||||
|  | 		.NormACA             = false, | ||||||
|  | 		.TrmTsk              = false, | ||||||
|  | 		.AERC                = false, | ||||||
|  | 
 | ||||||
|  | 		.AdditionalLength    = 0x1F, | ||||||
|  | 
 | ||||||
|  | 		.SoftReset           = false, | ||||||
|  | 		.CmdQue              = false, | ||||||
|  | 		.Linked              = false, | ||||||
|  | 		.Sync                = false, | ||||||
|  | 		.WideBus16Bit        = false, | ||||||
|  | 		.WideBus32Bit        = false, | ||||||
|  | 		.RelAddr             = false, | ||||||
|  | 
 | ||||||
|  | 		.VendorID            = "LUFA", | ||||||
|  | 		.ProductID           = "Bootloader", | ||||||
|  | 		.RevisionID          = {'0','.','0','0'}, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | /** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
 | ||||||
|  |  *  command is issued. This gives information on exactly why the last command failed to complete. | ||||||
|  |  */ | ||||||
|  | static SCSI_Request_Sense_Response_t SenseData = | ||||||
|  | 	{ | ||||||
|  | 		.ResponseCode        = 0x70, | ||||||
|  | 		.AdditionalLength    = 0x0A, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
 | ||||||
|  |  *  to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns | ||||||
|  |  *  a command failure due to a ILLEGAL REQUEST. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise | ||||||
|  |  */ | ||||||
|  | bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	bool CommandSuccess = false; | ||||||
|  | 
 | ||||||
|  | 	/* Run the appropriate SCSI command hander function based on the passed command */ | ||||||
|  | 	switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0]) | ||||||
|  | 	{ | ||||||
|  | 		case SCSI_CMD_INQUIRY: | ||||||
|  | 			CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_REQUEST_SENSE: | ||||||
|  | 			CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_READ_CAPACITY_10: | ||||||
|  | 			CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_SEND_DIAGNOSTIC: | ||||||
|  | 			CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_WRITE_10: | ||||||
|  | 			CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_READ_10: | ||||||
|  | 			CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_MODE_SENSE_6: | ||||||
|  | 			CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo); | ||||||
|  | 			break; | ||||||
|  | 		case SCSI_CMD_TEST_UNIT_READY: | ||||||
|  | 		case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: | ||||||
|  | 		case SCSI_CMD_VERIFY_10: | ||||||
|  | 			/* These commands should just succeed, no handling required */ | ||||||
|  | 			CommandSuccess = true; | ||||||
|  | 			MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			/* Update the SENSE key to reflect the invalid command */ | ||||||
|  | 			SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | ||||||
|  | 		                   SCSI_ASENSE_INVALID_COMMAND, | ||||||
|  | 		                   SCSI_ASENSEQ_NO_QUALIFIER); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Check if command was successfully processed */ | ||||||
|  | 	if (CommandSuccess) | ||||||
|  | 	{ | ||||||
|  | 		SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD, | ||||||
|  | 		               SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, | ||||||
|  | 		               SCSI_ASENSEQ_NO_QUALIFIER); | ||||||
|  | 
 | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
 | ||||||
|  |  *  and capabilities to the host. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	uint16_t AllocationLength  = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]); | ||||||
|  | 	uint16_t BytesTransferred  = MIN(AllocationLength, sizeof(InquiryData)); | ||||||
|  | 
 | ||||||
|  | 	/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */ | ||||||
|  | 	if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) || | ||||||
|  | 	     MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]) | ||||||
|  | 	{ | ||||||
|  | 		/* Optional but unsupported bits set - update the SENSE key and fail the request */ | ||||||
|  | 		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | ||||||
|  | 		               SCSI_ASENSE_INVALID_FIELD_IN_CDB, | ||||||
|  | 		               SCSI_ASENSEQ_NO_QUALIFIER); | ||||||
|  | 
 | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NULL); | ||||||
|  | 
 | ||||||
|  | 	/* Pad out remaining bytes with 0x00 */ | ||||||
|  | 	Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL); | ||||||
|  | 
 | ||||||
|  | 	/* Finalize the stream transfer to send the last packet */ | ||||||
|  | 	Endpoint_ClearIN(); | ||||||
|  | 
 | ||||||
|  | 	/* Succeed the command and update the bytes transferred counter */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
 | ||||||
|  |  *  including the error code and additional error information so that the host can determine why a command failed to complete. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; | ||||||
|  | 	uint8_t BytesTransferred = MIN(AllocationLength, sizeof(SenseData)); | ||||||
|  | 
 | ||||||
|  | 	Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NULL); | ||||||
|  | 	Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL); | ||||||
|  | 	Endpoint_ClearIN(); | ||||||
|  | 
 | ||||||
|  | 	/* Succeed the command and update the bytes transferred counter */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
 | ||||||
|  |  *  on the selected Logical Unit (drive), as a number of OS-sized blocks. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1); | ||||||
|  | 	uint32_t MediaBlockSize        = VIRTUAL_MEMORY_BLOCK_SIZE; | ||||||
|  | 
 | ||||||
|  | 	Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NULL); | ||||||
|  | 	Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NULL); | ||||||
|  | 	Endpoint_ClearIN(); | ||||||
|  | 
 | ||||||
|  | 	/* Succeed the command and update the bytes transferred counter */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
 | ||||||
|  |  *  board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is | ||||||
|  |  *  supported. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	/* Check to see if the SELF TEST bit is not set */ | ||||||
|  | 	if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) | ||||||
|  | 	{ | ||||||
|  | 		/* Only self-test supported - update SENSE key and fail the command */ | ||||||
|  | 		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | ||||||
|  | 		               SCSI_ASENSE_INVALID_FIELD_IN_CDB, | ||||||
|  | 		               SCSI_ASENSEQ_NO_QUALIFIER); | ||||||
|  | 
 | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Succeed the command and update the bytes transferred counter */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
 | ||||||
|  |  *  and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual | ||||||
|  |  *  reading and writing of the data. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  *  \param[in] IsDataRead  Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  |                                       const bool IsDataRead) | ||||||
|  | { | ||||||
|  | 	uint32_t BlockAddress; | ||||||
|  | 	uint16_t TotalBlocks; | ||||||
|  | 
 | ||||||
|  | 	/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */ | ||||||
|  | 	BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); | ||||||
|  | 
 | ||||||
|  | 	/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ | ||||||
|  | 	TotalBlocks  = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); | ||||||
|  | 
 | ||||||
|  | 	/* Check if the block address is outside the maximum allowable value for the LUN */ | ||||||
|  | 	if (BlockAddress >= LUN_MEDIA_BLOCKS) | ||||||
|  | 	{ | ||||||
|  | 		/* Block address is invalid, update SENSE key and return command fail */ | ||||||
|  | 		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, | ||||||
|  | 		               SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, | ||||||
|  | 		               SCSI_ASENSEQ_NO_QUALIFIER); | ||||||
|  | 
 | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ | ||||||
|  | 	if (IsDataRead == DATA_READ) | ||||||
|  | 	  VirtualFAT_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); | ||||||
|  | 	else | ||||||
|  | 	  VirtualFAT_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); | ||||||
|  | 
 | ||||||
|  | 	/* Update the bytes transferred counter and succeed the command */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
 | ||||||
|  |  *  the SCSI device, as well as the device's Write Protect status. | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with | ||||||
|  |  * | ||||||
|  |  *  \return Boolean true if the command completed successfully, false otherwise. | ||||||
|  |  */ | ||||||
|  | static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	/* Send an empty header response with the Write Protect flag status */ | ||||||
|  | 	Endpoint_Write_8(0x00); | ||||||
|  | 	Endpoint_Write_8(0x00); | ||||||
|  | 	Endpoint_Write_8(0x00); | ||||||
|  | 	Endpoint_Write_8(0x00); | ||||||
|  | 	Endpoint_ClearIN(); | ||||||
|  | 
 | ||||||
|  | 	/* Update the bytes transferred counter and succeed the command */ | ||||||
|  | 	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										85
									
								
								Bootloaders/Incomplete/MassStorage/Lib/SCSI.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								Bootloaders/Incomplete/MassStorage/Lib/SCSI.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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 SCSI.c. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _SCSI_H_ | ||||||
|  | #define _SCSI_H_ | ||||||
|  | 
 | ||||||
|  | 	/* Includes: */ | ||||||
|  | 		#include <avr/io.h> | ||||||
|  | 		#include <avr/pgmspace.h> | ||||||
|  | 
 | ||||||
|  | 		#include <LUFA/Drivers/USB/USB.h> | ||||||
|  | 
 | ||||||
|  | 		#include "../MassStorage.h" | ||||||
|  | 		#include "../Descriptors.h" | ||||||
|  | 		#include "VirtualFAT.h" | ||||||
|  | 
 | ||||||
|  | 	/* Macros: */ | ||||||
|  | 		/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
 | ||||||
|  | 		 *  is for convenience, as it allows for all three sense values (returned upon request to the host to give information about | ||||||
|  | 		 *  the last command failure) in a quick and easy manner. | ||||||
|  | 		 * | ||||||
|  | 		 *  \param[in] Key    New SCSI sense key to set the sense code to | ||||||
|  | 		 *  \param[in] Acode  New SCSI additional sense key to set the additional sense code to | ||||||
|  | 		 *  \param[in] Aqual  New SCSI additional sense key qualifier to set the additional sense qualifier code to | ||||||
|  | 		 */ | ||||||
|  | 		#define SCSI_SET_SENSE(Key, Acode, Aqual)  MACROS{ SenseData.SenseKey                 = (Key);   \ | ||||||
|  | 		                                                   SenseData.AdditionalSenseCode      = (Acode); \ | ||||||
|  | 		                                                   SenseData.AdditionalSenseQualifier = (Aqual); }MACROE | ||||||
|  | 
 | ||||||
|  | 		/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */ | ||||||
|  | 		#define DATA_READ           true | ||||||
|  | 
 | ||||||
|  | 		/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */ | ||||||
|  | 		#define DATA_WRITE          false | ||||||
|  | 
 | ||||||
|  | 		/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */ | ||||||
|  | 		#define DEVICE_TYPE_BLOCK   0x00 | ||||||
|  | 
 | ||||||
|  | 	/* Function Prototypes: */ | ||||||
|  | 		bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 
 | ||||||
|  | 		#if defined(INCLUDE_FROM_SCSI_C) | ||||||
|  | 			static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 			static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 			static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 			static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 			static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  | 			                                      const bool IsDataRead); | ||||||
|  | 			static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 		#endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
							
								
								
									
										154
									
								
								Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "VirtualFAT.h" | ||||||
|  | 
 | ||||||
|  | static const FATBootBlock_t BootBlock = | ||||||
|  | 	{ | ||||||
|  | 		.Bootstrap               = {0xEB, 0x3C, 0x90}, | ||||||
|  | 		.Description             = "mkdosfs", | ||||||
|  | 		.BlockSize               = VIRTUAL_MEMORY_BLOCK_SIZE, | ||||||
|  | 		.BlocksPerAllocationUnit = ALLOCATION_UNIT_BLOCKS, | ||||||
|  | 		.ReservedBlocks          = 1, | ||||||
|  | 		.FATCopies               = 2, | ||||||
|  | 		.RootDirectoryEntries    = 512, | ||||||
|  | 		.TotalBlocks16           = LUN_MEDIA_BLOCKS, | ||||||
|  | 		.MediaDescriptor         = 0xF8, | ||||||
|  | 		.BlocksPerFAT            = 1, | ||||||
|  | 		.BlocksPerTrack          = 32, | ||||||
|  | 		.Heads                   = 64, | ||||||
|  | 		.HiddenBlocks            = 0, | ||||||
|  | 		.TotalBlocks32           = 0, | ||||||
|  | 		.PhysicalDriveNum        = 0, | ||||||
|  | 		.ExtendedBootRecordSig   = 0x29, | ||||||
|  | 		.VolumeSerialNumber      = 0x12345678, | ||||||
|  | 		.VolumeLabel             = "LUFA BOOT  ", | ||||||
|  | 		.FilesystemIdentifier    = "FAT16   ", | ||||||
|  | 		.BootstrapProgram        = {0}, | ||||||
|  | 		.MagicSignature          = 0xAA55, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | static FATDirectoryEntry_t FirmwareFileEntry = | ||||||
|  | 	{ | ||||||
|  | 		.Filename        = "Firmware", | ||||||
|  | 		.Extension       = "bin", | ||||||
|  | 		.Attributes      = 0, | ||||||
|  | 		.Reserved        = {0}, | ||||||
|  | 		.CreationTime    = (1 << 11) | (1 << 5), | ||||||
|  | 		.CreationDate    = (9 << 9)  | (2 << 5) | (14 << 0), | ||||||
|  | 		.StartingCluster = 4, | ||||||
|  | 		.FileSize        = (FLASHEND + 1UL), | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | static void WriteBlock(uint16_t BlockNumber) | ||||||
|  | { | ||||||
|  | 	uint8_t BlockBuffer[512]; | ||||||
|  | 
 | ||||||
|  | 	/* Wait until endpoint is ready before continuing */ | ||||||
|  | 	if (Endpoint_WaitUntilReady()) | ||||||
|  | 	  return; | ||||||
|  | 
 | ||||||
|  | 	Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | ||||||
|  | 	Endpoint_ClearOUT(); | ||||||
|  | 
 | ||||||
|  | 	// TODO: Write to FLASH
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void ReadBlock(uint16_t BlockNumber) | ||||||
|  | { | ||||||
|  | 	uint8_t BlockBuffer[512]; | ||||||
|  | 	memset(BlockBuffer, 0x00, sizeof(BlockBuffer)); | ||||||
|  | 
 | ||||||
|  | 	switch (BlockNumber) | ||||||
|  | 	{ | ||||||
|  | 		case 0: | ||||||
|  | 			memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t)); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 1: | ||||||
|  | 		case 2: | ||||||
|  | 			/* Cluster 0: Media type/Reserved */ | ||||||
|  | 			((uint16_t*)&BlockBuffer)[0] = 0xFF00 | BootBlock.MediaDescriptor; | ||||||
|  | 
 | ||||||
|  | 			/* Cluster 1: Reserved */ | ||||||
|  | 			((uint16_t*)&BlockBuffer)[1] = 0xFFFF; | ||||||
|  | 
 | ||||||
|  | 			/* Cluster 2: Reserved */ | ||||||
|  | 			((uint16_t*)&BlockBuffer)[2] = 0xFFFF; | ||||||
|  | 
 | ||||||
|  | 			/* Cluster 3: FIRMWARE.BIN File Entry */ | ||||||
|  | 			((uint16_t*)&BlockBuffer)[3] = 0xFFFF; | ||||||
|  | 
 | ||||||
|  | 			/* Cluster 4 onwards: Cluster chain of FIRMWARE.BIN */ | ||||||
|  | 			for (uint16_t i = 0; i < ((FLASHEND + 1) / (VIRTUAL_MEMORY_BLOCK_SIZE * ALLOCATION_UNIT_BLOCKS)); i++) | ||||||
|  | 			{ | ||||||
|  | 				((uint16_t*)&BlockBuffer)[i + 4] = i + 5; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			/* Mark last cluster as end of file */ | ||||||
|  | 			((uint16_t*)&BlockBuffer)[((FLASHEND + 1) / (VIRTUAL_MEMORY_BLOCK_SIZE * ALLOCATION_UNIT_BLOCKS)) + 4] = 0xFFFF; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 3: | ||||||
|  | 			memcpy(BlockBuffer, &FirmwareFileEntry, sizeof(FATDirectoryEntry_t)); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Wait until endpoint is ready before continuing */ | ||||||
|  | 	if (Endpoint_WaitUntilReady()) | ||||||
|  | 	  return; | ||||||
|  | 
 | ||||||
|  | 	Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL); | ||||||
|  | 	Endpoint_ClearIN(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  |                             const uint32_t BlockAddress, | ||||||
|  |                             uint16_t TotalBlocks) | ||||||
|  | { | ||||||
|  | 	uint16_t CurrentBlock = (uint16_t)BlockAddress; | ||||||
|  | 
 | ||||||
|  | 	while (TotalBlocks--) | ||||||
|  | 	  WriteBlock(CurrentBlock++); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  |                            const uint32_t BlockAddress, | ||||||
|  |                            uint16_t TotalBlocks) | ||||||
|  | { | ||||||
|  | 	uint16_t CurrentBlock = (uint16_t)BlockAddress; | ||||||
|  | 
 | ||||||
|  | 	while (TotalBlocks--) | ||||||
|  | 	  ReadBlock(CurrentBlock++); | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										91
									
								
								Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef _VIRTUALFAT_H_ | ||||||
|  | #define _VIRTUALFAT_H_ | ||||||
|  | 
 | ||||||
|  | 	/* Includes: */ | ||||||
|  | 		#include <avr/io.h> | ||||||
|  | 		#include <avr/pgmspace.h> | ||||||
|  | 
 | ||||||
|  | 		#include <LUFA/Drivers/USB/USB.h> | ||||||
|  | 
 | ||||||
|  | 	/* Macros: */ | ||||||
|  | 		#define VIRTUAL_MEMORY_BLOCK_SIZE 512 | ||||||
|  | 		#define ALLOCATION_UNIT_BLOCKS    4 | ||||||
|  | 		#define LUN_MEDIA_BLOCKS          ((FLASHEND + 1) / VIRTUAL_MEMORY_BLOCK_SIZE) + 16 | ||||||
|  | 
 | ||||||
|  | 	/* Type Definitions: */ | ||||||
|  | 		typedef struct | ||||||
|  | 		{ | ||||||
|  | 			uint8_t  Bootstrap[3]; | ||||||
|  | 			uint8_t  Description[8]; | ||||||
|  | 			uint16_t BlockSize; | ||||||
|  | 			uint8_t  BlocksPerAllocationUnit; | ||||||
|  | 			uint16_t ReservedBlocks; | ||||||
|  | 			uint8_t  FATCopies; | ||||||
|  | 			uint16_t RootDirectoryEntries; | ||||||
|  | 			uint16_t TotalBlocks16; | ||||||
|  | 			uint8_t  MediaDescriptor; | ||||||
|  | 			uint16_t BlocksPerFAT; | ||||||
|  | 			uint16_t BlocksPerTrack; | ||||||
|  | 			uint16_t Heads; | ||||||
|  | 			uint32_t HiddenBlocks; | ||||||
|  | 			uint32_t TotalBlocks32; | ||||||
|  | 			uint16_t PhysicalDriveNum; | ||||||
|  | 			uint8_t  ExtendedBootRecordSig; | ||||||
|  | 			uint32_t VolumeSerialNumber; | ||||||
|  | 			uint8_t  VolumeLabel[11]; | ||||||
|  | 			uint8_t  FilesystemIdentifier[8]; | ||||||
|  | 			uint8_t  BootstrapProgram[448]; | ||||||
|  | 			uint16_t MagicSignature; | ||||||
|  | 		} FATBootBlock_t; | ||||||
|  | 
 | ||||||
|  | 		typedef struct | ||||||
|  | 		{ | ||||||
|  | 			uint8_t Filename[8]; | ||||||
|  | 			uint8_t Extension[3]; | ||||||
|  | 			uint8_t Attributes; | ||||||
|  | 			uint8_t Reserved[10]; | ||||||
|  | 			uint16_t CreationTime; | ||||||
|  | 			uint16_t CreationDate; | ||||||
|  | 			uint16_t StartingCluster; | ||||||
|  | 			uint32_t FileSize; | ||||||
|  | 		} FATDirectoryEntry_t; | ||||||
|  | 
 | ||||||
|  | 	/* Function Prototypes: */ | ||||||
|  | 		void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  | 		                            const uint32_t BlockAddress, | ||||||
|  | 		                            uint16_t TotalBlocks); | ||||||
|  | 
 | ||||||
|  | 		void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, | ||||||
|  | 		                           const uint32_t BlockAddress, | ||||||
|  | 		                           uint16_t TotalBlocks); | ||||||
|  | #endif | ||||||
							
								
								
									
										143
									
								
								Bootloaders/Incomplete/MassStorage/MassStorage.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								Bootloaders/Incomplete/MassStorage/MassStorage.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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 MassStorage demo. This file contains the main tasks of | ||||||
|  |  *  the demo and is responsible for the initial application hardware configuration. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "MassStorage.h" | ||||||
|  | 
 | ||||||
|  | /** LUFA Mass Storage Class driver interface configuration and state information. This structure is
 | ||||||
|  |  *  passed to all Mass Storage Class driver functions, so that multiple instances of the same class | ||||||
|  |  *  within a device can be differentiated from one another. | ||||||
|  |  */ | ||||||
|  | USB_ClassInfo_MS_Device_t Disk_MS_Interface = | ||||||
|  | 	{ | ||||||
|  | 		.Config = | ||||||
|  | 			{ | ||||||
|  | 				.InterfaceNumber           = 0, | ||||||
|  | 				.DataINEndpoint            = | ||||||
|  | 					{ | ||||||
|  | 						.Address           = MASS_STORAGE_IN_EPADDR, | ||||||
|  | 						.Size              = MASS_STORAGE_IO_EPSIZE, | ||||||
|  | 						.Banks             = 1, | ||||||
|  | 					}, | ||||||
|  | 				.DataOUTEndpoint           = | ||||||
|  | 					{ | ||||||
|  | 						.Address           = MASS_STORAGE_OUT_EPADDR, | ||||||
|  | 						.Size              = MASS_STORAGE_IO_EPSIZE, | ||||||
|  | 						.Banks             = 1, | ||||||
|  | 					}, | ||||||
|  | 				.TotalLUNs                 = 1, | ||||||
|  | 			}, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** Main program entry point. This routine contains the overall program flow, including initial
 | ||||||
|  |  *  setup of all components and the main program loop. | ||||||
|  |  */ | ||||||
|  | int main(void) | ||||||
|  | { | ||||||
|  | 	SetupHardware(); | ||||||
|  | 
 | ||||||
|  | 	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | ||||||
|  | 	GlobalInterruptEnable(); | ||||||
|  | 
 | ||||||
|  | 	for (;;) | ||||||
|  | 	{ | ||||||
|  | 		MS_Device_USBTask(&Disk_MS_Interface); | ||||||
|  | 		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); | ||||||
|  | 
 | ||||||
|  | 	/* Relocate the interrupt vector table to the bootloader section */ | ||||||
|  | 	MCUCR = (1 << IVCE); | ||||||
|  | 	MCUCR = (1 << IVSEL); | ||||||
|  | 
 | ||||||
|  | 	/* Hardware Initialization */ | ||||||
|  | 	LEDs_Init(); | ||||||
|  | 	USB_Init(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Event handler for the library USB Connection event. */ | ||||||
|  | void EVENT_USB_Device_Connect(void) | ||||||
|  | { | ||||||
|  | 	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Event handler for the library USB Disconnection event. */ | ||||||
|  | void EVENT_USB_Device_Disconnect(void) | ||||||
|  | { | ||||||
|  | 	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Event handler for the library USB Configuration Changed event. */ | ||||||
|  | void EVENT_USB_Device_ConfigurationChanged(void) | ||||||
|  | { | ||||||
|  | 	bool ConfigSuccess = true; | ||||||
|  | 
 | ||||||
|  | 	ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface); | ||||||
|  | 
 | ||||||
|  | 	LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Event handler for the library USB Control Request reception event. */ | ||||||
|  | void EVENT_USB_Device_ControlRequest(void) | ||||||
|  | { | ||||||
|  | 	MS_Device_ProcessControlRequest(&Disk_MS_Interface); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
 | ||||||
|  |  * | ||||||
|  |  *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface configuration structure being referenced | ||||||
|  |  */ | ||||||
|  | bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||||||
|  | { | ||||||
|  | 	bool CommandSuccess; | ||||||
|  | 
 | ||||||
|  | 	LEDs_SetAllLEDs(LEDMASK_USB_BUSY); | ||||||
|  | 	CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); | ||||||
|  | 	LEDs_SetAllLEDs(LEDMASK_USB_READY); | ||||||
|  | 
 | ||||||
|  | 	return CommandSuccess; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										80
									
								
								Bootloaders/Incomplete/MassStorage/MassStorage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								Bootloaders/Incomplete/MassStorage/MassStorage.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | |||||||
|  | /*
 | ||||||
|  |              LUFA Library | ||||||
|  |      Copyright (C) Dean Camera, 2013. | ||||||
|  | 
 | ||||||
|  |   dean [at] fourwalledcubicle [dot] com | ||||||
|  |            www.lufa-lib.org | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |   Copyright 2013  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 disclaims 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 MassStorage.c. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _MASS_STORAGE_H_ | ||||||
|  | #define _MASS_STORAGE_H_ | ||||||
|  | 
 | ||||||
|  | 	/* Includes: */ | ||||||
|  | 		#include <avr/io.h> | ||||||
|  | 		#include <avr/wdt.h> | ||||||
|  | 		#include <avr/power.h> | ||||||
|  | 		#include <avr/interrupt.h> | ||||||
|  | 		#include <string.h> | ||||||
|  | 
 | ||||||
|  | 		#include "Descriptors.h" | ||||||
|  | 
 | ||||||
|  | 		#include "Lib/SCSI.h" | ||||||
|  | 
 | ||||||
|  | 		#include <LUFA/Drivers/Board/LEDs.h> | ||||||
|  | 		#include <LUFA/Drivers/USB/USB.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 SetupHardware(void); | ||||||
|  | 
 | ||||||
|  | 		void EVENT_USB_Device_Connect(void); | ||||||
|  | 		void EVENT_USB_Device_Disconnect(void); | ||||||
|  | 		void EVENT_USB_Device_ConfigurationChanged(void); | ||||||
|  | 		void EVENT_USB_Device_ControlRequest(void); | ||||||
|  | 
 | ||||||
|  | 		bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
							
								
								
									
										48
									
								
								Bootloaders/Incomplete/MassStorage/makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Bootloaders/Incomplete/MassStorage/makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | #
 | ||||||
|  | #             LUFA Library
 | ||||||
|  | #     Copyright (C) Dean Camera, 2013.
 | ||||||
|  | #
 | ||||||
|  | #  dean [at] fourwalledcubicle [dot] com
 | ||||||
|  | #           www.lufa-lib.org
 | ||||||
|  | #
 | ||||||
|  | # --------------------------------------
 | ||||||
|  | #         LUFA Project Makefile.
 | ||||||
|  | # --------------------------------------
 | ||||||
|  | 
 | ||||||
|  | # Run "make help" for target help.
 | ||||||
|  | 
 | ||||||
|  | MCU          = at90usb1287 | ||||||
|  | ARCH         = AVR8 | ||||||
|  | BOARD        = USBKEY | ||||||
|  | F_CPU        = 8000000 | ||||||
|  | F_USB        = $(F_CPU) | ||||||
|  | OPTIMIZATION = s | ||||||
|  | TARGET       = MassStorage | ||||||
|  | SRC          = $(TARGET).c Descriptors.c Lib/SCSI.c Lib/VirtualFAT.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) | ||||||
|  | LUFA_PATH    = ../../../LUFA | ||||||
|  | CC_FLAGS     = -DUSE_LUFA_CONFIG_HEADER -IConfig/ | ||||||
|  | LD_FLAGS     = -Wl,--section-start=.text=$(BOOT_START_OFFSET) | ||||||
|  | 
 | ||||||
|  | # Flash size and bootloader section sizes of the target, in KB. These must
 | ||||||
|  | # match the target's total FLASH size and the bootloader size set in the
 | ||||||
|  | # device's fuses.
 | ||||||
|  | FLASH_SIZE_KB        := 128 | ||||||
|  | BOOT_SECTION_SIZE_KB := 8 | ||||||
|  | 
 | ||||||
|  | # Bootloader address calculation formulas
 | ||||||
|  | # Do not modify these macros, but rather modify the dependent values above.
 | ||||||
|  | CALC_ADDRESS_IN_HEX   = $(shell printf "0x%X" $$(( $(1) )) ) | ||||||
|  | BOOT_START_OFFSET     = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) | ||||||
|  | BOOT_SEC_OFFSET       = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - $(strip $(1)) ) | ||||||
|  | 
 | ||||||
|  | # Default target
 | ||||||
|  | all: | ||||||
|  | 
 | ||||||
|  | # Include LUFA build script makefiles
 | ||||||
|  | include $(LUFA_PATH)/Build/lufa_core.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_sources.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_build.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_cppcheck.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_doxygen.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_avrdude.mk | ||||||
|  | include $(LUFA_PATH)/Build/lufa_atprogram.mk | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dean Camera
						Dean Camera