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