Commit 77cd3a42 authored by Dean Camera's avatar Dean Camera
Browse files

Fixed TeensyHID bootloader not enumerating to the host correctly.

parent b408a5fe
...@@ -52,12 +52,12 @@ int main(void) ...@@ -52,12 +52,12 @@ int main(void)
while (RunBootloader) while (RunBootloader)
USB_USBTask(); USB_USBTask();
/* Turn off the USB interface, disconnect from the host */ /* Disconnect from the host - USB interface will be reset later along with the AVR */
USB_ShutDown(); USB_Detach();
/* Enable the watchdog and force a timeout to reset the AVR */ /* Enable the watchdog and force a timeout to reset the AVR */
wdt_enable(WDTO_250MS); wdt_enable(WDTO_250MS);
for (;;); for (;;);
} }
...@@ -100,53 +100,50 @@ void EVENT_USB_Device_UnhandledControlRequest(void) ...@@ -100,53 +100,50 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
switch (USB_ControlRequest.bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SetReport: case REQ_SetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) Endpoint_ClearSETUP();
{
Endpoint_ClearSETUP();
/* Wait until the command has been sent by the host */
while (!(Endpoint_IsOUTReceived()));
/* Read in the write destination address */ /* Wait until the command has been sent by the host */
uint16_t PageAddress = Endpoint_Read_Word_LE(); while (!(Endpoint_IsOUTReceived()));
/* Read in the write destination address */
uint16_t PageAddress = Endpoint_Read_Word_LE();
/* Check if the command is a program page command, or a start application command */
if (PageAddress == TEENSY_STARTAPPLICATION)
{
RunBootloader = false;
}
else
{
/* Erase the given FLASH page, ready to be programmed */
boot_page_erase(PageAddress);
boot_spm_busy_wait();
/* Check if the command is a program page command, or a start application command */ /* Write each of the FLASH page's bytes in sequence */
if (PageAddress == TEENSY_STARTAPPLICATION) for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
{
RunBootloader = false;
}
else
{ {
/* Erase the given FLASH page, ready to be programmed */ /* Check if endpoint is empty - if so clear it and wait until ready for next packet */
boot_page_erase(PageAddress); if (!(Endpoint_BytesInEndpoint()))
boot_spm_busy_wait();
/* Write each of the FLASH page's bytes in sequence */
for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
{ {
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */ Endpoint_ClearOUT();
if (!(Endpoint_BytesInEndpoint())) while (!(Endpoint_IsOUTReceived()));
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()));
}
/* Write the next data word to the FLASH page */
boot_page_fill(PageAddress + PageByte, Endpoint_Read_Word_LE());
} }
/* Write the filled FLASH page to memory */ /* Write the next data word to the FLASH page */
boot_page_write(PageAddress); boot_page_fill(PageAddress + PageByte, Endpoint_Read_Word_LE());
boot_spm_busy_wait();
/* Re-enable RWW section */
boot_rww_enable();
} }
Endpoint_ClearOUT(); /* Write the filled FLASH page to memory */
boot_page_write(PageAddress);
boot_spm_busy_wait();
Endpoint_ClearStatusStage(); /* Re-enable RWW section */
boot_rww_enable();
} }
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
break; break;
} }
......
...@@ -49,11 +49,6 @@ ...@@ -49,11 +49,6 @@
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Preprocessor Checks: */
#if !defined(__AVR_AT90USB162__) && !defined(__AVR_AT90USB646__)
#error This bootloader is not compatible with the selected AVR model.
#endif
/* Macros: */ /* Macros: */
/** HID Class specific request to send the next HID report to the device. */ /** HID Class specific request to send the next HID report to the device. */
#define REQ_SetReport 0x09 #define REQ_SetReport 0x09
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - AT90USB646
* - AT90USB162 * - AT90USB162
* - ATMEGA32U4
* - AT90USB646
* - AT90USB1286
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
...@@ -47,7 +49,9 @@ ...@@ -47,7 +49,9 @@
* This bootloader enumerates to the host as a HID Class device, allowing for Teensy compatible programming * This bootloader enumerates to the host as a HID Class device, allowing for Teensy compatible programming
* software to load firmware onto the AVR, such as the official software at <a>http://www.pjrc.com/teensy/</a>. * software to load firmware onto the AVR, such as the official software at <a>http://www.pjrc.com/teensy/</a>.
* *
* Out of the box this bootloader builds for the AT90USB162, and will fit into 4KB of bootloader space. * Out of the box this bootloader builds for the ATMEGA32U4, and will fit into 4KB of bootloader space. For other
* devices, the makefile will need to be updated to reflect the altered MCU model and bootloader start address. When
* calculating the bootloader start address, use (TARGET_FLASH_SIZE_BYTES - 4096).
* *
* This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains * This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains
* compatible with no changes. * compatible with no changes.
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
# MCU name # MCU name
MCU = at90usb162 MCU = atmega32u4
# Target board (see library "Board Types" documentation, USER or blank for projects not requiring # Target board (see library "Board Types" documentation, USER or blank for projects not requiring
...@@ -98,7 +98,7 @@ F_CLOCK = $(F_CPU) ...@@ -98,7 +98,7 @@ F_CLOCK = $(F_CPU)
# Starting byte address of the bootloader # Starting byte address of the bootloader
BOOT_START = 0xC000 BOOT_START = 0x7000
# Output format. (can be srec, ihex, binary) # Output format. (can be srec, ihex, binary)
...@@ -121,7 +121,6 @@ LUFA_PATH = ../.. ...@@ -121,7 +121,6 @@ LUFA_PATH = ../..
# LUFA library compile-time options # LUFA library compile-time options
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D CONTROL_ONLY_DEVICE
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
* - Fixed Still Image Host Class driver truncating the PIMA response code (thanks to Daniel Seibert) * - Fixed Still Image Host Class driver truncating the PIMA response code (thanks to Daniel Seibert)
* - Fixed USB_CurrentMode not being reset to USB_MODE_NONE when the USB interface is shut down and both Host and Device modes can be * - Fixed USB_CurrentMode not being reset to USB_MODE_NONE when the USB interface is shut down and both Host and Device modes can be
* used (thanks to Daniel Levy) * used (thanks to Daniel Levy)
* - Fixed TeensyHID bootloader not enumerating to the host correctly
* *
* \section Sec_ChangeLog091122 Version 091122 * \section Sec_ChangeLog091122 Version 091122
* *
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment