From 1c0a06ffcddfe060e8e598dc327d80f5efd8dd33 Mon Sep 17 00:00:00 2001
From: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Date: Sat, 6 Dec 2014 22:00:00 +0100
Subject: [PATCH 1/2] tinyUSBboard specific patches for USBaspLoader updater

The updater is still a mess and would need a cleanup.
However, hack some API in there and just use it for now.
(Updates should be tested before rollen out to users!)

For the lack of stand-alone compilability: Copy some
stuff from the API library in here...

Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
---
 updater/Makefile       |  4 ++-
 updater/iocomfort.h    | 38 ++++++++++++++++++++++
 updater/tinyusbboard.h | 40 +++++++++++++++++++++++
 updater/updater.c      | 86 +++++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 162 insertions(+), 6 deletions(-)
 create mode 100644 updater/iocomfort.h
 create mode 100644 updater/tinyusbboard.h

diff --git a/updater/Makefile b/updater/Makefile
index db0cd8c..3b70028 100644
--- a/updater/Makefile
+++ b/updater/Makefile
@@ -8,7 +8,7 @@
 include ../Makefile.inc
 
 # elsewise gcc would complain unnecessary
-CFLAGS = -Wall -Wno-pointer-to-int-cast -Os -g3 -ggdb -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) -DBOOTLOADER_ADDRESS=$(BOOTLOADER_ADDRESS) -DNEW_BOOTLOADER_ADDRESS=$(NEW_BOOTLOADER_ADDRESS) -DFLASHADDRESS=$(FLASHADDRESS) $(DEFINES)
+CFLAGS = -Wall -Wno-pointer-to-int-cast -Os -g3 -ggdb -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -I../firmware -I../firmware/usbdrv -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) -DBOOTLOADER_ADDRESS=$(BOOTLOADER_ADDRESS) -DNEW_BOOTLOADER_ADDRESS=$(NEW_BOOTLOADER_ADDRESS) -DFLASHADDRESS=$(FLASHADDRESS) $(DEFINES)
 LDFLAGS = -Wl,--relax,--gc-sections
 
 DEPENDS =  ../firmware/bootloaderconfig.h ../Makefile.inc
@@ -76,6 +76,7 @@ updater.asm: updater.elf $(DEPENDS)
 
 updater.hex: updater.elf updater.asm $(DEPENDS)
 	$(OBC) -j .text -j .data -O ihex updater.elf updater.hex
+	$(OBC) -j .text -j .data -O binary updater.elf updater.raw
 	$(ECHO) "."
 	$(ECHO) "."
 	$(SIZ) updater.elf
@@ -88,6 +89,7 @@ clean:
 	$(RM) usbasploader.o
 	$(RM) updater.o
 	$(RM) usbasploader.raw
+	$(RM) updater.raw
 	$(RM) updater.hex
 	$(RM) updater.asm
 	$(RM) updater.elf
diff --git a/updater/iocomfort.h b/updater/iocomfort.h
new file mode 100644
index 0000000..2137e84
--- /dev/null
+++ b/updater/iocomfort.h
@@ -0,0 +1,38 @@
+
+#ifndef __IOCOMFORT_H_2cb70d020b7f4d83b020d6fd1be7cc27
+#define __IOCOMFORT_H_2cb70d020b7f4d83b020d6fd1be7cc27 1
+
+#define		_internal_LETTER_OF(letter, bit)	(letter)
+#define		LETTER_OF(arg)				_internal_LETTER_OF(arg)
+
+#define		_internal_BIT_OF(letter, bit)		(bit)
+#define		BIT_OF(arg)				_internal_BIT_OF(arg)
+
+
+#define		DEFCONCAT(a,b)				a ## b
+#define		DEFCONCAT3(a,b,c)			a ## b ## c
+
+#define		_internal_PORT_OF(letter, bit)		DEFCONCAT(PORT, letter)
+#define		_internal_DDR_OF(letter, bit)		DEFCONCAT(DDR, letter)
+#define		_internal_PIN_OF(letter, bit)		DEFCONCAT(PIN, letter)
+
+#define		PORT_OF(arg)				_internal_PORT_OF(arg)
+#define		DDR_OF(arg)				_internal_DDR_OF(arg)
+#define		PIN_OF(arg)				_internal_PIN_OF(arg)
+
+
+#ifndef _BV
+#	define _BV(x)	(1<<(x))
+#endif
+
+#define		CFG_INPUT(arg)				_internal_DDR_OF(arg)&=~(_BV(_internal_BIT_OF(arg)))
+#define		CFG_OUTPUT(arg)				_internal_DDR_OF(arg)|= (_BV(_internal_BIT_OF(arg)))
+
+#define		SET_LOW(arg)				_internal_PORT_OF(arg)&=~(_BV(_internal_BIT_OF(arg)))
+#define		SET_HIGH(arg)				_internal_PORT_OF(arg)|= (_BV(_internal_BIT_OF(arg)))
+#define		TOGGLE(arg)				_internal_PORT_OF(arg)^= (_BV(_internal_BIT_OF(arg)))
+
+#define		CFG_PULLUP(arg)				{_internal_DDR_OF(arg)&=~(_BV(_internal_BIT_OF(arg))); _internal_PORT_OF(arg)|= (_BV(_internal_BIT_OF(arg)));}
+#define		IS_PRESSED(arg)				(!(_internal_PIN_OF(arg) & (_BV(_internal_BIT_OF(arg)))))
+
+#endif
\ No newline at end of file
diff --git a/updater/tinyusbboard.h b/updater/tinyusbboard.h
new file mode 100644
index 0000000..ec45dad
--- /dev/null
+++ b/updater/tinyusbboard.h
@@ -0,0 +1,40 @@
+
+#ifndef _TINYUSBBOARD_H_85047c6162b94e2382447fe91aefb5e3
+#define _TINYUSBBOARD_H_85047c6162b94e2382447fe91aefb5e3 1
+
+
+#if (defined(ARDUINO) && (ARDUINO >= 100))
+#	define Pins_Arduino_h
+#	include "pins_arduino.h"
+#endif
+
+#include <avr/io.h>
+#include "iocomfort.h"
+
+#ifdef TINYUSBBOARD_REV2
+#	ifndef BUTTON_PROG
+#		define BUTTON_PROG	D,7
+#	endif
+#else
+#	ifndef BUTTON_PROG
+#		define BUTTON_PROG	D,6
+#	endif
+#endif
+
+#ifndef LED_B
+#	define LED_B		B,0
+#endif
+
+#ifndef LED_PWM
+#	define LED_PWM		B,1
+#endif
+
+#ifndef LED_LEFT
+#	define LED_LEFT		D,5
+#endif
+
+#ifndef LED_RIGHT
+#	define LED_RIGHT	D,3
+#endif
+
+#endif
diff --git a/updater/updater.c b/updater/updater.c
index 0f459e4..6652f9e 100644
--- a/updater/updater.c
+++ b/updater/updater.c
@@ -7,6 +7,12 @@
 #include "../firmware/spminterface.h"
 #include "usbasploader.h"
 
+#include "usbconfig.h"
+#undef USB_PUBLIC
+#define USB_PUBLIC
+#include "usbdrv.h"
+#include "tinyusbboard.h" /* taken from the API */
+
 // activate updaters full set of features
 #ifndef CONFIG_UPDATER_REDUCEWRITES
   #define CONFIG_UPDATER_REDUCEWRITES
@@ -275,6 +281,45 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const
 #include "crccheck.c"
 #endif
 
+/* taken from the API: */
+#undef __BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS
+#define __BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS ((NEW_BOOTLOADER_ADDRESS) >> 1)
+int8_t bootloader_startup(void) {
+  wdt_enable(WDTO_15MS);
+  wdt_reset();
+  asm volatile (
+    "cli					\n\t"
+    "ldi	r29 ,		%[ramendhi]	\n\t"
+    "ldi	r28 ,		%[ramendlo]	\n\t"
+#if (FLASHEND>131071)
+    "ldi	r18 ,		%[bootaddrhi]	\n\t"
+    "st		Y+, 		r18		\n\t"
+#endif
+    "ldi	r18 ,		%[bootaddrme]	\n\t"
+    "st		Y+,		r18		\n\t"
+    "ldi	r18 ,		%[bootaddrlo]	\n\t"
+    "st		Y+,		r18		\n\t"
+    "out	%[mcucsrio],	__zero_reg__	\n\t"
+    "bootloader_startup_loop%=:			\n\t"
+    "rjmp bootloader_startup_loop%=		\n\t"
+    : 
+    : [mcucsrio]	"I"	(_SFR_IO_ADDR(MCUCSR)),
+#if (FLASHEND>131071)
+      [ramendhi]	"M"	(((RAMEND - 2) >> 8) & 0xff),
+      [ramendlo]	"M"	(((RAMEND - 2) >> 0) & 0xff),
+      [bootaddrhi]	"M"	(((__BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS) >>16) & 0xff),
+#else
+      [ramendhi]	"M"	(((RAMEND - 1) >> 8) & 0xff),
+      [ramendlo]	"M"	(((RAMEND - 1) >> 0) & 0xff),
+#endif
+      [bootaddrme]	"M"	(((__BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS) >> 8) & 0xff),
+      [bootaddrlo]	"M"	(((__BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS) >> 0) & 0xff)
+  );
+
+  return -1;
+};
+
+
 // #pragma GCC diagnostic ignored "-Wno-pointer-to-int-cast"
 int main(void)
 {
@@ -284,19 +329,31 @@ int main(void)
     size_t  i;
     uint8_t buffer[SPM_PAGESIZE];
     
-    MCUCSR = 0; /* do not care about previous reset - just disable the wdt */
+    i=MCUCSR;
+    MCUCSR = 0;
     wdt_disable();
+    usbDeviceDisconnect();
     cli();
 
+    CFG_PULLUP(BUTTON_PROG);
+
+    CFG_OUTPUT(LED_B);
+    CFG_OUTPUT(LED_PWM);
+    CFG_OUTPUT(LED_LEFT);
+    CFG_OUTPUT(LED_RIGHT);
+
+    SET_HIGH(LED_LEFT);
+
+    if ((i & _BV(WDRF))==0) {
 #if defined(UPDATECRC32)
     // check if new firmware-image is corrupted
     crcval = D_32;
     for (i=0;i<SIZEOF_new_firmware;i+=1) {
-#if (FLASHEND > 65535)
+#	if (FLASHEND > 65535)
       crcval = update_crc_32(crcval, pgm_read_byte_far(FULLCORRECTFLASHADDRESS(&new_firmware[i])));
-#else
+#	else
       crcval = update_crc_32(crcval, pgm_read_byte(FULLCORRECTFLASHADDRESS(&new_firmware[i])));
-#endif
+#	endif
     }
     crcval ^= D_32;
 
@@ -359,12 +416,31 @@ int main(void)
       }
 
 
-
+      SET_HIGH(LED_PWM);
     }
 
 #if defined(UPDATECRC32)
     }
 #endif
+    SET_HIGH(LED_B);
+#define UPDATEREBOOTDELAY 96
+    for (i=UPDATEREBOOTDELAY;i>0;i--) {
+      uint16_t j=i;
+      for (j=5+(j*3);j>0;j--) {
+	_delay_ms(1);
+	if (IS_PRESSED(BUTTON_PROG)) {
+	  i=UPDATEREBOOTDELAY;
+	  SET_LOW(LED_RIGHT);
+	  while (IS_PRESSED(BUTTON_PROG));
+	}
+      }
+      TOGGLE(LED_RIGHT);
+    }
+    bootloader_startup();
+    }
+
+    SET_HIGH(LED_RIGHT); /* indicate error */
+    while (1) wdt_reset();
 
     return 0;
 }
-- 
2.0.4


From a258043032133b5812ee1f111ac568d6b0d49e57 Mon Sep 17 00:00:00 2001
From: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Date: Sat, 6 Dec 2014 23:00:00 +0100
Subject: [PATCH 2/2] tinyUSBboard specific patches for USBaspLoader firmware

In order to match the correct size requirements, this firmware
needs to be build with avr-gcc version 4.8.1

	avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.3_1072) 4.8.1

Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
---
 Makefile.inc                |   8 ++-
 firmware/bootloaderconfig.h |  46 ++++++++++++--
 firmware/spminterface.h     | 152 ++++++++++++++++++++++++++++++++++++++++++++
 firmware/usbconfig.h        |  10 ++-
 4 files changed, 209 insertions(+), 7 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index e22133d..914ea60 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -12,7 +12,13 @@ DEVICE = atmega8
 FLASHADDRESS = 0x0000
 
 # use any fix (ATxmega compatible) crc32, uncomment to disable feature or set automatically with value "0"
-;UPDATECRC32  = 0
+UPDATECRC32  = 0
+
+# tinyUSBboard revision to build
+DEFINES += -DTINYUSBBOARD_REV3
+
+# build bootloader with internal credits - needs avr-gcc version 4.8.1 and 16MHz
+DEFINES += -DTINYUSBBOARD_WITHCREDITS
 
 # some MCU independent defines...
 #...will be extended within MCU dependend configuration below...
diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h
index b9428d1..a30bba7 100644
--- a/firmware/bootloaderconfig.h
+++ b/firmware/bootloaderconfig.h
@@ -69,9 +69,19 @@ these macros are defined, the boot loader usees them.
  * So abstract "USB_CFG_DPLUS_BIT" to this one here.
  */
 
+#ifdef TINYUSBBOARD_REV1
+#	ifndef TINYUSBBOARD_REV2
+#		define TINYUSBBOARD_REV2
+#	endif
+#endif
+
 #ifndef USB_CFG_DMINUS_BIT
-  /* This is Revision 3 and later (where PD6 and PD7 were swapped */
-  #define USB_CFG_DMINUS_BIT      7    /* Rev.2 and previous was 6 */
+#	ifdef TINYUSBBOARD_REV2
+    #define USB_CFG_DMINUS_BIT      6
+#	else
+    /* This is Revision 3 and later (where PD6 and PD7 were swapped */
+    #define USB_CFG_DMINUS_BIT      7    /* Rev.2 and previous was 6 */
+#	endif
 #endif
 /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
  * This may be any bit in the port.
@@ -90,8 +100,12 @@ these macros are defined, the boot loader usees them.
  * jumper is connected to this port
  */
 #ifndef JUMPER_BIT
-  /* This is Revision 3 and later (where PD6 and PD7 were swapped */
-  #define JUMPER_BIT           6       /* Rev.2 and previous was 7 */
+#	ifdef TINYUSBBOARD_REV2
+    #define JUMPER_BIT           7
+#	else
+    /* This is Revision 3 and later (where PD6 and PD7 were swapped */
+    #define JUMPER_BIT           6       /* Rev.2 and previous was 7 */
+#	endif
 #endif
 /* 
  * jumper is connected to this bit in port "JUMPER_PORT", active low
@@ -167,7 +181,29 @@ these macros are defined, the boot loader usees them.
  */
 
 /* all boards should use a magic to make it safe to confuse updatefiles :-)  */
-#define HAVE_SPMINTEREFACE_MAGICVALUE    0
+#ifdef TINYUSBBOARD_REV2
+#	if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe65a980
+#	else
+#		error tinyUSBboard rev2 only is implemented for ATmega8, yet
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0
+#	endif
+#else
+#	if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe9a5680
+#	elif defined (__AVR_ATmega328P__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe9a5680
+#	elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe9a5682
+#	elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe9a5683
+#	elif defined (__AVR_ATmega328__)
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0xfe6a5984
+#	else
+#		warning unknown tinyUSBboard
+#		define HAVE_SPMINTEREFACE_MAGICVALUE    0
+#	endif
+#endif
 /* If this feature is enabled (value != 0), the configured 32bit value is 
  * used as a magic value within spminterface. "bootloader__do_spm" will check
  * additional four (4) registers for this value and only proceed, if they contain
diff --git a/firmware/spminterface.h b/firmware/spminterface.h
index c1e8132..7d80460 100644
--- a/firmware/spminterface.h
+++ b/firmware/spminterface.h
@@ -94,6 +94,7 @@ ret
 #	include <avr/io.h>
 #endif
 
+#include <avr/pgmspace.h>
 
 /*
  * This MACRO commands the linker to place correspondig
@@ -456,6 +457,11 @@ void do_spm(const uint32_t flash_byteaddress, const uint8_t spmcrval, const uint
   #error undefined device selection - this should not happen! 
 #endif
 
+#ifdef TINYUSBBOARD_WITHCREDITS
+#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+const char credits[] BOOTLIBLINK = "USB v0.97.1, by Stephan Baerwolf";
+#endif
+#endif
 //assume  SPMCR==0x37, SPMEN==0x0, RWWSRE=0x4, RWWSB=0x6
 #if HAVE_SPMINTEREFACE_MAGICVALUE
 const uint16_t bootloader__do_spm[23] BOOTLIBLINK = {
@@ -515,6 +521,13 @@ const uint16_t bootloader__do_spm[15] BOOTLIBLINK = {
   #error undefined device selection - this should not happen! 
 #endif
 
+#ifdef TINYUSBBOARD_WITHCREDITS
+#if defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__)
+const char credits[] BOOTLIBLINK = "USBaspLoader v0.97.1, by Stephan Baerwolf in Schwansee";
+#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__)
+const char credits[] BOOTLIBLINK = "USB v0.97.1, by Stephan Baerwolf";
+#endif
+#endif
 //assume  SPMCR:=SPMCSR==0x37, SPMEN:=SELFPRGEN==0x0, RWWSRE=0x4, RWWSB=0x6
 #if HAVE_SPMINTEREFACE_MAGICVALUE
 const uint16_t bootloader__do_spm[23] BOOTLIBLINK = {
@@ -577,6 +590,145 @@ const uint16_t bootloader__do_spm[15] BOOTLIBLINK = {
   #error undefined device selection - this should not happen! 
 #endif
 
+#ifdef TINYUSBBOARD_WITHCREDITS
+#if defined (__AVR_ATmega328P__)
+const char credits[] BOOTLIBLINK = "USBaspLoader v0.97.1, by Stephan Baerwolf (matrixstorm@gmx.de), Schwansee 2014";
+
+const uint8_t freespace[] BOOTLIBLINK = {0xff, 0xff, 0xff, 0xff};
+#elif defined (__AVR_ATmega328__)
+const char credits[] BOOTLIBLINK = "USBaspLoader v0.97.1, by Stephan Baerwolf (matrixstorm@gmx.de), Schwansee 2014";
+
+const uint8_t freespace[] BOOTLIBLINK = {0xff, 0xff, 0xff, 0xff};
+#endif
+const uint8_t finalfreespace[] BOOTLIBLINK = {
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+#endif
+
 //assume  SPMCR:=SPMCSR==0x37, SPMEN:=SELFPRGEN==0x0, RWWSRE=0x4, RWWSB=0x6
 #if HAVE_SPMINTEREFACE_MAGICVALUE
 const uint16_t bootloader__do_spm[23] BOOTLIBLINK = {
diff --git a/firmware/usbconfig.h b/firmware/usbconfig.h
index 618d79b..868b1ff 100644
--- a/firmware/usbconfig.h
+++ b/firmware/usbconfig.h
@@ -164,7 +164,15 @@
 /* define this macro to 1 if you want the function usbMeasureFrameLength()
  * compiled in. This function can be used to calibrate the AVR's RC oscillator.
  */
-#define USB_USE_FAST_CRC                0
+#if (FLASHEND > 16384)
+#	define USB_USE_FAST_CRC                1
+#else
+#	if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+#		define USB_USE_FAST_CRC                1
+#	else
+#		define USB_USE_FAST_CRC                0
+#	endif
+#endif
 /* The assembler module has two implementations for the CRC algorithm. One is
  * faster, the other is smaller. This CRC routine is only used for transmitted
  * messages where timing is not critical. The faster routine needs 31 cycles
-- 
2.0.4

