Squashed 'tmk_core/' changes from caca2c0..dc0e46e
dc0e46e Rename LUFA to LUFA-git 3bfa7fa Remove LUFA-120730 215b764 Merge commit 'afa0f22a9299686fd88f58ce09c5b521ac917e8f' as 'protocol/lufa/LUFA' afa0f22 Squashed 'protocol/lufa/LUFA/' content from commit def7fca c0c42fa Remove submodule of LUFA 30f897d Merge commit '87ced33feb74e79c3281dda36eb6d6d153399b41' as 'protocol/usb_hid/USB_Host_Shield_2.0' 87ced33 Squashed 'protocol/usb_hid/USB_Host_Shield_2.0/' content from commit aab4a69 14f6d49 Remove submodule of USB_Host_Shield_2.0 git-subtree-dir: tmk_core git-subtree-split: dc0e46eaa4367d4e218f8816e3c117895820f07c
This commit is contained in:
parent
4d116a04e9
commit
f6d56675f9
1575 changed files with 421901 additions and 63190 deletions
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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
|
||||
*
|
||||
* Bootloader user application API functions.
|
||||
*/
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_erase_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_WritePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_write_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
|
||||
{
|
||||
boot_page_fill_safe(Address, Word);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address)
|
||||
{
|
||||
return boot_signature_byte_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadLock(void)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(GET_LOCK_BITS);
|
||||
}
|
||||
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits)
|
||||
{
|
||||
boot_lock_bits_set_safe(LockBits);
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 BootloaderAPI.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_API_H_
|
||||
#define _BOOTLOADER_API_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/boot.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
|
||||
/* Macros: */
|
||||
#if AUX_BOOT_SECTION_SIZE > 0
|
||||
#define AUX_BOOT_SECTION __attribute__((section(".boot_aux")))
|
||||
#else
|
||||
#define AUX_BOOT_SECTION
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address);
|
||||
void BootloaderAPI_WritePage(const uint32_t Address);
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word);
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadLock(void);
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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.
|
||||
*/
|
||||
|
||||
#if AUX_BOOT_SECTION_SIZE > 0
|
||||
#warning Using a AUX bootloader section in addition to the defined bootloader space (see documentation).
|
||||
|
||||
; Trampoline to jump over the AUX bootloader section to the start of the bootloader,
|
||||
; on devices where an AUX bootloader section is used.
|
||||
.section .boot_aux_trampoline, "ax"
|
||||
.global Boot_AUX_Trampoline
|
||||
Boot_AUX_Trampoline:
|
||||
jmp BOOT_START_ADDR
|
||||
#endif
|
||||
|
||||
; Trampolines to actual API implementations if the target address is outside the
|
||||
; range of a rjmp instruction (can happen with large bootloader sections)
|
||||
.section .apitable_trampolines, "ax"
|
||||
.global BootloaderAPI_Trampolines
|
||||
BootloaderAPI_Trampolines:
|
||||
|
||||
BootloaderAPI_ErasePage_Trampoline:
|
||||
jmp BootloaderAPI_ErasePage
|
||||
BootloaderAPI_WritePage_Trampoline:
|
||||
jmp BootloaderAPI_WritePage
|
||||
BootloaderAPI_FillWord_Trampoline:
|
||||
jmp BootloaderAPI_FillWord
|
||||
BootloaderAPI_ReadSignature_Trampoline:
|
||||
jmp BootloaderAPI_ReadSignature
|
||||
BootloaderAPI_ReadFuse_Trampoline:
|
||||
jmp BootloaderAPI_ReadFuse
|
||||
BootloaderAPI_ReadLock_Trampoline:
|
||||
jmp BootloaderAPI_ReadLock
|
||||
BootloaderAPI_WriteLock_Trampoline:
|
||||
jmp BootloaderAPI_WriteLock
|
||||
BootloaderAPI_UNUSED1:
|
||||
ret
|
||||
BootloaderAPI_UNUSED2:
|
||||
ret
|
||||
BootloaderAPI_UNUSED3:
|
||||
ret
|
||||
BootloaderAPI_UNUSED4:
|
||||
ret
|
||||
BootloaderAPI_UNUSED5:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; API function jump table
|
||||
.section .apitable_jumptable, "ax"
|
||||
.global BootloaderAPI_JumpTable
|
||||
BootloaderAPI_JumpTable:
|
||||
|
||||
rjmp BootloaderAPI_ErasePage_Trampoline
|
||||
rjmp BootloaderAPI_WritePage_Trampoline
|
||||
rjmp BootloaderAPI_FillWord_Trampoline
|
||||
rjmp BootloaderAPI_ReadSignature_Trampoline
|
||||
rjmp BootloaderAPI_ReadFuse_Trampoline
|
||||
rjmp BootloaderAPI_ReadLock_Trampoline
|
||||
rjmp BootloaderAPI_WriteLock_Trampoline
|
||||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1
|
||||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2
|
||||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3
|
||||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4
|
||||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5
|
||||
|
||||
|
||||
|
||||
; Bootloader table signatures and information
|
||||
.section .apitable_signatures, "ax"
|
||||
.global BootloaderAPI_Signatures
|
||||
BootloaderAPI_Signatures:
|
||||
|
||||
.long BOOT_START_ADDR ; Start address of the bootloader
|
||||
.word 0xDF30 ; Signature for the MS class bootloader, V1
|
||||
.word 0xDCFB ; Signature for a LUFA class bootloader
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 Mass Storage class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C
|
||||
#include "BootloaderMassStorage.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 = INTERFACE_ID_MassStorage,
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
bool RunBootloader = true;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
/** Indicates if the bootloader is allowed to exit immediately if \ref RunBootloader is \c false. During shutdown all
|
||||
* pending commands must be processed before jumping to the user-application, thus this tracks the main program loop
|
||||
* iterations since a SCSI command from the host was received.
|
||||
*/
|
||||
static uint8_t TicksSinceLastCommand = 0;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
bool JumpToApplication = false;
|
||||
|
||||
#if (BOARD == BOARD_LEONARDO)
|
||||
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
|
||||
PORTC |= (1 << 7);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If IO13 is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINC & (1 << 7)) != 0);
|
||||
|
||||
/* Disable pull-up after the check has completed */
|
||||
PORTC &= ~(1 << 7);
|
||||
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
/* Disable JTAG debugging */
|
||||
JTAG_DISABLE();
|
||||
|
||||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */
|
||||
PORTF |= (1 << 4);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If the TCK pin is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINF & (1 << 4)) != 0);
|
||||
|
||||
/* Re-enable JTAG debugging */
|
||||
JTAG_ENABLE();
|
||||
#endif
|
||||
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
{
|
||||
MagicBootKey = 0;
|
||||
JumpToApplication = true;
|
||||
}
|
||||
|
||||
if (JumpToApplication)
|
||||
{
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* enters a loop to run the application tasks in sequence.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
GlobalInterruptEnable();
|
||||
|
||||
while (RunBootloader || TicksSinceLastCommand++ < 0xFF)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
static 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();
|
||||
|
||||
/* Bootloader active LED toggle timer initialization */
|
||||
TIMSK1 = (1 << TOIE1);
|
||||
TCCR1B = ((1 << CS11) | (1 << CS10));
|
||||
}
|
||||
|
||||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
|
||||
ISR(TIMER1_OVF_vect, ISR_BLOCK)
|
||||
{
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
/* Indicate USB enumerating */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
|
||||
* the status LEDs and stops the Mass Storage management task.
|
||||
*/
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
/* Indicate USB not ready */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
bool ConfigSuccess = true;
|
||||
|
||||
/* Setup Mass Storage Data Endpoints */
|
||||
ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface);
|
||||
|
||||
/* Indicate endpoint configuration success or failure */
|
||||
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);
|
||||
|
||||
/* Signal that a command was processed, must not exit bootloader yet */
|
||||
TicksSinceLastCommand = 0;
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 BootloaderMassStorage.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_MASS_STORAGE_H_
|
||||
#define _BOOTLOADER_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 "Config/AppConfig.h"
|
||||
|
||||
#include "Lib/SCSI.h"
|
||||
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/* Global Variables: */
|
||||
extern bool RunBootloader;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int main(void) AUX_BOOT_SECTION;
|
||||
|
||||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
void EVENT_USB_Device_Connect(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_Disconnect(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_ConfigurationChanged(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_ControlRequest(void) AUX_BOOT_SECTION;
|
||||
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C)
|
||||
static void SetupHardware(void) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Mass Storage Class USB AVR Bootloader
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i>
|
||||
* \li ATMEGA32U2 - <i>See \ref SSec_Aux_Space</i>
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Mass Storage Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Bulk-Only Transport</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Mass Storage Standard \n
|
||||
* USB Bulk-Only Transport Standard \n
|
||||
* SCSI Primary Commands Specification \n
|
||||
* SCSI Block Commands Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a Mass Storage device, capable of reading and writing a new binary
|
||||
* firmware image file, to load firmware onto the AVR.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 6KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to
|
||||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the
|
||||
* bootloader from the normal user application.
|
||||
*
|
||||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device
|
||||
* lockbits are set.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* For board specific exceptions to the above, see below.
|
||||
*
|
||||
* \subsection SSec_XPLAIN Atmel Xplain Board
|
||||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
|
||||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \subsection SSec_Leonardo Arduino Leonardo Board
|
||||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
|
||||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* This bootloader uses the Mass Storage drivers inbuilt into all modern operating systems, thus no additional
|
||||
* drivers need to be supplied for correct operation.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* This bootloader is compatible with all operating systems that support the FAT12 file system format. To reprogram the
|
||||
* device, overwrite a file stored on the virtual FAT filesystem with a new binary (BIN format) image. Remember to safely
|
||||
* remove your device from the host using the host OS's ejection APIs, to ensure all data is correctly flushed to the
|
||||
* bootloader's virtual filesystem and not cached in the OS's file system driver.
|
||||
*
|
||||
* The current device firmware can be read from the device by reading a file from the virtual FAT filesystem.
|
||||
*
|
||||
* \warning This bootloader is currently <b>incompatible with the Apple MacOS X OS Finder GUI</b>, due to the
|
||||
* large amount of meta files this OS attempts to write to the disk along with the new binaries. On
|
||||
* this platform, firmwares must be copied to the disk via the Terminal application only to prevent
|
||||
* firmware corruption.
|
||||
*
|
||||
* \section Sec_API User Application API
|
||||
*
|
||||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader,
|
||||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data.
|
||||
*
|
||||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the
|
||||
* following layout:
|
||||
*
|
||||
* \code
|
||||
* #define BOOTLOADER_API_TABLE_SIZE 32
|
||||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
|
||||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
|
||||
*
|
||||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
|
||||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
|
||||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
|
||||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
|
||||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
|
||||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
|
||||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
|
||||
*
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
|
||||
*
|
||||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
|
||||
* #define BOOTLOADER_MASS_STORAGE_SIGNATURE 0xDF30
|
||||
*
|
||||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
|
||||
* #define BOOTLOADER_ADDRESS_LENGTH 4
|
||||
* \endcode
|
||||
*
|
||||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address
|
||||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader
|
||||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them
|
||||
* to the value \c BOOTLOADER_MASS_STORAGE_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes
|
||||
* of FLASH memory starting from address \c BOOTLOADER_ADDRESS_START.
|
||||
*
|
||||
* \subsection SSec_Aux_Space Auxiliary Bootloader Section
|
||||
* To make the bootloader function on smaller devices (those with a physical bootloader section of smaller than 6KB) a second
|
||||
* section of memory (called the <i>Auxiliary Bootloader Section</i>) is added before the start of the real bootloader section,
|
||||
* and is filled with a portion of the bootloader code. This allows smaller devices to run the bootloader, at the cost of an
|
||||
* additional portion of the device's FLASH (the bootloader section size in KB subtracted from the 6KB total size). A small
|
||||
* trampoline is inserted at the start of the auxiliary section so that the bootloader will run normally in the case of a blank
|
||||
* application section.
|
||||
*
|
||||
* On devices supporting a 8KB bootloader section size, the AUX section is not created in the final binary.
|
||||
*
|
||||
* \subsection SSec_API_MemLayout Device Memory Map
|
||||
* The following illustration indicates the final memory map of the device when loaded with the bootloader.
|
||||
*
|
||||
* \verbatim
|
||||
* +----------------------------+ 0x0000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | User Application |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE
|
||||
* | Booloader Start Trampoline |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + 4
|
||||
* | |
|
||||
* | Auxiliary Bootloader |
|
||||
* | Space for Smaller Devices |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
|
||||
* | |
|
||||
* | Bootloader Application |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - 96
|
||||
* | API Table Trampolines |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 32
|
||||
* | Bootloader API Table |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 8
|
||||
* | Bootloader ID Constants |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND
|
||||
* \endverbatim
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par In some cases, the application is not fully loaded into the device.
|
||||
* Write-caching on some operating systems may interfere with the normal
|
||||
* operation of the bootloader. Write caching should be disabled when using the
|
||||
* Mass Storage bootloader, or the file system synced via an appropriate command
|
||||
* (such as the OS's normal disk ejection command) before disconnecting the device.
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th><b>Define Name:</b></th>
|
||||
* <th><b>Location:</b></th>
|
||||
* <th><b>Description:</b></th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_APP_START_ON_EJECT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable automatic start of the loaded application when the virtual
|
||||
* Mass Storage disk is ejected on the host.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 Application Configuration Header File
|
||||
*
|
||||
* This is a header file which is be 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
|
||||
* \ref Sec_Options section of the application documentation.
|
||||
*/
|
||||
|
||||
#ifndef _APP_CONFIG_H_
|
||||
#define _APP_CONFIG_H_
|
||||
|
||||
// #define NO_APP_START_ON_EJECT
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 0
|
||||
#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
|
157
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Descriptors.c
Normal file
157
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Descriptors.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 SRAM 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(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2045,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,1),
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = NO_DESCRIPTOR,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.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 = INTERFACE_ID_MassStorage,
|
||||
.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
|
||||
}
|
||||
};
|
||||
|
||||
/** 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 void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
/* If/Else If chain compiles slightly smaller than a switch case */
|
||||
if (DescriptorType == DTYPE_Device)
|
||||
{
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_Configuration)
|
||||
{
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
88
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Descriptors.h
Normal file
88
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Descriptors.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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>
|
||||
|
||||
#include "BootloaderAPI.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;
|
||||
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_MassStorage = 0, /**< Mass storage interface descriptor ID */
|
||||
};
|
||||
|
||||
/* 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) AUX_BOOT_SECTION;
|
||||
|
||||
#endif
|
||||
|
294
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/SCSI.c
Normal file
294
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/SCSI.c
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 \c true if the command completed successfully, \c 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_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_START_STOP_UNIT:
|
||||
#if !defined(NO_APP_START_ON_EJECT)
|
||||
/* If the user ejected the volume, signal bootloader exit at next opportunity. */
|
||||
RunBootloader = ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[4] & 0x03) != 0x02);
|
||||
#endif
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
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 \c true if the command completed successfully, \c 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 \c true if the command completed successfully, \c 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 \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
Endpoint_Write_32_BE(LUN_MEDIA_BLOCKS - 1);
|
||||
Endpoint_Write_32_BE(SECTOR_SIZE_BYTES);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
||||
|
||||
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 \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const bool IsDataRead)
|
||||
{
|
||||
uint16_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 */
|
||||
for (uint16_t i = 0; i < TotalBlocks; i++)
|
||||
{
|
||||
if (IsDataRead == DATA_READ)
|
||||
VirtualFAT_ReadBlock(BlockAddress + i);
|
||||
else
|
||||
VirtualFAT_WriteBlock(BlockAddress + i);
|
||||
}
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES);
|
||||
|
||||
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 \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
/* Send an empty header response indicating Write Protect flag is off */
|
||||
Endpoint_Write_32_LE(0);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
84
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/SCSI.h
Normal file
84
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/SCSI.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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 "../BootloaderMassStorage.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) do { SenseData.SenseKey = (Key); \
|
||||
SenseData.AdditionalSenseCode = (Acode); \
|
||||
SenseData.AdditionalSenseQualifier = (Aqual); } while (0)
|
||||
|
||||
/** 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) AUX_BOOT_SECTION;
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const bool IsDataRead) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
482
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/VirtualFAT.c
Normal file
482
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/VirtualFAT.c
Normal file
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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
|
||||
*
|
||||
* Virtualized FAT12 filesystem implementation, to perform self-programming
|
||||
* in response to read and write requests to the virtual filesystem by the
|
||||
* host PC.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_VIRTUAL_FAT_C
|
||||
#include "VirtualFAT.h"
|
||||
|
||||
/** FAT filesystem boot sector block, must be the first sector on the physical
|
||||
* disk so that the host can identify the presence of a FAT filesystem. This
|
||||
* block is truncated; normally a large bootstrap section is located near the
|
||||
* end of the block for booting purposes however as this is not meant to be a
|
||||
* bootable disk it is omitted for space reasons.
|
||||
*
|
||||
* \note When returning the boot block to the host, the magic signature 0xAA55
|
||||
* must be added to the very end of the block to identify it as a boot
|
||||
* block.
|
||||
*/
|
||||
static const FATBootBlock_t BootBlock =
|
||||
{
|
||||
.Bootstrap = {0xEB, 0x3C, 0x90},
|
||||
.Description = "mkdosfs",
|
||||
.SectorSize = SECTOR_SIZE_BYTES,
|
||||
.SectorsPerCluster = SECTOR_PER_CLUSTER,
|
||||
.ReservedSectors = 1,
|
||||
.FATCopies = 2,
|
||||
.RootDirectoryEntries = (SECTOR_SIZE_BYTES / sizeof(FATDirectoryEntry_t)),
|
||||
.TotalSectors16 = LUN_MEDIA_BLOCKS,
|
||||
.MediaDescriptor = 0xF8,
|
||||
.SectorsPerFAT = 1,
|
||||
.SectorsPerTrack = (LUN_MEDIA_BLOCKS % 64),
|
||||
.Heads = (LUN_MEDIA_BLOCKS / 64),
|
||||
.HiddenSectors = 0,
|
||||
.TotalSectors32 = 0,
|
||||
.PhysicalDriveNum = 0,
|
||||
.ExtendedBootRecordSig = 0x29,
|
||||
.VolumeSerialNumber = 0x12345678,
|
||||
.VolumeLabel = "LUFA BOOT ",
|
||||
.FilesystemIdentifier = "FAT12 ",
|
||||
};
|
||||
|
||||
/** FAT 8.3 style directory entry, for the virtual FLASH contents file. */
|
||||
static FATDirectoryEntry_t FirmwareFileEntries[] =
|
||||
{
|
||||
/* Root volume label entry; disk label is contained in the Filename and
|
||||
* Extension fields (concatenated) with a special attribute flag - other
|
||||
* fields are ignored. Should be the same as the label in the boot block.
|
||||
*/
|
||||
[DISK_FILE_ENTRY_VolumeID] =
|
||||
{
|
||||
.MSDOS_Directory =
|
||||
{
|
||||
.Name = "LUFA BOOT ",
|
||||
.Attributes = FAT_FLAG_VOLUME_NAME,
|
||||
.Reserved = {0},
|
||||
.CreationTime = 0,
|
||||
.CreationDate = 0,
|
||||
.StartingCluster = 0,
|
||||
.Reserved2 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
/* VFAT Long File Name entry for the virtual firmware file; required to
|
||||
* prevent corruption from systems that are unable to detect the device
|
||||
* as being a legacy MSDOS style FAT12 volume. */
|
||||
[DISK_FILE_ENTRY_FLASH_LFN] =
|
||||
{
|
||||
.VFAT_LongFileName =
|
||||
{
|
||||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY,
|
||||
.Attribute = FAT_FLAG_LONG_FILE_NAME,
|
||||
.Reserved1 = 0,
|
||||
.Reserved2 = 0,
|
||||
|
||||
.Checksum = FAT_CHECKSUM('F','L','A','S','H',' ',' ',' ','B','I','N'),
|
||||
|
||||
.Unicode1 = 'F',
|
||||
.Unicode2 = 'L',
|
||||
.Unicode3 = 'A',
|
||||
.Unicode4 = 'S',
|
||||
.Unicode5 = 'H',
|
||||
.Unicode6 = '.',
|
||||
.Unicode7 = 'B',
|
||||
.Unicode8 = 'I',
|
||||
.Unicode9 = 'N',
|
||||
.Unicode10 = 0,
|
||||
.Unicode11 = 0,
|
||||
.Unicode12 = 0,
|
||||
.Unicode13 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
/* MSDOS file entry for the virtual Firmware image. */
|
||||
[DISK_FILE_ENTRY_FLASH_MSDOS] =
|
||||
{
|
||||
.MSDOS_File =
|
||||
{
|
||||
.Filename = "FLASH ",
|
||||
.Extension = "BIN",
|
||||
.Attributes = 0,
|
||||
.Reserved = {0},
|
||||
.CreationTime = FAT_TIME(1, 1, 0),
|
||||
.CreationDate = FAT_DATE(14, 2, 1989),
|
||||
.StartingCluster = 2,
|
||||
.FileSizeBytes = FLASH_FILE_SIZE_BYTES,
|
||||
}
|
||||
},
|
||||
|
||||
[DISK_FILE_ENTRY_EEPROM_LFN] =
|
||||
{
|
||||
.VFAT_LongFileName =
|
||||
{
|
||||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY,
|
||||
.Attribute = FAT_FLAG_LONG_FILE_NAME,
|
||||
.Reserved1 = 0,
|
||||
.Reserved2 = 0,
|
||||
|
||||
.Checksum = FAT_CHECKSUM('E','E','P','R','O','M',' ',' ','B','I','N'),
|
||||
|
||||
.Unicode1 = 'E',
|
||||
.Unicode2 = 'E',
|
||||
.Unicode3 = 'P',
|
||||
.Unicode4 = 'R',
|
||||
.Unicode5 = 'O',
|
||||
.Unicode6 = 'M',
|
||||
.Unicode7 = '.',
|
||||
.Unicode8 = 'B',
|
||||
.Unicode9 = 'I',
|
||||
.Unicode10 = 'N',
|
||||
.Unicode11 = 0,
|
||||
.Unicode12 = 0,
|
||||
.Unicode13 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
[DISK_FILE_ENTRY_EEPROM_MSDOS] =
|
||||
{
|
||||
.MSDOS_File =
|
||||
{
|
||||
.Filename = "EEPROM ",
|
||||
.Extension = "BIN",
|
||||
.Attributes = 0,
|
||||
.Reserved = {0},
|
||||
.CreationTime = FAT_TIME(1, 1, 0),
|
||||
.CreationDate = FAT_DATE(14, 2, 1989),
|
||||
.StartingCluster = 2 + FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES),
|
||||
.FileSizeBytes = EEPROM_FILE_SIZE_BYTES,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/** Starting cluster of the virtual FLASH.BIN file on disk, tracked so that the
|
||||
* offset from the start of the data sector can be determined. On Windows
|
||||
* systems files are usually replaced using the original file's disk clusters,
|
||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||
*/
|
||||
static const uint16_t* FLASHFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_FLASH_MSDOS].MSDOS_File.StartingCluster;
|
||||
|
||||
/** Starting cluster of the virtual EEPROM.BIN file on disk, tracked so that the
|
||||
* offset from the start of the data sector can be determined. On Windows
|
||||
* systems files are usually replaced using the original file's disk clusters,
|
||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||
*/
|
||||
static const uint16_t* EEPROMFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_EEPROM_MSDOS].MSDOS_File.StartingCluster;
|
||||
|
||||
/** Reads a byte of EEPROM out from the EEPROM memory space.
|
||||
*
|
||||
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||
* larger USB AVRs will break the linker. This function is marked as
|
||||
* never inlinable and placed into the normal text segment so that the
|
||||
* call to the EEPROM function will be short even if the AUX boot section
|
||||
* is used.
|
||||
*
|
||||
* \param[in] Address Address of the EEPROM location to read from
|
||||
*
|
||||
* \return Read byte of EEPROM data.
|
||||
*/
|
||||
static uint8_t ReadEEPROMByte(const uint8_t* const Address)
|
||||
{
|
||||
return eeprom_read_byte(Address);
|
||||
}
|
||||
|
||||
/** Writes a byte of EEPROM out to the EEPROM memory space.
|
||||
*
|
||||
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||
* larger USB AVRs will break the linker. This function is marked as
|
||||
* never inlinable and placed into the normal text segment so that the
|
||||
* call to the EEPROM function will be short even if the AUX boot section
|
||||
* is used.
|
||||
*
|
||||
* \param[in] Address Address of the EEPROM location to write to
|
||||
* \param[in] Data New data to write to the EEPROM location
|
||||
*/
|
||||
static void WriteEEPROMByte(uint8_t* const Address,
|
||||
const uint8_t Data)
|
||||
{
|
||||
eeprom_update_byte(Address, Data);
|
||||
}
|
||||
|
||||
/** Updates a FAT12 cluster entry in the FAT file table with the specified next
|
||||
* chain index. If the cluster is the last in the file chain, the magic value
|
||||
* \c 0xFFF should be used.
|
||||
*
|
||||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the
|
||||
* first file data cluster on the disk. See the FAT specification.
|
||||
*
|
||||
* \param[out] FATTable Pointer to the FAT12 allocation table
|
||||
* \param[in] Index Index of the cluster entry to update
|
||||
* \param[in] ChainEntry Next cluster index in the file chain
|
||||
*/
|
||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint16_t ChainEntry)
|
||||
{
|
||||
/* Calculate the starting offset of the cluster entry in the FAT12 table */
|
||||
uint8_t FATOffset = (Index + (Index >> 1));
|
||||
bool UpperNibble = ((Index & 1) != 0);
|
||||
|
||||
/* Check if the start of the entry is at an upper nibble of the byte, fill
|
||||
* out FAT12 entry as required */
|
||||
if (UpperNibble)
|
||||
{
|
||||
FATTable[FATOffset] = (FATTable[FATOffset] & 0x0F) | ((ChainEntry & 0x0F) << 4);
|
||||
FATTable[FATOffset + 1] = (ChainEntry >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
FATTable[FATOffset] = ChainEntry;
|
||||
FATTable[FATOffset + 1] = (FATTable[FATOffset] & 0xF0) | (ChainEntry >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates a FAT12 cluster chain in the FAT file table with a linear chain of
|
||||
* the specified length.
|
||||
*
|
||||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the
|
||||
* first file data cluster on the disk. See the FAT specification.
|
||||
*
|
||||
* \param[out] FATTable Pointer to the FAT12 allocation table
|
||||
* \param[in] Index Index of the start of the cluster chain to update
|
||||
* \param[in] ChainLength Length of the chain to write, in clusters
|
||||
*/
|
||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint8_t ChainLength)
|
||||
{
|
||||
for (uint8_t i = 0; i < ChainLength; i++)
|
||||
{
|
||||
uint16_t CurrentCluster = Index + i;
|
||||
uint16_t NextCluster = CurrentCluster + 1;
|
||||
|
||||
/* Mark last cluster as end of file */
|
||||
if (i == (ChainLength - 1))
|
||||
NextCluster = 0xFFF;
|
||||
|
||||
UpdateFAT12ClusterEntry(FATTable, CurrentCluster, NextCluster);
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads or writes a block of data from/to the physical device FLASH using a
|
||||
* block buffer stored in RAM, if the requested block is within the virtual
|
||||
* firmware file's sector ranges in the emulated FAT file system.
|
||||
*
|
||||
* \param[in] BlockNumber Physical disk block to read from/write to
|
||||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM
|
||||
* \param[in] Read If \c true, the requested block is read, if
|
||||
* \c false, the requested block is written
|
||||
*/
|
||||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read)
|
||||
{
|
||||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*FLASHFileStartCluster - 2) * SECTOR_PER_CLUSTER;
|
||||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) - 1);
|
||||
|
||||
/* Range check the write request - abort if requested block is not within the
|
||||
* virtual firmware file sector range */
|
||||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock)))
|
||||
return;
|
||||
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t FlashAddress = (uint32_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
#else
|
||||
uint16_t FlashAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
if (Read)
|
||||
{
|
||||
/* Read out the mapped block of data from the device's FLASH */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
BlockBuffer[i] = pgm_read_byte_far(FlashAddress++);
|
||||
#else
|
||||
BlockBuffer[i] = pgm_read_byte(FlashAddress++);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write out the mapped block of data to the device's FLASH */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2)
|
||||
{
|
||||
if ((FlashAddress % SPM_PAGESIZE) == 0)
|
||||
{
|
||||
/* Erase the given FLASH page, ready to be programmed */
|
||||
BootloaderAPI_ErasePage(FlashAddress);
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
BootloaderAPI_FillWord(FlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]);
|
||||
FlashAddress += 2;
|
||||
|
||||
if ((FlashAddress % SPM_PAGESIZE) == 0)
|
||||
{
|
||||
/* Write the filled FLASH page to memory */
|
||||
BootloaderAPI_WritePage(FlashAddress - SPM_PAGESIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads or writes a block of data from/to the physical device EEPROM using a
|
||||
* block buffer stored in RAM, if the requested block is within the virtual
|
||||
* firmware file's sector ranges in the emulated FAT file system.
|
||||
*
|
||||
* \param[in] BlockNumber Physical disk block to read from/write to
|
||||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM
|
||||
* \param[in] Read If \c true, the requested block is read, if
|
||||
* \c false, the requested block is written
|
||||
*/
|
||||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read)
|
||||
{
|
||||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*EEPROMFileStartCluster - 2) * SECTOR_PER_CLUSTER;
|
||||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) - 1);
|
||||
|
||||
/* Range check the write request - abort if requested block is not within the
|
||||
* virtual firmware file sector range */
|
||||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock)))
|
||||
return;
|
||||
|
||||
uint16_t EEPROMAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
|
||||
if (Read)
|
||||
{
|
||||
/* Read out the mapped block of data from the device's EEPROM */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
BlockBuffer[i] = ReadEEPROMByte((uint8_t*)EEPROMAddress++);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write out the mapped block of data to the device's EEPROM */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
WriteEEPROMByte((uint8_t*)EEPROMAddress++, BlockBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes a block of data to the virtual FAT filesystem, from the USB Mass
|
||||
* Storage interface.
|
||||
*
|
||||
* \param[in] BlockNumber Index of the block to write.
|
||||
*/
|
||||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber)
|
||||
{
|
||||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
|
||||
|
||||
/* Buffer the entire block to be written from the host */
|
||||
Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
switch (BlockNumber)
|
||||
{
|
||||
case DISK_BLOCK_BootBlock:
|
||||
case DISK_BLOCK_FATBlock1:
|
||||
case DISK_BLOCK_FATBlock2:
|
||||
/* Ignore writes to the boot and FAT blocks */
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_RootFilesBlock:
|
||||
/* Copy over the updated directory entries */
|
||||
memcpy(FirmwareFileEntries, BlockBuffer, sizeof(FirmwareFileEntries));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, false);
|
||||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads a block of data from the virtual FAT filesystem, and sends it to the
|
||||
* host via the USB Mass Storage interface.
|
||||
*
|
||||
* \param[in] BlockNumber Index of the block to read.
|
||||
*/
|
||||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber)
|
||||
{
|
||||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
|
||||
memset(BlockBuffer, 0x00, sizeof(BlockBuffer));
|
||||
|
||||
switch (BlockNumber)
|
||||
{
|
||||
case DISK_BLOCK_BootBlock:
|
||||
memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t));
|
||||
|
||||
/* Add the magic signature to the end of the block */
|
||||
BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55;
|
||||
BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA;
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_FATBlock1:
|
||||
case DISK_BLOCK_FATBlock2:
|
||||
/* Cluster 0: Media type/Reserved */
|
||||
UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor);
|
||||
|
||||
/* Cluster 1: Reserved */
|
||||
UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF);
|
||||
|
||||
/* Cluster 2 onwards: Cluster chain of FLASH.BIN */
|
||||
UpdateFAT12ClusterChain(BlockBuffer, *FLASHFileStartCluster, FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES));
|
||||
|
||||
/* Cluster 2+n onwards: Cluster chain of EEPROM.BIN */
|
||||
UpdateFAT12ClusterChain(BlockBuffer, *EEPROMFileStartCluster, FILE_CLUSTERS(EEPROM_FILE_SIZE_BYTES));
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_RootFilesBlock:
|
||||
memcpy(BlockBuffer, FirmwareFileEntries, sizeof(FirmwareFileEntries));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, true);
|
||||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write the entire read block Buffer to the host */
|
||||
Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
|
||||
Endpoint_ClearIN();
|
||||
}
|
302
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/VirtualFAT.h
Normal file
302
protocol/lufa/LUFA-git/Bootloaders/MassStorage/Lib/VirtualFAT.h
Normal file
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 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>
|
||||
|
||||
#include "../BootloaderAPI.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Size of the virtual FLASH.BIN file in bytes. */
|
||||
#define FLASH_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE)
|
||||
|
||||
/** Size of the virtual EEPROM.BIN file in bytes. */
|
||||
#define EEPROM_FILE_SIZE_BYTES E2END
|
||||
|
||||
/** Number of sectors that comprise a single logical disk cluster. */
|
||||
#define SECTOR_PER_CLUSTER 4
|
||||
|
||||
/** Size of a single logical sector on the disk. */
|
||||
#define SECTOR_SIZE_BYTES 512
|
||||
|
||||
/** Size of a logical cluster on the disk, in bytes */
|
||||
#define CLUSTER_SIZE_BYTES (SECTOR_PER_CLUSTER * SECTOR_SIZE_BYTES)
|
||||
|
||||
/** Number of sectors required to store a given size in bytes.
|
||||
*
|
||||
* \param[in] size Size of the data that needs to be stored
|
||||
*
|
||||
* \return Number of sectors required to store the given data on the disk.
|
||||
*/
|
||||
#define FILE_SECTORS(size) ((size / SECTOR_SIZE_BYTES) + ((size % SECTOR_SIZE_BYTES) ? 1 : 0))
|
||||
|
||||
/** Number of clusters required to store a given size in bytes.
|
||||
*
|
||||
* \param[in] size Size of the data that needs to be stored
|
||||
*
|
||||
* \return Number of clusters required to store the given data on the disk.
|
||||
*/
|
||||
#define FILE_CLUSTERS(size) ((size / CLUSTER_SIZE_BYTES) + ((size % CLUSTER_SIZE_BYTES) ? 1 : 0))
|
||||
|
||||
/** Total number of logical sectors/blocks on the disk. */
|
||||
#define LUN_MEDIA_BLOCKS (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) + FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) + 32)
|
||||
|
||||
/** Converts a given time in HH:MM:SS format to a FAT filesystem time.
|
||||
*
|
||||
* \note The minimum seconds resolution of FAT is 2, thus odd seconds
|
||||
* will be truncated to the previous integer multiple of 2 seconds.
|
||||
*
|
||||
* \param[in] hh Hours (0-23)
|
||||
* \param[in] mm Minutes (0-59)
|
||||
* \param[in] ss Seconds (0-59)
|
||||
*
|
||||
* \return Given time encoded as a FAT filesystem timestamp
|
||||
*/
|
||||
#define FAT_TIME(hh, mm, ss) ((hh << 11) | (mm << 5) | (ss >> 1))
|
||||
|
||||
/** Converts a given date in DD/MM/YYYY format to a FAT filesystem date.
|
||||
*
|
||||
* \param[in] dd Days in the month (1-31)
|
||||
* \param[in] mm Months in the year (1-12)
|
||||
* \param[in] yyyy Year (1980 - 2107)
|
||||
*
|
||||
* \return Given date encoded as a FAT filesystem datestamp
|
||||
*/
|
||||
#define FAT_DATE(dd, mm, yyyy) (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0))
|
||||
|
||||
/** Bit-rotates a given 8-bit value once to the right.
|
||||
*
|
||||
* \param x Value to rotate right once
|
||||
*
|
||||
* \return Bit-rotated input value, rotated once to the right.
|
||||
*/
|
||||
#define _ROT8(x) ((((x) & 0xFE) >> 1) | (((x) & 1) ? 0x80 : 0x00))
|
||||
|
||||
/** Computes the LFN entry checksum of a MSDOS 8.3 format file entry,
|
||||
* to associate a LFN entry with its short file entry.
|
||||
*
|
||||
* \param n0 MSDOS Filename character 1
|
||||
* \param n1 MSDOS Filename character 2
|
||||
* \param n2 MSDOS Filename character 3
|
||||
* \param n3 MSDOS Filename character 4
|
||||
* \param n4 MSDOS Filename character 5
|
||||
* \param n5 MSDOS Filename character 6
|
||||
* \param n6 MSDOS Filename character 7
|
||||
* \param n7 MSDOS Filename character 8
|
||||
* \param e0 MSDOS Extension character 1
|
||||
* \param e1 MSDOS Extension character 2
|
||||
* \param e2 MSDOS Extension character 3
|
||||
*
|
||||
* \return LFN checksum of the given MSDOS 8.3 filename.
|
||||
*/
|
||||
#define FAT_CHECKSUM(n0, n1, n2, n3, n4, n5, n6, n7, e0, e1, e2) \
|
||||
(uint8_t)(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(n0)+n1)+n2)+n3)+n4)+n5)+n6)+n7)+e0)+e1)+e2)
|
||||
|
||||
/** \name FAT Filesystem Flags */
|
||||
//@{
|
||||
/** FAT attribute flag to indicate a read-only file. */
|
||||
#define FAT_FLAG_READONLY (1 << 0)
|
||||
|
||||
/** FAT attribute flag to indicate a hidden file. */
|
||||
#define FAT_FLAG_HIDDEN (1 << 1)
|
||||
|
||||
/** FAT attribute flag to indicate a system file. */
|
||||
#define FAT_FLAG_SYSTEM (1 << 2)
|
||||
|
||||
/** FAT attribute flag to indicate a Volume name entry. */
|
||||
#define FAT_FLAG_VOLUME_NAME (1 << 3)
|
||||
|
||||
/** FAT attribute flag to indicate a directory entry. */
|
||||
#define FAT_FLAG_DIRECTORY (1 << 4)
|
||||
|
||||
/** FAT attribute flag to indicate a file ready for archiving. */
|
||||
#define FAT_FLAG_ARCHIVE (1 << 5)
|
||||
|
||||
/** FAT pseudo-attribute flag to indicate a Long File Name entry. */
|
||||
#define FAT_FLAG_LONG_FILE_NAME 0x0F
|
||||
|
||||
/** Ordinal flag marker for FAT Long File Name entries to mark the last entry. */
|
||||
#define FAT_ORDINAL_LAST_ENTRY (1 << 6)
|
||||
//@}
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the Root FAT file entry indexes on the disk. This can be used
|
||||
* to retrieve the current contents of a known directory entry.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/** Volume ID directory entry, giving the name of the virtual disk. */
|
||||
DISK_FILE_ENTRY_VolumeID = 0,
|
||||
/** Long File Name FAT file entry of the virtual FLASH.BIN image file. */
|
||||
DISK_FILE_ENTRY_FLASH_LFN = 1,
|
||||
/** Legacy MSDOS FAT file entry of the virtual FLASH.BIN image file. */
|
||||
DISK_FILE_ENTRY_FLASH_MSDOS = 2,
|
||||
/** Long File Name FAT file entry of the virtual EEPROM.BIN image file. */
|
||||
DISK_FILE_ENTRY_EEPROM_LFN = 3,
|
||||
/** Legacy MSDOS FAT file entry of the virtual EEPROM.BIN image file. */
|
||||
DISK_FILE_ENTRY_EEPROM_MSDOS = 4,
|
||||
};
|
||||
|
||||
/** Enum for the physical disk blocks of the virtual disk. */
|
||||
enum
|
||||
{
|
||||
/** Boot sector disk block. */
|
||||
DISK_BLOCK_BootBlock = 0,
|
||||
/** First copy of the FAT table block. */
|
||||
DISK_BLOCK_FATBlock1 = 1,
|
||||
/** Second copy of the FAT table block. */
|
||||
DISK_BLOCK_FATBlock2 = 2,
|
||||
/** Root file and directory entries block. */
|
||||
DISK_BLOCK_RootFilesBlock = 3,
|
||||
/** Start block of the disk data section. */
|
||||
DISK_BLOCK_DataStartBlock = 4,
|
||||
};
|
||||
|
||||
/* Type Definitions: */
|
||||
/** FAT boot block structure definition, used to identify the core
|
||||
* parameters of a FAT file system stored on a disk.
|
||||
*
|
||||
* \note This definition is truncated to save space; the magic signature
|
||||
* \c 0xAA55 must be appended to the very end of the block for it
|
||||
* to be detected by the host as a valid boot block.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Bootstrap[3];
|
||||
uint8_t Description[8];
|
||||
uint16_t SectorSize;
|
||||
uint8_t SectorsPerCluster;
|
||||
uint16_t ReservedSectors;
|
||||
uint8_t FATCopies;
|
||||
uint16_t RootDirectoryEntries;
|
||||
uint16_t TotalSectors16;
|
||||
uint8_t MediaDescriptor;
|
||||
uint16_t SectorsPerFAT;
|
||||
uint16_t SectorsPerTrack;
|
||||
uint16_t Heads;
|
||||
uint32_t HiddenSectors;
|
||||
uint32_t TotalSectors32;
|
||||
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;
|
||||
|
||||
/** FAT directory entry structure, for the various kinds of File and
|
||||
* directory descriptors on a FAT disk.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/** VFAT Long File Name file entry. */
|
||||
struct
|
||||
{
|
||||
uint8_t Ordinal;
|
||||
uint16_t Unicode1;
|
||||
uint16_t Unicode2;
|
||||
uint16_t Unicode3;
|
||||
uint16_t Unicode4;
|
||||
uint16_t Unicode5;
|
||||
uint8_t Attribute;
|
||||
uint8_t Reserved1;
|
||||
uint8_t Checksum;
|
||||
uint16_t Unicode6;
|
||||
uint16_t Unicode7;
|
||||
uint16_t Unicode8;
|
||||
uint16_t Unicode9;
|
||||
uint16_t Unicode10;
|
||||
uint16_t Unicode11;
|
||||
uint16_t Reserved2;
|
||||
uint16_t Unicode12;
|
||||
uint16_t Unicode13;
|
||||
} VFAT_LongFileName;
|
||||
|
||||
/** Legacy FAT MSDOS 8.3 file entry. */
|
||||
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 FileSizeBytes;
|
||||
} MSDOS_File;
|
||||
|
||||
/** Legacy FAT MSDOS (sub-)directory entry. */
|
||||
struct
|
||||
{
|
||||
uint8_t Name[11];
|
||||
uint8_t Attributes;
|
||||
uint8_t Reserved[10];
|
||||
uint16_t CreationTime;
|
||||
uint16_t CreationDate;
|
||||
uint16_t StartingCluster;
|
||||
uint32_t Reserved2;
|
||||
} MSDOS_Directory;
|
||||
} FATDirectoryEntry_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C)
|
||||
static uint8_t ReadEEPROMByte(const uint8_t* const Address) ATTR_NO_INLINE;
|
||||
|
||||
static void WriteEEPROMByte(uint8_t* const Address,
|
||||
const uint8_t Data) ATTR_NO_INLINE;
|
||||
|
||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint16_t ChainEntry) AUX_BOOT_SECTION;
|
||||
|
||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||
const uint16_t StartIndex,
|
||||
const uint8_t ChainLength) AUX_BOOT_SECTION;
|
||||
|
||||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read) AUX_BOOT_SECTION;
|
||||
|
||||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION;
|
||||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION;
|
||||
|
||||
#endif
|
156
protocol/lufa/LUFA-git/Bootloaders/MassStorage/asf.xml
Normal file
156
protocol/lufa/LUFA-git/Bootloaders/MassStorage/asf.xml
Normal file
|
@ -0,0 +1,156 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="Mass Storage Bootloader - 128KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.128_8" force-caption="true" workspace-name="lufa_ms_128kb_8kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1E000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1E000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 64KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.64_8" force-caption="true" workspace-name="lufa_ms_64kb_8kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xE000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xE000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 32KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.32_4" force-caption="true" workspace-name="lufa_ms_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x6810"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x6800"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 16KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.16_4" force-caption="true" workspace-name="lufa_ms_16kb_4kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x2810"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x2800"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.mass_storage" caption="Mass Storage Bootloader">
|
||||
<info type="description" value="summary">
|
||||
Mass Storage Class Bootloader, capable of reprogramming a device via binary BIN files copied to the virtual FAT12 file-system it creates when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderMassStorage.c"/>
|
||||
<build type="header-file" value="BootloaderMassStorage.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
<build type="c-source" value="BootloaderAPI.c"/>
|
||||
<build type="header-file" value="BootloaderAPI.h"/>
|
||||
<build type="asm-source" value="BootloaderAPITable.S"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
<build type="header-file" value="Config/AppConfig.h"/>
|
||||
|
||||
<build type="include-path" value="Lib"/>
|
||||
<build type="header-file" value="Lib/VirtualFAT.h"/>
|
||||
<build type="c-source" value="Lib/VirtualFAT.c"/>
|
||||
<build type="header-file" value="Lib/SCSI.h"/>
|
||||
<build type="c-source" value="Lib/SCSI.c"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderMassStorage.txt"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2365
protocol/lufa/LUFA-git/Bootloaders/MassStorage/doxyfile
Normal file
2365
protocol/lufa/LUFA-git/Bootloaders/MassStorage/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
68
protocol/lufa/LUFA-git/Bootloaders/MassStorage/makefile
Normal file
68
protocol/lufa/LUFA-git/Bootloaders/MassStorage/makefile
Normal file
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# 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 = BootloaderMassStorage
|
||||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S Lib/SCSI.c Lib/VirtualFAT.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)
|
||||
|
||||
# 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))) )
|
||||
|
||||
# Bootloader linker section flags for relocating the API table sections to
|
||||
# known FLASH addresses - these should not normally be user-edited.
|
||||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
|
||||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
|
||||
|
||||
# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the
|
||||
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum
|
||||
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices.
|
||||
ifeq ($(BOOT_SECTION_SIZE_KB),8)
|
||||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE=0
|
||||
else
|
||||
AUX_BOOT_SECTION_SIZE_KB = (6 - $(BOOT_SECTION_SIZE_KB))
|
||||
|
||||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE='($(AUX_BOOT_SECTION_SIZE_KB) * 1024)'
|
||||
LD_FLAGS += -Wl,--section-start=.boot_aux=$(call BOOT_SEC_OFFSET, (($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024 - 16))
|
||||
LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .boot_aux_trampoline, Boot_AUX_Trampoline, ($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024)
|
||||
endif
|
||||
|
||||
# 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…
Add table
Add a link
Reference in a new issue