Merge tag 'LUFA-170418' into ProMicro
authorPeter Henn <Peter.Henn@web.de>
Wed, 29 Dec 2021 12:10:53 +0000 (12:10 +0000)
committerPeter Henn <Peter.Henn@web.de>
Wed, 29 Dec 2021 13:42:06 +0000 (13:42 +0000)
- use merge strategy "theirs", means in principle rebase ProMicro branch
  to LUFA-170418
- remove the wrong FUSE_BOOTRST check in Application_Jump_Check
  which was added in the meantime

1  2 
Bootloaders/DFU/BootloaderDFU.c
Bootloaders/DFU/BootloaderDFU.h
Bootloaders/DFU/makefile
LUFA/StudioIntegration/lufa_toolchain.xml
LUFA/StudioIntegration/makefile

@@@ -1,13 -1,13 +1,13 @@@
  /*
               LUFA Library
-      Copyright (C) Dean Camera, 2013.
+      Copyright (C) Dean Camera, 2017.
  
    dean [at] fourwalledcubicle [dot] com
             www.lufa-lib.org
  */
  
  /*
-   Copyright 2013  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+   Copyright 2017  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
@@@ -108,7 -108,17 +108,17 @@@ void Application_Jump_Check(void
  {
        bool JumpToApplication = false;
  
-       #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+       #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();
  
                Delay_MS(10);
  
                /* If the TCK pin is not jumpered to ground, start the user application instead */
-               JumpToApplication |= ((PINF & (1 << 4)) != 0);
+               JumpToApplication = ((PINF & (1 << 4)) != 0);
  
                /* Re-enable JTAG debugging */
                JTAG_ENABLE();
 -              /* Check if the device's BOOTRST fuse is set */
 -              if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
 -              {
 -                      /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
 -                      if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
 -                        JumpToApplication = true;
 -
 -                      /* Clear reset source */
 -                      MCUSR &= ~(1 << EXTRF);
 -              }
 -              else
+       #else
+               {
+                       /* If the reset source was the bootloader and the key is correct, clear it and jump to the application;
+                        * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */
+                       if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
+                               JumpToApplication = true;
+                       /* Clear reset source */
+                       MCUSR &= ~(1 << WDRF);
+               }
        #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))
-         JumpToApplication |= true;
+       /* Don't run the user application if the reset vector is blank (no app loaded) */
+       bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
  
        /* If a request has been made to jump to the user application, honor it */
-       if (JumpToApplication)
+       if (JumpToApplication && ApplicationValid)
        {
                /* Turn off the watchdog */
-               MCUSR &= ~(1<<WDRF);
-               wdt_disable(); 
+               MCUSR &= ~(1 << WDRF);
+               wdt_disable();
  
                /* Clear the boot key and jump to the user application */
                MagicBootKey = 0;
        }
  }
  
 +
 +static volatile bool stayinbootloader;
 +
  /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
   *  runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
   *  the loaded application code.
@@@ -155,42 -182,14 +174,42 @@@ int main(void
        SetupHardware();
  
        /* Turn on first LED on the board to indicate that the bootloader has started */
 -      LEDs_SetAllLEDs(LEDS_LED1);
 +      //LEDs_SetAllLEDs(LEDS_LED1);
  
        /* Enable global interrupts so that the USB stack can function */
        GlobalInterruptEnable();
  
        /* Run the USB management task while the bootloader is supposed to be running */
 +      /*if bit_is_clear(PINB,PB5)     // PB5 is Digital 9 on Arduino Pro Micro
 +      {
 +              loop_until_bit_is_set(PINB,PB5);
 +
 +              while ((RunBootloader || WaitForExit) && bit_is_set(PINB,PB5))
 +                      USB_USBTask();
 +
 +              loop_until_bit_is_clear(PINB,PB5);
 +      }*/
 +
 +      stayinbootloader = false;
 +
 +      uint16_t i = 0;
        while (RunBootloader || WaitForExit)
 -        USB_USBTask();
 +      {
 +              USB_USBTask();
 +
 +              if (!stayinbootloader)
 +              {
 +                      _delay_ms(1);
 +                      if (i++ > 5000)
 +                      {
 +                              break;
 +                      }
 +              }
 +              else
 +              {
 +                      i = 0;
 +              }
 +      }
  
        /* Reset configured hardware back to their original states for the user application */
        ResetHardware();
@@@ -215,11 -214,7 +234,11 @@@ static void SetupHardware(void
  
        /* Initialize the USB and other board hardware drivers */
        USB_Init();
 -      LEDs_Init();
 +      //LEDs_Init();
 +      DDRB = 1;
 +      PORTB = _BV(PB5);
 +      DDRD = 0b00100000;
 +      PORTD = 0;
  
        /* Bootloader active LED toggle timer initialization */
        TIMSK1 = (1 << TOIE1);
@@@ -231,12 -226,8 +250,12 @@@ static void ResetHardware(void
  {
        /* Shut down the USB and other board hardware drivers */
        USB_Disable();
 -      LEDs_Disable();
 +      //LEDs_Disable();
 +      DDRB = 0;
 +      PORTB = 0;
 +      DDRD = 0;
 +      PORTD = 0;
-       
        /* Disable Bootloader active LED toggle timer */
        TIMSK1 = 0;
        TCCR1B = 0;
  /** 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);
 +      //LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
 +      PORTB &= ~_BV(PB0);
 +      _delay_ms(5);
 +      PORTB |= _BV(PB0);
  }
  
  /** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
@@@ -268,13 -256,8 +287,13 @@@ void EVENT_USB_Device_ControlRequest(vo
                return;
        }
  
 +stayinbootloader = true;
 +
        /* Activity - toggle indicator LEDs */
 -      LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
 +      //LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
 +      PORTB &= ~_BV(PB0);
 +      _delay_ms(5);
 +      PORTB |= _BV(PB0);
  
        /* Get the size of the command and data from the wLength value */
        SentCommand.DataSize = USB_ControlRequest.wLength;
                                                        }
  
                                                        /* Read the byte from the USB interface and write to to the EEPROM */
-                                                       eeprom_write_byte((uint8_t*)StartAddr, Endpoint_Read_8());
+                                                       eeprom_update_byte((uint8_t*)StartAddr, Endpoint_Read_8());
  
                                                        /* Adjust counters */
                                                        StartAddr++;
                case DFU_REQ_GETSTATUS:
                        Endpoint_ClearSETUP();
  
+                       while (!(Endpoint_IsINReady()))
+                       {
+                               if (USB_DeviceState == DEVICE_STATE_Unattached)
+                                 return;
+                       }
                        /* Write 8-bit status value */
                        Endpoint_Write_8(DFU_Status);
  
                case DFU_REQ_GETSTATE:
                        Endpoint_ClearSETUP();
  
+                       while (!(Endpoint_IsINReady()))
+                       {
+                               if (USB_DeviceState == DEVICE_STATE_Unattached)
+                                 return;
+                       }
                        /* Write the current device state to the endpoint */
                        Endpoint_Write_8(DFU_State);
  
@@@ -786,8 -781,9 +817,9 @@@ static void ProcessWriteCommand(void
                        }
                        else                                                               // Start via jump
                        {
-                               /* Set the flag to terminate the bootloader at next opportunity */
-                               RunBootloader = false;
+                               /* Set the flag to terminate the bootloader at next opportunity if a valid application has been loaded */
+                               if (pgm_read_word_near(0) == 0xFFFF)
+                                 RunBootloader = false;
                        }
                }
        }
  static void ProcessReadCommand(void)
  {
        const uint8_t BootloaderInfo[3] = {BOOTLOADER_VERSION, BOOTLOADER_ID_BYTE1, BOOTLOADER_ID_BYTE2};
-       const uint8_t SignatureInfo[3]  = {AVR_SIGNATURE_1,    AVR_SIGNATURE_2,     AVR_SIGNATURE_3};
+       const uint8_t SignatureInfo[4]  = {0x58, AVR_SIGNATURE_1, AVR_SIGNATURE_2, AVR_SIGNATURE_3};
  
-       uint8_t DataIndexToRead = SentCommand.Data[1];
+       uint8_t DataIndexToRead    = SentCommand.Data[1];
+       bool    ReadAddressInvalid = false;
  
-       if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00))                         // Read bootloader info
-         ResponseByte = BootloaderInfo[DataIndexToRead];
+       if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00))                        // Read bootloader info
+       {
+               if (DataIndexToRead < 3)
+                 ResponseByte = BootloaderInfo[DataIndexToRead];
+               else
+                 ReadAddressInvalid = true;
+       }
        else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01))                    // Read signature byte
-         ResponseByte = SignatureInfo[DataIndexToRead - 0x30];
- }
+       {
+               switch (DataIndexToRead)
+               {
+                       case 0x30:
+                               ResponseByte = SignatureInfo[0];
+                               break;
+                       case 0x31:
+                               ResponseByte = SignatureInfo[1];
+                               break;
+                       case 0x60:
+                               ResponseByte = SignatureInfo[2];
+                               break;
+                       case 0x61:
+                               ResponseByte = SignatureInfo[3];
+                               break;
+                       default:
+                               ReadAddressInvalid = true;
+                               break;
+               }
+       }
  
+       if (ReadAddressInvalid)
+       {
+               /* Set the state and status variables to indicate the error */
+               DFU_State  = dfuERROR;
+               DFU_Status = errADDRESS;
+       }
+ }
@@@ -1,13 -1,13 +1,13 @@@
  /*
               LUFA Library
-      Copyright (C) Dean Camera, 2013.
+      Copyright (C) Dean Camera, 2017.
  
    dean [at] fourwalledcubicle [dot] com
             www.lufa-lib.org
  */
  
  /*
-   Copyright 2013  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+   Copyright 2017  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
                #include "Config/AppConfig.h"
  
                #include <LUFA/Drivers/USB/USB.h>
 -              #include <LUFA/Drivers/Board/LEDs.h>
 +              //#include <LUFA/Drivers/Board/LEDs.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: */
                /** Major bootloader version number. */
@@@ -60,9 -66,9 +66,9 @@@
  
                /** Minor bootloader version number. */
                #define BOOTLOADER_VERSION_REV   0
-               
                /** Magic bootloader key to unlock forced application start mode. */
-               #define MAGIC_BOOT_KEY            0xDC42
+               #define MAGIC_BOOT_KEY           0xDC42
  
                /** Complete bootloader version number expressed as a packed byte, constructed from the
                 *  two individual bootloader version macros.
                        dfuMANIFEST                  = 7,
                        dfuMANIFEST_WAIT_RESET       = 8,
                        dfuUPLOAD_IDLE               = 9,
-                       dfuERROR                         = 10
+                       dfuERROR                     = 10
                };
  
                /** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
                        errUSBR                      = 12,
                        errPOR                       = 13,
                        errUNKNOWN                   = 14,
-                       errSTALLEDPKT                = 15
+                       errSTALLEDPKT                = 15
                };
  
        /* Function Prototypes: */
                        static void ProcessWriteCommand(void);
                        static void ProcessReadCommand(void);
                #endif
-               
                void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
  
  #endif
diff --combined Bootloaders/DFU/makefile
@@@ -1,6 -1,6 +1,6 @@@
  #
  #             LUFA Library
- #     Copyright (C) Dean Camera, 2013.
+ #     Copyright (C) Dean Camera, 2017.
  #
  #  dean [at] fourwalledcubicle [dot] com
  #           www.lufa-lib.org
@@@ -11,9 -11,9 +11,9 @@@
  
  # Run "make help" for target help.
  
 -MCU          = at90usb1287
 +MCU          = atmega32u4
  ARCH         = AVR8
 -BOARD        = USBKEY
 +BOARD        = USER
  F_CPU        = 8000000
  F_USB        = $(F_CPU)
  OPTIMIZATION = s
@@@ -26,30 -26,37 +26,37 @@@ LD_FLAGS     = -Wl,--section-start=.tex
  # 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
 +FLASH_SIZE_KB         = 32
 +BOOT_SECTION_SIZE_KB  = 4
  
  # 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)) )
+ 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=.apitable_$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=BootloaderAPI_$(strip $(2))
- BOOT_API_LD_FLAGS     = $(call BOOT_SECTION_LD_FLAG, trampolines, Trampolines, 96)
- BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, jumptable,   JumpTable,   32)
- BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, signatures,  Signatures,  8)
+ 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)
  
  # 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
+ # Include LUFA-specific DMBS extension modules
+ DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA
+ include $(DMBS_LUFA_PATH)/lufa-sources.mk
+ include $(DMBS_LUFA_PATH)/lufa-gcc.mk
+ # Include common DMBS build system modules
+ DMBS_PATH      ?= $(LUFA_PATH)/Build/DMBS/DMBS
+ include $(DMBS_PATH)/core.mk
+ include $(DMBS_PATH)/cppcheck.mk
+ include $(DMBS_PATH)/doxygen.mk
+ include $(DMBS_PATH)/dfu.mk
+ include $(DMBS_PATH)/gcc.mk
+ include $(DMBS_PATH)/hid.mk
+ include $(DMBS_PATH)/avrdude.mk
+ include $(DMBS_PATH)/atprogram.mk
@@@ -1,6 -1,6 +1,6 @@@
  <!--\r
               LUFA Library\r
-      Copyright (C) Dean Camera, 2013.\r
+      Copyright (C) Dean Camera, 2017.\r
  \r
    dean [at] fourwalledcubicle [dot] com\r
             www.lufa-lib.org\r
                                <toolchain-config name="avrgcc.compiler.optimization.OtherFlags" value="-fdata-sections" toolchain="avrgcc"/>\r
                                <toolchain-config name="avrgcc.compiler.optimization.PrepareFunctionsForGarbageCollection" value="True" toolchain="avrgcc"/>\r
                                <toolchain-config name="avrgcc.compiler.warnings.AllWarnings" value="True" toolchain="avrgcc"/>\r
-                               <toolchain-config name="avrgcc.compiler.miscellaneous.OtherFlags" value="-std=gnu99 -fno-strict-aliasing" toolchain="avrgcc"/>\r
+                               <toolchain-config name="avrgcc.compiler.miscellaneous.OtherFlags" value="-mrelax -std=gnu99 -fno-strict-aliasing -fno-jump-tables" toolchain="avrgcc"/>\r
                                <toolchain-config name="avrgcc.linker.optimization.GarbageCollectUnusedSections" value="True" toolchain="avrgcc"/>\r
                                <toolchain-config name="avrgcc.linker.optimization.RelaxBranches" value="True" toolchain="avrgcc"/>\r
 -                              <toolchain-config name="avrgcc.linker.miscellaneous.LinkerFlags" value="-Wl,--relax" toolchain="avrgcc"/>\r
                        </module>\r
                </select-by-device>\r
  \r
                        <toolchain-config name="avr32gcc.compiler.optimization.OtherFlags" value="-fdata-sections" toolchain="avr32gcc"/>\r
                        <toolchain-config name="avr32gcc.compiler.optimization.PrepareFunctionsForGarbageCollection" value="True" toolchain="avr32gcc"/>\r
                        <toolchain-config name="avr32gcc.compiler.warnings.AllWarnings" value="True" toolchain="avr32gcc"/>\r
-                       <toolchain-config name="avr32gcc.compiler.miscellaneous.OtherFlags" value="-std=gnu99 -fno-strict-aliasing -mno-cond-exec-before-reload" toolchain="avr32gcc"/>\r
+                       <toolchain-config name="avr32gcc.compiler.miscellaneous.OtherFlags" value="-mrelax -std=gnu99 -fno-strict-aliasing -mno-cond-exec-before-reload" toolchain="avr32gcc"/>\r
                        <toolchain-config name="avr32gcc.linker.optimization.GarbageCollectUnusedSections" value="True" toolchain="avr32gcc"/>\r
                        <toolchain-config name="avr32gcc.linker.optimization.RelaxBranches" value="True" toolchain="avr32gcc"/>\r
+                       <toolchain-config name="avr32gcc.linker.miscellaneous.LinkerFlags" value="-Wl,--relax" toolchain="avr32gcc"/>\r
                </module>\r
        </asf>\r
  </lufa>\r
@@@ -1,6 -1,6 +1,6 @@@
  #
  #             LUFA Library
- #     Copyright (C) Dean Camera, 2013.
+ #     Copyright (C) Dean Camera, 2017.
  #
  #  dean [at] fourwalledcubicle [dot] com
  #           www.lufa-lib.org
  # ---------------------------------------
  
  LUFA_ROOT            := ..
+ LUFA_VERSION_NUM     := $(shell grep -e "\#define *LUFA_VERSION_STRING " $(LUFA_ROOT)/Version.h | cut -d'"' -f2)
+ LUFA_VERSION_TYPE    := $(shell grep -e "\#define *LUFA_VERSION_RELEASE_TYPE " $(LUFA_ROOT)/Version.h)
+ ifneq ($(findstring LUFA_VERSION_RELEASE_TYPE_DEVELOPMENT, $(LUFA_VERSION_TYPE)),LUFA_VERSION_RELEASE_TYPE_DEVELOPMENT)
+   EXT_VERSION_NUM    := $(shell date +"%y.%m.%d").$(LUFA_VERSION_NUM)
+   EXT_VSIX_NAME      := LUFA-RELEASE-$(LUFA_VERSION_NUM).vsix
+ else
+   EXT_VERSION_NUM    := 0.$(shell date +"%y%m%d.%H%M%S")
+   EXT_VSIX_NAME      := LUFA-TESTING-$(shell date +"%y.%m.%d-%H.%M.%S").vsix
+   $(warning Development mode set - assuming a test version should be created.)
+ endif
  DOXYGEN_TAG_FILE_XML := $(LUFA_ROOT)/Documentation/lufa_doc_tags.xml
+ DOXYGEN_COMBINED_XML := $(LUFA_ROOT)/Documentation/xml/lufa_doc.xml
  TEMP_MANIFEST_XML    := manifest.xml
  EXTENSION_OUTPUT_XML := $(LUFA_ROOT)/../extension.xml
  MODULE_OUTPUT_XML    := $(LUFA_ROOT)/asf.xml
+ MSHELP_OUTPUT_XML    := $(LUFA_ROOT)/../lufa_help_$(subst .,_,$(EXT_VERSION_NUM)).mshc
  XML_FILES            := $(filter-out $(TEMP_MANIFEST_FILE), $(shell ls *.xml))
- LUFA_VERSION_NUM     := $(shell grep LUFA_VERSION_STRING $(LUFA_ROOT)/Version.h | cut -d'"' -f2)
- EXT_VERSION_NUM      := $(shell date +"%y.%m.%d").$(LUFA_VERSION_NUM)
- all: generate_xml check_filenames generate_vsix
+ VSIX_ASSETS          := $(LUFA_ROOT)/DoxygenPages/Images/LUFA_thumb.png     \
+                         $(LUFA_ROOT)/DoxygenPages/Images/LUFA.png           \
+                         $(LUFA_ROOT)/License.txt                            \
+                         VSIX/"[Content_Types].xml"                          \
+                         VSIX/LUFA.dll                                       \
+                         VSIX/LUFA.pkgdef
+ VSIX_GEN_PARAMS     := --stringparam extension-version "$(EXT_VERSION_NUM)" \
+                        --stringparam lufa-version "$(LUFA_VERSION_NUM)"     \
+                        --stringparam help-package-filename "$(notdir $(MSHELP_OUTPUT_XML))"
+ MSHELP_GEN_PARAMS   := --stringparam generate.toc "book toc"                \
+                        --stringparam chunk.quietly "1"                      \
+                        --stringparam chunk.section.depth "3"                \
+                        --stringparam chunk.first.sections "1"               \
+                        --stringparam chapter.autolabel "0"                  \
+                        --stringparam root.filename "LUFA"                   \
+                        --stringparam html.stylesheet "lufa_studio_help_styling.css"
+ all: clear_project_dirs generate_xml check_filenames generate_vsix
+ clear_project_dirs:
+       @make -s -C $(LUFA_ROOT)/.. clean
  
  clean:
-       @rm -f $(TEMP_MANIFEST_XML) $(MODULE_OUTPUT_XML) $(EXTENSION_OUTPUT_XML)
+       @rm -f $(TEMP_MANIFEST_XML) $(MODULE_OUTPUT_XML) $(EXTENSION_OUTPUT_XML) $(DOXYGEN_TAG_FILE_XML) $(DOXYGEN_COMBINED_XML) $(MSHELP_OUTPUT_XML)
+       @rm -rf mshelp
+       @cd $(LUFA_ROOT)/.. && rm -f contents.zip exampleProjects.xml content.xml.cache extension.vsixmanifest asf-manifest.xml extension.xml helpcontentsetup.msha $(notdir $(VSIX_ASSETS)) *.vsix *.mshc
  
  $(DOXYGEN_TAG_FILE_XML):
-       $(MAKE) -C ../ doxygen
+       @$(MAKE) -C ../ doxygen DOXYGEN_OVERRIDE_PARAMS="GENERATE_TAGFILE=Documentation/lufa_doc_tags.xml GENERATE_HTML=no GENERATE_XML=yes"
+ $(DOXYGEN_COMBINED_XML): $(DOXYGEN_TAG_FILE_XML)
+       @xsltproc $(dir $@)/combine.xslt $(dir $@)/index.xml > $(DOXYGEN_COMBINED_XML)
  
- $(TEMP_MANIFEST_XML): $(DOXYGEN_TAG_FILE_XML)
-       @echo "Generating Manifest XML..."
+ $(TEMP_MANIFEST_XML): $(DOXYGEN_TAG_FILE_XML) $(DOXYGEN_COMBINED_XML)
+       @echo Generating temporary module manifest XML...
  
-       @printf "<lufa-manifest version=\"%s\" tagfile=\"%s\">\n" $(LUFA_VERSION_NUM) $(DOXYGEN_TAG_FILE_XML) > $@
+       @printf "<lufa-manifest version=\"%s\" tagfile=\"%s\" docfile=\"%s\">\n" $(LUFA_VERSION_NUM) $(DOXYGEN_TAG_FILE_XML) $(DOXYGEN_COMBINED_XML) > $@
        @for i in $(XML_FILES); do \
                printf "\t<xml-source filename=\"%s\"/>\n" $$i >> $@; \
        done;
        @echo '</lufa-manifest>' >> $@
  
-       @echo "Manifest XML file generated."
+ $(MODULE_OUTPUT_XML): $(TEMP_MANIFEST_XML)
+       @echo Generating library core XDK module manifest file...
+       @xsltproc XDK/lufa_module_transform.xslt $< | xsltproc XDK/lufa_indent_transform.xslt - > $(MODULE_OUTPUT_XML)
+ $(EXTENSION_OUTPUT_XML): $(TEMP_MANIFEST_XML)
+       @echo Generating library XDK extension manifest file...
+       @xsltproc XDK/lufa_extension_transform.xslt $< | xsltproc XDK/lufa_indent_transform.xslt - > $(EXTENSION_OUTPUT_XML)
  
generate_xml: $(TEMP_MANIFEST_XML)
-       @echo "Processing asf.xml file..."
-       @xsltproc XSLT/lufa_module_transform.xslt $< | xsltproc XSLT/lufa_indent_transform.xslt - > $(MODULE_OUTPUT_XML)
-       @echo "Atmel Studio asf.xml file generated."
$(MSHELP_OUTPUT_XML): $(DOXYGEN_COMBINED_XML)
+       @echo Converting Doxygen XML to DocBook...
+       @-mkdir mshelp 2> /dev/null
+       @xsltproc HV1/lufa_docbook_transform.xslt $(DOXYGEN_COMBINED_XML) > mshelp/lufa_docbook.xml
  
-       @echo "Processing extension.xml file..."
-       @xsltproc XSLT/lufa_extension_transform.xslt $< | xsltproc XSLT/lufa_indent_transform.xslt - > $(EXTENSION_OUTPUT_XML)
-       @echo "Atmel Studio extension.xml file generated."
+       @echo Converting DocBook XML to Microsoft Help 1.0...
+       @cd mshelp && xsltproc $(MSHELP_GEN_PARAMS) ../HV1/lufa_hv1_transform.xslt lufa_docbook.xml
  
-       @rm $(TEMP_MANIFEST_XML)
+       @echo Copying help assets...
+       @cp HV1/lufa_studio_help_styling.css mshelp
+       @-mkdir mshelp/images 2> /dev/null
+       @cp `find $(LUFA_ROOT)/DoxygenPages/Images -type f` mshelp/images
  
- generate_vsix: $(EXTENSION_OUTPUT_XML) $(MODULE_OUTPUT_XML)
-       @echo "Generating ASF cache files..."
+       @echo Archiving help content...
+       @cd mshelp && zip ../$(MSHELP_OUTPUT_XML) -q -0  -r *.html *.css images
+       @echo Generating HV1 manifest...
+       @xsltproc $(VSIX_GEN_PARAMS) HV1/lufa_helpcontentsetup_transform.xslt HV1/helpcontentsetup.msha > $(LUFA_ROOT)/../helpcontentsetup.msha
+ generate_help: $(MSHELP_OUTPUT_XML)
+ generate_xml: $(EXTENSION_OUTPUT_XML) $(MODULE_OUTPUT_XML)
+ generate_vsix: $(EXTENSION_OUTPUT_XML) $(MODULE_OUTPUT_XML) $(MSHELP_OUTPUT_XML)
+       @echo Generating XDK cache files...
        @rm -f $(LUFA_ROOT)/../content.xml.cache
        @rm -f $(LUFA_ROOT)/../ExampleProjects.xml
-       @python generate_caches.py $(LUFA_ROOT)/../
+       @python VSIX/generate_caches.py $(LUFA_ROOT)/../
+       @echo Archiving XDK content...
+       @rm -f contents.zip
+       @cd $(LUFA_ROOT)/../ && zip contents.zip -q -0 -r --exclude=*Documentation* --exclude=*StudioIntegration* LUFA Bootloaders Demos Projects README.txt
  
-       @echo "Archiving Content..."
-       @cd $(LUFA_ROOT)/../ && zip contents.zip -q -0 -r --exclude=*Documentation* --exclude=*StudioIntegration* LUFA Bootloaders Demos Projects extension.xml README.txt
+       @echo Creating VSIX dependencies...
+       @cp $(VSIX_ASSETS) $(LUFA_ROOT)/..
+       @xsltproc $(VSIX_GEN_PARAMS) VSIX/lufa_vsmanifest_transform.xslt VSIX/extension.vsixmanifest > $(LUFA_ROOT)/../extension.vsixmanifest
+       @xsltproc $(VSIX_GEN_PARAMS) VSIX/lufa_asfmanifest_transform.xslt VSIX/asf-manifest.xml > $(LUFA_ROOT)/../asf-manifest.xml
  
-       @echo "Creating VSIX Dependencies..."
-       @cp $(LUFA_ROOT)/DoxygenPages/Images/LUFA_thumb.png $(LUFA_ROOT)/../PreviewThumb.png
-       @cp $(LUFA_ROOT)/DoxygenPages/Images/LUFA.png $(LUFA_ROOT)/../Preview.png
-       @cp $(LUFA_ROOT)/License.txt $(LUFA_ROOT)/../
-       @cp "VSIX/[Content_Types].xml" $(LUFA_ROOT)/../
-       @xsltproc --stringparam extension-version "$(EXT_VERSION_NUM)" XSLT/lufa_vsmanifest_transform.xslt VSIX/extension.vsixmanifest > $(LUFA_ROOT)/../extension.vsixmanifest
-       @xsltproc --stringparam lufa-version "$(LUFA_VERSION_NUM)" XSLT/lufa_asfmanifest_transform.xslt VSIX/asf-manifest.xml > $(LUFA_ROOT)/../asf-manifest.xml
+       @echo Generating Atmel Studio VSIX file...
+       cd $(LUFA_ROOT)/../ && zip $(EXT_VSIX_NAME) -q -9 contents.zip exampleProjects.xml content.xml.cache extension.vsixmanifest asf-manifest.xml extension.xml helpcontentsetup.msha $(notdir $(MSHELP_OUTPUT_XML)) $(notdir $(VSIX_ASSETS))
  
-       @echo "Generating Atmel Studio VSIX Extension file..."
-       @cd $(LUFA_ROOT)/../ && zip LUFA-$(LUFA_VERSION_NUM).vsix -q -9 contents.zip exampleProjects.xml content.xml.cache License.txt Preview.png PreviewThumb.png "[Content_Types].xml" extension.vsixmanifest asf-manifest.xml extension.xml
-       @echo "Atmel Studio VSIX Extension file generated."
+       @echo "Atmel Studio VSIX extension file generated."
  
  check_filenames: $(MODULE_OUTPUT_XML)
-       @echo Verifying referenced filenames of ASF.xml modules...
+       @echo Verifying referenced filenames of XDK modules...
        @for f in `find $(LUFA_ROOT)/../ -name "asf.xml"`; do \
                echo "Checking $$f..."; \
                asf_file_dir=`dirname $$f`; \
-               xsltproc XSLT/lufa_filelist_transform.xslt $$f | sed -e "/^$$/d" | while read -r i; do \
-                       if ( ! test -f "$$asf_file_dir/$$i" ); then \
+               xsltproc XDK/lufa_filelist_transform.xslt $$f | sed -e "/^$$/d" | while read -r i; do \
+                       if ( ( ! test -f "$$asf_file_dir/$$i" ) && ( ! test -d "$$asf_file_dir/$$i" ) ); then \
                                echo "Source file \"$$i\" referenced in $$f does not exist!"; \
                                exit 1; \
                        fi; \
                done || exit 1; \
        done;
 +      @echo Verified referenced filenames of ASF.xml modules.
  
- .PHONY: all clean generate_xml generate_vsix check_filenames
+ check_database:
+       python ProjectGenerator/project_generator.py -b $(LUFA_ROOT)/../ --main-ext-uuid=0e160d5c-e331-48d9-850b-e0387912171b CHECK
+ .PHONY: all clean generate_help generate_xml generate_vsix check_filenames check_database