Be doubly-certain that the incomming CDC class driver's endpoint/pipe is flushed...
[pub/USBasp.git] / Bootloaders / TeensyHID / TeensyHID.c
index 12d5c0d..6cacfaf 100644 (file)
@@ -1,21 +1,21 @@
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
+     Copyright (C) Dean Camera, 2010.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
+  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this \r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in \r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting \r
+  documentation, and that the name of the author not be used in \r
+  advertising or publicity pertaining to distribution of the \r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
  *  Main source file for the TeensyHID bootloader. This file contains the complete bootloader logic.\r
  */\r
  \r
-#define  INCLUDE_FROM_TEENSYHID_C\r
 #include "TeensyHID.h"\r
 \r
-/* Global Variables: */\r
 /** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run\r
  *  via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application\r
  *  started via a forced watchdog reset.\r
  */\r
 bool RunBootloader = true;\r
 \r
-\r
 /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously \r
  *  runs the bootloader processing routine until instructed to soft-exit.\r
  */\r
@@ -55,15 +52,12 @@ int main(void)
        while (RunBootloader)\r
          USB_USBTask();\r
        \r
-       /* Reset all configured hardware to their default states for the user app */\r
-       ResetHardware();\r
-\r
-       /* Wait 100ms to give the host time to register the disconnection */\r
-       _delay_ms(100);\r
+       /* Disconnect from the host - USB interface will be reset later along with the AVR */\r
+       USB_Detach();\r
 \r
        /* Enable the watchdog and force a timeout to reset the AVR */\r
        wdt_enable(WDTO_250MS);\r
-                                       \r
+\r
        for (;;);\r
 }\r
 \r
@@ -85,17 +79,10 @@ void SetupHardware(void)
        USB_Init();\r
 }\r
 \r
-/** Resets all configured hardware required for the bootloader back to their original states. */\r
-void ResetHardware(void)\r
-{\r
-       /* Shut down the USB subsystem */\r
-       USB_ShutDown();\r
-}\r
-\r
 /** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready\r
  *  to relay data to and from the attached USB host.\r
  */\r
-void EVENT_USB_ConfigurationChanged(void)\r
+void EVENT_USB_Device_ConfigurationChanged(void)\r
 {\r
        /* Setup HID Report Endpoint */\r
        Endpoint_ConfigureEndpoint(HID_EPNUM, EP_TYPE_INTERRUPT,\r
@@ -103,65 +90,60 @@ void EVENT_USB_ConfigurationChanged(void)
                                   ENDPOINT_BANK_SINGLE);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
+/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific\r
  *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
  *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
  */\r
-void EVENT_USB_UnhandledControlPacket(void)\r
+void EVENT_USB_Device_UnhandledControlRequest(void)\r
 {\r
        /* Handle HID Class specific requests */\r
        switch (USB_ControlRequest.bRequest)\r
        {\r
                case REQ_SetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       Endpoint_ClearSETUP();\r
+                       \r
+                       /* Wait until the command has been sent by the host */\r
+                       while (!(Endpoint_IsOUTReceived()));\r
+               \r
+                       /* Read in the write destination address */\r
+                       uint16_t PageAddress = Endpoint_Read_Word_LE();\r
+                       \r
+                       /* Check if the command is a program page command, or a start application command */\r
+                       if (PageAddress == TEENSY_STARTAPPLICATION)\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Wait until the command (report) has been sent by the host */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-\r
-                               /* Read in the write destination address */\r
-                               uint16_t PageAddress = Endpoint_Read_Word_LE();\r
+                               RunBootloader = false;\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Erase the given FLASH page, ready to be programmed */\r
+                               boot_page_erase(PageAddress);\r
+                               boot_spm_busy_wait();\r
                                \r
-                               /* Check if the command is a program page command, or a start application command */\r
-                               if (PageAddress == TEENSY_STARTAPPLICATION)\r
-                               {\r
-                                       RunBootloader = false;\r
-                               }\r
-                               else\r
+                               /* Write each of the FLASH page's bytes in sequence */\r
+                               for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)\r
                                {\r
-                                       /* Erase the given FLASH page, ready to be programmed */\r
-                                       boot_page_erase(PageAddress);\r
-                                       boot_spm_busy_wait();\r
-                                       \r
-                                       /* Write each of the FLASH page's bytes in sequence */\r
-                                       for (uint8_t PageByte = 0; PageByte < 128; PageByte += 2)\r
+                                       /* Check if endpoint is empty - if so clear it and wait until ready for next packet */\r
+                                       if (!(Endpoint_BytesInEndpoint()))\r
                                        {\r
-                                               /* Check if endpoint is empty - if so clear it and wait until ready for next packet */\r
-                                               if (!(Endpoint_BytesInEndpoint()))\r
-                                               {\r
-                                                       Endpoint_ClearOUT();\r
-                                                       while (!(Endpoint_IsOUTReceived()));\r
-                                               }\r
-\r
-                                               /* Write the next data word to the FLASH page */\r
-                                               boot_page_fill(PageAddress + PageByte, Endpoint_Read_Word_LE());\r
+                                               Endpoint_ClearOUT();\r
+                                               while (!(Endpoint_IsOUTReceived()));\r
                                        }\r
 \r
-                                       /* Write the filled FLASH page to memory */\r
-                                       boot_page_write(PageAddress);\r
-                                       boot_spm_busy_wait();\r
-\r
-                                       /* Re-enable RWW section */\r
-                                       boot_rww_enable();\r
+                                       /* Write the next data word to the FLASH page */\r
+                                       boot_page_fill(PageAddress + PageByte, Endpoint_Read_Word_LE());\r
                                }\r
 \r
-                               Endpoint_ClearOUT();\r
+                               /* Write the filled FLASH page to memory */\r
+                               boot_page_write(PageAddress);\r
+                               boot_spm_busy_wait();\r
 \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
+                               /* Re-enable RWW section */\r
+                               boot_rww_enable();\r
                        }\r
+\r
+                       Endpoint_ClearOUT();\r
+\r
+                       Endpoint_ClearStatusStage();\r
                        \r
                        break;\r
        }\r