aboutsummaryrefslogtreecommitdiffstats
path: root/Bootloaders
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2013-07-06 12:26:33 +0200
committerDean Camera <dean@fourwalledcubicle.com>2013-07-06 12:26:33 +0200
commit8cfa2e802332957d461dadfca156a847cf8f0cc3 (patch)
tree8b1d5d431c0c0e6757691a319e36677bed948db3 /Bootloaders
parentf0c72df67452dc1e921ee3673a37b26cbc408c34 (diff)
downloadlufa-8cfa2e802332957d461dadfca156a847cf8f0cc3.tar.gz
lufa-8cfa2e802332957d461dadfca156a847cf8f0cc3.tar.bz2
lufa-8cfa2e802332957d461dadfca156a847cf8f0cc3.zip
Add automatic application start on virtual disk ejection to the Mass Storage class bootloader.
Diffstat (limited to 'Bootloaders')
-rw-r--r--Bootloaders/MassStorage/BootloaderMassStorage.c47
-rw-r--r--Bootloaders/MassStorage/BootloaderMassStorage.h13
-rw-r--r--Bootloaders/MassStorage/BootloaderMassStorage.txt12
-rw-r--r--Bootloaders/MassStorage/Config/AppConfig.h47
-rw-r--r--Bootloaders/MassStorage/Lib/SCSI.c6
-rw-r--r--Bootloaders/MassStorage/Lib/SCSI.h1
6 files changed, 119 insertions, 7 deletions
diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.c b/Bootloaders/MassStorage/BootloaderMassStorage.c
index 28f42b6d2..1b6eda438 100644
--- a/Bootloaders/MassStorage/BootloaderMassStorage.c
+++ b/Bootloaders/MassStorage/BootloaderMassStorage.c
@@ -33,6 +33,7 @@
* 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
@@ -60,7 +61,30 @@ USB_ClassInfo_MS_Device_t Disk_MS_Interface =
},
};
+/** 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;
@@ -90,6 +114,13 @@ void Application_Jump_Check(void)
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
@@ -107,11 +138,22 @@ int main(void)
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
GlobalInterruptEnable();
- for (;;)
+ 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. */
@@ -189,5 +231,8 @@ bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSI
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
+ /* Signal that a command was processed, must not exit bootloader yet */
+ TicksSinceLastCommand = 0;
+
return CommandSuccess;
}
diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.h b/Bootloaders/MassStorage/BootloaderMassStorage.h
index 1fcce9063..d8271ea54 100644
--- a/Bootloaders/MassStorage/BootloaderMassStorage.h
+++ b/Bootloaders/MassStorage/BootloaderMassStorage.h
@@ -44,6 +44,7 @@
#include <string.h>
#include "Descriptors.h"
+ #include "Config/AppConfig.h"
#include "Lib/SCSI.h"
@@ -72,11 +73,15 @@
/** 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;
- static void SetupHardware(void) AUX_BOOT_SECTION;
-
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
void EVENT_USB_Device_Connect(void) AUX_BOOT_SECTION;
@@ -86,5 +91,9 @@
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
diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.txt b/Bootloaders/MassStorage/BootloaderMassStorage.txt
index 85cbc6f63..f7b303858 100644
--- a/Bootloaders/MassStorage/BootloaderMassStorage.txt
+++ b/Bootloaders/MassStorage/BootloaderMassStorage.txt
@@ -191,9 +191,15 @@
*
* <table>
* <tr>
- * <td>
- * None
- * </td>
+ * <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>
*/
diff --git a/Bootloaders/MassStorage/Config/AppConfig.h b/Bootloaders/MassStorage/Config/AppConfig.h
new file mode 100644
index 000000000..ada237153
--- /dev/null
+++ b/Bootloaders/MassStorage/Config/AppConfig.h
@@ -0,0 +1,47 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaims all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief 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
diff --git a/Bootloaders/MassStorage/Lib/SCSI.c b/Bootloaders/MassStorage/Lib/SCSI.c
index eeb2c252a..3bb868ccc 100644
--- a/Bootloaders/MassStorage/Lib/SCSI.c
+++ b/Bootloaders/MassStorage/Lib/SCSI.c
@@ -113,8 +113,12 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case SCSI_CMD_MODE_SENSE_6:
CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo);
break;
- case SCSI_CMD_SEND_DIAGNOSTIC:
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:
diff --git a/Bootloaders/MassStorage/Lib/SCSI.h b/Bootloaders/MassStorage/Lib/SCSI.h
index 8eb817fa7..afed5a664 100644
--- a/Bootloaders/MassStorage/Lib/SCSI.h
+++ b/Bootloaders/MassStorage/Lib/SCSI.h
@@ -42,6 +42,7 @@
#include <LUFA/Drivers/USB/USB.h>
+ #include "../BootloaderMassStorage.h"
#include "../Descriptors.h"
#include "VirtualFAT.h"